Каталог решений - Программно свернуть/развернуть узел динамического списка (с основной таблицей). Жирная точка над всеми i.

Программно свернуть/развернуть узел динамического списка (с основной таблицей). Жирная точка над всеми i.

Программно свернуть/развернуть узел динамического списка (с основной таблицей). Жирная точка над всеми i.

В наличии

Какой пользователь не мечтал поменьше тыркать кнопкой? Особенно в малюсенькие +/- в «древесных» динамических списках.
Если вас тоже озадачили, чтобы, при выборе узла дерева сами развернулись все его вложенные элементы , а при выборе другого узла — так же автоматом свернулась ранее развернутая ветка (причем эти узлы могут находится в разных «отношениях» друг с другом)… То вам — сюда.

Категория:

Описание

(NB: еще раз — речь про дин.  список с основной таблицей!)

Задача, с виду тривиальная,  оказалась с подвохом. Поведение ДС не совсем поддается логике кода 1С — кое-что разработчики платформы переложили на плечи магии.

Например, приходится методы Развернуть/Свернуть выносить в отдельные процедуры, которые подключаются через ПодключитьОбработчикОжидания. Непосредственное выполнение их в обработчике события активизации строки приводит к "барабашкам" (отлов которых отнял немало времени и нервов; описывать не буду — кто хочет, экспериментируйте!). 

А вот, собственно, задача и код:

1. Дело происходит в конфигурации Документооборот КОРП, в форме списка внутренних документов. Здесь есть дин. список с именем "Папки", с основной таблицей Справочник.ПапкиВнутреннихДокументов, в виде дерева. При выборе папки должно раскрыться ее содержимое; при выборе другой папки — если она не является "дочерней" — ранее выбранная должна свернуться. Уровней иерархии может быть много; понятно, что свернуть надо все (но так, чтобы выбранная не "закрылась").

2. Для этого дин. списка уже есть обработчик ПапкиПриАктивизацииСтроки:

  
  &НаКлиенте
  Процедура ПапкиПриАктивизацииСтроки(Элемент)
  	
  	Если ВидПросмотра = ПредопределенноеЗначение("Перечисление.ВидыПросмотраСпискаОбъектов.ПоПапкам")
  		И Элементы.СтраницаПапки.Видимость 
  		И ТекущаяПапка <> Элементы.Папки.ТекущаяСтрока Тогда 
  		
  		ТекущаяПапка = Элементы.Папки.ТекущаяСтрока;
  		
  		ПодключитьОбработчикОжидания("ОбработкаОжидания", 0.2, Истина);
  	КонецЕсли;
  	
  КонецПроцедуры

Здесь ТекущаяПапка — реквизит формы (а обработчик ОбработкаОжидания нам не интересен, на нашу задачу он не влияет).

В расширении я добавил два реквизита формы: ПапкаДляСворачивания  и ПапкаДляРазворачивания, а также два расширения — Перед и После — обработчика ПапкиПриАктивизацииСтроки:

  
  #Область АвторазворачиваниеПапок
  
  &НаКлиенте
  Процедура jibПапкиПриАктивизацииСтрокиПеред(Элемент)
  	
  	// ТекущаяПапка - та папка, которая была выбрана РАНЕЕ; Элементы.Папки.ТекущаяСтрока - та папка, выбор которой вызвал событие
  	Если ВидПросмотра = ПредопределенноеЗначение("Перечисление.ВидыПросмотраСпискаОбъектов.ПоПапкам")
  		И Элементы.СтраницаПапки.Видимость 
  		И НЕ Элементы.Папки.ТекущаяСтрока = ТекущаяПапка Тогда
  		
  		// проверка на случай, если выбранная папка принадлежит той, что уже развернута (т.е. ТекущаяПапка) - тогда ничего делать не надо
  		Если ВыбранаПапкаДругойВетки(Элементы.Папки.ТекущаяСтрока, ТекущаяПапка) Тогда
  			
  			ПапкаДляСворачивания = ТекущаяПапка;
  			ПодключитьОбработчикОжидания("СвернутьПапки", 0.1, Истина);
  			
  		КонецЕсли; 
  		
  	КонецЕсли; 
  	
  КонецПроцедуры
  
  &НаКлиенте
  Процедура jibПапкиПриАктивизацииСтрокиПосле(Элемент)
  	
  	Если ВидПросмотра = ПредопределенноеЗначение("Перечисление.ВидыПросмотраСпискаОбъектов.ПоПапкам")
  		И Элементы.СтраницаПапки.Видимость Тогда 
  		
  		ПапкаДляРазворачивания = Элементы.Папки.ТекущаяСтрока;
  		ПодключитьОбработчикОжидания("РазвернутьПапки", 0.1, Истина);
  		
  	КонецЕсли;
  	
  КонецПроцедуры
  
  &НаСервере
  Функция ВыбранаПапкаДругойВетки(ВыбраннаяПапка, ПредполагаемыйРодитель)
  	
  	Возврат ТипЗнч(ВыбраннаяПапка) = Тип("СправочникСсылка.ПапкиВнутреннихДокументов")
  		И ТипЗнч(ПредполагаемыйРодитель) = Тип("СправочникСсылка.ПапкиВнутреннихДокументов")
  		И НЕ ВыбраннаяПапка.ПринадлежитЭлементу(ПредполагаемыйРодитель);
  	
  КонецФункции
  
  &НаСервере
  Функция ПолучитьРодителяПапки(ВыбраннаяПапка)
  	
  	Возврат ВыбраннаяПапка.Родитель;
  	
  КонецФункции
  
  &НаКлиенте
  Процедура РазвернутьПапки()
  	
  	Если НЕ Элементы.Папки.Развернут(ПапкаДляРазворачивания) Тогда
  		
  		Элементы.Папки.Развернуть(ПапкаДляРазворачивания);
  		
  	КонецЕсли;
  	
  КонецПроцедуры
  
  &НаКлиенте
  Процедура СвернутьПапки()
  	
  	Если Элементы.Папки.Развернут(ПапкаДляСворачивания) Тогда
  		
  		Элементы.Папки.Свернуть(ПапкаДляСворачивания);
  		
  		// перебираем "предков" ранее развернутой папки: сворачиваем их; но если выбранная папка содержится каким-то из них - прерываем перебор
  		РодительПапкиДляСворачивания = ПолучитьРодителяПапки(ПапкаДляСворачивания);
  		Пока ЗначениеЗаполнено(РодительПапкиДляСворачивания) Цикл
  			// проверка: если выбранная папка принадлежит той, что уже развернута - ничего делать не надо
  			Если ВыбранаПапкаДругойВетки(ПапкаДляРазворачивания, РодительПапкиДляСворачивания) Тогда
  				Если Элементы.Папки.Развернут(РодительПапкиДляСворачивания) Тогда
  					Элементы.Папки.Свернуть(РодительПапкиДляСворачивания);
  				КонецЕсли; 
  				РодительПапкиДляСворачивания = ПолучитьРодителяПапки(РодительПапкиДляСворачивания);
  			Иначе
  				Прервать;
  			КонецЕсли; 
  		КонецЦикла;
  		
  	КонецЕсли;
  	
  КонецПроцедуры
  
  #КонецОбласти 
  

В общем-то, комментарии, наверно, излишни. Пользуйтесь на здоровье!

has been added to your cart:
Оформление заказа