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

[Solved] problem with concurrent update on popup window, please help me!!!

3 Answers 137 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.
Jekin
Top achievements
Rank 1
Jekin asked on 14 Sep 2011, 07:22 AM

Hi everybody,

I am using a Telerik grid to display my 'applicatioin' records which are stored in MS-SQL server2005, and I used Entity Framework 4. Everything is fine to insert, update,delete the data when only one user performed this.
But I have a trouble here when multiple users do this. For instance the following scenario:

  1. User A and User B are exploring the same page of my grid at this moment( of course, they saw the records)
  2. Now User A delete a record, let's say its Id is '100'.( so record 100 does not exist in database any more after this deletion) 
  3. User B doesn't know record 100 has actually been deleted by A, Then user B just try to edit record 100, he clicked the 'update' button in hoping of poping up the editing window to modify data. But in fact, the popup window becomes a strang empty div since there is no data to render.(it cannot retrieve record 100 from database)

 

The strange empty div is exact my problem! How to avoid this happening. (when there is no data to render should display a message telling the user what's hanppening rather than a strange div,you can see it from attachment.)

I think this is a very common scenario with concurrency operation, Could some one tell me how you deal this prolem?? Maybe I need add some client events to handle this.
 
Thanks a lot in advance!!!

The view is like this:

@model IEnumerable<DataModel.Models.Application>
@{
    ViewBag.Title = "Index";
}
  
@helper Gridzone()
{
    @(Html.Telerik().Grid(Model).Name("Grid")
        .Selectable()
        .ClientEvents(events => events.OnRowSelect("onRowSelected"))
        //.ClientEvents(events => events.OnRowDataBound("OnDataBound").OnDelete("Grid_onDelete"))        
        .Pageable()
        .Sortable()
        .Scrollable()
        .Pageable()
        .Filterable()
        .Resizable(resizing => resizing.Columns(true))
        .Reorderable(reorder => reorder.Columns(true))
        .DataKeys(keys => keys.Add(g => g.Id).RouteKey("MyId"))
        .Editable(editing => editing.Mode(GridEditMode.PopUp))
                .ToolBar(commands => { if (Roles.IsUserInRole("Administrators")) { commands.Insert(); } })
        .DataBinding(dataBinding =>
                dataBinding.Server()
                        .Select("Index", "Application")
                        .Insert("Insert", "Application")
                        .Update("Update", "Application")
                        .Delete("Delete", "Application"))
        .Columns(columns =>
        {
            columns.Bound(g => g.Id).Width(50).ReadOnly();
            columns.Bound(g => g.ApplicationCategory.Name).Title("Category").Width(120);
            columns.Bound(g => g.Name);
            columns.Bound(g => g.Description);
            if(Roles.IsUserInRole("Administrators"))
                {
                    columns.Command(command =>
                    {
                        command.Edit().ButtonType(GridButtonType.ImageAndText);
                        command.Delete().ButtonType(GridButtonType.ImageAndText);
                    }).Width(190);
                }
        })
    )
}

The popup window templete(to insert/update) is as below:
@model DataModel.Models.Application
  
    <fieldset>
        <legend>Application</legend>
  
        @Html.HiddenFor(model => model.Id)
  
        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
  
        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>
  
        <div class="editor-label">
            @Html.LabelFor(model => model.ApplicationCategoryId)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ApplicationCategoryId)
            @Html.ValidationMessageFor(model => model.ApplicationCategoryId)
        </div>
    </fieldset>

3 Answers, 1 is accepted

Sort by
0
Accepted
Rosen
Telerik team
answered on 14 Sep 2011, 01:10 PM
Hello Jekin,

As you are using server binding you may check if the item which will be edited does exists and if not show a warning message. I have attached a small sample which demonstrates a basic implementation of similar scenario.

Regards,
Rosen
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Jekin
Top achievements
Rank 1
answered on 16 Sep 2011, 10:05 AM
Rosen,

Thank you very much for your sample project and qucik response!
Yes, I see now, your idea helped me resolved my problem. My understanding is I have to check the entry inside Index action that is specified in (dataBinding.Server()
                        .Select("Index", "Application")

) whenever I am using sever binding(no need for ajax binding).

I changed the Index actioin to following code snippet. It works well! BTW,One more question, if I specified route key 'MyId' by
.DataKeys(keys => keys.Add(g => g.Id).RouteKey("MyId"))

I have to change the parameter name from 'id'(default) to 'MyId' for Index() ,Update(), Delete() action, right? But actually I found it's not mandatory for Update(), I mean Update(int id) is ok as well, not must be Update(int MyId) . I am confused with this. I know it must be something related to popup window when to edit, since it's <a href='...' /> liked to that popup window to show up. like this:

<A class="t-button t-button-icontext t-grid-edit" href="http://localhost:42063/Application.aspx?Grid-mode=edit&MyId=4"><SPAN class="t-icon t-edit"></SPAN>Edit</A>

Thanks again!



         public ActionResult Index(string MyId)
       {
           try
           {
               int appId = 0;
               if (int.TryParse(MyId, out appId))
               {
                   Application app = repo.FindApplication(appId);
                   if (app == null)
                   {
                       TempData["Message"] = "current record does not exist!";//display this message when next time request this action
                       return RedirectToAction("Index", this.GridRouteValues());//if current record does not exist, then redirect to Index again, force grid to refresh data. 
                   }
                   else
                       ViewBag.Application = app;
               }
               //if (!string.IsNullOrEmpty(id))
               //    ViewBag.Application = repo.FindApplication(int.Parse(id));
           }
           catch
           {
               ViewBag.Application = null;
           }
           ViewBag.ApplicationCategories = repo.GetApplicationCategories().OrderBy(c => c.Name);
           return View(repo.GetApplications());
       }
0
Rosen
Telerik team
answered on 16 Sep 2011, 11:16 AM
Hi Jekin,

Indeed, you should change the action parameter to match the DataKey's RouteKey value. 

I'm not able to recreate the behavior you have described, therefore could you please modify the project I have sent in my previous message and send it back to us.

All the best,
Rosen
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
Grid
Asked by
Jekin
Top achievements
Rank 1
Answers by
Rosen
Telerik team
Jekin
Top achievements
Rank 1
Share this question
or