Преди 2 дни видях в Ajaxian - A simple solution to the “other” problem with select boxes, което представлява решение на “другия” проблем, както би се превело буквално. Всъщносто там е представен jquery код с който когато от даден html select избереш “друг(other)” ти се появява input поленце където да кажеш какво точно е това другото. Вижте демо-то, защото май не го обясних добре.
Като идея е добре, но нещо jquery кода не ми се вижда много читав:
$(document).ready( function () {
$('.leader').each( function () {
var name = $(this).attr('name');
if ($(this).val()!='other') {
$(this).next().removeAttr('name').hide();
}
});
$('.leader').change(onChange);
function onChange(){
var desiredName = $(this).attr('name');
if ($('#'+desiredName).val()=='other') {
$('#'+desiredName).next().attr('name',desiredName).fadeIn('fast');
} else {
$('#'+desiredName).next().removeAttr('name').fadeOut('fast');
}
}
});
Много бях изненадан, че това стигна до Ajaxian (въпреки че доста са свалили летвата напоследък). В този код има няколко неща, които не ми харесват:
- 2 пъти прави почти едно и също, избира всичките елементи с клас “leader” и проверява дали е избрана като стойност “other”, за да покаже/скрие следващия елемент.
- 2 пъти прави $(’.leader’), като явно е забравил, че едно от най-яките неща в jquery e changing-a. Спокойно е можел да направи просто $(’.leader).each( … ).change( … )
- на 3тия ред ( var name = $(this).attr(’name’) ), защо го има това и какво прави така и не разбрах, никъде в този scope не ползва name променливата, а и аз лично бих ползвал getAttribute за извличане на атрибута.
- в each-a се вика 3 пъти $() за един и същ елемент ( this в случая), по-добре е добре да се вземе jQuery инстанцията и да се запише в променлива - ще бъде доста по-бързо, когато се ползва.
- аз лично нямаше да сложа скобите на if-a в each-a, защото когато се пише javascript всеки байт е важен
- така и не ми стана ясно защо декларира функция onChange като може да ползва директно анонимна функция при $(’.leader’).change( … ).
- тук добре е направил, че е взел desiredName и го сложил в променлива, но ако някой ми каже защо при положение, че има this му трябва цели 3 пъти да вика jquery css selector с #id (и даже да не го записва в поменлива) ?!?
- малко ме подразниха и излишните празни редове и разстояния
Това са горе долу лошите неща, които видях, въпреки че не пиша много jquery код ми се струва че ако напише кода по този начин ще е доста по-добре:
$(document).ready(function(){
$('.leader').change(function(
var select = $(this);
if(select.val() == 'other')
select.next().attr('name', select.getAttribute('name')).fadeIn('fast');
else
select.next().removeAttr('name').fadeOut('fast');
)).triggerHandler('change');
});
естествено и моята версия не е перфектна, даже davecardwell е написал доста по-добра версия. Даже John-David Dalton е направил и Prototype версия : http://pastie.org/255119, от която най-много ми хареса допълнението на Element.fire, която я очаквам в новата версия на Prototype
п.п. Някои хора виждат и проблем, че само при стойност “other” се появява полето “други” и ако имаш два или повече езика би било проблем. Обаче аз виждам нещата така - това би бил селекта за български език например:
<select name="language"> <option>Български</option> <option>Английски</option> <option value="other">Друг ...</option> </select>
т.е. value може и да е “other” но за потребителя да е всеки избран език ![]()

