Кастомизация
15
Июл
43

Много-много JavaScript’а

Представляю подборку яваскрипт кода написанную Michael Höhne, переведенную и озвученную (ээээ… что-то не то… ну да ладно 🙂 ) мной.

Замена контената IFRAME’а

В данном случае IFRAME служит для резервирования места на форме и хранения ссылки на него, а с помощью javascript’а Вы подменяете его на Ваш реальный HTML-код:

crmForm.all.IFRAME_NAME_d.innerHTML ="<b>Некоторый HTML код</b>";

Эта строчка заменяет весь элемент IFRAME Вашим собственным HTML-кодом. Все, что Вам требуется, так это заменить IFRAME_NAME на имя Вашего IFRAME’а и повесить его на онлоад формы. Также отметьте обязательное наличие «_d» в конце IFRAME_NAME.

Добавление дополнительных значений к полям «Срок»

Следующий скрипт добавляет новую опцию «42 Минуты» к полю actualdurationminutes в задаче:

var duration = crmForm.all.actualdurationminutesSelect;

var tables = duration.getElementsByTagName("table");
var table = tables[1];

var row = table.insertRow();
var newOption = row.insertCell(-1);

var newValue = "42 Минуты";
newOption.setAttribute("val", newValue);
newOption.innerText = newValue;

Изменение заголовка CRM формы

document.title = "Hello World!";

Изменение связи символа валюты с MSN Money на Yahoo Finances

Это — неподдерживаемое решение, поскольку это включает изменение файлов сервера!
Откройте на CRM сервере файл: C:\Inetpub\wwwroot\_static\_forms\controls\INPUT.text.ticker.htc и найдите следующую функцию:

function Launch() {
	if(value.length > 0) {
		Parse();

		safeWindowOpen("http://go.microsoft.com/fwlink?linkid=8506&clcid=" + 
        CrmEncodeDecode.CrmUrlEncode(USER_LANGUAGE_CODE) + "&Symbol=" +
    	CrmEncodeDecode.CrmUrlEncode(value), "", "height=" + (screen.availHeight * .75) + ",width=" + (screen.availWidth * .75) +
		",scrollbars=1,resizable=1,status=1,toolbar=1,menubar=1,location=1");
	}
}

И замените ее на:

function Launch() {
	if(value.length > 0) {
		Parse();

		/*
        safeWindowOpen("http://go.microsoft.com/fwlink?linkid=8506&clcid=" + 
        CrmEncodeDecode.CrmUrlEncode(USER_LANGUAGE_CODE) + "&Symbol=" +
    	CrmEncodeDecode.CrmUrlEncode(value), "", "height=" + (screen.availHeight * .75) + ",width=" + (screen.availWidth * .75) +
		",scrollbars=1,resizable=1,status=1,toolbar=1,menubar=1,location=1");
        */
        
		window.open("http://finance.yahoo.com/q?s=" +
        encodeURIComponent(value), "", "height=" + (screen.availHeight * .75) +
        ",width=" + (screen.availWidth * .75) +
        ",scrollbars=1,resizable=1,status=1,toolbar=1,menubar=1,location=1");
	}
}

Сохраните файл.

Откройте Internet Explorer и удалите все временные интернет-файлы, чтобы обновленный htc файл был загружен. Переместитесь к любому символу тикера, введите действительное значение и двойной щелчок это.

Подсчет числа определенных символов в строке

Вы можете использовать эти два фрагмента кода с любым искомым символом или группой символов – просто впишите их в код.

Решение 1:

var text = "hardware\\printers\\Epson"; //исходная строка
var paths = text.split("\\"); //укажите искомый символ или группу символов
alert(paths.length -1);

Решение 2:

var text = "hardware\\printers\\Epson"; //исходная строка
var numBs = 0;
var index = 0;

while(index != -1) {
	index = text.indexOf("\\", index); //укажите искомый символ или группу символов

	if (index != -1) {
		numBs++;
		index++;
	}
}

alert(numBs);

Изменение заголовка поля на форме

crmForm.all.revenue_c.innerText = "Ежики в снегу";

Замените revenue на имя Вашего поля и добавьте к нему «_c».

Изменение цвета одного пункта в picklist’е

Вы можете изменить цвет текста и цвет фона строчки в пиклистес помощью следующего кода:

// Замените <имя_пиклиста> на имя Вашего пиклиста.
var list = crmForm.all.<имя_пиклиста>;

// делаем ссылку на строчку в пикличте. В данномслучаи на первую, т.к. нумерация начинается с нуля.
var option = list.options[0];

//Устанавливаем цвет фона в шестнадцетиричном формате.
option.style.backgroundColor = "#FF0000";

//Устанавливаем цвет текста в шестнадцетиричном формате.
option.style.color = "#FFFFFF";

Подобрать шестнадцетиричные цвета можете в педевикии.

Открытие нового окна IE без меню и строки состояния

Следующий код представляет собой простую HTML страницу, содержащую ссылку и javascript код привязанный к ней. При клике по ссылке откроется новое окно браузер, с адресом указанном в первом параметре, заголовком окна ‘stunnware’, без всяких меню , строки состояния, линий прокрутки и без возможности изменять его размер. Конструкцию window.open() из этого примера Вы можете использовать на событиях ончейндж и онлоад формы CRM.

<html>
<head/>
<body>
<p>
<a href="javascript:;" onClick="window.open('http://www.stunnware.com/crm','stunnware', 'toolbar=no,status=no,menubar=no,scrollbars=yes,resizable=yes'); 
return false">Stunnware</a>
</p>
</body>
</html>

Получение текстового значения поля лукап

var lookup = crmForm.all.<имя_лукап_поля>.DataValue;

if (lookup[0] != null) {
	var theText = lookup[0].name;
}

Дезактивирование формы

document.body.disabled = true;

Этот код отключает все средства управления формы кроме вкладки Примечания, где Вы все еще можете введить новые примечания.

Приведение значения текстового поля к заглавным буквам

Поместите следующий скрипт на случай OnChange текстового поля:

crmForm.all.<имя_текстового_поля>.DataValue = crmForm.all.<имя_текстового_поля>.DataValue.toUpperCase();

Получение сообщения о том какая вкладка выбрана (при их смене)

Поместите следующий код на событие OnLoad Вашей формы:

crmForm.all.tab0Tab.onclick = function() {
	alert("Tab 0 clicked");
}

crmForm.all.tab1Tab.onclick = function() {
	alert("Tab 1 clicked");
}

Системные имена вкладок всегда называют «tabxTab», где x — число, начинающееся от 0 (первая вкладка) до (n-1), где n — общее количество вкладок.

id записи открытой в текущей форме

Первичный ключ всегда доступен с помощью следующего кода

crmForm.ObjectId

Но он имеет значение null, если запись еще не была сохранена. Есть также некоторые другие полезные свойства формы. Ищите «Form Object Model» в SDK для получения дополнительной информации.

Установление поля даты/времени в «сегодняшний день»

crmForm.all.<имя_поля_дата_время>.DataValue = new Date();

Изменение URL’а для IFRAME’а

Установите начальный URL IFRAME’а в about:blank и используйте следующую строку:

document.all.IFRAME_<имя_айфрейма>.src = "http://domain/file";

Отображение изображения на форме CRM и использование текстового поля для хранения имени рисунка

Допустим, у Вас есть кастомное поле new_pictureName, хранящее название картинки. Тогда на событие OnLoad поместите следующий код:

if ((crmForm.all.new_pictureName != null) && (crmForm.all.new_pictureName.DataValue != null)) {
	document.all.IFRAME_<имя_айфрейма>.src = "http://server/dir/images/" +  crmForm.all.new_pictureName.DataValue;
}

А на событие OnChange поля new_pictureName другой код:

if (crmForm.all.new_pictureName.DataValue != null) {
	document.all.IFRAME_<имя_айфрейма>.src = "http://server/dir/images/" + 
	crmForm.all.new_pictureName.DataValue;
} else {
	document.all.IFRAME_<имя_айфрейма>.src = "about:blank"
}

Не забудьте только создать айфрем, который будет отображать рисунок и изменить путь к папке, которая содержит рисунки.

Изменение заданного по умолчанию типа поля лукап

В некоторых лукапах при открытии диалогового окна поиска Вы можете выбирать значения из объектов нескольких типов. Чтобы задать какой-либо из этих объектов в диалоге поиска по умолчанию, используйте следующий скрипт:

if (crmForm.all.regardingobjectid != null) {
	crmForm.all.regardingobjectid.setAttribute("defaulttype", "2");
}

