Да, давно не писал, но это жизнь, которой мало, и работа, которой много. Вот по работе иногда приходится хлопать одной ладонью.
Так и на прошлой неделе - нужно было приделать к редактору модели в jqGrid свой элемент для редактирования дат, наподобие того, что генерят рельсы в ответ на select_date. Скудость документации и отсутствие толковых примеров и как следствие полдня экспериментов на пути к желаемому и стали причинами появления данного поста.
Для начала обратимся к истокам и объявим наше поле как custom, указав свои функции для создания элемента и извлечения значения из него.{name:'v_birth', index:'v_birth',formoptions:{elmprefix:"*  "},edittype:'custom',editable:true,editoptions:{custom_element:dinput, custom_value:dvalue}}
Дальше немного JS магии.
function dinput (value, options) { | |
var m = document.createElement("select"); | |
var d = document.createElement("select"); | |
var y = document.createElement("select"); | |
m.setAttribute('class', 'month'); | |
var o = document.createElement('option'); | |
var t = document.createTextNode('--'); | |
o.appendChild(t); | |
m.appendChild(o); | |
for(var month = 1; month <= 12 ; month++) | |
{ | |
o = document.createElement('option'); | |
t = document.createTextNode(month); | |
o.setAttribute('value', month); | |
if(month == Number(value.substring(0,2))) | |
{ | |
o.setAttribute('selected', 'yes'); | |
} | |
o.appendChild(t); | |
m.appendChild(o); | |
} | |
d.setAttribute('class', 'day'); | |
o = document.createElement('option'); | |
t = document.createTextNode('--'); | |
o.appendChild(t); | |
d.appendChild(o); | |
for( var day = 1; day <= 31; day++ ) { | |
o = document.createElement('option'); | |
t = document.createTextNode(day); | |
o.setAttribute('value', day); | |
if(day == Number(value.substring(3,5))) | |
{ | |
o.setAttribute('selected', 'yes'); | |
} | |
o.appendChild(t); | |
d.appendChild(o); | |
} | |
y.setAttribute('class', 'year'); | |
o = document.createElement('option'); | |
t = document.createTextNode('--'); | |
o.appendChild(t); | |
y.appendChild(o); | |
for( var year = 1850 ; year <= 2010; year++ ) { | |
o = document.createElement('option'); | |
t = document.createTextNode(year); | |
o.setAttribute('value', year); | |
if(year == Number(value.substring(6,10))) | |
{ | |
o.setAttribute('selected', 'yes'); | |
} | |
o.appendChild(t); | |
y.appendChild(o); | |
} | |
var b = document.createElement('button'); | |
t = document.createTextNode('X'); | |
b.appendChild(t); | |
$(b).click(function(){ | |
$(m).find('option:first').attr('selected', 'yes'); | |
$(d).find('option:first').attr('selected', 'yes'); | |
$(y).find('option:first').attr('selected', 'yes'); | |
}); | |
return [m,d,y, b]; | |
} | |
function dvalue(elem) | |
{ | |
var res = $(elem).filter('select').map(function() { | |
return $(this).val(); | |
}).get().join('-'); | |
if(res == '--------') | |
{ | |
return ''; | |
} else { | |
return res; | |
} | |
} |
Создаём, заполняем значениями с выбором одного из них, и возвращаем массивом три select'а и кнопку сброса.
Подразумевается, что в таблицу дата приходит в американском формате (mm-dd-yyyy), именно поэтому у меня поле называется v_birth - это виртуальный атрибут, в базе это естественно тип Date. О валидации таких атрибутов и их применении совместно с jqGrid стоит сказать, пожалуй, отдельно, своим постом.
Пользователь увидит три селекта и кнопку сброса их в начальное значение (--). Браузер - невалидный код (три селекта с одинаковым id), но промолчит. Функция извлечения значения благодаря этому увидит все три select'а, отмапит их в массив выбранных значений и склеит из него строку. Бэкенд - либо опять же дату в американском формате, либо пустую строку, если пользователь сбросил дату, либо неверную дату, и может сохранить, об NULL'ить или остановить валидацию на своё усмотрение.
И для завершения - ещё один штрих. Истоки.
...
.navGrid('#my_pager', {edit:true,add:true,del:true,search:false,refresh:true}, {recreateForm:true, afterSubmit:function(r,data){return afterSubmit(r,data,'edit');}},
....
Такие вот пироги. Надеюсь, юбилейная 200-я запись была вам полезна.