Author Topic: "Loading" box not displayed for Nesting of grids with lazy loading  (Read 1000 times)

RamC

  • Pro Enterprise
  • Newbie
  • *
  • Posts: 11
    • View Profile
Hello,

I have updated PQ Grid to Ver 9.1 from 3.3, and have some nested grids with "remote" Datamodel.
In newer version "Loading" box not displaying for nested grids , I also gone through https://paramquery.com/pro/demos91 and updated the code as well.

Please let me know if i missed any thing or have any other impacts.


Thanks.

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6375
    • View Profile
Re: "Loading" box not displayed for Nesting of grids with lazy loading
« Reply #1 on: March 05, 2025, 04:05:06 pm »
Loading box is displaying fine in v9.1.1

https://paramquery.com/pro/demos91/nesting

No idea why it's not working for you. I can look into it if you have a jsfiddle to share.

RamC

  • Pro Enterprise
  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: "Loading" box not displayed for Nesting of grids with lazy loading
« Reply #2 on: March 06, 2025, 11:08:16 am »
I have updated the code as per new V 9.1, please JSFiddle- https://jsfiddle.net/s270rzho/latest/ and  find below code block and let me know if you found anything missing.

//common options used in all grids.
var options = {
    fillHandle: 'all',
    blur: function () {
        this.Selection().removeAll();
    }
};

//Initialize the Main Grid
function InitialiseDevicesgrid() {
 
    //initialize main grid
    $("#DeviceList").pqGrid(Object.assign({}, options, {
        width: '100%',
        height: CalculateGridHeight(),
        dataModel: { location: "local" },           
        scrollModel: {autoFit:true, flexContent: true },
        stripeRows: true,
        collapsible: false,
        flex: { one: true },
        selectionModel: { type: 'row' },
        hwrap: false,
        wrap: false,
        create: function (evt, ui) {
            var colMod = [{ value: "Gateway", title: "Gateway" }, { value: "DataSource", title: "DataSource" }, { value: "DataTransfer", title: "DataTransfer" }, { value: "System", title: "System" }, { value: "Module", title: "Module" }],
                $sel = $("#SearchList"),
                optionElement = '';
           
            // add column to the dropdown
            $.each(colMod , function (i, column) {
                optionElement = '<option value="' + column.value + '">' + column.title + '</option>';
                $sel.append(optionElement);
            });
            // Refresh to show
            $sel.selectpicker('refresh');
        },
       
        colModel: [
            {
                title: "", minWidth: 27, maxWidth: 27, type: "detail", resizable: false, editable: false, sortable: false,
                render: function (ui) { ui.rowData.rowId = 'DeviceList_' + ui.rowIndx; }
            },
            { title: 'Customer', dataIndx: 'customer_name', editable: false, render: filterRender }
        ],
        numberCell: { show: false },
        sortModel: { sorter: [{ dataIndx: "customer_name", dir: "up" }], cancel: false, type: "local" },
        resizable: true,     
        toolbar: {
            cls: "pq-toolbar-search",
            items: [
                {
                    type: 'textbox',
                    attr: 'placeholder="' + "Find" + '"',
                    cls: "filterValue clearable",
                    listeners: [
                        { 'keyup': DevicesSearchHandler },
                        { 'change': DevicesSearchHandler }
                    ]
                },
                {
                    type: '<select id="SearchList" class="search-list" data-width="150px" data-height="10px" data-style="btn-default btn-sm" data-dropup-auto=false></select>'
                }
            ],
        },
       
        detailModel: {
            cache: true,           
            collapseIcon: "ui-icon-plus",
            expandIcon: "ui-icon-minus",
            init: function (ui) {
                var rowData = ui.rowData,                       
                    dataHubDetailObj = gridDataHubDetailModel(this, rowData), //get a copy of gridDetailModel                       
                    $grid = $("<div id=" + rowData.rowId + "></div>").pqGrid(dataHubDetailObj); //init the detail grid.
                return $grid;
            }
               
        },
        cellClick: function (event, ui) {
            if (typeof ui.rowData.pq_detail != 'undefined') {
                $("DeviceList_1").pqGrid("showLoading");
                //$('#' + ui.rowData.rowId).pqGrid("showLoading");
                if ((typeof ui.rowData != 'undefined') && (ui.rowData.pq_detail.show)) {
                    if (initialisedDataHubsGridIds.indexOf(ui.rowData.rowId) < 0) { initialisedDataHubsGridIds.push(ui.rowData.rowId); }
                } else if ((typeof ui.rowData != 'undefined') && (!ui.rowData.pq_detail.show)) {
                    initialisedDataHubsGridIds.pop(ui.rowData.rowId);
                }
            }
       
        }
    }));

    $("#SearchList").on('changed.bs.select', function (e, clickedIndex, newValue, oldValue) {
        //Reset the Grid and then continue searching with the changed value
        for (var i = 0; i < searchGridIds.length; i++) {
            $(searchGridIds).pqGrid("reset", { filter: true });
        }
        DevicesSearchHandler();
    });
}

function onTabsActive(evt, ui) {
    //grid requires refresh whenever corresponding tab is refreshed.
    ui.newPanel.find(".pq-grid").pqGrid("refresh");
};

//Datahub Grid function called by Main Grid
var gridDataHubDetailModel = function (gridMain, rowData) {
    var datahubGridId = '#' + rowData.rowId;
    return Object.assign({}, options, {
        width: "100%",
        pageModel: { type: "local", rPP: 10, curPage: 1, strDisplay: "{0} to {1} of {2}" },
        columnBorders: false,
        showTop: false,
        showBottom: true,
        scrollModel: { autoFit: true, flexContent: true },
        dataModel: {
            location: "remote",               
            dataType: "JSON",
            method: "GET",
            url: "../connections/datahubs/" + updatedEncodeURIComponent(rowData.customer_name) + "?customerName=" + updatedEncodeURIComponent(rowData.customer_name) + "&region=" + updatedEncodeURIComponent(rowData.region) + "&country=" + updatedEncodeURIComponent(rowData.country) + "&city=" + updatedEncodeURIComponent(rowData.city),
            getData: function (dataJSON) {
                var data = dataJSON.datahubs;
                if (typeof data != "undefined" && JSON.stringify(data) != "") {
                    for (var i = 0; i < dataJSON.datahubs.length; i++) {
                        data.hub_name = data.name;
                    }
                }
                return { curPage: dataJSON.curPage, totalRecords: dataJSON.length, data: data };
            }
        },
        colModel : [
            { title: "", minWidth: 27, maxWidth: 27, type: "detail", resizable: false, editable: false, sortable: false },
            {
                title: "Lab Name", width: "15%", dataType: "string", dataIndx: "hub_name", editable: false, sortable: true, render: filterRender
            },
         {
                title: "Gateway Name", width: "25%", dataType: "string", dataIndx: "dns_name", editable: false, sortable: true, render: function (ui) {
                    var gatewayName = (typeof ui.rowData.dns_name != 'undefined' && ui.rowData.dns_name.trim() != '')?ui.rowData.dns_name:ui.rowData.datahub_id;
                    return {
                        text: "<span title='" + ReplaceSpecialCharacter(gatewayName) + "'>" + gatewayName + "</span>"
                    };
            }
            },
            {
                title: "Status", dataType: "string", dataIndx: "status", editable: false, sortable: true, width: "15%",
                render: function (data) {
                    return {
                        text: "<span class='" + GetStatusBitforConnectionStatus(data.rowData.status)["css"] + "'></span>" + "<span>  " + filterRender(data) + "</span>"
                    };
                }
            },
            {
                title: "Last Contact Time", dataType: "date", dataIndx: "last_contact_time", editable: false, sortable: true, width: "20%",
                render: function (data) {
                    var lastContactDate = new Date(data.rowData.last_contact_time);
                    var currentDate = new Date();
                    var cellHTML = '';
                    if (currentDate - lastContactDate <= 360000) {
                        cellHTML = cellHTML + "<span class='status-text-green'";
                    }
                    else if (currentDate - lastContactDate <= 86400000 && data.rowData.statusBit == 1) {
                        cellHTML = cellHTML + "<span class='status-text-orange'";
                    }
                    else {
                        cellHTML = cellHTML + "<span class='status-text-red'";
                    }
                    cellHTML = cellHTML + " title = '" + ReplaceSpecialCharacter(getDisplayDateTime(new Date(data.rowData.last_contact_time))) + "'>" + getDisplayDateTime(new Date(data.rowData.last_contact_time)) + '</span>';
                    return {
                        text: cellHTML
                    };
                }
            },
            {
                title: "",
                dataIndx: "DeleteDataHub",
                align: "center",
                editable: false,
                sortable: false, width: "12%",
                render: function (ui) {
                    ui.rowData.rowId = rowData.rowId + "_" + ui.rowIndx;
                    return {
                        text: "<a class='my-tool-tip' data-toggle='tooltip' data-placement='left' title='Delete Gateway'><i class='glyphicon glyphicon-trash' style='font-family:Glyphicons Halflings'></i></a>",
                    };
                }
         },
         {
            title: "",
            dataIndx: "AnonymizeDataHub",
            align: "center",
            editable: false,
                sortable: false, width: "12%", 
            render: function (ui) {
               ui.rowData.rowId = rowData.rowId + "_" + ui.rowIndx;
               return {
                        text: (ui.rowData.status.toLowerCase() != 'anonymized')?
                        "<a class='my-tool-tip' data-toggle='tooltip' data-placement='left' title='Anonymize Gateway'><i class='glyphicon glyphicon-user' style='font-family:Glyphicons Halflings'></i></a>":
                        "<a class='my-tool-tip' data-toggle='tooltip' data-placement='left' title='Gateway successfully anonymized' style='cursor: not-allowed' disabled><i class='glyphicon glyphicon-user' style='font-family:Glyphicons Halflings;color:Gray'></i></a>"
               };
            }
         }
        ],
        refresh: function (evt, ui) {
            if (ui.source != "flex") {
                this.flex();
            }
        },
        flex: { one: true },
        height: 'flex',
        numberCell: { show: false },   
        complete: function (event, ui) {
            AddRefreshTextInParamQueryGrid();
        },
        sortModel: { sorter: [{ dataIndx: "hub_name", dir: "up" }], cancel: false, type: "local" },
        detailModel: {
            collapseIcon: "ui-icon-plus",
            expandIcon: "ui-icon-minus",
            cache: false,
            init: function (ui) {
                var rowData = ui.rowData,
                    rdata = rowData,
                    dataHubDetailObj = gridDataSourceDetailModel($(this).pqGrid('instance'), rdata),
                    html = $("#tmpl").html(),
                    //create new detail place holder
                    $grid = $("<div tabindex='0'></div>");

                dtsDetailObj = gridDTSDetailModel($(this).pqGrid('instance'), rdata),
                    $grid = $("<div tabindex='1'></div>");

                html = html.replace("%=1", "#" + rowData.rowId);
                html = html.replace("%=2", "#DTS" + rowData.rowId);
                html = html.replace("%=id-1", rowData.rowId);
                html = html.replace("%=id-2", "DTS" + rowData.rowId);

                $grid.html(html);

                $grid.find(".pq-tabs").tabs().on("tabsactivate", onTabsActive);

                //append pqGrid in the 2nd tab.   
                var id = "#" + rowData.rowId;
                $("<div/>").appendTo($(id, $grid)).pqGrid(dataHubDetailObj);
                $grid.find(id + "> .pq-grid").attr('id', "Tab" + rowData.rowId);
                var dtsId = "#DTS" + rowData.rowId;
                $("<div/>").appendTo($(dtsId, $grid)).pqGrid(dtsDetailObj);
                $grid.find(dtsId + "> .pq-grid").attr('id', "TabDTS" + rowData.rowId);
                gridId = rowData.rowId;
                return $grid;
            }
        },
        cellClick: function (event, ui) {
            if (typeof ui.rowData.pq_detail != 'undefined') {
                if ((typeof ui.rowData != 'undefined') && (ui.rowData.pq_detail.show)) {
                    if (initialisedDataSourceGridIds.indexOf("Tab" +ui.rowData.rowId) < 0) {
                        initialisedDataSourceGridIds.push("Tab" + ui.rowData.rowId);
                    }
                    if (initialisedDTSGridIds.indexOf("TabDTS" + ui.rowData.rowId) < 0) {
                        initialisedDTSGridIds.push("TabDTS" + ui.rowData.rowId);
                    }
                } else if ((typeof ui.rowData != 'undefined') && (!ui.rowData.pq_detail.show)) {
                    initialisedDataSourceGridIds.pop("Tab" + ui.rowData.rowId);
                    initialisedDTSGridIds.pop("TabDTS" + ui.rowData.rowId);
                }
            }
            if (ui.column != undefined && ui.column.dataIndx == 'DeleteDataHub') {
                var id = ui.rowData.id, level = "datahub";
                if(ui.rowData.status != "Connected") {
                    var url = "../api/GetDeviceCount/" + updatedEncodeURIComponent(id) + "/" + updatedEncodeURIComponent(level);
                    var requestResult = Ajax(url);
                    requestResult.done(function (data) {
                        if (data == 0) {
                            var Id = { level: "datahub", datahubId: ui.rowData.id, datasourceId: null, systemId: null, moduleId: null };
                            ShowDeviceManagementAlert('confirmGatewayDeletion', {"Id":Id, "datahubGridId": datahubGridId });
                        } else {
                            ShowDeviceManagementAlert('dataSourceDelete');
                        }
                    });
                } else {
                    ShowDeviceManagementAlert('connectedDevice', {"deviceType": "Gateway"});
                }
         }
            else if (ui.column != undefined && ui.column.dataIndx == "AnonymizeDataHub" && ui.rowData.status.toLowerCase() != 'anonymized') {
                var id = ui.rowData.id, level = "datahub";
            var url = "../api/GetAnonymizationRequestStatus/" + updatedEncodeURIComponent(id) + "/" + updatedEncodeURIComponent(level);
                ShowLoading("Checking...");
                var requestResult = Ajax(url);
                requestResult.done(function (data) {
                    HideLoading();
                    if (data == 0) {
                        ShowDeviceManagementAlert('confirmAnonymization', { 'dns_name': ui.rowData.dns_name, "ui":ui })
                    } else if (data == 1) {
                        ShowDeviceManagementAlert('anonymizationScheduled',{'dns_name': ui.rowData.dns_name})
                    } else if (data == 2) {
                        ShowDeviceManagementAlert('anonymizationCompleted', { 'dns_name': ui.rowData.dns_name })
               } else {
                  alert('There was error while adding Gateway anonymization request. Kindly try after some time.');
               }
            });
         }
        }
    });
};
« Last Edit: March 06, 2025, 11:20:04 am by RamC »

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6375
    • View Profile
Re: "Loading" box not displayed for Nesting of grids with lazy loading
« Reply #3 on: March 06, 2025, 11:15:14 pm »
I was hoping to see the live issue on jsfiddle. Since your jsfiddle is not functioning, I can only make a guess. There are a couple of showLoading and hideLoading calls in your code. Please comment them one by one and see how it goes.

RamC

  • Pro Enterprise
  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: "Loading" box not displayed for Nesting of grids with lazy loading
« Reply #4 on: March 13, 2025, 11:06:37 am »
Hi Paramvir, I found the cause of issue its because of jQuery version Library v3.7.1 . So any work around for jQuery 3x version as it working fine with jQuery 2x. versions ?

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6375
    • View Profile
Thanks for reporting the issue. It's caused by change in functioning of jquery show method in 3.x, it only works if the element is attached to DOM.

There are 2 alternate ways to fix it.

1) Use this patch:

Code: [Select]
$.paramquery.pqGrid.prototype.showLoading = function () {
  this.loading = true
  this.$loading[0].style.display = "block"
}

or
2. Change the detailModel.init method

Code: [Select]
        init: function (ui) {
          var rowData = ui.rowData,
            detailobj = gridDetailModel(this, rowData), //get a copy of gridDetailModel
            $grid = $("<div/>") //.pqGrid(detailobj) //init the detail grid.

          setTimeout( _ => $grid.pqGrid(detailobj) );

          return $grid
        },

jsfiddle: https://jsfiddle.net/rpx0dkef/1/
« Last Edit: Today at 08:51:54 am by paramvir »