This is a migrated thread and some comments may be shown as answers.

[Solved] Grid BatchEditing Update Not Working as Expected

3 Answers 175 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Douglas
Top achievements
Rank 1
Douglas asked on 09 Apr 2012, 02:17 PM
Hello,

I've implemented an MVC3/Razor Grid Control from the Editing Batch example in the Telerik Extensions for ASP.NET MVC and for the most part, I think it's working, however I have noticed that while the updates appear to be working on the client, the underlying database tables are not updated.

I thought that I may have missed some step in my implementation of this, however after doing an update in the Batch Editing example for a Product Name in the Northwind database, the underlying data tables also is not changed.

VIEW:

@model IEnumerable<MarketingWebsiteTools.Models.EditableCallout>
 
@using MarketingWebsiteTools.Extensions;
@using MarketingWebsiteTools.Models;
 
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<h2>Marketing Messages</h2>
 
 
@(Html.Telerik().Grid<MarketingWebsiteTools.Models.EditableCallout>()
    .Name("Grid")
            .DataKeys(keys =>
            {
                keys.Add(p => p.id);
            })
        .ToolBar(commands =>
        {
            commands.Insert();
            commands.SubmitChanges();
        })
    .Columns(columns =>
    {
         
        columns.Bound(o => o.ProductIdentifier).Width(125);
        columns.Bound(o => o.DateStart).Width(75);
        columns.Bound(o => o.DateEnd).Width(75);
        columns.Bound(o => o.Value).Width(75);
        columns.Bound(o => o.IsActive).Width(75);
        columns.Command(commands => commands.Delete()).Width(125).Title("Delete");
    })
                .ClientEvents(events => events.OnDataBinding("Grid_onDataBinding").OnError("Grid_onError"))
                .Editable(editing => editing.Mode(GridEditMode.InCell).DefaultDataItem(new EditableCallout
                {
                    DateStart = DateTime.Today
 
                }))
            .DataBinding(dataBinding => dataBinding.Ajax()
            .Select("_Index", "Callouts")
            .Update("_SaveBatchEditing", "Callouts")
            )
 
            .Pageable()
            .Scrollable()
            .Sortable()
            .Groupable()
            .Filterable()
)
 
