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

Using a ViewModel, RESTful API, and Grid Inline Editing

7 Answers 72 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Joe
Top achievements
Rank 1
Joe asked on 27 Jan 2017, 06:26 PM

I have a form which a user fills in and submits to perform a search.  This request is then set to a RESTful WebAPI service, and receives a list of UploadedDocuments.  The user is then re-directed to a new view showing those results in a grid using a ViewModel:

public ActionResult DocumentSearch(string docketNumber, string ssnNumber, string lastName, string firstName, string caseID, string garnishType, string clientId)
        {
            GarnishmentDocumentSearch docSearch = new GarnishmentDocumentSearch()
            {
                DocketNumber = docketNumber,
                SSNNumber = ssnNumber,
                LastName = lastName,
                FirstName = firstName,
                CaseID = caseID,
                GarnishType = garnishType,
                ClientId = clientId
            };
 
            // send the new document link to the service layer, for saving to the DB
            List<UploadedDocument> response = WebApiHelper.CallPostAPI<List<UploadedDocument>, GarnishmentDocumentSearch>($"{_baseURL}/api/Garnishments/DocumentSearch", docSearch);
 
            return View("DocumentResults", response);
        }

 

The results are populated in the grid ok, but now I want to also support inline editing.  However, my Edit button doesn;t seem to do anything.  I have tried both GridEditMode.Inline and GridEditMode.PopUp.  I have added an appropriate Update() to the grid.

@(Html.Kendo().Grid(Model)
      .Name("docResults")
      .TableHtmlAttributes(new { @class = "table-condensed"})
      .Columns(cols =>
      {
          cols.Bound(c => c.Id).Width(35).ClientTemplate("<input type=\"checkbox\" />");
          cols.Bound(c => c.DocketNumber);
          cols.Bound(c => c.CaseId);
          cols.Bound(c => c.Type);
          cols.Bound(c => c.ClientId);
          cols.Bound(c => c.SSN);
          cols.Bound(c => c.LastName);
          cols.Bound(c => c.FirstName);
          cols.Bound(c => c.Name).Title("Document");
          cols.Command(c => c.Edit());
      })
      .Resizable(r => r.Columns(true))
      .Scrollable(s => s.Height("auto"))
      .Sortable()
      .Pageable(p => p
          .Refresh(true)
          .PageSizes(new List<object> { 10, 20, 30, 40, 50, "all" })
          .ButtonCount(10))
      .Filterable(f => f.Enabled(true))
      .Events(ev => ev.DataBound("gridBound"))
      .DataSource(ds => ds
          .Ajax()
          .PageSize(20)
          .Model(m => m.Id(d => d.Id))
          // .ServerOperation(false)
          .Update(u => u.Action("EditInline", "Document"))
          .Events(e => e.Error("error_handler"))
      )
      .ToolBar(tb => tb.Custom().Text("Clear Filter").HtmlAttributes(new { id = "gridFilterReset", style = "float:right;" }))
      .Editable(e => e.Mode(GridEditMode.PopUp  ))
)

 

