DatePicker options "changemonth" and "changeyear" not working in jqGrid's edit form
Asked Answered
A

3

5

I have customized jqGrid's edit form to have some fields that use jQuery's DatePicker to fill them up. I have configure it as follows in the colModel option:

colModel: [
...
    { name: 'Column', editable: true, index: 'Column', width: width,
      align: "center", editrules: { integer: true, required: true }, 
      editoptions: { size: 5, dataInit: function (el) {
                     setTimeout(function () { 
                           SetDatepicker('input[name^="' + el.name + '"]'); 
                     }, 100);                
                   } },
      formoptions: { rowpos: 1 }
    },
...
],

This works, insofar that it deploys the DatePicker calendar when the input field is clicked.

Not the SetDatepicker function looks as follows:

function SetDatepicker(control) {
    $.datepicker.setDefaults($.datepicker.regional['es']);

    $(control).datepicker({
        changeMonth: true,
        changeYear: true,
        monthNamesShort: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"]
    });
}

It has changeMonth and changeYear set to true, so the DatePicker should have in its header two selects, one for the year and one for the year, along with the arrows to move along the calendar manually. The problem is, the selects' options cannot be displayed: they are just unresponsive to the mouse clicks. The arrows do they job, so you can move forward and backwards one month at a time, but the idea of using these options is not having to do that.

I have another field, outside jqGrid's edit forms, that also has a DatePicker attached to it using the same function. It works properly, so that makes me think the problem lies with jqGrid's event handling.

Any ideas?

Thanks

UPD

It works fine in Firefox, but it doesn't in IE9-7 nor Chrome.

UPD2

I have created a jsFiddle example with the code for the input with datepicker and how I set jqGrid to use that functionality: http://jsfiddle.net/rUkyF/

Assoil answered 4/9, 2012 at 19:57 Comment(0)
E
8

The modal mode is the problem. When you click out the modal jqGrid try to focus to the first element of the form , as you can see jquery-ui append the div calendar on the body and its out the modal div. Comment the modal: true so fixed it.

grid.jqGrid('editGridRow', rowID, {
    addCaption: "Agregar Proyecto",
    topinfo: "Introduzca los nuevos datos del proyecto.",
    viewPagerButtons: false,
    //modal: true,
    jqModal: true,
    saveicon: [true, "left", "ui-icon-disk"],
    closeicon: [true, "right", "ui-icon-close"],
    closeAfterEdit: true,
    resize: false,
    width: wWidth,
    reloadAfterSubmit: true
});

http://jsfiddle.net/rUkyF/70/

Embryectomy answered 27/10, 2012 at 2:43 Comment(2)
+1 from me! Very good mention the problem with modal: true!Amey
Thank you, collect your reward.Assoil
A
5

I suppose that the problem will be solved if you would use

SetDatepicker(el);

instead of

SetDatepicker('input[name^="' + el.name + '"]');

UPDATED: Your jsFiddler demo had some bugs. Look at the modified demo http://jsfiddle.net/rUkyF/7/ and try to reproduce the problem. I see no problem.

UPDATED 2: I find that iJD found the origin of the problem. I wanted just to describe why modal: true disturbs working of jQuery Datepicker. I wanted that iJD award the bounty and I wrote the text below only for other reader which want to understand whether they should or should not use the options modal: true or jqModal: false.

If one uses modal: true option of editGridRow then the method $.jgrid.viewModal which displays the form will be called here with modal: true option and the option will be forwarded (see the line) to jQuery.jqm ($.fn.jqm) defined in module jqModal.js. As the result the L function is called with the parameter 'bind' in the line of jqm code. So the function L will bind (see the line of code) keypress, keydown and mousedown events of the document to the event handler m defined in the next line as

var m = function (e) {
    var h = H[A[A.length - 1]],
        r = (!$(e.target).parents('.jqmID' + h.s)[0]);
    if(r) f(h);
    return !r;
}

where the function f are defined in the like as

var f = function (h) {
    try {
        $(':input:visible', h.w)[0].focus();
    } catch (_) {}
}

So we can see that the usage of modal: true follows blocking of all controls which are not parents of div with the class '.jqmID' + h.s ( typically '.jqmID1'). In the case the first visible <input> field of the form will get focus (because of calling of the function f).

It's known that many jQuery UI controls create elements (menus, datepicker etc) which are direct children of <body> (for example the Datepicker creates <div id="ui-datepicker-div"> which is direct children of <body>). So keyboard and mouse events could be blocked for such controls.

So you should not use modal: true option if you want to use some jQuery UI controls of some other controls inside of jqGrid forms.

