ParamQuery Grid

 


VS install  

nuget ParamQueryGrid




javascript modify version (demo code is not work for me)


<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <meta charset="utf-8" />


    <link href="/Content/themes/base/jquery-ui.css" rel="stylesheet" />

    <script src="/Scripts/jquery-3.4.1.min.js"></script>

    <script src="/Scripts/jquery-ui-1.9.2.min.js"></script>

    <link href="/Content/pqgrid.min.css" rel="stylesheet" />

    <link href="/Content/pqgrid.css" rel="stylesheet" />

    <script src="/Scripts/pgrid/pqgrid.min.js"></script>


    <style>

        div.pq-grid {

            box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75);

            margin-bottom: 12px;

            font-family: Arial;

            font-size: 12px;

        }


        div.pq-toolbar button {

            margin: 0px 5px;

        }


        button.delete_btn {

            margin: -3px 0px;

            height: 30px;

        }


        .pq-row-delete {

            text-decoration: line-through;

        }

            .pq-row-delete > .pq-grid-cell {

                background-color: pink;

            }

    </style>


    <script>

        $(function () {

            var interval;

            function saveChanges() {

                /**

                1. if there is no active ajax request.

                2. there is no ongoing editing in the grid.

                3. grid is dirty.

                4. all changes are valid.

                */


                //$("#grid").pqGrid("getChanges");

                var $grid = $(this); 

   

                if (grid.pqGrid("saveEditCell") === false) { 

                    return false;

                }


                var gridChanges = grid.pqGrid("getChanges");

                if (gridChanges.updateList.length > 0 || gridChanges.deleteList.length > 0 || gridChanges.addList.length > 0) {


                    $.ajax({

                        url: '/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)

                        },

                        dataType: "json",

                        type: "POST",

                        async: true,

                        beforeSend: function (jqXHR, settings) {

                            //grid.option("strLoading", "Saving..");


                            grid.pqGrid("option", "strLoading", "Saving..");

                            grid.pqGrid("showLoading");


                            //grid.showLoading();

                        },

                        success: function (changes) {

                            //commit the changes.

                            grid.pqGrid("commit", { type: 'add', rows: changes.addList });

                            grid.pqGrid("commit", { type: 'update', rows: changes.updateList });

                            grid.pqGrid("commit", { type: 'delete', rows: changes.deleteList });

                            grid.pqGrid("commit");

                            grid.pqGrid("history", { method: 'reset' });   

                        },

                        complete: function () {

                            grid.pqGrid("hideLoading");

                            grid.pqGrid("option", "strLoading", $.paramquery.pqGrid.defaults.strLoading);

                        }

                    })

                }

            }

            //save changes from a timer.

            interval = setInterval(saveChanges, 5000);


            var obj = {

                hwrap: false,

                resizable: true,

                rowBorders: false,

                //autoRow: false,

                rowHt: 32,

                trackModel: { on: true }, //to turn on the track changes.

                toolbar: {

                    items: [{

                        type: 'button',

                        icon: 'ui-icon-plus',

                        label: 'New Product',

                        listener: function () {

                            //append empty row at the end.

                            var rowData = { ProductName: 'new product', UnitPrice: 0.2 }; //empty row

                            var rowIndx = grid.addRow({ rowData: rowData });

                            grid.pqGrid("addRow", { rowData: rowData });

                            grid.pqGrid("editFirstCellInRow", { rowIndx: rowIndx });


                        }

                    },

                        { type: 'separator' },

                        {

                            type: 'button', icon: 'ui-icon-plus', label: '新規', listeners: [

                                {

                                    "click": function (evt, ui) {


                                        var rowData = { ProductName: 'new', UnitPrice: 0.2 }; //empty row  

                                        var rowIndx = grid.pqGrid("addRow", { rowData: rowData });

                                        grid.pqGrid("addRow", { rowData: rowData });

                                        grid.pqGrid("editFirstCellInRow", { rowIndx: rowIndx });

                                        var $tr = $(this).closest("tr");

                                        var $grid = $(this);

                                        var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;

                                        grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: false });

                                    }

                                }]

                        },

                        { type: 'separator' },

                    {

                        type: 'button',

                        icon: 'ui-icon-arrowreturn-1-s',

                        label: 'Undo',

                        options: { disabled: true },

                        listener: function () {

                            grid.history({ method: 'undo' });

                        }

                    },

                    {

                        type: 'button',

                        icon: 'ui-icon-arrowrefresh-1-s',

                        label: 'Redo',

                        options: { disabled: true },

                        listener: function () {

                            grid.history({ method: 'redo' });

                        }

                    }]

                },

                scrollModel: { autoFit: true },

                editor: { select: true },

                title: "<b>Auto save</b>",

                change: function (evt, ui) {

                    //saveChanges can also be called from change event.

                },

                destroy: function () {

                    //clear the interval upon destroy.

                    clearInterval(interval);

                },

                history: function (evt, ui) {

                    //var $tb = this.toolbar(),

@*                    var $tb = toolbar;

                    $undo = $tb.find("button:contains('Undo')");

                        $redo = $tb.find("button:contains('Redo')");


                    if (ui.canUndo != null) {

                        $undo.button("option", { disabled: !ui.canUndo });

                    }

                    if (ui.canRedo != null) {

                        $redo.button("option", "disabled", !ui.canRedo);

                    }

                    $undo.button("option", { label: 'Undo (' + ui.num_undo + ')' });

                    $redo.button("option", { label: 'Redo (' + ui.num_redo + ')' });*@

                },

                colModel: [

                    { title: "Product ID", dataType: "integer", dataIndx: "ProductID", editable: false, width: 80 },

                    {

                        title: "Product Name", width: 165, dataType: "string", dataIndx: "ProductName",

                        validations: [

                            { type: 'minLen', value: 1, msg: "Required" },

                            { type: 'maxLen', value: 40, msg: "length should be <= 40" }

                        ]

                    },

                    {

                        title: "Quantity Per Unit", hidden: true, width: 140, dataType: "string", dataIndx: "QuantityPerUnit",


                    },

                    {

                        title: "Unit Price", width: 100, dataType: "float", dataIndx: "UnitPrice", format: "$#,###.00",


                    },

                    {

                        title: "Units In Stock", width: 100, dataType: "integer", dataIndx: "UnitsInStock",


                    },

                    {

                        title: "Discontinued", width: 100, dataType: "bool", align: "center", dataIndx: "Discontinued",

                        editor: false,

                        type: 'checkbox',

    

                    },

                    {

                        title: "", editable: false, minWidth: 85, sortable: false,

                        render: function (ui) { 

                            return "<button type='button' class='delete_btn'>Delete</button>";

                        },

                        postRender: function (ui) {


                            //https://paramquery.com/forum/index.php?topic=2020.msg8156#msg8156

                            //Pro version has postRender callback which can be used to do DOM related stuff while column.render callback in free version can return string only.


                            console.log('postRender');

                            alert("Delete2");


                            //var $tr = $(this).closest("tr");

                            //var $grid = $(this);

                           // var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;

                           // grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: false });


                            //var grid = this,

                            //    $cell = grid.getCell(ui);

                            //$cell.find(".delete_btn")

                            //    .button({ icons: { primary: 'ui-icon-scissors' } })

                            //    .bind("click", function (evt) {


                            //        alert("Delete!");

                            //        grid.deleteRow({ rowIndx: ui.rowIndx });

                            //    });

                        }

                    }

                ],

                postRenderInterval: -1, //synchronous post render.

                pageModel: { type: "local", rPP: 20 },

                dataModel: {

                    dataType: "JSON",

                    location: "remote",

                    recIndx: "ProductID",

                    url: "/products/get", //for ASP.NET

                    //url: "/products.php", //for PHP

                    getData: function (response) {

                        return { data: response.data };

                    }

                },

                  

                load: function (evt, ui) {

                    var grid = this,

                        data = grid.option('dataModel').data;


                   // $("div#grid").pqGrid('option', 'dataModel.data', gridData);


                    grid.widget().pqTooltip(); //attach a tooltip.


                    //validate the whole data.

                    grid.isValid({ data: data });

                },


                refresh: function () {

                    $("#grid_editing").find("button.delete_btn").button({ icons: { primary: 'ui-icon-scissors' } })

                        .unbind("click")

                        .bind("click", function (evt) {

                            console.log('isDirty=' + grid.pqGrid("isDirty"));

                            var $tr = $(this).closest("tr");

                            var $grid = $(this);

                            var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;

                            grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: true });   

                            console.log('---');

                        });

                }

            };

            //var grid = pq.grid("#grid_editing", obj);

            var grid = $("#grid_editing").pqGrid(obj);

        });

    </script>