When I click the Edit button when using PopUp, a popup screen does display very quickly, but then it just disappears.  So how can I enable editing in the grid (I'd prefer to use the PopUp method) while using a ViewModel that's been pushed to the View versus having the grid pull the data?  Is it even possible?

7 Answers, 1 is accepted

Sort by
0
Joe
Top achievements
Rank 1
answered on 27 Jan 2017, 07:54 PM

For the sake of argument, I re-structured things a bit, instead of the grid populating via the ViewModel pushed to the View, I implemented a Read action to populate the grid.  And it works fine.  But the EDIT button behaves the exact same.  When using PopUp mode, the popup shows then just immediately shuts back down.  I can briefly see there are form field controls on the popup, but it's too fast to get a screenshot of it.

If I try InCell editing, double clicking a cell shows an entry box (textfield) but then immediately disappears as well.  And then finally trying the InLine, clicking the Edit button doesn't appear to do anything.

I'm getting super frustrated...  Any suggestions at all on what may be happening?

0
Joe
Top achievements
Rank 1
answered on 27 Jan 2017, 08:23 PM

Ok, since unfortunately these forums are too slow to be productive during the day, I was left with my own devices to try and figure this thing out.  I'm not really any closer, but I do have much more information and code to share.

First, as I stated above, I restructured things around quite a bit.  Now when the user presses the Search button, from the Search field, it submits to this action:

public ActionResult DocumentSearch(string docketNumber, string ssnNumber, string lastName, string firstName, string caseID, string garnishType, string clientId)
{
    GarnishmentDocumentSearch docSearch = new GarnishmentDocumentSearch()
    {
        DocketNumber = docketNumber,
        SSNNumber = ssnNumber,
        LastName = lastName,
        FirstName = firstName,
        CaseID = caseID,
        GarnishType = garnishType,
        ClientId = clientId
    };
 
    return View("SearchResults", docSearch);
}

 

All this does is load up a new View, passing into it the search criteria as ViewModel.  This is the appropriate view:

@using Vensure.Dashboard.DataEntity
@model GarnishmentDocumentSearch
 
@{
    ViewBag.Title = "Document Search";
}
 
<h2>@ViewBag.Title</h2>
 
@(Html.Kendo().Grid<UploadedDocument>()
      .Name("docResults")
      .TableHtmlAttributes(new { @class = "table-condensed" })
      .Columns(cols =>
      {
          cols.Bound(c => c.Id).Width(35).ClientTemplate("<input type=\"checkbox\" />");
          cols.Bound(c => c.DocketNumber);
          cols.Bound(c => c.CaseId);
          cols.Bound(c => c.Type);
          cols.Bound(c => c.ClientId);
          cols.Bound(c => c.SSN);
          cols.Bound(c => c.LastName);
          cols.Bound(c => c.FirstName);
          cols.Bound(c => c.Name).Title("Document");
          cols.Command(c => c.Edit());
      })
      .Resizable(r => r.Columns(true))
      .Scrollable(s => s.Height("auto"))
      .Sortable()
      .Pageable(p => p
          .Refresh(true)
          .PageSizes(new List<object> { 10, 20, 30, 40, 50, "all" })
          .ButtonCount(10))
      .Filterable(f => f.Enabled(true))
      .Events(ev => ev.DataBound("gridBound"))
      .AutoBind(true)
      .DataSource(ds => ds
          .Ajax()
          .PageSize(20)
          .Model(m => m.Id(d => d.Id))
          .Read(r => r.Action("GetSearchResults", "Document", new { docketNumber = @Model.DocketNumber,
                                                                    ssnNumber = @Model.SSNNumber,
                                                                    lastName = @Model.LastName,
                                                                    firstName = @Model.FirstName,
                                                                    caseID = @Model.CaseID,
                                                                    garnishType = @Model.GarnishType,
                                                                    clientID = @Model.ClientId }).Type(HttpVerbs.Get))
          .Update(u => u.Action("EditInline", "Document"))
          .Events(e => e.Error("error_handler"))
      )
      .ToolBar(tb => tb.Custom().Text("Clear Filter").HtmlAttributes(new { id = "gridFilterReset", style = "float:right;" }))
      .Editable(e => e.Mode(GridEditMode.PopUp))
    )
 
<script type="text/javascript">
    $(document).ready(function () {
        $("#docResults").click(function (e) {
            e.preventDefault();
            var ds = $("#docResults").data("kendoGrid").dataSource;
            ds.filter([]);
        });
    });
 
    function error_handler(e) {
        if (e.errors) {
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
        }
    }
</script>

 

So when I clicked the EDIT button on a row, the popup editing screen would flash on the screen and immediately disappear.  So far, everything other than the restructuring of the grid (push versus pull) is the same.

However, what I did notice was that in VS2015 (while debugging), everytime I pressed the EDIT button, in the Event monitor of the Diagnostic Tools would show a call to the Action used to populate the grid in the first place.  So I placed a breakpoint in there, and sure enough when I pressed the EDIT button, my breakpoint hit and the popup editor screen remained on screen. (I've also included two screen shots as attachements)

So now I'm doubly confused. 
0
Joe
Top achievements
Rank 1
answered on 27 Jan 2017, 08:26 PM

Ok, since unfortunately these forums are too slow to be productive during the day, I was left with my own devices to try and figure this thing out.  I'm not really any close, but I do have much more information and code to share.

First, as I stated above, I restructured things around quite a bit.  Now when the user presses the Search button, from the Search field, it submits to this action:

public ActionResult DocumentSearch(string docketNumber, string ssnNumber, string lastName, string firstName, string caseID, string garnishType, string clientId)
{
    GarnishmentDocumentSearch docSearch = new GarnishmentDocumentSearch()
    {
        DocketNumber = docketNumber,
        SSNNumber = ssnNumber,
        LastName = lastName,
        FirstName = firstName,
        CaseID = caseID,
        GarnishType = garnishType,
        ClientId = clientId
    };
 
    return View("SearchResults", docSearch);
}

 

All this does is load up a new View, passing into it the search criteria as ViewModel.  This is the appropriate view:

@using Vensure.Dashboard.DataEntity
@model GarnishmentDocumentSearch
 
@{
    ViewBag.Title = "Document Search";
}
 
<h2>@ViewBag.Title</h2>
 
@(Html.Kendo().Grid<UploadedDocument>()
      .Name("docResults")
      .TableHtmlAttributes(new { @class = "table-condensed" })
      .Columns(cols =>
      {
          cols.Bound(c => c.Id).Width(35).ClientTemplate("<input type=\"checkbox\" />");
          cols.Bound(c => c.DocketNumber);
          cols.Bound(c => c.CaseId);
          cols.Bound(c => c.Type);
          cols.Bound(c => c.ClientId);
          cols.Bound(c => c.SSN);
          cols.Bound(c => c.LastName);
          cols.Bound(c => c.FirstName);
          cols.Bound(c => c.Name).Title("Document");
          cols.Command(c => c.Edit());
      })
      .Resizable(r => r.Columns(true))
      .Scrollable(s => s.Height("auto"))
      .Sortable()
      .Pageable(p => p
          .Refresh(true)
          .PageSizes(new List<object> { 10, 20, 30, 40, 50, "all" })
          .ButtonCount(10))
      .Filterable(f => f.Enabled(true))
      .Events(ev => ev.DataBound("gridBound"))
      .AutoBind(true)
      .DataSource(ds => ds
          .Ajax()
          .PageSize(20)
          .Model(m => m.Id(d => d.Id))
          .Read(r => r.Action("GetSearchResults", "Document", new { docketNumber = @Model.DocketNumber,
                                                                    ssnNumber = @Model.SSNNumber,
                                                                    lastName = @Model.LastName,
                                                                    firstName = @Model.FirstName,
                                                                    caseID = @Model.CaseID,
                                                                    garnishType = @Model.GarnishType,
                                                                    clientID = @Model.ClientId }).Type(HttpVerbs.Get))
          .Update(u => u.Action("EditInline", "Document"))
          .Events(e => e.Error("error_handler"))
      )
      .ToolBar(tb => tb.Custom().Text("Clear Filter").HtmlAttributes(new { id = "gridFilterReset", style = "float:right;" }))
      .Editable(e => e.Mode(GridEditMode.PopUp))
    )
 
<script type="text/javascript">
    $(document).ready(function () {
        $("#docResults").click(function (e) {
            e.preventDefault();
            var ds = $("#docResults").data("kendoGrid").dataSource;
            ds.filter([]);
        });
    });
 
    function error_handler(e) {
        if (e.errors) {
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
        }
    }
</script>

 

So when I clicked the EDIT button on a row, the popup editing screen would flash on the screen and immediately disappear.  So far, everything other than the restructuring of the grid (push versus pull) is the same.

However, what I did notice was that in VS2015 (while debugging), everytime I pressed the EDIT button, in the Event monitor of the Diagnostic Tools would show a call to the Action used to populate the grid in the first place.  So I placed a breakpoint in there, and sure enough when I pressed the EDIT button, my breakpoint hit and the popup editor screen remained on screen.

So now I'm doubly confused. 

 

Screenshots of the VS2015 Event Monitor, and the Debugging screen:

 

https://www.dropbox.com/s/hpwsjyq3ybhgecb/EventMonitorVS2015.png?dl=0

https://www.dropbox.com/s/dyv07i6mamipr4y/BreakPointEditScreen.png?dl=0

 

0
Joe
Top achievements
Rank 1
answered on 27 Jan 2017, 08:28 PM
I apologize for the doubel post... The forum, upon submitting the first message says there was an error, so I added the second message, which also told me there was an error.  I was about to re-type everything again when I noticed they were in fact there.  So it's not just the Telerik Grid frustrating me, but the forum now as well... ARGH!!!!
0
Joe
Top achievements
Rank 1
answered on 27 Jan 2017, 09:12 PM
Adding .ServerOperation(false) stops it from calling into the Read action (GetSearchResults), but the damn edit popup still shows, then immediately shuts back down.  ARGH!!!
0
Accepted
Konstantin Dikov
Telerik team
answered on 31 Jan 2017, 02:33 PM
Hello Joe,

You should remove the following lines which force the Grid to rebind after each click within it:
$("#docResults").click(function (e) {
            e.preventDefault();
            var ds = $("#docResults").data("kendoGrid").dataSource;
            ds.filter([]);
        });


Best Regards,
Konstantin Dikov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Joe
Top achievements
Rank 1
answered on 31 Jan 2017, 02:39 PM

Thank you, thank you, thank you...  I mean it, I cannot thank you enough...

That was a holdover from another grid elsewhere in the application, and in trying to keep consistency, I kept it.  I really didn't think it would interfere with the Edit button, but since removing it as you suggested, it now works as expected.  Again, thank you.  Truly thank you.

Tags
Grid
Asked by
Joe
Top achievements
Rank 1
Answers by
Joe
Top achievements
Rank 1
Konstantin Dikov
Telerik team
Share this question
or