Author Topic: Paging of the tree grid  (Read 420 times)

STEVE

  • Pro Enterprise
  • Jr. Member
  • *
  • Posts: 50
    • View Profile
Paging of the tree grid
« on: September 21, 2022, 08:24:29 pm »
Hello  Paramvir?

I found that the speed of the web page of the tree grid was too slow.

Are there ways to get the data from the database for only one or two pages at the first time?

It seems to have no way to page the data from the fetch of the query.

Best regards,
Steve.

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6124
    • View Profile
Re: Paging of the tree grid
« Reply #1 on: September 22, 2022, 05:30:41 am »
Lazy loading of nodes can be used to fetch large data efficiently in case of treegrid.

Example of lazy loading of nodes: https://paramquery.com/pro/demos/treegrid-lazy
« Last Edit: September 22, 2022, 05:59:16 am by paramvir »

STEVE

  • Pro Enterprise
  • Jr. Member
  • *
  • Posts: 50
    • View Profile
Re: Paging of the tree grid
« Reply #2 on: October 13, 2022, 06:49:19 pm »
I couldn't make it.  Sorry for that.
It was really difficult for me to understand to adopt your sample code and guide.

This code seems to have a problem I can't understand.
Quote
var url = 'treegrid?fid=' + node.fid;

I just met the endless cycling of clock sticks.

I need a parent node and his children ranked as level 2 from the first query.
And then expand one of the nodes. I think it is a lazy query.

What should I do now?  Please guide me.

Code: [Select]
<?php
    
require_once '../grid/include.php';
    include 
'include/dropdown.php';
    
?>

<script>
$(function () {

function getChanges(grid) {           
    return grid.getChanges({ format: 'byVal' });                   
}

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 changes = getChanges(grid), Tree = grid.Tree();

        //post changes to server, assign unique id to rows in addList
        changes.addList.forEach(function( rd ){
            //rd.id = Math.random() * Math.random();
            Tree.updateId(rd, Math.random() * Math.random());
        })           

        //and commit in grid, refer to batch editing example.           
        grid.commit({
            type: 'add',
            rows: changes.addList
        });

        grid.commit();
       
    }

    grid.History().reset();
}

var obj = {       
    height: 'flex',
    //rowHt: 33, autoRow: false,
    maxHeight: 500,               
    numberCell: {width: 50},
    dragModel: {
        on: true,
        diHelper: ['fnm'],
        /*dragNodes: function (rd, evt) {
            var checkNodes = this.Tree().getCheckedNodes();
            return (checkNodes.length && checkNodes.indexOf(rd) > -1) ? checkNodes : [rd];
        },*/
        isDraggable: function (ui) {
            return !ui.rowData.pq_gsummary;
        }
    },
    dropModel: {
        on: true,
        divider: 200, //v7.4
        isDroppable: function (evt, uiDrop) {

            var Drag = uiDrop.helper.data('Drag'),
                uiDrag = Drag.getUI(),
                rdDrag = uiDrag.rowData,
                rdDrop = uiDrop.rowData,
                Tree = this.Tree(),
                denyDrop = (
                    rdDrop == rdDrag ||
                    (rdDrop && rdDrop.pq_gsummary) ||
                    (rdDrop && Tree.isAncestor(rdDrop, rdDrag))
                );

            return !denyDrop;
        }
    },
    //filterModel: { on: true, mode: "AND", header: true },
    menuIcon: true,
    stripeRows: false,
    toolbar: {
        items: [
            {
                type: 'button', icon: 'ui-icon-plus', label: 'Root node', listener: function () {                     
                    var grid = this,
                        ri,
                        newRow = { id: "new_" + Math.random(), fnm: "new item" };

                    grid.Tree().addNodes([newRow])

                    //get rowIndx of newly inserted row.
                    ri = grid.getRowIndx({ rowData: newRow }).rowIndx;

                    grid.scrollRow({ rowIndx: ri }, function () {
                        grid.editFirstCellInRow({ rowIndx: ri })
                    });
                }
            },
            {
                type: 'button', icon: 'ui-icon-plus', label: 'Child node', listener: function () {                       
                    var grid = this,
                        sel = grid.Selection().getSelection(),
                        parent;

                    if (sel.length && (parent = sel[0].rowData) ){                           
                        var newRow = { id: "new_" + Math.random(), fnm: "new item" };

                        grid.Tree().expandNodes( [ parent ] );

                        //append new node to selected parent.
                        grid.Tree().addNodes([ newRow ], parent);

                        //get rowIndx of newly inserted row.
                        var ri = grid.getRowIndx({ rowData: newRow }).rowIndx;
                        grid.scrollRow({ rowIndx: ri }, function () {
                            grid.editFirstCellInRow({ rowIndx: ri })
                        });                           
                    }
                    else {
                        alert("Select parent node");
                    }
                }
            },
            { type: 'separator' },
            {
                type: 'button',
                icon: 'ui-icon-disk',
                label: 'Save',
                cls: 'changes',
                listener: saveChanges,
                options: { disabled: true }
            },
            {
                type: 'button',
                icon: 'ui-icon-cart',
                label: 'Get Changes',
                cls: 'changes',
                listener: function () {
                    var changes = getChanges(this);                       
                    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().undo();
                },
                options: { disabled: true }
            },
            { type: 'button', icon: 'ui-icon-arrowrefresh-1-s', label: 'Redo', listener: function () {
                    this.History().redo();
                },
                options: { disabled: true }
            },
            {
                    type: 'button',
                    label: "Export",
                    icon: 'ui-icon-arrowthickstop-1-s',
                    listener: function () {
                        this.exportData({
                            url: "exportData.php",
                            format: "xlsx",
                            render: false
                        });
                    }
                    }
        ]
    },
   
    title: "<b>기능분해도</b>",

    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 + ')' });
    },
    treeModel: {
        dataIndx: 'fnm',
        id: 'fid',
        parentId: 'fidp'
    },
    sortModel: {ignoreCase: true},
    scrollModel: { horizontal: true  },         //autoFit: true
    // columnTemplate: { minWidth: '10%', maxWidth: '80%', width: 100 },
    //selectionModel: {mode: 'single', type:'row'},
   
    // beforeTreeExpand: function(evt, ui){
    //         //debugger;
    //         var grid = this, tree = grid.Tree();
    //         ui.nodes.forEach(function( node ){
    //             //node is collapsed and children nodes are not added yet.
    //             if( tree.isCollapsed( node ) && !node._nodesAdded){
    //                 grid.showLoading();
                       
    //                 var url = 'treegrid?fid=' + node.fid;

    //                 $.getJSON(url, function( response ){
    //                     //debugger;
    //                     node._nodesAdded = true;         
    //                     tree.addNodes(response.data, node);
    //                     grid.hideLoading();
    //                 });                   
    //             }
    //         })
    //     },
    colModel: [
        {dataIndx: 'id', title: 'ID', dataType: 'string' , width: 70, hidden: true },
        {dataIndx: 'seq', title: '순번', dataType: 'string', width: 70 },
        {dataIndx: 'ocd', title: '기관', dataType: 'string', width: 70 },
        {dataIndx: 'scd', title: '시스템', dataType: 'string', width: 80 },
        {dataIndx: 'lvl', title: '수준', dataType: 'string', width: 70 },
        {dataIndx: 'fid', title: '기능ID', dataType: 'string', width: 130 },
         {
            dataIndx: 'fnm', title: '기능명', align: "center",
            // validations:[{
            //     type: 'minLen', value: 1, msg: "Required"
            // }],
            exportRender: true,
            minWidth: 500
        },
        {dataIndx: 'ep', title: '끝', dataType: 'string', width: 70 },
        //
        { title: "기능설명", width: 300, dataType: "string", dataIndx: "fdsc" },
        { title: "연관시스템", width: 80, dataType: "string", dataIndx: "isys" },
        { title: "수행조직", width: 100, dataType: "string", dataIndx: "actr" },
        { title: "작성자", width: 80, dataType: "string", dataIndx: "wrkr" , hidden: true },
        { title: "자동화여부", width: 80, dataType: "string", dataIndx: "aut" },
        { title: "공통여부", width: 80, dataType: "string", dataIndx: "cmyn" },
        { title: "흐름반영여부", width: 80, dataType: "string", dataIndx: "flyn" },
        { title: "기능유형", width: 100, dataType: "string", dataIndx: "trx" },
        { title: "비고", width: 300, dataType: "string", dataIndx: "rmk" },
        //
        {dataIndx: 'fidp', title: '부모기능ID', dataType: 'string', width: 150 , hidden: true },   // parent of fid   
        { title: "", editable: false, minWidth: 83, sortable: false,
            menuInHide: true,
            render: function (ui) {
                if( !ui.rowData.pq_gsummary )
                    return "<button type='button' class='delete_btn'>Delete</button>";
            },
            postRender: function (ui) {
                var rowIndx = ui.rowIndx,
                    grid = this,
                    $cell = grid.getCell(ui);

                $cell.find("button").button({ icons: { primary: 'ui-icon-scissors'} })
                .bind("click", function () {

                    grid.addClass({ rowIndx: ui.rowIndx, cls: 'pq-row-delete' });

                    setTimeout(function () {
                        var ans = window.confirm("Are you sure to delete row No " + (rowIndx + 1) + "?");
                        grid.removeClass({ rowIndx: rowIndx, cls: 'pq-row-delete' });
                        if (ans) {
                            //grid.deleteRow({ rowIndx: rowIndx });
                            grid.Tree().deleteNodes([ui.rowData]);
                        }
                    })
                });
            }
        }
    ],
    postRenderInterval: -1, //call postRender synchronously.       
    create: function(){
        this.widget().pqTooltip();
    },
    complete: function () {
        this.flex({dataIndx:['fnm']});
    },
    collapsible: {on: false},
    dataModel: {
        dataType: "JSON",             
        location: 'remote',
        recIndx: "id",
        url: "ab01db.php"
        // ,
        // getData: function(response){               
        //     return {data: response};
        // }   
    },
    trackModel: {on: true},
    showTitle: true ,
    pasteModel: {type:"replace"} //don't want new rows from pasted data.
}
pq.grid( "#tree_grid", obj);

});     
</script>
</head>
  <body>
    <div id="tree_grid" style="margin: auto;">
    </div>
  </body>
</html>   
   

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6124
    • View Profile
Re: Paging of the tree grid
« Reply #3 on: October 14, 2022, 03:18:24 pm »
From your code I understand that you have been trying to combine lazy loading, batch editing and drag and drop of nodes all together.

Currently they are not supported and are not tested together.