понедельник, 28 января 2013 г.

Создание отношений между списками


Довольно популярная задача, возникающая в рамках практически любого решения на SharePoint  – создание отношений между родительским и дочерним списками. К примеру “Проект – Задачи”, “Район – Улицы”, “Начальник – Подчиненные” и т.д.
Самый очевидный способ связать элементы разных списков – использовать поле “Подстановка” (lookup). На примере отношения “Проект – Задачи”:
Вариант 1: находясь на странице создания задачи (tasks/newform.aspx), выбираем обычным способом родительский проект из списка, это не требует никаких вмешательств в штатный функционал. Способ очень неудобный тем, что при большом количестве проектов приходится искать их в выпадающем списке.
Вариант 2: на странице просмотра проекта (projects/dispform.aspx) размещаем ссылку/кнопку, по клику на которую открывается форма создания задачи (tasks/newform.aspx) с уже заполненным полем “Проект”
Код ссылки/кнопки, который нужно вставить на странице projects/dispform.aspx:

<a href="/../Lists/Tasks/NewForm.aspx?ActID={$Param1}&amp;Source=https%3A%2F%2F..Lists%2Fprojects%2FDispForm%2Easpx&#063;ID={$Param1}">Создать задачу</a>
При этом должен быть заведен параметр в веб-части, в которой мы размещаем ссылку. Заведён так, как показано на рисунке.

Из переменной в адресной строке браузера этот параметр попадёт в tasks/newform.aspx , а атрибут “Source=…” нужен для корректного возврата после сохранения элемента в нужный projects/dispform.aspx
Для того, чтобы значение отобразилось в поле “подстановка” формы tasks/newform.aspx, необходимо вставить на эту страницу код на языке javascript – см. пример в конце статьи.

Отображение связанных записей в DispForm родительского списка

Для того, чтобы связанные записи были видны в форме, делаем следующее.
1. Создаём веб-часть представления дочернего списка в DispForm родительского списка.

 
Поигравшись с вкладкой “конструктор” на Ribbon-панели, можно придать веб-части удобоваримый вид. Например, если известно, что в рамках одного проекта обычно генерируется-назначается 5-6 задач, то очень хорошо подходит вот такой вид:

2. Необходимо добавить фильтр на представление, без него мы будем видеть все элементы списка Задачи. а нам нужны только связанные с конкретным проектом. ID проекта содержится в адресной строке браузера. Как создать параметр, получающий значение из адресной строки – было показано на первом рисунке.
Однако, если мы зададим условие фильтрации “Проект = Param1”, условие не сработает. Дело в том, что фактически мы сравниваем “1#;<название проекта>” и “1” и такое условие не может быть true. Для того, чтобы у нас было корректное поле для сравнения с параметром, нужно в свойствах списка, в параметрах поля-подстановки активировать дополнительное поле Проект:ИД

и уже это поле Проект:ИД использовать в условии фильтрации

Как скрыть поля связи (“lookup”, оно же “подстановка”) из форм

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

или непосредственно в браузере, последовательно – активировать управление типами содержимого в параметрах списка, зайти в тип содержимого, перевести столбец в “скрытый”. убрать управление типами содержимого.
Если нужно скрыть поле только из определённых форм, можно использовать утилиту SharePoint Manager
Она позволяет менять свойства SPField - ShowInEditForm, ShowInDisplayForm, ShowInNewForm. Лежит тут http://spm.codeplex.com/
Запускается на сервере с Sharepoint.

Можно отредактировать форму по умолчанию в дизайнере 2010 :
http://office.microsoft.com/ru-ru/sharepoint-designer-help/HA010378258.aspx
И, наконец, можно скрыть ненужные поля (или даже отобразить дополнительные) с помощью jquery, уже на стороне клиента, в браузере.


Пример установки поля “подстановка” в значение, полученное из адресной строки браузера и последующего скрытия строки с полем “подстановка”:

<script language="javascript" src="../frms/jquery-1.8.2.js" type="text/javascript"></script>
<script language="javascript" src="../frms/jquery.SPServices-0.7.2.js" type="text/javascript"></script>
<script type="text/javascript">
    // This javascript sets the default value of a lookup field identified
    // by <<FIELD DISPLAY NAME>> to the value stored in the querysting variable
    // identified by <<QUERYSTRING VARIABLE NAME>>
    // Customize this javascript by replacing <<FIELD DISPLAY NAME>> and
    // <<QUERYSTRING VARIABLE NAME>> with appropriate values.
    // Then just paste it into NewForm.aspx inside PlaceHolderMain
  
    _spBodyOnLoadFunctionNames.push("fillDefaultValues");
    function fillDefaultValues() {
      var qs = location.search.substring(1, location.search.length);
      var args = qs.split("&");
      var vals = new Object();
      for (var i=0; i < args.length; i++) {
        var nameVal = args[i].split("=");
        var temp = unescape(nameVal[1]).split('+');
        nameVal[1] = temp.join(' ');
        vals[nameVal[0]] = nameVal[1];
      }
      setLookupFromFieldName("Проект", vals["ID"]);
      $('#ctl00_m_g_e74ceaaa_2dcf_4cef_af99_40f05b6563c0_ff20_1_ctl00_ctl01').closest('tr').hide();   //   JQuery
    }
   
    function setLookupFromFieldName(fieldName, value) {
      if (value == undefined) return;
      var theSelect = getTagFromIdentifierAndTitle("select","Lookup",fieldName);
    // if theSelect is null, it means that the target list has more than
    // 20 items, and the Lookup is being rendered with an input element
      if (theSelect == null) {
        var theInput = getTagFromIdentifierAndTitle("input","",fieldName);
        ShowDropdown(theInput.id); //this function is provided by SharePoint
        var opt=document.getElementById(theInput.opt);
        setSelectedOption(opt, value);
        OptLoseFocus(opt); //this function is provided by SharePoint
      } else {
        setSelectedOption(theSelect, value);
      }
    }

    function setSelectedOption(select, value) {
      var opts = select.options;
      var l = opts.length;
      if (select == null) return;
      for (var i=0; i < l; i++) {
        if (opts[i].value == value) {
          select.selectedIndex = i;
          return true;
         }
       }
       return false;
     }
     
    function getTagFromIdentifierAndTitle(tagName, identifier, title) {
        var len = identifier.length;
        var tags = document.getElementsByTagName(tagName);
        for (var i=0; i < tags.length; i++) {
          var tempString = tags[i].id;
          if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length - len)) {
            return tags[i];
          }
        }
        return null;
    }
    </script>

Комментариев нет:

Отправить комментарий