</head>

<body>

    <div id="grid_editing" style="margin: auto;"> </div>

    @RenderBody()

</body>

</html>





C#
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace MVCTest.Controllers
{
    public class productsController : Controller
    {
        // GET: products

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }



        private void addList(List<Product> addList)
        {
            List<Product> products = ((List<Product>)Session["Products"]);
            int max;
            if (products.Count == 0)
            {
                max = 0;
            }
            else
            {
                max = products.OrderByDescending(x => x.ProductID).First().ProductID;
            }

            for (int i = 0; i < addList.Count; i++)
            {
                Product product = addList[i];
                product.ProductID = max + 1 + i;
                AddProduct(product);
                products.Add(product);
            }




        }



        private void AddProduct(Product p)
        {

            try
            {

                using (var db = new ModelFinance())
                { // Create and save a new Blog 
                    //var account = new Account { ID = TextBoxID.Text, PW = TextBoxPW.Text, DeptID = Convert.ToInt32(DropDownListDept.SelectedValue) }; //造一個Blog加到Blogs資料集裡面
                    db.Product.Add(p); //存入db資料內容類別裡
                    db.SaveChanges();
                }
                //BindData();
            }
            catch (Exception ex)
            {

                Response.Write(ex.ToString());
            }



 

        }

            private void updateList(List<Product> updateList)
        {
            List<Product> products = ((List<Product>)Session["Products"]);

            for (int i = 0; i < updateList.Count; i++)
            {
                Product product2 = updateList[i];

                Product product = products.Find(Product => Product.ProductID == product2.ProductID);
                if (product == null)
                {
                    products.Add(product2);
                }
                else
                {
                    product.ProductID = product2.ProductID;
                    product.ProductName = product2.ProductName;
                    product.QuantityPerUnit = product2.QuantityPerUnit;
                    product.UnitPrice = product2.UnitPrice;
                    product.UnitsInStock = product2.UnitsInStock;
                    product.UnitsOnOrder = product2.UnitsOnOrder;
                    product.Discontinued = product2.Discontinued;


                    using (var db = new ModelFinance())
                    {
                        var product3 = db.Product.Find(product2.ProductID);

                        product3.ProductName = product2.ProductName;
                        product3.QuantityPerUnit = product2.QuantityPerUnit;
                        product3.UnitPrice = product2.UnitPrice;
                        product3.UnitsInStock = product2.UnitsInStock;
                        product3.UnitsOnOrder = product2.UnitsOnOrder;
                        product3.Discontinued = product2.Discontinued;
                        db.SaveChanges();
                    }

                }
            }
        }
        private void deleteList(List<Product> deleteList)
        {
            List<Product> products = ((List<Product>)Session["Products"]);

            using (var db = new ModelFinance())
            {

                for (int i = 0; i < deleteList.Count; i++)
                {
                    Product product2 = deleteList[i];
                    Product product = products.Find(Product => Product.ProductID == product2.ProductID);
                    products.Remove(product);


                    var product3 = db.Product.Find(product2.ProductID);
                    db.Product.Remove(product3);
                    db.SaveChanges();

                } 
            }

 


        }
        [HttpPost]
        public String batch(String list)
        {
            fillInSession();

            JavaScriptSerializer js = new JavaScriptSerializer();
            Dictionary<String, List<Product>> dlist = js.Deserialize<Dictionary<String, List<Product>>>(list);

            this.updateList(dlist["updateList"]);
            this.addList(dlist["addList"]);
            this.deleteList(dlist["deleteList"]);
            return js.Serialize(dlist);
        }
        public ActionResult get()
        {
             fillInSession();
            var products2 = (from product in (List<Product>)Session["Products"]
                             orderby product.ProductID
                             select product);

            StringBuilder sb = new StringBuilder(@"{""data"":");

            JavaScriptSerializer js = new JavaScriptSerializer();

            //string json = js.Serialize(products2);
            string json = JsonConvert.SerializeObject(products2, new Newtonsoft.Json.Converters.IsoDateTimeConverter() { DateTimeFormat = "MM/dd/yyyy" }); 

            //JsonConvert.SerializeObject(products2, new Newtonsoft.Json.Converters.IsoDateTimeConverter() { DateTimeFormat = "MM/dd/yyyy" });
            //return JsonConvert.SerializeObject(dlist, new Newtonsoft.Json.Converters.IsoDateTimeConverter() { DateTimeFormat = "MM/dd/yyyy" });

            sb.Append(json);
            sb.Append("}");

            return this.Content(sb.ToString(), "text/text");
        }

        private void fillInSession()
        {
            if (Session["Products"] == null)
            {
                ModelFinance db = new ModelFinance();
                //add in session["Products"];
                Session["Products"] = new List<Product>();
                List<Product> products = db.Database.SqlQuery<Product>("Select productid, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued from Product").ToList();
                foreach (Product product in products)
                {
                    ((List<Product>)Session["Products"]).Add(product);
                }
            }
        }

    }
}


































