<script type="text/javascript">
    function Grid_onError(args) {
        if (args.textStatus == "modelstateerror" && args.modelState) {
            var message = "Errors:\n";
            $.each(args.modelState, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            args.preventDefault();
            alert(message);
        }
    }
    function Grid_onDataBinding(e) {
        var grid = $(this).data('tGrid');
        if (grid.hasChanges()) {
            if (!confirm('You are going to lose any unsaved changes. Are you sure?')) {
                e.preventDefault();
            }
        }
    }
</script>
 
 
@section HeadContent {
<style type="text/css">
    .field-validation-error
    {
        position: absolute;
        display: block;
    }
     
    * html .field-validation-error { position: relative; }
    *+html .field-validation-error { position: relative; }
     
    .field-validation-error span
    {
        position: absolute;
        white-space: nowrap;
        color: red;
        padding: 17px 5px 3px;
        background: transparent url('@Url.Content("~/Content/Common/validation-error-message.png") ') no-repeat 0 0;
    }
     
    /* in-form editing */
    .t-edit-form-container
    {
        width: 350px;
        margin: 1em;
    }
     
    .t-edit-form-container .editor-label,
    .t-edit-form-container .editor-field
    {
        padding-bottom: 1em;
        float: left;
    }
     
    .t-edit-form-container .editor-label
    {
        width: 30%;
        text-align: right;
        padding-right: 3%;
        clear: left;
    }
     
    .t-edit-form-container .editor-field
    {
        width: 60%;
    }
</style>
}

CONTROLLER:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PagedList;
using Telerik.Web.Mvc;
using MarketingWebsiteTools.Models;
using MarketingWebsiteTools.ViewModels;
//using MarketingWebsiteTools.Services;
using MarketingWebsiteTools.Filters;
 
namespace MarketingWebsiteTools.Controllers
{
    public partial class CalloutsController : Controller
    {
        [SourceCodeFile("EditableCallout", "~/Models/EditableCallout.cs", Order=1 )]
        [SourceCodeFile("SessionCalloutRepository", "~/Models/SessionCalloutRepository.cs", Order = 2)]
        [SourceCodeFile("SessionCalloutRepository", "~/Models/SessionCalloutRepository.cs", Order = 3)]
 
 
        public int PageSize = 30;
       public ActionResult Index()
        {
            return View();
        }
 
 
        [GridAction]
        public ActionResult _Index()
        {
            return View(new GridModel(SessionCalloutRepository.All()));
        }
 
        [AcceptVerbs(HttpVerbs.Post)]
        [CultureAwareAction]
        [GridAction]
        public ActionResult _SaveBatchEditing([Bind(Prefix =
            "inserted")]IEnumerable<EditableCallout> insertedCallouts,
            [Bind(Prefix = "updated")]IEnumerable<EditableCallout> updatedCallouts,
            [Bind(Prefix = "deleted")]IEnumerable<EditableCallout> deletedCallouts)
        {
            if (insertedCallouts != null)
            {
                foreach (var callouts in insertedCallouts)
                {
                    SessionCalloutRepository.Insert(callouts);
                }
            }
            if (updatedCallouts != null)
            {
                foreach (var callouts in updatedCallouts)
                {
 
                    var target = SessionCalloutRepository.One(p => p.id == callouts.id);
                    if (target != null)
                    {
                        target.DateStart = callouts.DateStart;
                        target.DateEnd = callouts.DateEnd;
                        target.Value = callouts.Value;
                        target.IsActive = callouts.IsActive;
                        SessionCalloutRepository.Update(target);
                    }
                }
            }
            if (deletedCallouts != null)
            {
                foreach (var product in deletedCallouts)
                {
                    SessionCalloutRepository.Delete(product);
                }
            }
            return View(new GridModel(SessionCalloutRepository.All()));
        }
 
 
 
        
        // GET: /Callouts/Create
 
        public ActionResult Create()
        {
            return View();
        }
 
        
    }
}

MODEL:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
 
namespace MarketingWebsiteTools.Models
{
    //[KnownType(typeof(EditableCallout))]
    public class EditableCallout
    {
        //[ScaffoldColumn(false)]
        [DisplayName("id")]
        public int id { get; set; }
 
        //[Required]
        //[DisplayName("CalloutID")]
        //public int CalloutID { get; set; }
 
        //[Required]
        //[DisplayName("CalloutTypeID")]
        //public int? CalloutTypeID { get; set; }
 
        [Required]
        [DisplayName("ProductIdentifier")]
        public string ProductIdentifier { get; set; }
 
        [DisplayName("DateStart")]
        public DateTime? DateStart { get; set; }
 
        [DisplayName("DateEnd")]
        public DateTime? DateEnd { get; set; }
 
        [DisplayName("IsActive")]
        public int? IsActive { get; set; }
 
        //[DisplayName("CalloutValue")]
        //public string CalloutValue { get; set; }
 
        //[DisplayName("Comment")]
        //public string Comment { get; set; }
 
 
        [DisplayName("Value")]
        public string Value { get; set; }
    }
     
 
 
}


REPOSITORY:
namespace MarketingWebsiteTools.Models
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using MarketingWebsiteTools.ViewModels;
    using MarketingWebsiteTools.Models;
 
    public static class SessionCalloutRepository
    {
        public static IList<EditableCallout> All()
        {
            WebsiteDataContext wdc = new WebsiteDataContext();
            //CalloutContext db = new CalloutContext();
            IList<EditableCallout> result = (IList<EditableCallout>)HttpContext.Current.Session["Callouts"];
             
            if (result == null)
            {
                HttpContext.Current.Session["Callouts"] = result =
                   (from c in wdc.CalloutToProducts
                    join cv in wdc.CalloutValues on c.CalloutID equals cv.CalloutID
                    select new EditableCallout
                    {
                        id = c.id,
                        ProductIdentifier = c.ProductIdentifier,
                        DateStart = c.DateStart,
                        DateEnd = c.DateEnd,
                        Value = cv.Value,
                        IsActive = c.IsActive
                    }).ToList();
            }
 
            return result;
        }
 
 
        public static EditableCallout One(Func<EditableCallout, bool> predicate)
        {
            return All().Where(predicate).FirstOrDefault();
        }
        public static void Insert(EditableCallout callout)
        {
            callout.id = All().OrderByDescending(c => c.id).First().id+ 1;
            All().Insert(0, callout);
        }
 
        public static void Update(EditableCallout callout)
        {
            EditableCallout target = One(c => c.id == callout.id);
            if (target != null)
            {
                target.ProductIdentifier = callout.ProductIdentifier;
                target.DateEnd = callout.DateEnd;
                target.DateStart = callout.DateStart;
                target.Value = callout.Value;
                target.IsActive = callout.IsActive;
                 
 
            }
        }
        public static void Delete(EditableCallout callout)
        {
            EditableCallout target = One(c => c.id== callout.id);
            if (target != null)
            {
                All().Remove(target);
            }
        }
    }
}

To me It looks like there's no actual CRUD actions taken on the database anywhere.  The only thing happening here is Inserting, Updating or Deleting the IList object.

If this is true, how does one go about updating the database?

The batch update isn't much good if it doesn't do that, correct?

Thanks

Doug

3 Answers, 1 is accepted

Sort by
0
Douglas
Top achievements
Rank 1
answered on 10 Apr 2012, 01:31 PM
anybody?

0
Douglas
Top achievements
Rank 1
answered on 11 Apr 2012, 02:45 PM
I still haven't figured this out.

Can anyone at Telerik please give me some insight on what I need to do to update the database?
0
Alan
Top achievements
Rank 1
answered on 07 Aug 2012, 03:07 AM
Agreed - this is so frustrating! I've spent hours on this..

Everything appears to be working on the front end, but underlying table not updated
Tags
Grid
Asked by
Douglas
Top achievements
Rank 1
Answers by
Douglas
Top achievements
Rank 1
Alan
Top achievements
Rank 1
Share this question
or