Перейти к содержимому

Динамические 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/

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *