Recent Posts

Pages: 1 ... 4 5 [6] 7 8 ... 10
51
Bug Report / Re: Another v10.0.0 bug with fix
« Last post by paramvir on November 20, 2024, 12:00:50 pm »
This is fixed in v10.1.0

Test case:

https://jsfiddle.net/u0n296ym/1/
52
Bug Report / Re: Tiny bug in v10.0.1
« Last post by paramvir on November 20, 2024, 11:58:48 am »
This is a duplicate of the issue already raised by you and this is fixed in v10.1.0

Test case:

https://jsfiddle.net/u0n296ym/1/
53
Bug Report / Re: Please change one line of code in next version
« Last post by paramvir on November 20, 2024, 11:48:49 am »
This is fixed in v10.1.0
54
Bug Report / Re: Listener bug in v10.1.0
« Last post by paramvir on November 20, 2024, 11:45:22 am »
I understand that your goal is to trigger filter on a certain timeout ( time lapse ). And if user press enter key before that time lapse, filtering should be triggered immediately and pending filter due to timeout shouldn't be triggered after that.

Default filter listener in v10.1.0 does that.

Please read the column.filter documentation for more details: https://paramquery.com/pro/api#option-column-filter

Please remove your custom code to get rid of the issues faced by you.
55
Dear Paramvir,
I changed code of demo in https://paramquery.com/pro/demos/editing_custom , you can copy all code to your demo and press "edit and run".
Firstly batch-copy many "USA"(this should be pre-copied in excel) to first row, secondly press "get change", then you will find than updatelist has no content in the console.
I put screencopy in the attach.

Here is the changed code:
$(function () { 
function saveChanges() { 
var grid = this; 
//attempt to save editing cell. 
if (grid.saveEditCell() === false) { 
return false; 
}


        if (grid.isDirty() && grid.isValidChange({ focusInvalid: true }).valid) {

            var gridChanges = grid.getChanges({ format: 'byVal' });

            //post changes to server
            $.ajax({
                dataType: "json",
                type: "POST",
                async: true,
                beforeSend: function (jqXHR, settings) {
                    grid.showLoading();
                },
                url: "/pro/products/batch", //for ASP.NET, java   
                //url: '/products.php?pq_batch=1', for PHP                                           
                data: {
                    //JSON.stringify not required for PHP
                    list: JSON.stringify(gridChanges)
                },
                success: function (changes) {
                    //debugger;
                    grid.commit({ type: 'add', rows: changes.addList });
                    grid.commit({ type: 'update', rows: changes.updateList });
                    grid.commit({ type: 'delete', rows: changes.deleteList });

                    grid.history({ method: 'reset' });
                },
                complete: function () {
                    grid.hideLoading();
                }
            });
        }
    }

    //rename the bootstrap datepicker to avoid conflict with jquery date picker.
    if (typeof $.fn.datepicker.noConflict == "function") {
        $.fn.bootstrapDatepicker = $.fn.datepicker.noConflict();
    }

    var books = [
        "ActionScript",
        "AppleScript",
        "Asp",
        "BASIC",
        "C",
        "C++",
        "Clojure",
        "COBOL",
        "ColdFusion",
        "Erlang",
        "Fortran",
        "Groovy",
        "Haskell",
        "Java",
        "JavaScript",
        "Lisp",
        "Perl",
        "PHP",
        "Python",
        "Ruby",
        "Scala",
        "Scheme"
    ];
    function autoCompleteEditor(source) {
        return function (ui) {
            ui.$cell.addClass('ui-front');//so that dropdown remains with input.

            //initialize the editor
            ui.$editor.autocomplete({
                //appendTo: ui.$cell, //for grid in maximized state.
                source: source,
                position: {
                    collision: 'flipfit',
                    within: ui.$editor.closest(".pq-grid")
                },
                selectItem: { on: true }, //custom option
                highlightText: { on: true }, //custom option
                minLength: 0
            }).one('focus', function () {
                //open the autocomplete upon focus
                $(this).autocomplete("search", "");
            });
        }
    }
    function dateEditor(ui) {

        //initialize the editor
        ui.$cell.find("input")
            .attr('readonly', 'readonly')
            .datepicker({
                changeMonth: true,
                changeYear: true,
                //convert from excel to jquery ui format
                dateFormat: pq.excelToJui(ui.column.format),
                showAnim: '',
                onSelect: function () {
                    this.firstOpen = true;
                },
                beforeShow: function (input, inst) {
                    setTimeout(function () {
                        //to fix the issue of datepicker z-index when grid is in maximized state.
                        $('.ui-datepicker').css('z-index', 999999999999);
                    });
                    //return !this.firstOpen; uncomment if don't want to allow datepicker editor to open upon focus in editor after first opening.
                },
                onClose: function () {
                    this.focus();
                }
            });
    }

    function bootstrapDateEditor(ui) {
        //initialize the editor
        ui.$cell.find("input")
            .bootstrapDatepicker({
                format: ui.column.format,
            })
            .on('changeDate', function (e) {
                $(this).focus();
                $(this).bootstrapDatepicker('hide');
            })

    }

    var colM = [
        {
            title: "Ship Country", dataIndx: "ShipCountry", width: 120,
            cls: 'pq-drop-icon pq-side-icon',
            editor: {
                type: "textbox",
                attr: "autocomplete='off'",
                init: autoCompleteEditor("/pro/demos/getCountries")
            },
            validations: [
                { type: 'minLen', value: 1, msg: "Required" },
                {
                    type: function (ui) {
                        var value = ui.value,
                            _found = false;
                        //remote validation
                        //debugger;
                        $.ajax({
                            url: "/pro/demos/checkCountry",
                            data: { 'country': value },
                            async: false,
                            success: function (response) {
                                if (response == "true") {
                                    _found = true;
                                }
                            }
                        });
                        if (!_found) {
                            ui.msg = value + " not found in list";
                            return false;
                        }
                    }
                }
            ]
        },
        {
            title: "Books", dataIndx: "books", width: 90,
            cls: 'pq-drop-icon pq-side-icon',
            editor: {
                type: "textbox",
                attr: "autocomplete='off'",
                init: autoCompleteEditor(books)
            },
            validations: [
                { type: 'minLen', value: 1, msg: "Required" },
                {
                    type: function (ui) {
                        var value = ui.value;
                        if (books.indexOf(value) == -1) {
                            ui.msg = value + " not found in list";
                            return false;
                        }
                    }, icon: 'ui-icon-info'
                }
            ]
        },
        {
            title: "Fruits", dataIndx: "fruits", width: 140,
            //custom editor.
            editor: {
                options: ['Apple', 'Orange', 'Kiwi', 'Guava', 'Grapes'],
                type: 'div',
                init: function (ui) {
                    //debugger;
                    var options = ui.column.editor.options,
                        str = options.map(function (option) {
                            var checked = (option == ui.cellData) ? 'checked = checked' : '';
                            return "<input type='radio' " + checked + " name='" + ui.dataIndx + "' style='margin-left:5px;' value='" + option + "'>  " + option;
                        }).join("");

                    //ui.$cell.append("<div class='pq-editor-focus' tabindex='0' style='padding:5px;margin-top:1px;'>" + str + "</div>");
                    ui.$cell.children('div').css({ padding: '5px' }).html(str);
                },
                getData: function (ui) {
                    return ui.$cell.find('input:checked').val();
                }
            }
        },
        {
            title: "Order ID", width: 100, dataIndx: "OrderID",
            editor: {
                type: "textbox",
                //make it html5 number editor.
                attr: "type='number'"
            }
        },
        {
            title: "Date jui",
            width: "120",
            dataIndx: "OrderDate",
            dataType: 'date',
            format: 'dd-mm-yyyy', //display format.
            fmtDateEdit: 'dd-mm-yyyy', //format of date value in editor
            cls: 'pq-calendar pq-side-icon',
            editor: {
                type: 'textbox',
                init: dateEditor
            },
            validations: [
                { type: 'regexp', value: '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', msg: 'Not in yyyy-mm-dd format' }
            ]
        },
        {
            title: "Date bootstrap",
            width: "120",
            dataIndx: "OrderDate2",
            dataType: 'date',
            format: 'yyyy-mm-dd', //display format.
            fmtDateEdit: 'yyyy-mm-dd', //format of date value in editor
            cls: 'pq-calendar pq-side-icon',
            editor: {
                type: 'textbox',
                init: bootstrapDateEditor,
                preventClose: function (ui) {
                    return $(".datepicker-dropdown").is(":visible");
                }
            },
            validations: [
                { type: 'regexp', value: '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', msg: 'Not in yyyy-mm-dd format' }
            ]
        },
        //column with pqselect editor
        {
            title: "Shipping Via", dataIndx: "ShipVia", width: 110,
            cls: 'pq-drop-icon pq-side-icon',
            editor: {
                type: 'select',
                options: [
                    { "SE": "Speedy Express" },
                    { "UP": "United Package" },
                    { "FS": "Federal Shipping" }
                ],
                init: function (ui) {
                    ui.$cell.find("select").pqSelect();
                    setTimeout(function () {
                        ui.$cell.find("select").pqSelect('open');
                    })
                }
            },
            //render required to display options text corresponding to value stored in the cell.
            render: function (ui) {
                var option = ui.column.editor.options.find(option => option[ui.cellData] != null);
                return option ? option[ui.cellData] : "";
            },
            validations: [
                { type: 'minLen', value: 1, msg: "Required" },
                {
                    type: function (ui) {
                        var value = ui.value,
                            option = ui.column.editor.options.find(option => option[value] != null);
                        if (!option) {
                            ui.msg = value + " not found in list";
                            return false;
                        }
                    }, icon: 'ui-icon-info'
                }
            ]
        },
        {
            title: "Shipping Via2", dataIndx: "ShipVia2", width: 110,
            cls: 'pq-drop-icon pq-side-icon',
            editor: {
                type: 'select',
                valueIndx: "value",
                labelIndx: "text",
                options: [
                    { value: "", text: "" },
                    { value: "SE", text: "Speedy Express" },
                    { value: "UP", text: "United Package" },
                    { value: "FS", text: "Federal Shipping" }
                ]
            },
            //render required to display options text corresponding to value stored in the cell.
            render: function (ui) {
                var option = ui.column.editor.options.find(option => option.value == ui.cellData );                   
                return option ? option.text : "";
            },
            validations: [
                { type: 'minLen', value: 1, msg: "Required" },
                {
                    type: function (ui) {
                        var value = ui.value,
                            option = ui.column.editor.options.find(option => option.value == value );
                        if (!option) {
                            ui.msg = value + " not found in list";
                            return false;
                        }
                    }, icon: 'ui-icon-info'
                }
            ]
        },
        {
            title: "Shipping Address", width: 200, dataIndx: "ShipAddress",
            editor: {
                style: {
                    width: "auto"
                }
            },
            editModel: {
                saveKey: '' //disable or set it to some other key code to free up use of Enter key for line breaks.
            },
            validations: [{ type: 'minLen', value: 1, msg: "Required" }]
        },
        {
            title: "Freight", dataIndx: "Freight", dataType: "float", width: 100, format: '$#,###.00',
            editor: { select: true },
            validations: [{ type: 'gte', value: 1, msg: "should be >= 1" }],
            editModel: { keyUpDown: true }
        }
    ];
    var dataModel = {
        location: "remote",
        dataType: "JSON",
        method: "GET",
        url: "/content/invoice.json",
        getData: function (response) {
            response.data.forEach(function (rd) {
                //convert dates from 'mm/dd/yyyy' to ISO format.
                rd.OrderDate = pq.parseDate(rd.OrderDate, 'mm/dd/yyyy');

                //make ShipAddress multiline text.
                rd.ShipAddress = rd.ShipAddress + "\n" + rd.ShipCity + "\n" + (rd.ShipRegion || "") + "\n" + rd.ShipPostalCode;
            })
            return response;
        }
    }

    //finally define the grid.
    $("div#grid_custom_editing").pqGrid({
                  toolbar: {
            items: [
                {
                    type: 'button', icon: 'ui-icon-plus', label: 'New Product', listener: function () {
                        //append empty row at the end.                           
                        var rowData = { ProductID: 34, UnitPrice: 0.2 }; //empty row
                        var rowIndx = this.addRow({ rowData: rowData, checkEditable: true });
                        this.goToPage({ rowIndx: rowIndx });
                        this.editFirstCellInRow({ rowIndx: rowIndx });
                    }
                },
                { type: 'separator' },
                {
                    type: 'button', icon: 'ui-icon-disk', label: 'Save Changes', cls: 'changes', listener: saveChanges,
                    options: { disabled: true }
                },
                {
                    type: 'button', icon: 'ui-icon-cancel', label: 'Reject Changes', cls: 'changes', listener: function () {
                        this.rollback();
                        this.history({ method: 'resetUndo' });
                    },
                    options: { disabled: true }
                },
                {
                    type: 'button', icon: 'ui-icon-cart', label: 'Get Changes', cls: 'changes', listener: function () {
                        var changes = this.getChanges({ format: 'byVal' });
                        if (console && console.log) {
                            console.log(changes);
                        }
                        alert("Please see the log of changes in your browser console.");
                    },
                    options: { disabled: true }
                },
                { type: 'separator' },
                {
                    type: 'button', icon: 'ui-icon-arrowreturn-1-s', label: 'Undo', cls: 'changes', listener: function () {
                        this.history({ method: 'undo' });
                    },
                    options: { disabled: true }
                },
                {
                    type: 'button', icon: 'ui-icon-arrowrefresh-1-s', label: 'Redo', listener: function () {
                        this.history({ method: 'redo' });
                    },
                    options: { disabled: true }
                }
            ]
        },
                  trackModel: { on: true }, //to turn on the track changes.   
        history: function (evt, ui) {
            var $tb = this.toolbar();
            if (ui.canUndo != null) {
                $("button.changes", $tb).button("option", { disabled: !ui.canUndo });
            }
            if (ui.canRedo != null) {
                $("button:contains('Redo')", $tb).button("option", "disabled", !ui.canRedo);
            }
            $("button:contains('Undo')", $tb).button("option", { label: 'Undo (' + ui.num_undo + ')' });
            $("button:contains('Redo')", $tb).button("option", { label: 'Redo (' + ui.num_redo + ')' });
        },
        title: "Shipping Orders <b>(Custom editing)</b>",
        dataModel: dataModel,
        colModel: colM,
        //we don't want to allow invalid values while paste of data.
        pasteModel: {allowInvalid: false},
        //scrollModel: { autoFit: true },
        columnTemplate: {
            valign: 'center',
            width: 150
        },
        create: function (evt, ui) {
            this.widget().pqTooltip();
        },
        editModel: {
            //clicksToEdit: 1,
            keyUpDown: false,
            onBlur: 'save'
        },
        numberCell: { show: false },
        resizable: true
    });
});
56
Bug Report / Listener bug in v10.1.0
« Last post by jplevene on November 19, 2024, 11:59:46 pm »
I had a listener that previously worked.  The idea of the listener is that the filter starts either when the [ENTER] key is pressed or the timeout happens. v10.0.0 and below worked fine, v10.0.1 now has an issue, in that every keypress, the filter starts due to the timeout.

