[2.1] GridPanelFor Batch Update

Page 1 of 3 123 LastLast
  1. #1

    [CLOSED] [2.1] GridPanelFor Batch Update

    Hi,
    I'm watching the GridPanelFor example.
    Since it should be the right way to make "Generics" GridPanels, there is a way to implement also Batch Update features (CRUD)?

    I would like to have a generic grid which does batch update setting only the value for model, without any other hard coded reference to a specific table.

    Thanks.
    Last edited by millenovanta; Dec 26, 2012 at 12:27 PM. Reason: CLOSED
  2. #2
    I tryied porting the Bath Update sample to gridpanel for, but it works only with deleted records.

    It seems that the store does not pass created and updated records during the controller call:

    .DirectEvents(de =>
    {
        de.Click.Url = Url.Action("HandleChanges");
    
    
    
        de.Click.ExtraParams.Add(new Parameter
        {
            Name = "data",
            Value = "this.up('window').down('component[itemId=gridPanel]').store.getChangedData({skipIdForNewRecords : false})",
            Mode = ParameterMode.Raw,
            Encode = true
        });
    })
    I've no errors to work on, neither in visual studio, nor in the javascript console.
    How can I proceed?
    There is a good sample of batch saving using the GridPanelFor?

    Thanks
  3. #3
    I tried online sample
    http://mvc.ext.net/#/GridPanel_Update/Batch/

    and it works fine for me, updated records are passed to the server
    Vladimir Shcheglov
    Sr. Developer
  4. #4
    I'm sorry for the misunderstanding: the sample works fine. It is only myporting in GridPanelFor which does not work.

    Can you provide me a way to make it?
    Should that sample work with gridpanelfor too?

    Thanks.
  5. #5
    You should provide simple test sample (view and controller) which demonstrate your issue
    Vladimir Shcheglov
    Sr. Developer
  6. #6
    Ok! Well..

    My view is:

    (....)
    items.Add(Html.X().GridPanelFor(Model)
                                    .ItemID("gridPanel")
                                    .Title("Templs")
                                    .Width(700)
                                    .Height(500)
                                    .Listeners(list =>
                                        {
                                            list.SelectionChange.Handler = "if (this.up('window').down('component[itemId=gridPanel]').selModel.hasSelection()) {" +
                                                                            "this.up('window').down('component[itemId=btnDelete]').enable();}" +
                                                                            "else{this.up('window').down('component[itemId=btnDelete]').disable();}";
                                        })
                                    .Plugins(plugins =>
                                    {
                                        plugins.Add(Html.X().CellEditing()
                                            .ClicksToEdit(1)
                                        );
                                    })
    
                                    .SelectionModel(selectionModel => selectionModel.Add(Html.X().RowSelectionModel()
                                        .Mode(SelectionMode.Multi)
                                    ))
    
                                    .Editor(editors =>
                                    {
                                        editors.Add(Html.X().TextField()
                                        );
                                    })
                                    .Buttons(buttons =>
                                    {
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnAdd")
                                            .Text("Insert")
                                            .Icon(Icon.Add)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').store.insert(0, {});" +
                                                                          "this.up('window').down('component[itemId=gridPanel]').editingPlugin.startEditByPosition({row:0, column:0});";
                                            }));
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnDelete")
                                            .Text("Delete")
                                            .Icon(Icon.Delete)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').deleteSelected();" +
                                                                          "if (!this.up('window').down('component[itemId=gridPanel]').hasSelection()) " +
                                                                          "{this.up('window').down('component[itemId=btnDelete]').disable();}";
                                            }));
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnClear")
                                            .Text("Clear")
                                            .Icon(Icon.Cancel)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').getSelectionModel().deselectAll();" +
                                                                          "if (!this.up('window').down('component[itemId=gridPanel]').hasSelection()) " +
                                                                          "{this.up('window').down('component[itemId=btnDelete]').disable();}";
                                            }));
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnRefresh")
                                            .Text("Refresh")
                                            .Icon(Icon.ArrowRefresh)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').store.load();";
                                            }));
    
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnSync")
                                            .Text("Sync")
                                            .Icon(Icon.Disk)
                                            .DirectEvents(de =>
                                            {
                                                de.Click.Url = Url.Action("HandleChanges");
    
    
    
                                                de.Click.ExtraParams.Add(new Parameter
                                                {
                                                    Name = "data",
                                                    Value = "this.up('window').down('component[itemId=gridPanel]').store.getChangedData({skipIdForNewRecords : false})",
                                                    Mode = ParameterMode.Raw,
                                                    Encode = true
                                                });
                                            }));
                                        
                                    })
    
                                );
    And my controller:

    public ActionResult HandleChanges(StoreDataHandler handler)
            {
                ChangeRecords<Templ> persons = handler.BatchObjectData<Templ>();
                //var store = this.GetCmp<Store>("Store1");
                Templ templ = new Templ();
    
                ProvaContext db = new ProvaContext();
                var set = db.Set<Templ>();
    
    
                foreach (Templ created in persons.Created)
                {
                    set.Add(created);
    
                    //var record = store.GetByInternalId(created.TemplID);
                    //record.CreateVariable = true;
                    //record.SetId(created.Id);
                    //record.Commit();
                    //created.PhantomId = null;
                }
    
                foreach (Templ deleted in persons.Deleted)
                {
    
                    set.Attach(deleted);
                    set.Remove(deleted);
    
                    //Templ.DeletePerson(deleted.Id.Value);
                    //store.CommitRemoving(deleted.Id.Value);
                }
    
                foreach (Templ updated in persons.Updated)
                {
                    set.Attach(updated);
                    db.Entry<Templ>(updated).State = EntityState.Modified;
    
                    //Templ.UpdatePerson(updated);
    
                    //var record = store.GetById(updated.Id.Value);
                    //record.Commit();
                }
    
                db.SaveChanges();
    
                return this.Direct();
            }
    Finally, my model, quite standard:

        [Model(Name = "Person", ClientIdProperty = "PhantomId")]
        [JsonWriter(Encode = true, Root = "data")]
        public class Templ
        {
            [ModelField(IDProperty=true)]
            [Column(Hidden=true)]
            public int TemplID { get; set; }
            public string Codice { get; set; }
            public string Desc { get; set; }
            public decimal Quant { get; set; }
            public decimal Numer { get; set; }
        }
    So, I know that the lines commented out in the controller are necessary to have the store up to date with db changes.
    But, I'm going step by step. If I run this sample, and i breakpoint after the line

    ChangeRecords<Templ> persons = handler.BatchObjectData<Templ>();
    , and I watch at the value of "persons", it containes only deleted items, and not created and updated items. So, there are not items which go in created and updated "foreach cicles".

    It lets me think that there is something wrong in the view which doesn't pass thorugh "data", cerated and updated items...


    Thanks again!
  7. #7
    Please provide Controller and View do not require any changes from our side (i don't see what model you pass to the view)
    Vladimir Shcheglov
    Sr. Developer
  8. #8
    The model definition in the view is

    @model IEnumerable<object>
    In the Index method of the controller I return

    Ext.Net.MVC.PartialViewResult{ ViewName = "Window", Model = List<Templ>}
    If it can be helpful I can post entire view and controller.
    Thanks.
  9. #9
    These are full view and controller:

    View (it is a partial view, the Index view contains only a button which renders thid partial view):
    @model IEnumerable<object>
    @(
    
    
    
     Html.X().Window()
        .Title("WINDOW 1")
        .CloseAction(CloseAction.Destroy)
        .Icon(Icon.Application)
        .Height(600)
        .Width(800)
        .BodyStyle("background-color: #fff")
        .BodyPadding(5)
        .Modal(false)
        
        .Items(items =>
                            {
    
                                items.Add(Html.X().GridPanelFor(Model)
                                    .ItemID("gridPanel")
                                    .Title("Templs")
                                    .Width(700)
                                    .Height(500)
                                    .Listeners(list =>
                                        {
                                            list.SelectionChange.Handler = "if (this.up('window').down('component[itemId=gridPanel]').selModel.hasSelection()) {" +
                                                                            "this.up('window').down('component[itemId=btnDelete]').enable();}" +
                                                                            "else{this.up('window').down('component[itemId=btnDelete]').disable();}";
                                        })
                                    .Plugins(plugins =>
                                    {
                                        plugins.Add(Html.X().CellEditing()
                                            .ClicksToEdit(1)
                                        );
                                    })
    
                                    .SelectionModel(selectionModel => selectionModel.Add(Html.X().RowSelectionModel()
                                        .Mode(SelectionMode.Multi)
                                    ))
    
                                    .Editor(editors =>
                                    {
                                        editors.Add(Html.X().TextField()
                                        );
                                    })
    
                                    //.EditorStrategy(strategy =>
                                    //{
                                    //    strategy.Handler = "return record.data.editor";    
                                    //})
    
                                    
                                    
                                    
    
    
                                    .Buttons(buttons =>
                                    {
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnAdd")
                                            .Text("Insert")
                                            .Icon(Icon.Add)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').store.insert(0, {});" +
                                                                          "this.up('window').down('component[itemId=gridPanel]').editingPlugin.startEditByPosition({row:0, column:0});";
                                            }));
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnDelete")
                                            .Text("Delete")
                                            .Icon(Icon.Delete)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').deleteSelected();" +
                                                                          "if (!this.up('window').down('component[itemId=gridPanel]').hasSelection()) " +
                                                                          "{this.up('window').down('component[itemId=btnDelete]').disable();}";
                                            }));
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnClear")
                                            .Text("Clear")
                                            .Icon(Icon.Cancel)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').getSelectionModel().deselectAll();" +
                                                                          "if (!this.up('window').down('component[itemId=gridPanel]').hasSelection()) " +
                                                                          "{this.up('window').down('component[itemId=btnDelete]').disable();}";
                                            }));
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnRefresh")
                                            .Text("Refresh")
                                            .Icon(Icon.ArrowRefresh)
                                            .Listeners(listeners =>
                                            {
                                                listeners.Click.Handler = "this.up('window').down('component[itemId=gridPanel]').store.load();";
                                            }));
    
                                        buttons.Add(Html.X().Button()
                                            .ItemID("btnSync")
                                            .Text("Sync")
                                            .Icon(Icon.Disk)
                                            .DirectEvents(de =>
                                            {
                                                de.Click.Url = Url.Action("HandleChanges");
    
    
    
                                                de.Click.ExtraParams.Add(new Parameter
                                                {
                                                    Name = "data",
                                                    Value = "this.up('window').down('component[itemId=gridPanel]').store.getChangedData({skipIdForNewRecords : false})",
                                                    Mode = ParameterMode.Raw,
                                                    Encode = true
                                                });
                                            }));
                                        
                                    })
    
                                );
                                
                                
                            }
            )
    
    )
    Controller:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MvcApp.Models;
    using Ext.Net;
    using Ext.Net.MVC;
    using System.Web.Services;
    using System.Data;
    
    namespace MvcApp.Controllers
    {
        public class HomeController : System.Web.Mvc.Controller
        {
            public ActionResult Index()
            {
    
    
                //Database.SetInitializer<ProvaContext>(new CustomDbInitializer());
                
                ProvaContext db = new ProvaContext();
                
                db.Database.CreateIfNotExists();
                
    
                ViewBag.Message = "Welcome to ASP.NET MVC!";
    
                return View();
            }
            public ActionResult Prova()
            {
    
                return View();
            }
    
    
            public ActionResult RenderWindow(string id) {
                Ext.Net.Examples.DataService ds = new Ext.Net.Examples.DataService();
                
                Ext.Net.MVC.PartialViewResult partial = new Ext.Net.MVC.PartialViewResult();
    
                if(id == "Templ"){
                    partial = new Ext.Net.MVC.PartialViewResult { ViewName = "Window", Model = ds.GetAllTempls() };
                }
    
                if (id == "Templnew")
                {
                    partial = new Ext.Net.MVC.PartialViewResult { ViewName = "Window", Model = ds.GetAllTemplnews() };
                }
    
                return partial;
    
            }
    
    
    
    
    
    
    
            public ActionResult HandleChanges(StoreDataHandler handler)
            {
                ChangeRecords<Templ> persons = handler.BatchObjectData<Templ>();
                //var store = this.GetCmp<Store>("Store1");
                Templ templ = new Templ();
    
                ProvaContext db = new ProvaContext();
                var set = db.Set<Templ>();
    
    
                foreach (Templ created in persons.Created)
                {
                    set.Add(created);
    
                    //var record = store.GetByInternalId(created.TemplID);
                    //record.CreateVariable = true;
                    //record.SetId(created.Id);
                    //record.Commit();
                    //created.PhantomId = null;
                }
    
                foreach (Templ deleted in persons.Deleted)
                {
    
                    set.Attach(deleted);
                    set.Remove(deleted);
    
                    //Templ.DeletePerson(deleted.Id.Value);
                    //store.CommitRemoving(deleted.Id.Value);
                }
    
                foreach (Templ updated in persons.Updated)
                {
                    set.Attach(updated);
                    db.Entry<Templ>(updated).State = EntityState.Modified;
    
                    //Templ.UpdatePerson(updated);
    
                    //var record = store.GetById(updated.Id.Value);
                    //record.Commit();
                }
    
                db.SaveChanges();
    
                return this.Direct();
            }
    
    
    
    
    
    
    
        }
    }
    I'm stopped again with that "persons" in the Controller (HandleChanges), which contains only deleted items (not created or updated), like if would be the view who does not pass them via the store.getChangedData...
  10. #10
    Hello,

    We've noticed the same strange behavior while trying to reproduce the grid batch example (mvc batch example) with our own models. getChangedData only returned deleted items (not created or updated).

    However, in the example, the ID property of the model is nullable and it may be the cause of this bug. Putting a nullable ID on our model, made the example work as expected and getChangedData returned all modified items (created updated and deleted).

    Is it required to have a nullable ID on our model?
Page 1 of 3 123 LastLast

Similar Threads

  1. [CLOSED] MVC Grid Batch Editing
    By adelaney in forum 2.x Legacy Premium Help
    Replies: 19
    Last Post: Sep 27, 2012, 5:55 AM
  2. [CLOSED] How to show mask on ajax update panel update
    By egvt in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: May 18, 2012, 9:36 PM
  3. [CLOSED] Update displayfield on directevents, update its size
    By SouthDeveloper in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Nov 16, 2011, 9:57 PM
  4. Replies: 2
    Last Post: Jun 16, 2011, 6:50 AM
  5. [CLOSED] Update ASP Update Panel with Direct Event
    By sharif in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Jun 24, 2010, 12:48 AM

Tags for this Thread

Posting Permissions