Только измените в нем имя лукапа (regardingobjectid) и задайте код объекта, который нужно использовать по умолчанию. Коды объектов можете посмотреть в статье или по ссылке

Проверка, присутствует ли поле на форме

if (crmForm.all.<name of field> != null) {
    //код
}

Вы должны всегда проверять, существует ли поле прежде, чем обратиться к нему, иначе Ваш скрипт может выдать ошибку, если это поле не вынесено на форму.

Установление поля даты на основе выбранного значения picklist’а

Следующий скрипт предполагает, что у Вас есть picklist с тремя значениями (например, «1 год», «2 года» и «3 года»).

var years = 0;

switch(crmForm.all.<имя_пиклиста>.DataValue) {

	//Следующие строчки учитывают только три значения поиклиста, если у Вас их больше добавьте еще по аналогии.
	case "1":
		years = 1;
		break;

	case "2":
		years = 2;
		break;

	case "3":
		years = 3;
		break;
}

if (years != 0) {

	var date = new Date();
	date.setYear(date.getYear() + years);

	crmForm.all.<имя_поля_дата_время>.DataValue = date;
}

Создание нового письма в Вашей почтовой программе по двойному щелчку по текстовому полю

if (crmForm.all.<имя_текстового_поля> != null) {

	crmForm.all.<имя_текстового_поля>.ondblclick = function() {

		var email = crmForm.all.<имя_текстового_поля>.DataValue;

		if ((email != null) && (email.length > 0)) {
			window.navigate("mailto:" + email);
		}
	}
}

Восстановление значения поля, если проверка валидации не пройдена

На событие OnLoad поместите следующий код:

crmForm.all.<имя_поля>.setAttribute("lastKnownGood", crmForm.all.<имя_поля>.DataValue);

Этот код добавляет новый атрибут lastKnownGood к полю и записывает в него значение поля на момент открытия формы. А в событие OnChange поместите следующее:

//в зависимости от того, что содержится в checkFailed – истина или ложь – происходит либо возврат к предыдущиму значению, либо установка нового базового значения в атрибут lastKnownGood
if (checkFailed) {
	crmForm.all.<field to check>.DataValue = crmForm.all.fieldToCheck.getAttribute("lastKnownGood");
} else {
	crmForm.all.<field to check>.setAttribute("lastKnownGood", crmForm.all.fieldToCheck.DataValue);
}

Вставка разрывов строк в текстовую область

Поместите следующее на событие OnLoad:

crmForm.all.<имя_текстового_поля>.style.whiteSpace = "pre";

Скрытие строки формы CRM

//поле которое Вы хотите скрыть
var field = crmForm.all.name;

//поиск строки таблицы HTML в которую входит искомое поле
while ((field.parentNode != null) && (field.tagName.toLowerCase() != "tr")) {
	field = field.parentNode;
}

//если строка найдена то скрываем ее
if (field.tagName.toLowerCase() == "tr") {
	field.style.display = "none";
}

Отключение выбора времени в полях даты/времени

Вы можете динамически включить или отключить меню выбора времени для полей даты/времени использовав следующий синтаксис:

var dateField = crmForm.all.<имя_поля_даты_времени>;

//Проверка существования поля времени. 
if (dateField.all.time != null) {

	//Дективируем поле времени
	dateField.all.time.disable();

	//Активирование поля времени
	dateField.all.time.enable();
}

Изменение интервала времени в полях даты/времени

Меню выбора времени поля даты/времени использует 30-минутный интервал. Вы можете изменить это на различный интервал, используя следующий код на событии OnLoad:

var dateField = crmForm.all.<name of datetime field>;

//Проверка существования поля даты/времени
if (dateField != null) {

	var timeField = dateField.all.time;

	//Проверка существования поля времени
	if (timeField != null) {

		//Задание нового интервала в минутах
		var interval = 15;
		var tables = timeField.getElementsByTagName("table");

		if ((tables != null) && (tables.length > 0)) {

			var table = tables[1];

			//Удаление старых значений из меню выбора времени
			while (table.firstChild != null) {
				table.removeChild(table.firstChild);
			}

			//Добавление новых значений в меню выбора времени
			for (hour = 0; hour < 24; hour++) {
				for (min = 0; min < 60; min += interval) {

					var row = table.insertRow();
					var cell = row.insertCell();
					var time = ((hour < 10) ? "0" : "") + hour + ":" + ((min < 10) ? "0" : "") + min;

					cell.setAttribute("val", time);
					cell.innerText = time;
				}
			}
		}
	}
}

Получение id предложения из формы Продукты для предложения

Есть скрытое поле на форме продукты для предложения, хранящее id предложения. Вы можете обратиться к этому полю с помощью следующего кода:

alert("Quote ID = " + crmForm.all.quoteid.DataValue);

Как узнать, какая кнопка вызвала событие OnSave

В данном случае имеются в виду кнопки «Сохранить», «Сохранить и закрыть», «Сохранить как завершенное» и т.д. Для этого Вы можете использовать свойство event.Mode в событии OnSave. Оно скажет Вам, какая кнопка использовалась, чтобы сохранить объект.

Поместите следующий код на событие OnSave:

alert ("event.Mode = " + event.Mode);
event.returnValue = false;
return false;

Этот код делает невозможным сохранить объект, но позволит Вам узнать, какой код соответствует нажатой кнопке и передается в событие OnSave. Например, обычному сохранению соответствует код 1, для «Сохранить и закрыть» код 2 и т.д. Другие значения кодов(но не все) определены в /_common/scripts/formevt.js.

Доступ к базе данных CRM из JavaScript

Чтобы обратиться к базе данных CRM из JavaScript, используйте следующий код как шаблон:

var connection = new ActiveXObject("ADODB.Connection");
var connectionString = "Provider=SQLOLEDB;Server=STUNNWARECRM;Database=stunnware_mscrm;Integrated Security=sspi";

connection.Open(connectionString);

var query = "SELECT name FROM FilteredAccount";
var rs = new ActiveXObject("ADODB.Recordset");

rs.Open(query, connection, /*adOpenKeyset*/1, /*adLockPessimistic*/2);
rs.moveFirst();

var values = "";

while (!rs.eof) {
	values += rs.Fields(0).Value.toString() + " ";
	rs.moveNext();
}

connection.Close();

alert(values);

Вам, возможно, придется подкорректировать параметры безопасности в IE, чтобы выполнить этот код.

Выбор в лукапе потенциального клиента (на форме возможной сделки) только из бизнес-партнеров

Поместите следующий код на событие OnLoad:

crmForm.all.customerid.setAttribute("lookuptypes", "1");

Этот код «говорит» диалогу поиска отображать только бизнес-партнеров (код 1). Значение же 2 разрешит поиск только среди контактов.

Скрытие и отображение полей основанное на значениях других полей

Допустим, у Вас есть picklist, названный «new_category», и у него есть следующие значения:

  1. Бизнес-требование
  2. Скрытый
  3. Не определено

Далее предположим, что Вы хотите скрыть поля «new_a» и «new_b», когда пользователь выбирает опцию «Скрытый» в пилисте, но они должны быть видимыми, если выбрана какая-либо другая опция. Поместите этот скрипт на событие OnChange пиклиста:

var hideValues = (crmForm.all.new_category != null) && (crmForm.all.new_category.DataValue == "2");
var displayStyle = hideValues ? "none" : "";

crmForm.all.new_a.style.display = displayStyle;
crmForm.all.new_b.style.display = displayStyle;

А чтобы выполнить этот код при начально загрузки формы, поместите на событие OnLoad скрипт:

if (crmForm.all.new_category != null) {
	crmForm.all.new_category.FireOnChange();
}

Тест на нулевое значение crmForm.all.new_category включен, чтобы избежать ошибок, если поле не доступно на форме. Это — истина для быстрого, создают формы, если поле потребовало, чтобы уровень не был установлен в требуемый бизнес или рекомендуемый бизнес.

Удаление значения поля лукап

crmForm.all.<имя_лукапа>.DataValue = null;

Скрытие вкладок

Вы можете скрывать и показывать все вкладки, используя следующий код:

//Добавьте Ваше условие тут. Обычно используется на событии OnChange
if (condition == true) {
	//Скрываем вкладку
	crmForm.all.tab1Tab.style.display = "none";
}
else {
	//Отображаем вкладку
	crmForm.all.tab1Tab.style.display = "";
}

Вкладки имеют имена «tab0Tab», «tab1Tab», «tab2Tab» и так далее.

Установка фокуса

Данный скрипт устанавливает фокус на указанное поле и если это необходимо переключает вкладки и/или перематывает содержимое формы к этому полю:

crmForm.all.<имя_поля>.SetFocus();

Отображение связанных объектов вместо формы при открытии записи

Чтобы открыть связанное представление объекта левой навигационной панели (как контакты в объекте бизнес-партнеры), Вы можете использовать следующее:

loadArea("areaContacts");

У каждой кнопки в навигационной панели есть уникальное название области (areaContacts, например). Загрузите и установите Internet Explorer Developer Toolbar (кстати, в IE8 он встроен), чтобы найти это название.

Изменение цвета заблокированных полей формы

Заблокированные поля формы являются иногда трудночитаемыми. Если сделать цвет немного более темнее – это улучшит его читаемость не снимая визуального сообщения что поле только для чтения.

Откройте следующий файл в веб папке CRM: /_forms/controls/controls.css. Найдите следующий код:

INPUT.ro,TEXTAREA.ro,DIV.ro,SPAN.ro {
	background-color: #ffffff;
	color:    #808080;
	border-color:  #808080;
}

По умолчанию цвет атрибута светло-серый. Вы можете изменить его, например, на #404040, чтобы получить немного более темный оттенок. Если Вы не увидите новых цветов в IE после изменения файла, нажмите CTRL+F5, чтобы перезагрузить исходные файлы записанные в кэщ.

Удаление кнопки с навигационной панели формы

Чтобы удалить кнопку с навигационной панели используйте следующий код:

var navigationBarEntry = document.getElementById("navProds");

if (navigationBarEntry != null) {

	var lbArea = navigationBarEntry.parentNode;

	if (lbArea != null) {
		lbArea.removeChild(navigationBarEntry);
	}
}

Единственное, что Вам нужно сделать, так это взять Internet Explorer Developer Toolbar, и найти название кнопки на навигационной панели (и подставить вместо navProds в первой строке).

Изменение цвета метки на форме

var label = crmForm.all.<field name>_c;
label.innerHTML = "<font color='#FF0000'>" + label.innerText + "</font>";

Задание цвета фона формы CRM

Если Вы хотите облегчить для пользователя идентификацию текущего отрытого в форме CRM объекта, Вы можете изменить цвет его фона:

document.body.style.backgroundColor = 'red';

Поместите его на событие OnLoad формы, которую Вы хотите покрасить 🙂 и замените ‘red’ (красный) на тот цвет, который Вам нужен.

Некоторые вычисляемые поля на форме CRM не сохраняются в базе данных

Если поле заблокировано, что является обычной делом для вычисляемых полей, то оно не отправляется на сервер, когда форма сохраняется. Чтобы изменить это поведение, добавьте эту строчку к своему коду:

crmForm.all.your_field.ForceSubmit = true;

Исправление проблем с пустыми обработчиками событий OnChange

Изменив определение поля с помощью скрипта, Вы лишаетесь возможности использовать событие OnChange.

Чтобы преодолеть эту ситуацию, поместите следующий скрипт после того, как Вы заменили код HTML:

crmForm.all.<ваше_поле>.onchange = function() {
	//код события ончейндж нового поля
}

Если Вы хотите инициировать вызов OnChange, используйте этот код:

your_field_OnChange = function() {
	// код события ончейндж нового поля
}

//присоединяем к событию ончейндж функцию
crmForm.all.your_field.onchange = your_field_OnChange;

//вызов события (что-то типа FireOnChange()) 
your_field_OnChange();

Установка бизнес-требования для поля

Вы можете обратиться к уровню требований к заполнению поля при использовании свойства RequiredLevel:

var reqLevel = crmForm.all.your_Field.RequiredLevel;