If I comment out the "timeout", it works fine except the timeout is never triggered.  If I include the timeout, it goes all wrong.

Ideally I would like to avoid using the "do_filter" function and just use the default filter start trigger, but I don't know how to call that.

Code: [Select]
var text_listener = {
"keydown": function(e, ui)
{
if(e.key==="Enter")
do_filter(ui);
},
// If I comment out below for v10.0.1 there are no wrong filter triggers
"timeout": function(e, ui){
do_filter(ui);
}
};

function do_filter(ui)
{
var rule = { condition: ui.column.filter.crules[0].condition,  dataIndx: ui.column.dataIndx, value: ui.value, value2: ui.value2 },
CM = $("#grid").pqGrid("getColModel");

// Check if the filter is not already applied
for(var i=0, len = CM.length; i < len; i++){
// If there is no change
if( CM[i]["dataIndx"]===ui.column.dataIndx && ui.value===CM[i]["filter"]["crules"][0]["value"] && ui.value2===CM[i]["filter"]["crules"][0]["value2"] )
rule = null;
}

// If we have a rule, apply it
if(rule)
$("#grid").pqGrid("filter", {
oper: "add",
rules: [
rule
]
});
}

...

columnModel = [
{dataIndx:"NAME", title:"NAME", filter:{crules:[{condition:"contain"}], style:"text-align:"+dir, listener:text_listener}},
...
];

