Динамические SELECT-ы на JavaScript или Организация выбора даты в форме

Эта статья расскажет Вам как правильно сделать выбор даты в форме, если день, месяц и год разделены и выбираются отдельно, используя тэг SELECT.

Выглядит это примерно так:

Дата рождения

HTML-код данного куска формы следующий (со вставками на PHP для удобства):

День:
<select name=“day” id=“day”>
<?php
    for ($i = 0; $i < 32; $i++)
    {
        if ($i == 0)
        {
            echo ‘<option value=”0″ selected>-</oplion>’;
        }
        else
        {
            echo ‘<option value=”‘.$i.’”>’.$i.’</oplion>’;
        }
    }
?>
</select>
Месяц:
<select name=“month” id=“month” onChange=“rewrite_days();”>
    <option value=“0″ selected></option>
    <option value=“1″>Январь</option>
    <option value=“2″>Февраль</option>
    <option value=“3″>Март</option>
    <option value=“4″>Апрель</option>
    <option value=“5″>Май</option>
    <option value=“6″>Июнь</option>
    <option value=“7″>Июль</option>
    <option value=“8″>Август</option>
    <option value=“9″>Сентябрь</option>
    <option value=“10″>Октябрь</option>
    <option value=“11″>Ноябрь</option>
    <option value=“12″>Декабрь</option>
</select>
Год:
<select name=“year” id=“year” onChange=“rewrite_days();”>
<?php
    for ($i = 1958; $i < date(“Y”) - 15; $i++)
    {
        echo ‘<option value=”‘.$i.’”>’.$i.’</option>’;
    }
?>
</select>

В принципе все понятно, определено три тега select с именами day - для дней, month - для месяцев и year - для лет.

Для формирования списков options используется php-код, согласитесь, писать на html все 31 день несколько накладно :)

Так же хочу обратить Ваше внимание на следующее: для каждого из select-ов определен id с таким же значением, как и name - это нам понадобится далее в JavaScript-е. И для месяцев и лет определен обработчик события onChange, который будет срабатывать каждый раз при изменении пользователем года или месяца.

Зачем это нужно, спросите Вы? Ответ прост: сейчас у нас вырисовывается 31 день, но при выборе, например, февраля месяца, нам необходимо пересчитывать кол-во дней в первом select-е, что бы нельзя было выбрать, например, 31 февраля.

А теперь напишем и разберем этот самый функцию-обработчик rewrite_days(), который и будет перерисовывать дни в первом select-е.

Код будет следующий:

<script>
function rewrite_days()
{
    var days = document.getElementById(“day”);
    var month = document.getElementById(“month”);
    var year = document.getElementById(“year”);
    var days_in_month = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
    if (month.value != 0)
    {
        if ((year.value % 4 == 0) && (month.value == 2))
        {
            days.length = 30;
            days.item(29).value = 29;
            days.item(29).text = 29;
        }
        else
        {
            days.length = days_in_month[month.value - 1] + 1;
            for (var i = 29; i < days.length; i++)
            {
                days.item(i).value = i;
                days.item(i).text = i;
            }
        }
    }
}
</script>

Итак, в первых 3-х строчках функции, мы для простоты определяем 3 переменные, которые и будут нашими select-ами.

    var days = document.getElementById(“day”);
    var month = document.getElementById(“month”);
    var year = document.getElementById(“year”);

В 4-й строке мы определим массив из 12 чисел, а именно с кол-вом дней в каждом месяце, например, январь - 31, февраль - 28 и т.д.

    var days_in_month = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

Мы не будем изменять дату, когда пользователь выбрал 1-й пункт из списка месяцев, а именно “—”, поэтому заключим весь наш дальнейший функционал в if.

    if (month.value != 0)

month.value - это текущее выбранное значение месяца. Далее мы разделим логику на 2 ветви: 1-я, когда пользователь выбрал високосный год и февраль месяц, нам необходимо показать пользователю 29 дней, и 2-я, в остальных случаях, просто нарисуем кол-во дней в выбранном месяце, используя значения из массива.

Первая ветвь выглядит:

        if ((year.value % 4 == 0) && (month.value == 2))
        {
            days.length = 30;
            days.item(29).value = 29;
            days.item(29).text = 29;
        }

Оператор “%” возвращает остаток от деления, соответвенно, если год делится на 4 без остатка, год високосный. days.length = 30; - мы меняем кол-во отображаемых элементов в select-е для дней - на 30. Почему не на 29, ведь дней в феврале високосного года 29? Не забываем об 1-м элементе - прочерке.

В следующих 2-х строках прописывам для option-а под номером 29 пару значений value/text вручную. Зачем? Смотрите ситуацию, пользователь выбрал невисокосный год, февраль. В данной ситуации у нас 28 дней, соответственно значений в select-е 29. Потом выбрал високосный год, февраль. Мы изменяем кол-во значений select-а на 30, но последний элемент имеет пустые значения value/text. Поэтому пропишем их вручную.

Для варианта №2, когда пользователь не выбирает високосный год, февраль, код одинаковый:

            days.length = days_in_month[month.value - 1] + 1;
            for (var i = 29; i < days.length; i++)
            {
                days.item(i).value = i;
                days.item(i).text = i;
            }

Здесь мы вычисляем кол-во элементов в select-е используя значения массива. И далее, вручную прописываем значения value/text для элементов от 29 и выше, т.к. они могут терятся.

Вот и все, что я хотел рассказать в данной статье. Если у Вас будут какие-либо замечания по коду - милости прошу, пишите комменты, буду рад.

Удачи в кодинге :)

Автор: http://antoxa.name/



Опубликовал admin
1 Мар, Суббота 2008г.



Программирование для чайников.