Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple datepicker problem with same ID

here is my problem:

<input type="text" class="datepick1" id="date" />
<input type="text" class="datepick2" id="date" />
<input type="text" class="datepick3" id="date" />

then i apply datepicker on dom (by classname)

$('.datepick1').datepicker();
$('.datepick2').datepicker();
$('.datepick3').datepicker();

=> the three dom have datepicker but, onselect date, it change automatically the first one (datepick1)

HELP

like image 422
namezero Avatar asked Mar 12 '10 09:03

namezero


3 Answers

Your three inputs have the same id attribute on them. You can't do that, id attributes must be unique within the document. (Having the same name, on the other hand, is fine in forms -- and common, for instance for radio buttons.)

Edit So your code posted to the comment below wants to be changed to:

$('<td></td>').append(
    $(NewLivraison.template.date)
        .val(arguments.date_livraison)
        .attr('id','date_' + arguments.num) // <== Note it's "id" we're making unique
        .addClass('date_' + arguments.num)  // <== You can probably drop this entirely
        .datepicker()
).css('vertical-align','top');
like image 59
T.J. Crowder Avatar answered Nov 10 '22 21:11

T.J. Crowder


Supposed to be like this

<input type="text" id="datepick1" class="date" />
<input type="text" id="datepick2" class="date" />
<input type="text" id="datepick3" class="date" />

$('.date').datepicker();
like image 29
Ergec Avatar answered Nov 10 '22 20:11

Ergec


the problem lies within the jquery datepicker code in the _attachHandlers function. The argument to the function is the instance of the current datepicker 'inst'. The correct input is inst.input. But the 'id' is only a string representation and you can never get the correct input if you have duplicate id's. The easy workaround is to replace the argument 'id' in the handler functions with the inst.input so it will point to the correct input.

Also if you take a closer look inside the handler functions then you can see they try reverse engineer through the id back to the correct input... Yet it will get you the first matching element with that id witch is not what we'd want.

var target = $(id),
    inst = this._getInst(target[0]);

And as $(inst.input) returns us inst.input we can easily fix it with this tiny adjustment.

Cheers

Original jquery code ui.1.10.3

    _attachHandlers: function(inst) {
        var stepMonths = this._get(inst, "stepMonths"),
            id = "#" + inst.id.replace( /\\\\/g, "\\" );
        inst.dpDiv.find("[data-handler]").map(function () {
            var handler = {
                prev: function () {
                    $.datepicker._adjustDate(id, -stepMonths, "M");
                },
                next: function () {
                    $.datepicker._adjustDate(id, +stepMonths, "M");
                },
                hide: function () {
                    $.datepicker._hideDatepicker();
                },
                today: function () {
                    $.datepicker._gotoToday(id);
                },
                selectDay: function () {
                    $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
                    return false;
                },
                selectMonth: function () {
                    $.datepicker._selectMonthYear(id, this, "M");
                    return false;
                },
                selectYear: function () {
                    $.datepicker._selectMonthYear(id, this, "Y");
                    return false;
                }
            };
            $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
        });
    },

Fix, replaced the argument 'id' in the handler functions with the 'inst.input'

    _attachHandlers: function(inst) {
        var stepMonths = this._get(inst, "stepMonths"),
            id = "#" + inst.id.replace( /\\\\/g, "\\" );
        inst.dpDiv.find("[data-handler]").map(function () {
            var handler = {
                prev: function () {
                    $.datepicker._adjustDate(inst.input, -stepMonths, "M");
                },
                next: function () {
                    $.datepicker._adjustDate(inst.input, +stepMonths, "M");
                },
                hide: function () {
                    $.datepicker._hideDatepicker();
                },
                today: function () {
                    $.datepicker._gotoToday(inst.input);
                },
                selectDay: function () {
                    $.datepicker._selectDay(inst.input, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
                    return false;
                },
                selectMonth: function () {
                    $.datepicker._selectMonthYear(inst.input, this, "M");
                    return false;
                },
                selectYear: function () {
                    $.datepicker._selectMonthYear(inst.input, this, "Y");
                    return false;
                }
            };
            $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
        });
    },
like image 4
Hendrik Kangro Avatar answered Nov 10 '22 21:11

Hendrik Kangro