Doing a console log I found the bug.  The timeout in the listener is getting the "keydown" event and not getting the "timeout" event.   I commented out the "keydown" listener and timeout worked.

I tried below, but either keydown or timeout get missed:

Code: [Select]
var text_listener = {
"keydown": function(e, ui)
{
if(e.type==="keydown" && e.key==="Enter")
do_filter(ui);
},
// If I comment out below for v10.0.1 there are no wrong filter triggers
"timeout": function(e, ui){
if(e.type==="timeout")
do_filter(ui);
}
};

I shouldn't have to test for the event as that function should never be called for a different event.
57
Bug Report / Tiny bug in v10.0.1
« Last post by jplevene on November 19, 2024, 09:27:14 pm »
If the grid is created inside a hiden parent (parent hidden before grid created, like a jquery UI dialog), errors occure unless the following code is added:

getTop: function(ri, actual) {
   var top = this.topArr ? this.topArr[ri] : 0,
         ....

getLeft: function(_ci, actual) {
   if(typeof(this.leftArr)==="undefined") return 0;
        ....

calcTopBottom: function(left) {
   if(typeof(this.dims)==="undefined") return 0;
   ...
58
Suggest new features / Re: Quick and simple documentation request
« Last post by jplevene on November 19, 2024, 07:41:45 pm »
 :) Thank you for doing this.  It's the little things that make things great.
59
Batch editing is based on grid getChanges method.

getChanges include the updates due to copy paste in select lists similar to inline editing of individual editing of select lists.

So I don't see any issue there unless you share some technical details.
60
News / Upgrade to Pro Version 10.1.0
« Last post by paramvir on November 18, 2024, 01:52:05 pm »
Dear All

In continuation with the 10th version series of ParamQuery Pro, we are excited to announce the latest update, version v10.1.0, packed with enhancements and crucial bug fixes!

Key Enhancements:

Much faster Spreadsheet Loading: Our latest optimization delivers a dramatic improvement in performance when working with large spreadsheets. Enjoy substantially faster loading times, enhancing your efficiency and productivity.

Clear Text Icon in Header Filters and cell editors: Added a convenient '✖' icon in textboxes to clear text, it can be used in header filters, cell editors or toolbar. Enable this feature by simply adding the attribute is='clear-text' to any input with type "date", "text", or "number".

Examples:

Cell editors: https://paramquery.com/pro/demos/editing_custom
Toolbar filter textbox: https://paramquery.com/pro/demos/pivot_tabs
Header filters: https://paramquery.com/pro/demos/filter_initial

Enrichment of Tabs API:
1) Set grid options across all spreadsheet tabs with single API call.
2) Invoke grid methods across all spreadsheet tabs together.

Example: set localFmt option and compute formulas across all tabs with single API call:

https://paramquery.com/pro/demos/format_date

Improved filter listener:
Multiple filter listeners in string format i.e., 'timeout keyup', etc are introduced in header filter textboxes which trigger the filtering when specified events are fired without any concern of duplicate filter triggering when multiple events are fired together. The default listener is 'timeout change', which is generally sufficient and typically doesn't require any modifications. Check out the column.filter.listener for more details:
https://paramquery.com/pro/api#option-column-filter


Stay tuned for more updates and enhancements as we continue to improve your PQ experience!

Best Regards
The ParamQuery Team
Pages: 1 ... 4 5 [6] 7 8 ... 10