final version

<!DOCTYPE html>

<html>

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <meta charset="utf-8" />





    <link href="../Content/themes/base/jquery-ui.css" rel="stylesheet" />

    <script src="../Scripts/jquery-3.4.1.min.js"></script>

    <script src="../Scripts/jquery-ui-1.9.2.min.js"></script>

    <link href="../Content/pqgrid.min.css" rel="stylesheet" />

    <link href="../Content/pqgrid.css" rel="stylesheet" />

    <script src="../Scripts/pgrid/pqgrid.min.js"></script>

    <!--




    <link href="/Content/themes/base/jquery-ui.css" rel="stylesheet" />

    <script src="/Scripts/jquery-3.4.1.min.js"></script>

    <script src="/Scripts/jquery-ui-1.9.2.min.js"></script>

    <link href="/Content/pqgrid.min.css" rel="stylesheet" />

    <link href="/Content/pqgrid.css" rel="stylesheet" />

    <script src="/Scripts/pgrid/pqgrid.min.js"></script>



    <link href="/products/Content/themes/base/jquery-ui.css" rel="stylesheet" />

    <script src="/products/Scripts/jquery-3.4.1.min.js"></script>

    <script src="/products/Scripts/jquery-ui-1.9.2.min.js"></script>

    <link href="/products/Content/pqgrid.min.css" rel="stylesheet" />

    <link href="/products/Content/pqgrid.css" rel="stylesheet" />

    <script src="/products/Scripts/pgrid/pqgrid.min.js"></script>

        -->




    <style>

        div.pq-grid {

            box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75);

            margin-bottom: 12px;

            font-family: Arial;

            font-size: 12px;

        }


        div.pq-toolbar button {

            margin: 0px 5px;

        }


        button.delete_btn {

            margin: -3px 0px;

            height: 30px;

        }


        .pq-row-delete {

            text-decoration: line-through;

        }


            .pq-row-delete > .pq-grid-cell {

                background-color: pink;

            }

    </style>


    <script>






        $(function () {

            var interval;

            function saveChanges() {

                /**

                1. if there is no active ajax request.

                2. there is no ongoing editing in the grid.

                3. grid is dirty.

                4. all changes are valid.

                */


                //$("#grid").pqGrid("getChanges");

                var $grid = $(this);


                if (grid.pqGrid("saveEditCell") === false) {

                    return false;

                }



                //grid.isDirty();

                grid.pqGrid("isDirty");

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


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


                if (gridChanges.updateList.length > 0 || gridChanges.deleteList.length > 0 || gridChanges.addList.length > 0) {


                    $.ajax({

                        url: '../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)

                        },

                        dataType: "json",

                        type: "POST",

                        async: true,

                        beforeSend: function (jqXHR, settings) {

                            //grid.option("strLoading", "Saving..");


                            grid.pqGrid("option", "strLoading", "Saving..");

                            grid.pqGrid("showLoading");


                            //grid.showLoading();

                        },

                        success: function (changes) {

                            //commit the changes.

                            grid.pqGrid("commit", { type: 'add', rows: changes.addList });

                            grid.pqGrid("commit", { type: 'update', rows: changes.updateList });

                            grid.pqGrid("commit", { type: 'delete', rows: changes.deleteList });

                            grid.pqGrid("commit");

                            grid.pqGrid("history", { method: 'reset' });

                        },

                        complete: function () {

                            grid.pqGrid("hideLoading");

                            grid.pqGrid("option", "strLoading", $.paramquery.pqGrid.defaults.strLoading);

                        }

                    })

                }

            }

            //save changes from a timer.

            //interval = setInterval(saveChanges, 5000);


            var obj = {

                width: "3100",

                height: "100%",

                //hwrap: false,

                resizable: true,




                //rowBorders: false,

                //autoRow: false,

                //rowHt: 32,

                trackModel: { on: true }, //to turn on the track changes.

                toolbar: {

                    items: [



                        {

                            type: 'button', icon: 'ui-icon-plus', label: 'New Product', listener:

                            {







                                "click": function (evt, ui) {

                                    //append empty row at the end.     

                                    if ($("#TextRawID").val().trim().length > 0) {





                                        var $grid = $(this);

                                        var obj = grid.pqGrid("getData", { dataIndx: ['ControlNO'] })

                                        var check = true;







                                        for (var i = 0; i < obj.length; i++) {

                                            // look for the entry with a matching `code` value

                                            if (obj[i].ControlNO == $("#TextRawID").val().trim()) {

                                                alert("Control NO已存在!");

                                                check = false;

                                            }

                                        }




                                        if (check) {


                                            var rowData = { ControlNO: $("#TextRawID").val().trim() }; //empty row             

                                            var rowIndx = grid.pqGrid("addRow", { rowData: rowData, checkEditable: true });

                                            grid.pqGrid("goToPage", { rowIndx: rowIndx });

                                            grid.pqGrid("editFirstCellInRow", { rowIndx: rowIndx });

                                            saveChanges();

                                            jQuery("#TextRawID").val("");

                                        }











                                    } else {

                                        alert("請輸入Control NO");

                                        $("#TextRawID").focus();

                                    }

                                }








                            }

                        },


                        { type: 'separator' },


                        {

                            type: 'button', icon: 'ui-icon-disk', label: 'Save Changes', cls: 'changes', listener:

                            {

                                "click": function (evt, ui) {

                                    saveChanges();

                                }

                            },

                            options: { disabled: true }

                        },

                    

                    {

                            type: 'button', icon: 'ui-icon-cancel', label: 'Reject Changes', cls: 'changes', listener:

                            {

                            "click": function (evt, ui) {

                                var $grid = $(this);

                                    grid.pqGrid("rollback");

                                    grid.pqGrid("history", { method: 'resetUndo' });

                                }

                            },

                            options: { disabled: true }

                        }, 

                        { type: 'separator' },

                        {

                            type: 'button', icon: 'ui-icon-arrowreturn-1-s', label: 'Undo', cls: 'changes', listener:

                            {

                                "click": function (evt, ui) {


                                    var $grid = $(this);

                                    grid.pqGrid("history", { method: 'undo' });

                                    //grid.pqGrid("history", { method: 'undo' });

                                }

                            },

                            options: { disabled: true }

                        },

                        {

                            type: 'button', icon: 'ui-icon-arrowrefresh-1-s', label: 'Redo', listener:

                            {

                                "click": function (evt, ui) {

                                    var $grid = $(this);

                                    grid.pqGrid("history", { method: 'redo' });

                                    //$grid.pqGrid("history", { method: 'redo' });

                                }

                            },

                            options: { disabled: true }

                        }




                    ]

                },

                scrollModel: { autoFit: true },

                //editor: { select: true },

                title: "<b>Auto save</b>",

                change: function (evt, ui) {

                    //saveChanges can also be called from change event.

                },

                destroy: function () {

                    //clear the interval upon destroy.

                    clearInterval(interval);

                },

                history: function (evt, ui) {

                    //var $tb = this.toolbar(),

                   //var $tb = toolbar;

                    var $grid = $(this);

                    if (ui.canUndo != null) {

                        $("button.changes", $grid).button("option", { disabled: !ui.canUndo });

                    }

                    if (ui.canRedo != null) {

                        $("button:contains('Redo')", $grid).button("option", "disabled", !ui.canRedo);

                    }

                    $("button:contains('Undo')", $grid).button("option", { label: 'Undo (' + ui.num_undo + ')' });

                    $("button:contains('Redo')", $grid).button("option", { label: 'Redo (' + ui.num_redo + ')' });

                },







                colModel: [

                    {

                        title: "Control NO", dataType: "string", dataIndx: "ControlNO", resizable: true, editable: true,

                        

                    validations: [

                        { type: 'minLen', value: 1, msg: "Required" },

                        {

                            type: function (ui) {

                                var value = ui.value,

                                    _found = false;

                                //remote validation

                                //debugger;

                                $.ajax({


                                    url: "../products/checkPK", //for ASP.NET

                                    data: { 'country': value },

                                    async: false,

                                    success: function (response) {

                                        if (response == "true") {

                                            _found = true;

                                        }

                                    }

                                });

                                if (!_found) {

                                    //ui.msg = value + " not found in list";

                                    ui.msg ="";

                                    return false;

                                }

                            }

                        }

                    ]




                    },

                    { title: "Shipping Type", dataType: "string", dataIndx: "ShippingType", resizable: true },

                    { title: "Ship", dataType: "string", dataIndx: "ShipM", resizable: true},

                    //{title: "Ship Date", dataType: "date", format: "yyyy/mm/dd", resizable: true, dataIndx: "ShipDate"},

                    $.extend(true, { title: "Ship Date", dataIndx: "ShipDate" }, date_column),

                    {

                        title: "", editable: false, minWidth: 85, sortable: false,

                        render: function (ui) {

                            return "<button type='button' class='delete_btn'>Delete</button>";

                        },

                        postRender: function (ui) {


                            //https://paramquery.com/forum/index.php?topic=2020.msg8156#msg8156

                            //Pro version has postRender callback which can be used to do DOM related stuff while column.render callback in free version can return string only.


                        }

                    }

                ],

                postRenderInterval: -1, //synchronous post render.

                pageModel: { type: "local", rPP: 20 },

                dataModel: {

                    dataType: "JSON",

                    location: "remote",

                    recIndx: "ControlNO",

                    url: "../products/get", //for ASP.NET

                    //url: "/products.php", //for PHP

                    getData: function (response) {

                        return { data: response.data };

                    }

                },


                load: function (evt, ui) {

                    var $grid = $(this);

                    data = grid.pqGrid("option", "dataModel");

                    //grid.widget().pqTooltip();

                    grid.pqGrid("widget").pqTooltip(); //attach a tooltip.


                    //validate the whole data.

                    grid.pqGrid("isValid", { data: data });

                },


                refresh: function () {

                    $("#grid_editing").find("button.delete_btn").button({ icons: { primary: 'ui-icon-scissors' } })

                        .unbind("click")

                        .bind("click", function (evt) {

                            var $tr = $(this).closest("tr");

                            var $grid = $(this);

                            var rowIndx = grid.pqGrid("getRowIndx", { $tr: $tr }).rowIndx;

                            grid.pqGrid("deleteRow", { rowIndx: rowIndx, track: true });

                        });

                }

            };

            var grid = $("#grid_editing").pqGrid(obj);



        });



        var date_column = {

            dataType: 'date',

            format: 'yyyy/mm/dd',

            editor: {

                type: 'textbox',

                init: dateEditor

            },

            validations: [

                { type: 'regexp', value: '^[0-9]{2}/[0-9]{2}/[0-9]{4}$', msg: 'Not in yyyy/mm/dd format' }

            ]

        };


        function dateEditor(ui) {


            var $inp = ui.$cell.find("input"),

                di = ui.dataIndx,

                rd = ui.rowData,

                minDate, maxDate,

                startDate = rd.startDate,

                endDate = rd.endDate,

                grid = this,

                validate = function (that) {

                    var valid = grid.isValid({

                        dataIndx: ui.dataIndx,

                        value: $inp.val(),

                        rowIndx: ui.rowIndx

                    }).valid;

                    if (!valid) {

                        that.firstOpen = false;

                    }

                };


            //calculate minDate and maxDate.

            if (di == "startDate") {

                maxDate = rd.endDate;

            }

            else if (di == "endDate") {

                minDate = rd.startDate;

            }


            //initialize the editor

            $inp

                .on("input", function (evt) {

                    validate(this);

                })

                .datepicker({

                    minDate: minDate,

                    maxDate: maxDate,

                    changeMonth: true,

                    changeYear: true,

                    showAnim: '',

                    onSelect: function () {

                        this.firstOpen = true;

                        validate(this);

                    },

                    beforeShow: function (input, inst) {

                        return !this.firstOpen;

                    },

                    onClose: function () {

                        this.focus();

                    }

                });

        };







        $(function () {



            function dateEditor(ui) {


                var $inp = ui.$cell.find("input"),

                    di = ui.dataIndx,

                    rd = ui.rowData,

                    minDate, maxDate,

                    startDate = rd.startDate,

                    endDate = rd.endDate,

                    grid = this,

                    validate = function (that) {

                        var valid = grid.isValid({

                            dataIndx: ui.dataIndx,

                            value: $inp.val(),

                            rowIndx: ui.rowIndx

                        }).valid;

                        if (!valid) {

                            that.firstOpen = false;

                        }

                    };


                //calculate minDate and maxDate.

                if (di == "startDate") {

                    maxDate = rd.endDate;

                }

                else if (di == "endDate") {

                    minDate = rd.startDate;

                }


                //initialize the editor

                $inp

                    .on("input", function (evt) {

                        validate(this);

                    })

                    .datepicker({

                        minDate: minDate,

                        maxDate: maxDate,

                        changeMonth: true,

                        changeYear: true,

                        showAnim: '',

                        onSelect: function () {

                            this.firstOpen = true;

                            validate(this);

                        },

                        beforeShow: function (input, inst) {

                            return !this.firstOpen;

                        },

                        onClose: function () {

                            this.focus();

                        }

                    });

            };




            var date_column = {

                dataType: 'date',

                format: 'yy-mm-dd',

                editor: {

                    type: 'textbox',

                    init: dateEditor

                },

                validations: [

                    { type: 'regexp', value: '^[0-9]{2}/[0-9]{2}/[0-9]{4}$', msg: 'Not in mm/dd/yyyy format' }

                ]

            },

                colM = [

                    { title: "Order ID", dataIndx: "OrderID", editable: false },

                    $.extend(true, { title: "Start Date", dataIndx: "startDate" }, date_column),

                    $.extend(true, { title: "End Date", dataIndx: "endDate" }, date_column)

                ],

                dataModel = {

                    location: "remote",

                    method: "GET",

                    url: "/content/invoice.json"

                };


 

        });

 

   

    </script>

