Кастомизация
08
Сен
19

Динамический picklist

Небольшой пример динамического пиклиста. В основе лежат массивы для каждой из «групп», в которых заданы целочисленные значения тех опций picklist’а, которые допустимы для каждой из группы. Когда изменено значение группы (т.е. значение родительского пиклиста) использую оператор case, чтобы применить нужный массив опций к дочернему пиклисту.

В примере фильтруется список городов (new_city, подчиненный пиклист), основанных на федеральном округе (new_region, основной пиклист).

На онлоад повесьте следующий скрипт:

// Задействем динамический пиклист, только на форме Создания или Обновлния. На Дактивированных или формах Только для чтения динамический пиклист без надобности!
if (crmForm.FormType == 1 || crmForm.FormType == 2) {

	// создаем ссылки на пиклисты
	main = crmForm.all.new_region;   
	sub = crmForm.all.new_city;

	// сохраняем копию оригинальных опций picklist'а
	sub.originalPicklistValues = sub.Options;

	//создаем массив, для хранения необходимые значения picklist'а для каждой категории
	oArraySever = new Array();   
	oArrayYug = new Array();   
	oArrayUral = new Array();   

	// Перечислите в скобках позиции зависимого пикликлиста, которые должны отображаться при выборее соответствующего значения в основном пиклисте
	oArraySever.push(1);   
	oArrayYug.push(2,3);   
	oArrayUral.push(4,5);

	
	document.filterPicklist = function (oDesiredOptions) {   
 
		oTempArray = new Array();   
	  
		// просматриваем все элементы подчиненного пиклиста
		for (var i=sub.length-1;i >= 0;i--) {   
	  
		// если значение опции находится в списке требуемых значений для этой группы
		// тогда добавляем опцию к нашему временному массиву и удаляем   
		// элемент из требуемого массива опции
			for (j=oDesiredOptions.length;j >= 0;j--) {   
				if(sub[i].value == oDesiredOptions[j]) {   
					oTempArray[i] = true;   
				}   
			}   
		}   
	  
    	// Теперь удаляем все опции из подчиненного списка, которые не были отмечены как требуемые
    	for (var i=sub.length;i >= 0;i--) {   
        	if(oTempArray[i] != true) {   
            	sub.remove(i)   
        	}   
    	}   
	}     

}

// если в основном пиклисте при загрузке уже выбрано значение (сохранено ранее), то необходимо в соответствии ему отфильтровать подчиненный пиклист
crmForm.all.new_region.FireOnChange();

А на ончейндж основного пиклиста поместите:

// Задействем динамический пиклист, только на форме Создания или Обновлния. На Дактивированных или формах Только для чтения динамический пиклист без надобности!
if (crmForm.FormType == 1 || crmForm.FormType == 2) {

	// Сбрасываем значения picklist'а на исходные прежде повторно произвести удаление ненужных 	if(!sub.originalPicklistValues) {
	sub.Options = sub.originalPicklistValues;

 	// Теперь вызываем соответствующие параметры фильтрации:
	// значения в каждом выражении "case" берутся из основного пиклиста и передают функции filterPicklist соответствующий им массив
	// Если значение не выбрано, то список очищается

	switch(main.SelectedText) {

		case 'Северо-западный':
		document.filterPicklist(oArraySever);
		break;   

		case 'Южный':
		document.filterPicklist(oArrayYug);
		break;   

		case 'Уральский':
		document.filterPicklist(oArrayUral);
		break;
			
		default:  
		for (var i=sub.length;i >= 0;i--) {  
			sub.remove(i);  
		}  
		break;
	}
}



