1

I want to use the ShieldUI library (grid component) in order to present tabular data to the user.
The issue with this library is that if I create a new item and right after I want to edit or delete it, the grid is unable to provide its id (as the database generates for me), although I return the id from backend after the INSERT query is executed. Here is what I tried:

<!-- HTML and JS part -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>jQuery Shield UI Demos</title>
    <link id="themecss" rel="stylesheet" type="text/css" href="//www.shieldui.com/shared/components/latest/css/light/all.min.css" />
    <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/shieldui-all.min.js"></script>
</head>
<body class="theme-light">
<div id="grid"></div>
<script type="text/javascript">
    $(document).ready(function () {
        $("#grid").shieldGrid({
            dataSource: {
                remote: {
                    read: "/products",
                    modify: {
                        create: {
                            url: "/products/productCreate",
                            type: "post",
                            data: function (edited) {
                                var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
                                return {
                                    Active: edited[0].data.Active,
                                    AddedOn: date,
                                    Category: edited[0].data.Category,
                                    Name: edited[0].data.Name,
                                    Price: edited[0].data.Price,
                                    Id: edited[0].data.Id
                                };
                            }
                        },
                        update: {
                            url: "/products/productUpdate",
                            type: "post",
                            data: function (edited) {
                                var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
                                return { 
                                    Active: edited[0].data.Active,
                                    AddedOn: date,
                                    Category: edited[0].data.Category,
                                    Name: edited[0].data.Name,
                                    Price: edited[0].data.Price,
                                    Id: edited[0].data.Id
                                };
                            }
                        },
                        remove: {
                            url: "/products/productRemove",
                            type: "post",
                            data: function (removed) {
                                return { id: removed[0].data.Id };
                            }
                        }
                    }
                },
                schema: {
                    fields: {
                        Id: { path: "Id", type: Number },
                        Price: { path: "Price", type: Number },
                        Name: { path: "Name", type: String },
                        Category: { path: "Category", type: String },
                        AddedOn: { path: "AddedOn", type: Date },
                        Active: { path: "Active", type: Boolean }
                    }
                }
            },
            rowHover: false,
            columns: [
                { field: "Name", title: "Product Name", width: "300px" },
                { field: "Price", title: "Price", width: "100px" },
                { field: "Category", title: "Category", width: "200px" },
                { field: "AddedOn", title: "Added On", format: "{0:MM/dd/yyyy}" },
                { field: "Active", title: "Active" },
                {
                    title: " ",
                    width: "100px",
                    buttons: [
                        { cls: "deleteButton", commandName: "delete", caption: "<img src='/Content/img/grid/delete.png' /><span>Delete</span>" }
                    ]
                }
            ],
            editing: {
                enabled: true,
                event: "click",
                type: "cell",
                confirmation: {
                    "delete": {
                        enabled: true,
                        template: function (item) {
                            return "Delete row with ID = " + item.Id
                        }
                    }
                }
            },
            toolbar: [
                {
                    buttons: [
                        { commandName: "insert", caption: "Add Product" }
                    ],
                    position: "top"
                }
            ]
        });
    });
</script>
<style>
    .deleteButton img
    {
        margin-right: 3px;
        vertical-align: bottom;
    }
</style>
</body>
</html>

Below is the ASP.MVC part:

[ActionName("productCreate")]
public Product PostProduct(Product item)
{
    if (item == null)
    {
         throw new ArgumentNullException("item");
    }
    item.Id = Products.Max(i => i.Id) + 1;
    Products.Add(item);
    return item;
}

To make this work, I need to refresh the grid's content by performing a sort operation (the framework updates the grid before sorting) or worse, a page refresh.
So what is the issue with this approach? Am I missing something?

Dani Grosu
  • 544
  • 1
  • 4
  • 22
  • Can you provide a JSBin example that uses your web service and reproduces the issue? – Vladimir Georgiev Oct 25 '18 at 07:43
  • And in the meanwhile you can use a modify.create function to handle the creation and pass the Id to the data, like shown in this example: http://demos.shieldui.com/web/grid-editing/editing-restful-web-service – Vladimir Georgiev Oct 25 '18 at 07:44
  • 1
    Thank you for guiding me to the restful web service example. By using an AJAX call and updating the newly-created item's id it works fine. I thought that the library would do it for me. – Dani Grosu Oct 26 '18 at 08:57

1 Answers1

1

We need to modify the create object and use AJAX call in order to make this work.
So instead of:

create: {
    url: "/products/productCreate",
    type: "post",
    data: function (edited) {
        var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
        return {
            Active: edited[0].data.Active,
            AddedOn: date,
            Category: edited[0].data.Category,
            Name: edited[0].data.Name,
            Price: edited[0].data.Price,
            Id: edited[0].data.Id
        };
    }
}

You have to do:

create: function (items, success, error) {
    var newItem = items[0];
    $.ajax({
        type: "POST",
        url: "/products/productCreate",
        dataType: "json",
        data: newItem.data,
        complete: function (xhr) {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    // update the id of the newly-created item with the 
                    // one returned from the server
                    newItem.data.Id = xhr.responseJSON.Id;
                    success();
                    return;
                }
            }
            error(xhr);
        }
    });
}
Dani Grosu
  • 544
  • 1
  • 4
  • 22