</head>

<body>

    Control NO<input id="TextRawID" type="text" />

    <div id="grid_editing" style="margin: auto;"> </div>


</html>








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



 $(function () {

        var interval;


        function saveChanges() {

            /**

            1. if there is no active ajax request.

            2. there is no ongoing editing in the grid.

            3. grid is dirty.

            4. all changes are valid.

            */

            if (!$.active && !grid.getEditCell().$cell && grid.isDirty() && grid.isValidChange({ allowInvalid: true }).valid) {


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

                $.ajax({

                    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 )

                    },

                    dataType: "json",

                    type: "POST",

                    async: true,

                    beforeSend: function (jqXHR, settings) {

                        grid.option("strLoading", "Saving..");

                        grid.showLoading();

                    },

                    success: function (changes) {

                        //commit the changes.                

                        grid.commit({ type: 'add', rows: changes.addList });

                        grid.commit({ type: 'update', rows: changes.updateList });

                        grid.commit({ type: 'delete', rows: changes.deleteList });

                    },

                    complete: function () {

                        grid.hideLoading();

                        grid.option("strLoading", $.paramquery.pqGrid.defaults.strLoading);

                    }

                });

            }

        }

        //save changes from a timer.

        interval = setInterval(saveChanges, 1000);


        var obj = {

            hwrap: false,

            resizable: true,

            rowBorders: false,

            //autoRow: false,

            rowHt: 32,

            trackModel: { on: true }, //to turn on the track changes.            

            toolbar: {

                items: [{

                    type: 'button',

                    icon: 'ui-icon-plus',

                    label: 'New Product',

                    listener: function () {

                        //append empty row at the end.                            

                        var rowData = { ProductName: 'new product', UnitPrice: 0.2 }; //empty row

                        var rowIndx = grid.addRow({ rowData: rowData });

                        grid.goToPage({ rowIndx: rowIndx });

                        grid.editFirstCellInRow({ rowIndx: rowIndx });

                    }

                },

                { type: 'separator' },

                {

                    type: 'button',

                    icon: 'ui-icon-arrowreturn-1-s',

                    label: 'Undo',                    

                    options: { disabled: true },

                    listener: function () {

                        grid.history({ method: 'undo' });

                    }

                },

                {

                    type: 'button',

                    icon: 'ui-icon-arrowrefresh-1-s',

                    label: 'Redo',

                    options: { disabled: true },

                    listener: function () {

                        grid.history({ method: 'redo' });

                    }

                }]

            },

            scrollModel: { autoFit: true },            

            editor: { select: true },

            title: "<b>Auto save</b>",

            change: function (evt, ui) {

                //saveChanges can also be called from change event.

            },

            destroy: function () {

                //clear the interval upon destroy.

                clearInterval(interval);

            },

            history: function (evt, ui) {

                var $tb = this.toolbar(), 

                    $undo = $tb.find("button:contains('Undo')"), 

                    $redo = $tb.find("button:contains('Redo')");


                if (ui.canUndo != null) {

                    $undo.button("option", { disabled: !ui.canUndo });

                }

                if (ui.canRedo != null) {

                    $redo.button("option", "disabled", !ui.canRedo);

                }

                $undo.button("option", { label: 'Undo (' + ui.num_undo + ')' });

                $redo.button("option", { label: 'Redo (' + ui.num_redo + ')' });

            },

            colModel: [

                { title: "Product ID", dataType: "integer", dataIndx: "ProductID", editable: false, width: 80 },

                { title: "Product Name", width: 165, dataType: "string", dataIndx: "ProductName",

                    validations: [

                        { type: 'minLen', value: 1, msg: "Required" },

                        { type: 'maxLen', value: 40, msg: "length should be <= 40" }

                    ]

                },

                { title: "Quantity Per Unit", hidden: true, width: 140, dataType: "string", dataIndx: "QuantityPerUnit",

                    validations: [

                        { type: 'minLen', value: 1, msg: "Required." },

                        { type: 'maxLen', value: 20, msg: "length should be <= 20" }

                    ]

                },

                { title: "Unit Price", width: 100, dataType: "float", dataIndx: "UnitPrice", format: "$#,###.00",

                    validations: [

                        { type: 'nonEmpty', msg: "Required" },

                        { type: 'gt', value: 0.5, msg: "better be > 0.5", warn: true}

                    ]

                },

                { title: "Units In Stock", width: 100, dataType: "integer", dataIndx: "UnitsInStock",

                    validations: [{ type: 'gte', value: 0, msg: "Required"}]

                },

                { title: "Discontinued", width: 100, dataType: "bool", align: "center", dataIndx: "Discontinued",

                    editor: false,

                    type: 'checkbox',

                    validations: [{ type: 'nonEmpty', msg: "Required"}]

                },

                { title: "", editable: false, minWidth: 85, sortable: false,

                    render: function (ui) {

                        return "<button type='button' class='delete_btn'>Delete</button>";

                    },

                    postRender: function (ui) {

                        var grid = this,

                            $cell = grid.getCell(ui);

                        $cell.find(".delete_btn")

                            .button({ icons: { primary: 'ui-icon-scissors'} })

                            .bind("click", function (evt) {

                                grid.deleteRow({ rowIndx: ui.rowIndx });

                            });

                    }

                }

            ],

            postRenderInterval: -1, //synchronous post render.

            pageModel: { type: "local", rPP: 20 },

            dataModel: {

                dataType: "JSON",

                location: "remote",

                recIndx: "ProductID",

                url: "/pro/products/get", //for ASP.NET

                //url: "/pro/products.php", //for PHP

                getData: function (response) {

                    return { data: response.data };

                }

            },

            load: function (evt, ui) {

                var grid = this,

                    data = grid.option('dataModel').data;


                grid.widget().pqTooltip(); //attach a tooltip.


                //validate the whole data.

                grid.isValid({ data: data });

            }

        };

        var grid = pq.grid("#grid_editing", obj);

    });