Комментарии (19)
  • Alberto Farinacci 08.09.2009

    Кривовато работает. Два недочета:

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

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

  • slivka_83 08.09.2009

    Спасибо! 🙂 Поправил 🙂

  • Сергей 08.09.2009

    Еще один недочет — при загрузке сохраненных ранее значение подчиненного пиклиста сбрасывается к первому значению

  • slivka_83 08.09.2009

    На выходныйх поправлю 🙂 если не забуду 🙂 напоминайте если что 🙂

  • Игорь 08.09.2009

    Может подскажете каким образом сделать зависимость пиклиста от текстового поля на одной форме?

  • Игорь 08.09.2009

    В смысле, если текстовое поле равно нулю, то пиклист=2, иначе =1

  • slivka_83 08.09.2009

    Если я правильно Вас понял, то на onChange текстоволго поля нужно повесить примерно такой скрипт:

    var z = crmForm.all.<имя_текстового_поля>.DataValue;
    if (z == "0") {
    crmForm.all.<имя_пиклиста>.DataValue = 2;
    }
    
  • Игорь 08.09.2009

    Спасибо, помогло

  • Николай 08.09.2009

    Забыли поправить «Еще один недочет – при загрузке сохраненных ранее значение подчиненного пиклиста сбрасывается к первому значению»

  • slivka_83 08.09.2009

    Уффф… да забыл 🙂 каюсь 🙂 нада будет поправить… 🙂

  • slivka_83 08.09.2009

    Проверил 🙂 ничего не збрасывается 🙂

  • Николай 08.09.2009

    Ну Вы меня конечно извините, но сброс происходит! Единственное отличие от Вашего скрипта в том, что я использую не SelectedText, а DataValue в коде onChange

  • Николай 08.09.2009

    Даже проверил с SelectedText, все равно сбрасывает!

  • Николай 08.09.2009

    Разобрался. Надо на onLoad добавить
    var p = crmForm.all.ИМЯ.DataValue; (это подчиненный picklist)
    а после
    // если в основном пиклисте при загрузке уже выбрано значение (сохранено ранее), то необходимо в соответствии ему отфильтровать подчиненный пиклист
    crmForm.all.new_region.FireOnChange();
    добавить
    crmForm.all.ИМЯ.DataValue = p; (это подчиненный picklist)

  • slivka_83 08.09.2009

    Разобрались и хорошо… хотя у меня и не воспроизводилось 🙂 может ролапы у нас разные, или какие-то еще факторы на это влияют… ладно, дойдут руки проапгрейжу его до 2011 версии — там и разберемся 🙂

  • Sergey 08.09.2009

    Есть проблема. В объект Звонок, я добавил Пиклист «Результат звонка» и хотел настроить его фильтрацию в зависимости от значения Направления звонка, «Входящее» или «Исходящее»… но вмест отфильтрованных значений получаю пустой пиклист.
    Может подвох в том, что направление звонка имеет тип «bit»? Как тогда надо поступить в этом случаи?

  • slivka_83 08.09.2009

    Направление завонка на форме выглядит как радиобаттоны если мне не изменяет память 🙂 Попробуйте изменить их визуальный вид на ниспадающий список 🙂

  • Николай 08.09.2009

    Сталкивался с такой проблемой. Решил путем добавления нового пиклиста и в зависимости от направления менял пиклист, и тогда зависимость работает.

  • Макс 08.09.2009

    Искал подобную вещь, прежде чем натолкнуться на вашу запись склепал скрипт аля из быдлокодинга, но тоже работает))
    Изначально удалив на онЛоад все значения пиклиста
    Помещаем скрипт на онЧенж поля пиклиста

    value = crmForm.all.new_city.DataValue;
    switch (value)
    {
    case ‘1’:
    crmForm.all.new_post.DeleteOption(1);
    crmForm.all.new_post.DeleteOption(2);
    crmForm.all.new_post.DeleteOption(3);
    crmForm.all.new_post.DeleteOption(4);
    crmForm.all.new_post.DeleteOption(5);
    crmForm.all.new_post.DeleteOption(6);
    crmForm.all.new_post.DeleteOption(7);
    crmForm.all.new_post.AddOption(‘Заведущий складом’, 1);
    crmForm.all.new_post.AddOption(‘Старший кассир’, 2);
    crmForm.all.new_post.AddOption(‘Кассир’, 3);
    crmForm.all.new_post.AddOption(‘Продавец’, 4);
    crmForm.all.new_post.AddOption(‘Мастер сервисного обслуживания’, 5);
    crmForm.all.new_post.AddOption(‘Кладовщик’, 6);

    crmForm.all.new_date.DeleteOption(12);
    crmForm.all.new_date.DeleteOption(1);
    crmForm.all.new_date.DeleteOption(2);
    crmForm.all.new_date.DeleteOption(3);
    crmForm.all.new_date.DeleteOption(4);
    crmForm.all.new_date.AddOption(‘12.09’, 2);
    crmForm.all.new_date.AddOption(‘13.09’, 3);
    crmForm.all.new_date.AddOption(‘14.09’, 4);
    break;
    case ‘2’:
    crmForm.all.new_post.DeleteOption(1);
    crmForm.all.new_post.DeleteOption(2);
    crmForm.all.new_post.DeleteOption(3);
    crmForm.all.new_post.DeleteOption(4);
    crmForm.all.new_post.DeleteOption(5);
    crmForm.all.new_post.DeleteOption(6);
    crmForm.all.new_post.DeleteOption(7);
    crmForm.all.new_post.AddOption(‘Администратор магазина’, 7);
    crmForm.all.new_post.AddOption(‘Кассир’, 3);
    crmForm.all.new_post.AddOption(‘Продавец’, 4);
    crmForm.all.new_post.AddOption(‘Мастер сервисного обслуживания’, 5);
    crmForm.all.new_post.AddOption(‘Кладовщик’, 6);

    crmForm.all.new_date.DeleteOption(12);
    crmForm.all.new_date.DeleteOption(1);
    crmForm.all.new_date.DeleteOption(2);
    crmForm.all.new_date.DeleteOption(3);
    crmForm.all.new_date.DeleteOption(4);
    crmForm.all.new_date.AddOption(‘10.09’, 12);
    crmForm.all.new_date.AddOption(‘11.09’, 1);
    break;
    }

    Ужасно не красиво конечно, но за то тоже работает

*

code