суббота, 6 декабря 2014 г.

Работа с полями элемента с помощью jQuery (jQuery + SharePoint 2013 Fields Part 3)

В продолжении своих статей:
Сегодня я раскажу:
1. Скрываем поля в зависимости от значения поля Да/Нет
2. Собираем значение текстового поля из других полей


Скрываем поля в зависимости от значения поля Да/Нет
Допустим у нас есть поле «Установить ПО» типа Да/Нет, и нам нужно в зависимости от его значения скрывать поле «Дополнительное ПО».
Так как по умолчанию поле  «Установить ПО» имеет значение Нет, то при загрузке формы поле «Дополнительное ПО» должно быть уже скрыто.

$(document).ready(function() {
  $('nobr:contains("Дополнительное ПО")').closest('tr').hide();
});

Далее нам нужно ждать, когда изменится значение поля «Установить ПО»
_spBodyOnLoadFunctionNames.push("changePO");
function changePO()
{
 $("input[title='Установить ПО']").change(function () {
  alert('test')
 });
}

Хорошо, следующий этап получать значение поля и в зависимости от этого скрывать/открывать поле  «Дополнительное ПО»

if($("input[title='Установить ПО']").prop('checked'))
{             
                $('nobr:contains("Дополнительное ПО")').closest('tr').show();
}
else{
                $('nobr:contains("Дополнительное ПО")').closest('tr').hide();              
}


Отлично, получили чего хотели, но мне не понравилась работа скрипта. Не хватало плавности и анимации. И тогда я решил добавить «эффектов»
$('nobr:contains("Дополнительное ПО")').closest('tr').show(100);
Но не получил нужный результат, т.к. поле «Дополнительное ПО» имело тип Многострочный текст, то ото в себе содержит еще один большой блок td, который уже отображается и плавности я не получил. Тогда я решил добавить скрытие, а потом отображение внутреннего td
$('nobr:contains("Дополнительное ПО")').closest('td').next('td').hide()
                $('nobr:contains("Дополнительное ПО")').closest('td').next('td').show(600)
Теперь все.
Весь код:


_spBodyOnLoadFunctionNames.push("changePO");

function changePO()
{

 $("input[title='Установить ПО']").change(function () {

  if($("input[title='Установить ПО']").prop('checked'))
  {
   $('nobr:contains("Дополнительное ПО")').closest('tr').show(100);
   $('nobr:contains("Дополнительное ПО")').closest('td').next('td').hide()
   $('nobr:contains("Дополнительное ПО")').closest('td').next('td').show(600)
  }
  else{
   $('nobr:contains("Дополнительное ПО")').closest('td').next('td').hide("slow")
   $('nobr:contains("Дополнительное ПО")').closest('tr').hide("fast");  
  }
 });
}
Полученный результат

Собираем значение текстового поля из других полей
Разберем ситуацию, когда пользователь заполняет заявку на виртуальную машину, и нужно построить  название новой виртуальной машины из значений нескольких полей : «Принадлежность к системе», «Назначение машины» и «Номер машины». Из которых 2 поля меню (выбор) и одно число.
Алгоритм я реализовал следующий:
Добавляем код, который будет реагировать на изменение каждого поля и в случае изменения запускается функция, которая получает значение всех трех полей, строит строку и заполняет значение в нужное поле (Название)
Первое, сделаем «Название» не доступное для редактирования

$(document).ready(function() {
    $("input[title='Название']").attr("disabled", "disabled");      
});


Далее функции реагирующие на изменение полей и функция изменяющая название.


_spBodyOnLoadFunctionNames.push("changeSysMash");

function changeSysMash()
{
$("Select[title='Принадлежность к системе']").change(function () {
setTitle();
});
}

_spBodyOnLoadFunctionNames.push("changeTypeMash");

function changeTypeMash(){
$("Select[title='Назначение машины']").change(function () {
setTitle();
});
}
_spBodyOnLoadFunctionNames.push("changeNumMash");

function changeNumMash()
{
$("input[title='Номер машины']").change(function () {
setTitle();
});
}
function setTitle()
{
// меняем название элемента
                var sys = $("select[title='Принадлежность к системе'] option:selected").text();
                var typeSys = $("select[title='Назначение машины'] option:selected").text();
                var numMash = $("input[title='Номер машины']").val();
                if (typeSys == 'Prod')
                {
                               var nameMash = sys + '-' + numMash
                }
                else
                {
                               var nameMash = sys + '-'+ typeSys + '-' + numMash
                }
               
                $("input[title='Название']").val(nameMash);
}
В последней функции я предусмотрел проверку значения, если 'Назначение машины' продуктивная, то значение поля не участвует в формировании названия.
Вот результат 


P.S. единственным минусом работы на клиенте, это то что работаем мы с displayname названиями полей и следовательно, нужно быть внимательными при переименовании полей.

Обновление!!! 19.02.2015

К полям можно обращаться по ID, а не по отображаемому имени и тем самым мы уходим от проблемы изменения отображаемого имени.
пример скрытия поля, где мы обращаемся по IntarnalName поля

$("[id^='Title']").closest('tr').hide();