ASP Code

//Model class

public class Product

{

    public int ProductID { get; set; }

    public String ProductName { get; set; }

    public String QuantityPerUnit { get; set; }

    public decimal UnitPrice { get; set; }

    public short UnitsInStock { get; set; }

    public short UnitsOnOrder { get; set; }

    public short ReorderLevel { get; set; }

    public bool Discontinued { get; set; }

}

public partial class productsController : Controller  //MVC

{

    private void addList(List<Product> addList)

    {

        List<Product> products = ((List<Product>)Session["Products"]);

        int max;

        if (products.Count == 0)

        {

            max = 0;

        }

        else

        {

            max = products.OrderByDescending(x => x.ProductID).First().ProductID;

        }


        for (int i = 0; i < addList.Count; i++)

        {                

            Product product = addList[i];

            product.ProductID = max + 1 + i;

            products.Add(product);

        }

    }        

    private void updateList(List<Product> updateList)

    {

        List<Product> products = ((List<Product>)Session["Products"]);


        for (int i = 0; i < updateList.Count; i++)

        {

            Product product2 = updateList[i];


            Product product = products.Find(Product => Product.ProductID == product2.ProductID);

            if (product == null)

            {

                products.Add(product2);

            }

            else

            {

                product.ProductID = product2.ProductID;

                product.ProductName = product2.ProductName;

                product.QuantityPerUnit = product2.QuantityPerUnit;

                product.UnitPrice = product2.UnitPrice;

                product.UnitsInStock = product2.UnitsInStock;

                product.UnitsOnOrder = product2.UnitsOnOrder;

                product.Discontinued = product2.Discontinued;

            }

        }            

    }                