Однако, поскольку свойство только для чтения, Вы не можете использовать его, чтобы изменить необходимый уровень заполнения. Есть недокументированный (и поэтому неподдерживаемый метод объекта crmForm, позволяющем сделать поле обязательным или не обязательнымдлязаполнения:

function SetFieldReqLevel(sField, bRequired);

Если bRequired установлен в ноль (ложь), то поле свободно для заполнения. Если bRequired установлен во что-нибудь другое (т.е. истина), поле становится обязательным для заполнения. Например так:

crmForm.SetFieldReqLevel("new_partnerid", 0);

Заметьте: Вы не можете использовать этот метод, чтобы сделать поле рекомендуемым для заполнения.
Вот код, чтобы установить поле в любое из возможных состояний:

//Не обязательно
//------------------------------
crmForm.all.<имя_поля>.setAttribute("req", 0);
crmForm.all.<имя_поля>_c.className = "n";

//Рекомендуемо
//------------------------------
crmForm.all.<имя_поля>.setAttribute("req", 1);
crmForm.all.<имя_поля>_c.className = "rec";

//Обязательно
//------------------------------
crmForm.all.<имя_поля>.setAttribute("req", 2);
crmForm.all.<имя_поля>_c.className = "req";

Установка значения по умолчанию для поля даты

Поле даты на форме CRM всегда содержит дату и если необходимо время. Иногда полезно назначить заданное по умолчанию время, например, 8:30, но пока пользователь не ввел корректную дату, меню выбора фрагмента времени заблокировано. Вот код, чтобы установить заданное по умолчанию время, как только пользователь определил часть даты:

На OnLoad:

//проверка существования поля
if (crmForm.all.your_DateField != null) {
	//сохранение значения для будущей ссылки на него.
	_previousValue = crmForm.all.your_DateField.DataValue;
}

На OnChange Вашего поля даты:

var dateField = crmForm.all.your_DateField;
var currentValue = dateField.DataValue;

//Если пользователь меняет дату с нуля на корректную дату, установить время в 8:30
if ((currentValue != null) && (_previousValue == null)) {
	dateField.DataValue = new Date(currentValue.getYear(), currentValue.getMonth(), currentValue.getDate(), 8, 30);
}

//обновляем переменную  _previousValue
_previousValue = currentValue;

Диалоговое окно с вариантами ответа да/нет

Вы можете использовать window.confirm, чтобы представить пользователю диалоговое окно вида «да/нет», в котором пользователю необходимо ответить на вопрос. Фактически же кнопки называются «Да» и «Отмена», поэтому Вы должны использовать соответствующее описание в тексте сообщения. Результатом взаимодействия будет либо истина (кнопка Да), либо ложь (кнопка Отмена):

var answer = window.confirm("Вопрос?");

if (answer) {
	//Код, если пользователь нажал Да
} else {
	//Код, если пользователь нажал Отмена
}

Сравнение значений даты

Это частая ошибка непосредственно сравнить два значения даты, например, так:

var date1 = new Date(2007, 4, 30);
var date2 = new Date(2007, 5, 1);

if (date1 > date2) {
	//какой-нить код тут
}

Вы можете ожидать, что это будет работать, но по Фэн-шую Вы должны использовать метод valueOf объекта Date:

var date1 = new Date(2007, 4, 30);
var date2 = new Date(2007, 5, 1);

if (date1.valueOf() > date2.valueOf()) {
	//какой-нить код тут
}

Получение уведомления при вводе данных в поля формы

Событие OnChange поля происходит, когда фокус покидает поле (и конечно изменили его значение). Если Вы хотите выполнить какое-либо действие при вводе данных в поле, используйте событие onfocus:

crmForm.all.your_field.onfocusin = function() {
	alert("Received focus");
}

Замена события произошедшего в результате клика по полю lookup

Если Вы должны запустить какой-либо код, когда пользователь нажимает на кнопку поиска поля лукап, используйте следующий код, чтобы отменить стандартную реализацию события клика:

//переопределение стандартного событиеr
crmForm.all.your_lookupField.onclick = function() {

	alert("Диалог поиска сейчас откроется");

	//открытие диалогапоиска
	crmForm.all.your_lookupField.Lookup(true);

	alert("Диалог поиска закрыт");
}

Но будьте осторожны с этим, поскольку некоторые поля лукап определяют дополнительные параметры при событии клика.

Форматирование даты к YYYYMMDD

Нет никакой функции в JavaScript, которая позволила бы Вам отформатировать значение даты, поэтому Вы должны сделать это «ручками»:

  • getYear возвращает текущий год
  • getMonth возвращает месяц (начинается с 0 – январь и до 11 – декабрь)
  • getDate возвращает день месяца (1-31)
var now = new Date(); //получаем текущую дату

var year = now.getYear().toString(); //из текущей даты вырезаем год и конвертируем в строковый тип
var month = (now.getMonth() + 1).toString(); //из текущей даты вырезаем месяц и конвертируем в строковый тип (обратите внимание что к месяцу добавили единицу, т.к. в типе данных времени месяцы нумеруются от 0 до 11)
var dayOfMonth = now.getDate().toString(); //из текущей даты вырезаем день месяца и конвертируем в строковый тип

if (month.length == 1) {
	month = "0" + month;
}

if (dayOfMonth.length == 1) {
	dayOfMonth = "0" + dayOfMonth;
}

var yyyymmdd = year + month + dayOfMonth;

Запуск приложения из формы CRM

var shell = new ActiveXObject("WScript.Shell");

if (shell != null) {
	shell.Run("c:\\directory\\application.exe " + crmForm.ObjectId);
}

Вы можете столкнуться с проблемами при выполнении этого кода, вызванными настройками безопасности – так что придется подкорректировать их 🙂

Изменение доступных для поиска объектов в диалоговом окне лукапа

Используйте одну из следующих строк на событии OnLoad:

//Разрешает для выбора только бизнес-партнеров
crmForm.all.regardingobjectid.setAttribute("lookuptypes", "1");

//Разрешает для выбора только контакты
crmForm.all.regardingobjectid.setAttribute("lookuptypes", "2");

//Разрешает выбор и контактов и бизнес-партнеров
crmForm.all.regardingobjectid.setAttribute("lookuptypes", "1,2");

Это не изменит поведение помощника формы, но диалог поиска не будет отображать другие объекты. Вы можете использовать этот код для любого поля, позволяющего выбор множественных типов объектов (обычно это поля выбора клиентов).

Задание текста для кнопки «Сохранить как завершенное»

Чтобы отобразить текст «Сохранить как завершенное» рядом с кнопкой на панели инструментов, выполняющей это действие, поместите этот код на событие OnLoad:

document.all._MBSaveAsCompleted.children[0].innerHTML += "Save as completed";

Кстати… этот способ является неподдерживаемым 🙂

Вычисление срока

Следующий код вычитает текущую дату из даты, определенной на форме CRM, и вычисляет оставшиеся или прошедшие дни, часы или минуты до нее.

var displayField = crmForm.all.<имя_текстового_поля>;
var formDate = crmForm.all.<имя_поля_даты>.DataValue;
var now = new Date();
var ms = formDate.valueOf() - now.valueOf();
var minutes = ms / 1000 / 60;
var hours = minutes / 60;
var days = hours / 24;

if (days >= 1) {
	displayField.DataValue = Math.floor(days) + " day(s) left";
} else if (hours >= 1) {
	displayField.DataValue = Math.floor(hours) + " hour(s) left";
} else if (minutes >= 1) {
	displayField.DataValue = Math.floor(minutes) + " minute(s) left";
} else if (days <= -1) {
	displayField.DataValue = Math.floor(-days) + " day(s) late";
} else if (hours <= -1) {
	displayField.DataValue = Math.floor(-hours) + " hour(s) late";
} else if (minutes <= -1) {
	displayField.DataValue = Math.floor(-minutes) + " minute(s) late";
} else {
	displayField.DataValue = "NOW";
}

Скрытие поля

crmForm.all.<имя_поля>_c.style.display = "none"; //Скрытие метки поля
crmForm.all.<имя_поля>_d.style.display = "none"; //Скрытие самого поля

Установка значения текстового поля равное типу объекта выбранному в лукапе

if (crmForm.all.<имя_лукапа>.DataValue == null) {
	crmForm.all.<имя_текстового_поля>.DataValue = null;
} else {
	crmForm.all.<имя_текстового_поля>.DataValue = crmForm.all.<имя_лукапа>.DataValue[0].name;
}

Отслеживание события изменения чекбокса прежде, чем фокус переместится на другой объект

Событие OnChange бинарных полей происходит, когда курсор покидает поле. Иногда требуется, чтобы событие происходило как только пользователь переключает значение бинарного поля, а не при смене фокуса. Вот код, который создает обработчик события клика по полю:

crmForm.all.<имя_чекбокса>.onclick = function() {
	crmForm.all.<имя_чекбокса>.FireOnChange();
}

Очевидно, что событие onClick происходит при щелчке на чекбоксе. Не столь очевидный тот факт, что оно также происходит и при изменении значения с помощью клавиатуры (клавиша «Пробел»). Т.к. вышеупомянутый код вызывает обработчика событий OnChange, то это же событие происходит при смене фокуса. Если это проблема, то переместите весь существующий код обработчика события OnChange в событие onclick:

crmForm.all.<имя_чекбокса>.onclick = function() {
	//переместите сюда код события OnChange
}

Только не забудьте удалить код из события OnChange чекбокса.

Выполнение события OnChange при закрытии формы

Чтобы вызвать обработчик события OnChange, если инициировано закрытие формы, добавьте следующий код к событию OnLoad:

//объявление глобальной переменной
_windowClosing = false;

//onbeforeunload вызывается когда закрываете форму, но прежде чем событие OnChange сработает

window.onbeforeunload = function() {
	_windowClosing = true;
}

В событии OnChange, сделайте следующее:

if (!_windowClosing) {
	//добавьте сюда Ваш скрипт
}

Я опубликовал последнюю статью «Большего количества JavaScript» прогрессия больше чем половину года назад и думал, что не было еще много, чтобы сказать. Кажется, что я был неправ с тем предположением, таким образом вот четвертая часть. Я также обновил Каталог Отрывков JavaScript соответственно.

Раскрытие формы на полный экран

Поместите следующие две строки программы на событие OnLoad, чтобы раскрыть форму:

window.moveTo(0,0);
window.resizeTo(screen.availWidth, screen.availHeight);

moveTo перемещает окно в указанное местоположение, а resizeTo изменяет его размер. screen — глобальный объект и предоставляет Вам доступную ширину и высоту экрана в соответствующих свойствах.

Использование кнопки с панели инструментов, чтобы открыть связанный объект

Допустим, Вы добавили поле лукап на форму, ссылающейся на один из Ваших кастомных объектов, и Вы добавили кнопку на панель в isv.config.xml. При нажатии по ней должн открыться объект, связанный с лукапом, что по сути является тем же самым что и щелчек по лукапу.

Вот код:

var lookup = crmForm.all.<имя_лукапа>;

if ((lookup != null) && (lookup.DataValue != null)) {
	var objectTypeCode = lookup[0].type;
	var objectId = lookup[0].id;
	var url = '/userdefined/edit.aspx?id=" + objectId + '&etc=' + objectTypeCode;

	window.open(url);
}

Заметьте, что, используя системный объект, Вы должны заменить /userdefined/edit.aspx соответствующим URL.

Вычисление суммы двух или более полей

Хотя это кажется простым – подсчитать сумму полей данных в форме – Вы можете легко столкнуться с проблемами с нулевыми значениями. Вот типовой скрипт, который подсчитывает сумму трех полей (your_field1, your_field2, your_field3) и сохраняет ее в your_sum:

var value1 = crmForm.all.your_field1.DataValue;
var value2 = crmForm.all.your_field2.DataValue;
var value3 = crmForm.all.your_field3.DataValue;

value1 = (value1 == null) ? 0 : value1;
value2 = (value2 == null) ? 0 : value2;
value3 = (value3 == null) ? 0 : value3;

crmForm.all.your_sum.DataValue = value1 + value2 + value3;

Вычисление итоговых затрат, основанных на продолжительности, почасовой ставке, разовых затратах и налоговой ставке

Я создал 4 атрибута в объекте Обращение:

  • new_hourlyrate – picklist (значения 95.00 и 125.00)
  • new_taxrate – picklist (значения .06 и.07)
  • new_tripcharge – picklist (значения 0.00, 15.00, 30.00, 60.00)
  • new_totalcharge – деньги

Предположим, что нужно заполнить поле totalcharge, основанное на атрибуте actualdurationminutes используя следующие математическое уравнение:

totalcharge = actualdurationminutes/60 (чтобы получить часы) умноженный почасовой ставкой, добавляют tripcharge, умноженные налоговой ставкой. К полученному значению добавляется почасовая ставка, умноженной на часы, далее прибавляем разовые расходы, чтобы получить итоговую сумму.

И вот код:

var hourlyRateField = crmForm.all.new_hourlyrate;
var taxRateField = crmForm.all.new_taxrate;
var tripChargeField = crmForm.all.new_tripcharge;
var totalChargeField = crmForm.all.new_totalcharge;
var actualDurationMinutesField = crmForm.all.actualdurationminutes;

//Проверка, что все нужные поля доступны на форме
if (hourlyRateField && taxRateField && tripChargeField && totalChargeField && actualDurationMinutesField) {

	var hourlyRate = (hourlyRateField.DataValue == null) ? 0 : parseFloat(hourlyRateField.SelectedText);
	var taxRate = (taxRateField.DataValue == null) ? 0 : parseFloat(taxRateField.SelectedText);
	var tripCharge = (tripChargeField.DataValue == null) ? 0 : parseFloat(tripChargeField.SelectedText);
	var actualDurationMinutes = (actualDurationMinutesField.DataValue == null) ? 0 : parseFloat(actualDurationMinutesField.DataValue);

	var totalCharge = (actualDurationMinutes/60 * hourlyRate) + tripCharge;
	var totalTax = totalCharge * taxRate;

	totalChargeField.DataValue = totalCharge + totalTax;
}

Заметьте, что в вышеупомянутом коде parseFloat использует свойство SelectedText пиклиста, вместо DataValue.

Изменение сообщений об ошибках на форме CRM

Иногда сообщения об ошибках, которые отображаются при вводя неправильных значение, не совсем корректны. Например, сообщение о форматах даты.

Вы можете изменять эти сообщения об ошибках на лету, просто заменяя соответствующую переменную в OnLoad. Запомните сообщение об ошибке и ищите его в исходных файлах. Вы найдете что-то вроде:

var LOCID_ALERT_ENTER_VALID_DATE = "De opgegeven datum is ongeldig. voer een datum in met de notatie: D/M/YYYY.";

Чтобы изменить ее, поместите следующую строку на событие OnLoad:

LOCID_ALERT_ENTER_VALID_DATE = "De opgegeven datum is ongeldig. voer een datum in met de notatie: DD-MM-YYYY.";

Установка кастомного поля даты к другой дате минус 60 дней

Допустим, Вы хотите вычислить дату, основанную на значении поля даты effectiveto на Вашей форме, минус 60 дней. Вот код:

var effectiveTo = crmForm.all.effectiveto.DataValue;

var remindOn = new Date(
	effectiveTo.getYear(),
	effectiveTo.getMonth(),
	effectiveTo.getDate() - 60
);

или

var effectiveTo = crmForm.all.effectiveto.DataValue;

var remindOn = new Date(
	effectiveTo.getYear(),
	effectiveTo.getMonth() - 2,
	effectiveTo.getDate()
);

Различие между этими двумя способами в том, что первый вычитает ровно 60 дней, тогда как второй вычитает два месяца, дни которых могут варьироваться от 58 до 62.

Изменение заданной по умолчанию высоты окна лукапа

Это неподдерживаемое изменение, но если Вы хотите изменить начальный размер диалогового окна лукапа, откройте /_controls/lookup/lookup.js в веб папке CRM и найдите функцию BuildFeatures (lookupStyle). В этой функции найдите следующие строки:

switch (lookupStyle)
{
case "multi":
oFeatures.height = "460px";
oFeatures.width = "600px";
break;
case "single":
oFeatures.height = "488px";
oFeatures.width = "600px";
break;

oFeatures.height и oFeatures.width — начальные размерности диалогового окна лукапа. После изменения их, очистите кэш браузера, чтобы перезагрузить файлы, иначе IE будет все еще использовать кэшируемые значения, и Вы не увидите изменений.

Доступ к предыдущему значению поля в OnChange

Иногда Вы должны знать предыдущее значение поля в событие OnChange, или же начальное значение после того, как форма загрузилась. Эта информация конечно будет потеряна после события OnChange, поскольку значение поля уже будет изменено. Вот простой работа:

// на событие OnLoad
// здесь не используется var, т.к. объявляется глобальная переменная
_oldDateValue = crmForm.all.the_fieldName.DataValue;

// на событие OnChange
if (_oldDateValue == null) {
	//нет пердыдущих значений
} else {
	var currentValue = crmForm.all.the_fieldName.DataValue;
	DoStuff(currentValue, _oldValue);

	//обновляем старое значение новым
	_oldDateValue = currentValue;
}

Автоматическое вычисление суммы налога в строке счета (invoicedetail)

CRM не вычисляет сумму налога и если Вы хотите автоматизировать это действие, Вы должны написать кастомный скрипт. Здесь показан пример для invoicedetail (продукты для заказа), поэтому на событие OnLoad этой формы добавьте следующее:

CalculateTax = function() {

	var pricePerUnit = 0;
	var quantity = 0;
	var manualDiscount = 0;

	if (crmForm.all.priceperunit.DataValue != null) {
		pricePerUnit = crmForm.all.priceperunit.DataValue;
	}

	if (crmForm.all.quantity.DataValue != null) {
		quantity = crmForm.all.quantity.DataValue;
	}

	if (crmForm.all.manualdiscountamount.DataValue != null) {
		manualDiscount = crmForm.all.manualdiscountamount.DataValue;
	}

	crmForm.all.tax.DataValue = (pricePerUnit * quantity - manualDiscount) * 0.175;
}

А в события OnChange полей priceperunit, quantity и manualdiscountamount добавьте:

CalculateTax();

Измените 0.175 (17.5 %) на налог, который Вы должны использовать. Вы можете также добавить новое поле для хранения ставки налога, вместо того, чтобы использовать фиксированное значение в коде скрипта.

Выполнение действий при закрытии формы CRM

Если Вы хотите запускать свой скрипт всякий раз, когда форма закрывается, вне зависимости от того сохранена она или нет, то поместите Ваш скрипт в событие onunload:

window.onunload = function() {
	//а сюда поместите Ваш код
}

Изменение заголовка формы (не заголовка браузера)

Форма CRM отображает заголовок объекта большим полужирным шрифтом под панелью кнопок. Если Вы хотите изменить отображаемый текст, поместите следующий код на событие OnLoad:

ar cells = document.getElementsByTagName("td");

for (var i = 0; i &lt; cells.length; i++) {
	if (cells[i].className == "formTitle") {
		cells[i].innerText = "Текст нового заголовка";
		break;
	}
}

Передача параметров из кнопки с панели инструментов на форму CRM

Иногда в целях кастомизации, приходится добавлять кнопки на панель инструментов формы, которые создают новый объект. Однако в созданном объекте Вы должны знать, был ли он создан путем нажатия Вашей кнопки или каким-либо другим образом. Вот простой способ передать дополнительный параметр, который Вы можете проверить в объекте OnLoad формы.

Начнем с кнопки на панели инструментов. Обычно Url имеет слудующий атрибут

/userdefined/edit.aspx?etc=10018

Добавить дополнительный параметр можно так:

/userdefined/edit.aspx?etc=10018&template=1

На событие OnLoad целевого объекта (с кодом 10018) поместите следующий скрипт, чтобы извлечь дополнительный параметр из строки запроса:

var QueryString = ParseQueryString();
var template = QueryString["template"];

alert(template);

if (template == "1") {
	// Если объект создан путем нажатия кнопки…
} else {
	// В противном случаи…
}

function ParseQueryString() {

	var dict = new Object();

	if ((document.location.search != null) && (document.location.search != "?")) {
		var qsParts = document.location.search.substr(1).split("&");
		var index;

		for(index in qsParts) {
			var keyValue = qsParts[index].split("=");
			dict[keyValue[0]] = unescape(decodeURIComponent(keyValue[1]));
		}
	}

	return dict;
}

Отмена операции OnChange

Чтобы лучше понять решение: я заполнил picklist некоторыми значениями и добавил код на событие OnChange(). Когда пользователь изменит значение picklist’а в ниспадающем меню, выскочит диалоговое окно и «попросит», чтобы пользователь подтвердил изменение. Если пользователь выбирает нет, восстановливается значение до события OnChange():

// На событие OnLoad
// Заметьте, что ключевое слово "var" пропущено, чтобы объявить глобальную переменную prevPicklistValue
prevPicklistValue = crmForm.all.the_picklist.DataValue;

// На событие OnChange
var currentPicklistValue = crmForm.all.the_picklist.DataValue;

if (prevPicklistValue == currentPicklistValue) {
	//Восстанавливаем предыдущее значение
	return;
}

var answer = window.confirm("Нажмите Да чтобы продолжить или Отмена чтобы отменить операцию.");

if (answer) {
	//Пользователь нажал Да - сохраняем текущее значение в глобальной переменной
	prevPicklistValue = currentPicklistValue;
} else {
	//Пользовал выбрал Отмена -> Восстанавливаем предыдущее значение.
	crmForm.all.the_picklist.DataValue = prevPicklistValue
}

Форматирование международных телефонных номеров

Простое правило форматирования заменяет любое вхождение скобок или пробелов на тире. Люди могут тогда ввести номер телефона своим привилегированным способом, но получить тот же самый вывод.

var originalPhoneNumber = "+49 (89) 12345678";
var formattedPhoneNumber = originalPhoneNumber.replace(/[^0-9,+]/g, "-");
formattedPhoneNumber = formattedPhoneNumber.replace(/-+/g, "-");
alert(formattedPhoneNumber);

Сначала в номере телефона каждый символ, не являющейся цифрой или знаком плюс, заменяется на тире. Вторым ходом все многократные вхождения тире заменяются одним, делая окончательный результат примерно таким: +49-89-12345678.

Округление числовых полей

Округление полей сделано также как и в любом другом языке программирования. Следующий пример округляет значение с плавающей точкой, используя точность до двух позиций после запятой:

function round(value) {
	return Math.round(value * 100) / 100;
}

Объект Math включает три метода для операции округления:

  • Math.ceil(параметр): Возвращает целочисленное значение, равное наименьшему целому числу, которое больше аргумента или равное ему;
  • Math.floor(параметр): Возвращает целочисленное значение, равное самому большому целому числу, которое меньше аргумента или равное ему;
  • Math.round(параметр): Если десятичная часть числа 0.5 или больше, возвращаемое значение равно наименьшему целому числу, которое больше аргумента. Иначе, round возвращает наибольшее целое число, которое меньше аргумента или равное ему.

Знайте о значениях пустого указателя в полях Boolean

Работая с полями типа Boolean, кажется естественным сравнить их значения или с истиной или с ложью:

var value = crmForm.all.my_bool.DataValue;

if (value == true) {
	//делаем что-нибудь
} else {
	// делаем что-нибудь еще
}

Однако, значение может также быть также и null. Поэтому Вы должны удостовериться, что Ваш код обрабатывает это значение правильно:

var value = crmForm.all.my_bool.DataValue;

if (value == null) {
	// если поле не имеет значения
} else if (value == true) {
	// делаем что-нибудь
} else {
	// делаем что-нибудь еще
}

Если Вы хотите прировнять значение null к «истине» или «лжи», то можете воспользоватьсяследующимкодом:

var value = crmForm.all.my_bool.DataValue;

// По умолчанию отсутствие значения приравнено к истине
if (value == null) {
	value = true;
}

if (value == true) {
	// делаем что-нибудь
} else {
	// делаем что-нибудь еще
}

Многократное использование кода в OnLoad и обработчиках события OnChange

Часто при разработки происходит дублирование одного и того же кода… например, так:

OnLoad:

if (crmForm.all.my_lookup_field.DataValue != null) {
	crmForm.all.my_text_field.DataValue = crmForm.all.my_lookup_field.DataValue[0].name;
}

OnChange:

if (crmForm.all.my_lookup_field.DataValue != null) {
	crmForm.all.my_text_field.DataValue = crmForm.all.my_lookup_field.DataValue[0].name;
}

Код идентичен в обоих событиях: он копирует отображаемое имя выбранного элемента в лукапе в текстовое поле. Позже Вы замечаете, что он не удаляет существующее значение в текстовом поле, если пользователь очищает значение лукапа и изменяете код OnChange на:

if (crmForm.all.my_lookup_field.DataValue != null) {
	crmForm.all.my_text_field.DataValue = crmForm.all.my_lookup_field.DataValue[0].name;
} else {
	crmForm.all.my_text_field.DataValue = null;
}

Но иногда случается, что при этом Вы забываете изменять код на OnLoad. Поэтому вместо копирования кода между OnChange и OnLoad, Вы должны использовать одину из следующих реализации:

  1. Написание кода только в обработчике событий OnChange и использовании FireOnChange, чтобы вызвать его в событии OnLoad:
    OnLoad

    crmForm.all.my_lookup_field.FireOnChange();

    OnChange

    if (crmForm.all.my_lookup_field.DataValue != null) {
    	crmForm.all.my_text_field.DataValue = crmForm.all.my_lookup_field.DataValue[0].name;
    } else {
    	crmForm.all.my_text_field.DataValue = null;
    }
    
  2. Написание кода в OnLoad и вызов его из события OnChange:
    OnLoad

    MyLookup_OnChange = function() {
    	if (crmForm.all.my_lookup_field.DataValue != null) {
    		crmForm.all.my_text_field.DataValue = crmForm.all.my_lookup_field.DataValue[0].name;
    	} else {
    		crmForm.all.my_text_field.DataValue = null;
        }
    }
    
    MyLookup_OnChange();
    

    OnChange

    MyLookup_OnChange();
    

У второй реализации есть преимущество в том, что весь Ваш код находится в одном месте.

Совет: вышеуказанный код может быть переписан к такому виду:

var lookupValue = crmForm.all.my_lookup_field.DataValue;
crmForm.all.my_text_field.DataValue = (lookupValue == null) ? null : lookupValue[0].name;

Получение уведомления, когда пользователь выбрал адрес в компоненте выбора адреса (предложение, заказ, счет)

Работая с предложениями, заказами или счетами, Вы выбираете адрес, по которому отправится счет и груз. Хотя поля адреса должным образом заполняются выбранными значениями, при этом никакого случая OnChange не происходит на форме CRM. Вот простой, но неподдерживаемый способ, который будет информировать, когда пользователь закрывает диалоговое окно поиска адреса:

if (document.all._MBLookupAddress != null) {
	document.all._MBLookupAddress.onclick = function() {
		LookupAddress();
		alert("Поиск адреса закрыт");
	}
}

Сообщение выскакивает после того, как диалоговое окно поиска адреса закрыто, но при этом нет никакого способа различить, выбрал ли пользователь адрес или отменил выбор. Конечно же, это неподдерживаемая настройка, т.к. используются неописанные функции.

if (условие) ? действие если истина : действие если ложь;

Я часто использую вышеупомянутую конструкцию, потому что это – легкий способ установить значение в один из двух значений. Эта конструкция доступна в C, C++, Java, C#, и я уверен, что у большинства других языков есть подобные команды. Вот аналог этой конструкции, но уже с использованием if/then/else:

if (условие) {
	//действие если истина;
} else {
	//действие если ложь;
}

А вот реальный пример:

var s = (crmForm.all.my_lookup.DataValue == null) ? null : crmForm.all.my_lookup.DataValue[0].name;

И то же самое с if/then/else:

var s;

if (crmForm.all.my_lookup.DataValue == null) {
	s = null;
} else {
	s = crmForm.all.my_lookup.DataValue[0].name;
}

Перечисление всех полей на форме CRM

Если Вы хотите перебрать в цикле все поля (поля ввода) на форме CRM, Вы можете использовать следующий скрипт как отправную точку:

for (var index in crmForm.all) {
	var control = crmForm.all[index];

	if (control.req && (control.Disabled != null)) {
		//скриптик
	}
}

Условия означают, что у поля должен быть атрибут «req» и метод Disabled. Ккажется это хороший индикатор для поля CRM формы.

Как узнать с какой версией CRM (3.0 или 4.0) Вы работаете?

Довольно легко определить работает ли Ваш код на CRM 4.0 или нет. Только выберите метод или переменную, которая не существовала в CRM 3.0 и проверьте доступна ли она:

if (typeof(GenerateAuthenticationHeader) == "undefined") {
	alert("Версия 3");
} else {
	alert("Версия 4");
}

GenerateAuthenticationHeader была введена в CRM 4.0 и является глобальной функцией, доступной во всех формах.

Отображение/скрытие вкладок на основе выбранного значения в picklist’е

Следующий скрипт скрывает одну из трех вкладок, в зависимости от выбранного значения в поле new_combo. Если же не выбрано ни одно значение или выбрано значение отличное от первых трех, отображаются все вкладки.

OnLoad:

//Проверяем существование поля new_combo
if (crmForm.all.new_combo != null) {
	crmForm.all.new_combo.FireOnChange();
}

OnChange:

//Проверяем что форма создания, обновления, только для чтения или деактивированная
if ((crmForm.FormType >= 1) && (crmForm.FormType <= 4)) {

	var value = crmForm.all.new_combo.DataValue;

	crmForm.all.tab1Tab.style.display = (value == "1") ? "none" : "";
	crmForm.all.tab2Tab.style.display = (value == "2") ? "none" : "";
	crmForm.all.tab3Tab.style.display = (value == "3") ? "none" : "";
}

Изменение цвета фона формы (CRM 4.0)

Просто скопируйте следующий код на событие OnLoad:

document.all.areaForm.style.backgroundColor = 'yellow';
document.all.tab0.style.backgroundColor = 'red';
document.all.tab1.style.backgroundColor = 'blue';
document.all.tab2.style.backgroundColor = 'green';
document.all.tab3.style.backgroundColor = 'cyan';

Вышеупомянутый код работает для объекта с 4 вкладками. Если у Вас количество вкладок различается, то удалите нужно количество последних строк или добавьте нужное количество по аналогии с ними же (tab0 = первая вкладка, tab1 = вторая вкладка и т.д.).

Вместо того, чтобы использовать названия цветов, Вы также можете задать их с помощью RGB, например:

document.all.tab0.style.backgroundColor = '#A040FF';

Вычисление разницы между двумя числовыми полями

Это кажется достаточно простым:

var result = crmForm.all.num_field1.DataValue - crmForm.all.num_field2.DataValue;

Но этот код сломается, если любое из этих двух полей будет равно null (т.е. пустым). Поэтому вместо этого используйте:

var fieldValue1 = (crmForm.all.num_field1.DataValue == null) ? 0 : crmForm.all.num_field1.DataValue;
var fieldValue2 = (crmForm.all.num_field2.DataValue == null) ? 0 : crmForm.all.num_field2.DataValue;
var diff = fieldValue1 - fieldValue2;

Или так (оно проще, но первое более информативно):

var fieldValue1 = crmForm.all.num_field1.DataValue ? 0 : crmForm.all.num_field1.DataValue;
var fieldValue2 = crmForm.all.num_field2.DataValue ? 0 : crmForm.all.num_field2.DataValue;
var diff = fieldValue1 - fieldValue2;

Деактивация всех полей формы

for (var index in crmForm.all) {
	var control = crmForm.all[index];

	if (control.req && (control.Disabled != null)) {
		control.Disabled = true;
	}
}
Комментарии (43)
  • Антон 15.07.2009

    Супер!
    Я, человек который низрена не знает в JavaScript и иже с ними — смог написать скрипт для события OnLoad и скрыть/показать вкладки, и сделать неактивными некоторые поля при(в зависимости от) выборе определенного пункта пикЛиста.

    Теперь у меня есть вопрос — есть некое кастомное поле в формате «bit» на форме Oportunity — можно ли его заполнить в зависимости от наличии позиции в счете для этой Oportunity? т.е. если в счете есть позиция — то на поле должна появится «галка» ???

  • slivka_83 15.07.2009

    Я не совсем понял про счет? Вы имеете ввиду объект Счет?

  • Антон 15.07.2009

    Ну да, Объект счет — в нем один из пунктов (продукт/услуга), например — «Техобслуживание а/м иностранного производства». Так вот задача — на основнии «наличия» данного пункта в объете счет — в объекте Возможная Сделка (Oportunity) — поставить «галочку» — Иноморка…
    Вот такая вот задача. Если она, конечно решаема..

  • slivka_83 15.07.2009

    Это можно сделать с помощью SOAP запроса. Суть в том, что нужно запросить с формы объекта Возможная сделка значение какого-либо поля объекта Счет. Вот подходящий пример http://technet.microsoft.com/en-us/library/cc677073.aspx . Берете этот пример и изменяете содержимое самого запроса с помощью утилиты FetchXML Builder: http://mmcrm.ru/?p=494

  • Антон 15.07.2009

    Про Lookup по-умолчанию — скрипт следовало написать:
    if (crmForm.all. != null) {
    crmForm.all..setAttribute(«defaulttype», «2»);
    }

    (во второй строчке пропущено — долго искал «грабли»

  • slivka_83 15.07.2009

    Спасибо 🙂 поправим 🙂

  • Антон 15.07.2009

    вопрос: можно ли чтобы в поле лукапа автоматичесуи подставлялоь первое значени?
    т.е. например при добавлении продукта в Заказ — поле Еденица измерения заполнялось еденицей измерения (она одна у каждой позиции прайс-листа)

  • slivka_83 15.07.2009

    ничего кроме того же soap-запрса в голову не приходит 🙂

  • Антон 15.07.2009

    Осталось разобраться в этом «могучем SOAP — запросе» )))
    ps а у меня еще какойто Stunware стоит (покупал лицензию на сервер и пользователей) — с чем его едят и для чего он нужен?? а то деньги то уплочены(((

  • slivka_83 15.07.2009

    А можно поподробнее про «какой-то» :)Stunware это компания и выпускает несколько программных прдуктов (относящихся к CRM).

  • Антон 15.07.2009

    filtered lookup©

  • slivka_83 15.07.2009

    В основно эта штука служит для сильной кастомизации лукапов. В частности позволяет с помощью визуальных инструментов настроить фильтры на лукап. Т.е. например можно позволить пользователю выбирать записи для лоукапа с определеных значение какого-либо поля. Также очень интресная функция создания мульти-лукапов (в стандартной системе можно создавать лукапы только для одного объекта).
    Вот страничка этого продукта: http://www.stunnware.com/default.aspx?area=products&group=fld4&subarea=fld4-overview
    тут есть несколько скриншотов 🙂

  • Stanislav 15.07.2009

    Доброго времени суток!
    Как сгенерировать ссылку такого вида в iFrame
    http:///Workplace/home_activities.aspx
    для отображения действий совешенных с конкретной организацией?
    Я так понимаю в поле «кому звонок», формы можно запростить ID организации. И его подставить в эту сслку тогда, будет отображение «Журнала» Организации. Так получится?

  • Азат 15.07.2009

    Помогите скрыть вкладку по условию!
    Ситуация такая: объект доступен для чтения всей организации, однако часть информации (которая располагается на отдельной вкладке в форме) должна быть доступна не всем. Если юзер принадлежит тому же подразделению, что и создатель/владелец объекта, вкладка должна быть видна, если юзер из другого подразделения, то скрыта.
    Какой код нужно добавить к вышеприведенному в «Скрытие вкладок»?

  • slivka_83 15.07.2009

    Добрый день.
    1. Подразделение владельца записи есть в одно системном поле на форме. Сейчас не могу точно посмотреть гео название, но если не ошибаюсь оно называется что-то вроде ownerbusinessunit.
    2. Потм слеедуюет вытащить подразделение текущего пользователя. В этом Вам могут помочь http://mmcrm.ru/?p=291 и http://msdn.microsoft.com/en-us/library/cc677076.aspx
    3. Ну а дальше сравниваете их и в зависимости отрезультатов сравнения скрываете или не скрвыаете вкладку 🙂

  • Азат 15.07.2009

    1. owningbusinessunit
    2. Решение нашел тут:
    http://mscrmblogger.com/2009/09/30/get-current-users-business-unit-for-hiding-fields/
    3. Завтра попробую реализовать

  • Азат 15.07.2009

    Итак, скрытие конфиденциальных полей и закладок

    function GetMyBusinessUnit() {  
        var xml = "" +  
        "<?xml version='1.0' encoding='utf-8'?>" +  
        "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +  
        " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +  
        " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +  
        GenerateAuthenticationHeader() +  
        "<soap:Body>" +  
        "<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +  
        "<fetchXml>" +  
        " &lt;fetch mapping='logical' count='1'&gt;" +  
        " &lt;entity name='businessunit'&gt;" +  
        " &lt;attribute name='name' /&gt;" +  
        " &lt;filter&gt;" +  
        " &lt;condition attribute='businessunitid' operator='eq-businessid' /&gt;" +  
        " &lt;/filter&gt;" +  
        " &lt;/entity&gt;" +  
        " &lt;/fetch&gt;" +  
        "</fetchXml>" +  
        "</Fetch>" +  
        "</soap:Body>" +  
        "</soap:Envelope>";  
        var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");  
        xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);  
        xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");  
        xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");  
        xmlHttpRequest.setRequestHeader("Content-Length", xml.length);  
        xmlHttpRequest.send(xml);  
        var resultXml = xmlHttpRequest.responseXML;  
        var resultSet = resultXml.text;  
        resultSet.replace('&lt;', '< ');  
        resultSet.replace('&gt;', '>');  
        var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");  
        oXmlDoc.async = false;  
        oXmlDoc.loadXML(resultSet);  
        var result = oXmlDoc.getElementsByTagName('name');    
        return result[0].text;  
    } 
    function UserHasBusinessUnit(businessUnits)  
    {  
      var mybu = GetMyBusinessUnit();  
      for (j = 0; j < businessUnits.length; j++)  
      {  
        // If there is a match, return true, found  
        if (mybu == businessUnits[j]) return true;  
      }    
      //otherwise return false  
      return false;  
    }  
    
    if (UserHasBusinessUnit(["Название подразделения1", "Название подразделения2"]) == false){
    	crmForm.all.tab0Tab.style.display = "none"; //Скрываем вкладку
            crmForm.all.<fieldname>_c.style.display = "none"; //Скрытие метки поля
            crmForm.all.<fieldname>_d.style.display = "none"; //Скрытие самого поля
    }
    

    В данном примере скрываются закладка и поле, если юзер не является членом одной из перечисленных организации.

    Однако вопрос, как получить организацию создателя/собственника формы, остается открытым.

    crmForm.all.owningbusinessunit.DataValue не помогает 🙁

    Ай нид хелп!

  • екатерина 15.07.2009

    как замутить такую штуку: надо чтоб на закрытие возможной сделки выполнялся скрипт, прописанный на onload формы клиента?

  • slivka_83 15.07.2009

    Добрый день 🙂

    -> Азат
    Так просто до owningbusinessunit не добраться 🙂 оно не вынесено на форму поэтом не содержится в массиве crmForm.all 🙂 А на форму его поместить нельзя, т.к. оно системное.

    Вариант 1:
    Создаете кастомное лукап на объект Организация и выводите его на форму. Далее создаете простой бизнес-процесс, который будет копировать значение из поля owningbusinessunit в кастомный лукап (вынесенный на форму) 🙂 Срабатыванием поставить создание карточки и изменение поля owningbusinessunit 🙂

    Вариант 2:
    Написать SOAP запроса, который будет обращяться к текущей записи за полем owningbusinessunit 🙂

    Но учтите, что owningbusinessunit хранит организацию текущего владельца, а не создателя карточки 🙂 Поэтому, Вам нужно будет также написать SOAP запрос, который будет вытаскивать продразделение создателя карточки из объекта systemuser 🙂
    Ну, или как вариант: также бизнес-процесскопирующий значение Организация с карточки пользователя в лукап текущей формы 🙂

  • slivka_83 15.07.2009

    -> екатерина

    Вроде как все просто 🙂
    Создаете на онлоаде глобальную функцию, в которую помещаете весь код онлоада. Там жее ее и вызываете, чтобы сработал онлоад 🙂

    gFunc = function() {
     alert("Привед!");
    }
    
    gFunc();
    

    а потом на онсейве также ее вызываете 🙂

    gFunc();
    

    П.С. надеюсь под закрытием Вы имели ввиду онсейв 🙂

  • екатерина 15.07.2009

    ну не совсем
    суть в том чтобы при закрытии сделки происходило событие OnLoad и OnSave для формы Бизнес-партнера к которому она относится
    Это в принципе возможно?

  • slivka_83 15.07.2009

    Так, давайте уточним…
    Вы но онсейве Возможной сделки вешаете перехват события «закрытие» и хотите выполнить код расположенный на OnLoad и OnSave формы связанного Бизнес-партнера? причем сама форма этого связанного Бизнес-партнера не открыта? и причем этот код должен выполниться в отношении этой не открытой формы связанного Бизнес-пртнера?

  • екатерина 15.07.2009

    Суть в том, что в форме Бизнес-партнера на онлоад прописан код, который считает фактический доход от всех сделок с этим партнером. Хочется, чтобы когда закрывается сделка, происходила актуализация этих данных в форме бизнес-партнера. соответственно, чтобы для этого не приходилось открывать и сохранять форму бизнес-партнера.

  • slivka_83 15.07.2009

    Ясно:
    1. Выолнить JS-код на не открытой форме нельзя 🙂
    2. Код на Бизнес-партнере у Вас обращается к веб-сервису чтобы собрать информацию по Возможным сделка и произвести расчеты. Поэтому аналогичный код Вы можете повесить и на онсейв Возожной сделки, чтобы он подсчитываел доход и сохранял в карточке Бизнес-партнера без ее открытия 🙂

  • екатерина 15.07.2009

    это-то понятно
    я не понимаю, как обращаться к полям формы Бизнес-партнера из формы Возможной сделки.

  • екатерина 15.07.2009

    ребята подскажите где в этой части кода косяк?
    if (crmForm.new_id.DataValue==null)
    {
    crmForm.all.estimatedclosedate.DataValue=new Date(’01/01/2020′);}

    if (crmForm.estimatedvalue.DataValue==0)
    {
    if( crmForm.new_vol.DataValue==0)
    {
    crmForm.new_classification.DataValue=1;
    crmForm.closeprobability.value=0;
    }
    else
    {

    if(crmForm.all.estimatedclosedate.DataValue==new Date(’01/01/2020′))
    {
    crmForm.new_classification.DataValue=2;
    crmForm.closeprobability.value=10;
    }
    else
    {
    crmForm.new_classification.DataValue=3;
    crmForm.closeprobability.value=40;
    }
    }
    }
    else
    {
    crmForm.new_classification.DataValue=4;
    crmForm.closeprobability.value=70;
    }

    никогда не переходит по ветке, где дата, даже если она по умолчанию не меняется

  • slivka_83 15.07.2009

    А можно поподробнее? номер строчки до которой код не доходит? и еще… на какой форме скрипт работает? и объясните плиз бизнес-смысл этого кода 🙂

  • Александр 15.07.2009

    Добрый день!

    Подскажите, на форме есть поле которое доступно для чтения, которое меняется в JavaScript коде по событию OnChange другого поля. Но при сохранении формы, поле которое было доступно для чтения не сохраняет новое значение, каким образом можно это поправить?

  • slivka_83 15.07.2009

    Добрый день 🙂
    Для отключенного поля нужно выполнить такую строчку:

    crmForm.all.<имя_поля>.ForceSubmit;
    
  • Александр 15.07.2009

    Спасибо за ответ!

    Вешал данный код на Onload формы все равно не помогло.
    Сейчас работает так:
    На Onload повесил блокирование полей для редактирования+ForceSubmit, а на событие OnSave снимаю запрет редактирования полей, которые блокирую в OnLoad.

  • Дмитрий 15.07.2009

    Добрый день!

    подскажите плиз как преобразовать срм дату (в строке) в обычную.
    используя soap я получаю дату создания объекта в виде строке в формате «2010-11-21 T00:00:00 +03:00»
    каким образом я могу преобразовать его в Date

  • slivka_83 15.07.2009

    В статье http://mmcrm.ru/?p=1009 раздел «Форматирование даты/времени»

  • Дмитрий 15.07.2009

    loadArea(«areaContacts»);

    Пишет необходим объект. Подскажите пожалуйста какой?

  • slivka_83 15.07.2009

    Добрый день.

    А можно спросить что Вы делаете и что получаете?

  • Дмитрий 15.07.2009

    вставляю строчку

    loadArea(«areaContacts»);

    в обработчик формы.

    получаю ошибку.

    Понятно что loadArea функция объекта, но вот какого понять не могу. 🙁

    Антиспам защита: сколько будет 6 + 2 ?
    8

  • slivka_83 15.07.2009

    > Понятно что loadArea функция объекта, но вот какого понять не могу.
    Любого 🙂

    Вопрос в том что Вы передаете в эту функцию 🙂
    В данном примере:

    loadArea(«areaContacts»);

    В левой навигационной области карточки Бизнес-партнера открывается свзяанное Представление Контактов.

    При этом у каждой ссылки в навигационной панели есть уникальное название (которое и передается в функцию loadArea). Чтобы узнать его, можно воспользоваться Explorer Developer Toolbar (в IE8 и выше он встроен — вызывается по F12).

  • Азат 15.07.2009

    Коллеги, подкиньте код, как скрыть один из пунктов пиклиста в зависимости от значения другого поля?
    Динамический пиклист не интересует

  • slivka_83 15.07.2009

    какой CRM? 🙂

  • Азат 15.07.2009

    4.0. Плиз, хелп

  • slivka_83 15.07.2009

    А почем динамический не интересует?

  • Азат 15.07.2009

    Потомучто поля, от которых должен зависеть перечень пунктов для отображения в зависимом пиклисте, не являются пиклистами :))

  • Ярослав 15.07.2009

    Смею заметить, getYear устаревший метод.
    Для работы с датой используйте getFullYear.

*

code