By the way the default value of jqModal option of editGridRow is already true (see the documentation). So one can remove the jqModal: true from the current code like some other options of editGridRow. If one would use jqModal: false instead, the jqModal.js plugin will not used by editGridRow and the modal: true option will be ignored too. In the case the whole HTML page will be not blocked. The current grid only will be blocked by the corresponding overlay of the grid.

In my personal default settings which I use per $.extend($.jgrid.edit, {...}) the jqModal is switched off:

$.extend($.jgrid.edit, {
    recreateForm: true,
    jqModal: false,
    closeAfterAdd: true,
    closeAfterEdit: true,
    ... // other less common settings
});

You should decide yourself which default settings you want use.

UPDATED 3: I posted the bug report which suggest how the code of jqGrid could be fixed. If one changes the line

m=function(e){var h=H[A[A.length-1]],r=(!$(e.target).parents('.jqmID'+h.s)[0]);if(r)f(h);return !r;},

to the lines

m=function(e){
    var h=H[A[A.length-1]],
        r=(!$(e.target).parents('.jqmID'+h.s)[0]);
    if(r) {
        // e.target could be inside of element with absolute position like menu item
        // in the case parents call above will don't find the modal dialog
        // To fix the problem we verify additionally whether e.target is inside of
        // an element having the class 'jqmID'+h.s
        $('.jqmID'+h.s).each(function() {
            var $self = $(this), offset = $self.offset();
            if (offset.top <= e.pageY && e.pageY <= offset.top + $self.height() &&
                    offset.left <= e.pageX && e.pageX <= offset.left + $self.width()) {
                r = false; // e.target is do inside of the dialog
                return false; // stop the loop
            }
        });
        f(h);
    }
    return !r;
},

then the problem should be fixed. The demo uses modal: true option and datepicker works in edit dialog. It uses the fixes which I described.

UPDATED 4: The bug fix, which I described in UPDATED 3 of my answer, is now included (see here) in the main code of jqGrid. So the versions > 4.4.5 should not have the described problem.

Amey answered 5/9, 2012 at 13:38 Comment(13)
@Heathcliff: Sorry, but I use the settings permanently and it works. Just try for example the demo from today's answer. The both settings changeMonth: true and changeYear: true work in form editing and in inline editing.Amey
I have done something similar, but still doesn't work. Thanks anyway.Assoil
@Heathcliff: The only way to find the reason of your problem is to compare exactly the differences between two examples (one from there is working and another not working). You can try to transform one example to another one in steps and find out the main reason of the problem. Alternatively you can post URL of your example and I'd take a look on this.Amey
I have updated my post with a jsFiddle example. I haven't been able to make it work, probably because I haven't used jsFiddle before, but the code is that.Assoil
It is weird, because even if I add the Today button, it works, and so do the arrow buttons to change months manually, but not the selects.Assoil
@Heathcliff: I am not sure what you mean. If you use arrow buttons to change the month or the year you will see the list of the days in the month. You still have to choose the date in the month. Only after the clicking on the corresponding day the date will be changed.Amey
No, I mean the arrows to the sides of the month-year bar (datepicker's titlebar), the ones that allow you to navigate one month forward and one month backward. The selects can't be expanded.Assoil
@Heathcliff: I see only some problems in the jqFiddle demo which you used. For example you used id="#tGrid" instead of id="tGrid". Try jsfiddle.net/rUkyF/7/embedded/result instead. All works without any problems.Amey
Ah, here's a clue. I'm not using jqGrid's built-in edit form, I use a custom form (I mean, I set the grid.jqGrid('navGrid', '#pager', { edit: false}), and then I add a button in the navBar for edit). Now, it doesn't work, and it does the same thing that in my project: when one of the selects is clicked, it focuses the first input: jsfiddle.net/rUkyF/15Assoil
@Heathcliff: I updated my answer (see UPDATED 2) after reading the answer from iJD.Amey
@Heathcliff: Look at UPDATED 3 part of my answer.Amey
@Heathcliff: See UPDATED 4 part of my answer.Amey
Great! I'd be taking it into account for the next time.Assoil
E
1

In your jsfiddle you have set the id attributes with a # symbol in the beginning. As far as I know, you should only use a-zA-Z_ symbols. At least in my experience I had a lot of problems with that in mainly in IE.

After I removed that #(http://jsfiddle.net/tftd/gwC4F/1/), everything worked like a charm in the latest FF, Chrome, Opera and Safari.

Erlanger answered 29/10, 2012 at 19:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.