    private void deleteList(List<Product> deleteList)

    {

        List<Product> products = ((List<Product>)Session["Products"]);


        for (int i = 0; i < deleteList.Count; i++)

        {

            Product product2 = deleteList[i];

            Product product = products.Find(Product => Product.ProductID == product2.ProductID);

            products.Remove(product);

        }        

    }

    [HttpPost]

    public String batch(String list)

    {

        fillInSession();


        JavaScriptSerializer js = new JavaScriptSerializer();

        Dictionary<String, List<Product>> dlist = js.Deserialize<Dictionary<String, List<Product>>>(list);


        this.updateList(dlist["updateList"]);

        this.addList(dlist["addList"]);

        this.deleteList(dlist["deleteList"]);

        return js.Serialize(dlist);

    }

    public ActionResult get()

    {

        fillInSession();

        var products2 = (from product in (List<Product>)Session["Products"]

                            orderby product.ProductName

                            select product);


        StringBuilder sb = new StringBuilder(@"{""data"":");


        JavaScriptSerializer js = new JavaScriptSerializer();


        string json = js.Serialize(products2);

        sb.Append(json);

        sb.Append("}");


        return this.Content(sb.ToString(), "text/text");

    }


    private void fillInSession()

    {

        if (Session["Products"] == null)

        {

            pqTestContext db = new pqTestContext();

            //add in session["Products"];

            Session["Products"] = new List<Product>();

            List<Product> products = db.Database.SqlQuery<Product>("Select productid, ProductName, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued from products").ToList();

            foreach (Product product in products)

            {

                ((List<Product>)Session["Products"]).Add(product);

            }

        }

    }


}


留言

熱門文章