We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

How to bind Grid datasource to a string model property that contains JSON?

Hi

This is simple. When I post my form, if Model State is not valid, I get back to the same page with a couple of error messages. When I do that, I lose the grid data. I need to be able to retain it.

This grid starts with no datasource defined, but because I am converting the grid data to JSON via Javascript when posting it to the server, I have a model property filled with the JSON, so I was wondering if I can use this property to reassing the data to the grid if page reloads with error. 

Here is my GRID code:

@(Html.EJ().Grid<object>("MultiplesImputacionesGrid")

.EditSettings(edit => { edit.AllowAdding().AllowDeleting().AllowEditing().RowPosition(RowPosition.Bottom); })
.ToolbarSettings(toolbar =>
{
toolbar.ShowToolbar().ToolbarItems(items =>
{
items.AddTool(ToolBarItems.Add);
items.AddTool(ToolBarItems.Edit);
items.AddTool(ToolBarItems.Delete);
items.AddTool(ToolBarItems.Update);
items.AddTool(ToolBarItems.Cancel);
});
})
.ClientSideEvents(clientevent => clientevent.ActionComplete("ActionCompleted").ActionBegin("ActionBegin"))

.Columns(col =>

{
col.Field("InfraccionId").HeaderText("ID").TextAlign(TextAlign.Center).IsPrimaryKey(true).Visible(false).Add();

col.Field("Infraccion").HeaderText("Infracción").TextAlign(TextAlign.Center).Add();

col.Field("Fecha").HeaderText("Fecha").Format("{0:dd/MM/yyyy}").TextAlign(TextAlign.Center).EditType(EditingType.Datepicker).Add();

col.Field("Periodos").HeaderText("Periodos").TextAlign(TextAlign.Center).Add();

col.Field("MultaAdministrativa").HeaderText("Multa Administrativa").Format("{0:C2}").TextAlign(TextAlign.Center).EditType(EditingType.Numeric).NumericEditOptions(new EditorProperties() { DecimalPlaces = 2 }).Add();

col.Field("GastosAdministrativos").HeaderText("Gastos Administrativos").Format("{0:C2}").TextAlign(TextAlign.Center).EditType(EditingType.Numeric).NumericEditOptions(new EditorProperties() { DecimalPlaces = 2 }).Add();


})


)

So, how can I do it? Can I bind the grid to a single model property or there is another workaround for this??? Thank you!

12 Replies

SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team August 11, 2017 07:29 AM UTC

Hi Samuel,  
 
We could see you would like to perform editing action along with the Model Validation in the server-end. By default, Grid provides an option to handle the Editing Action in the Ajax based. This can be enabled using the RemoteSaveAdaptor of the Grid. Using this adaptor, you can avail a CRUD operation in a Grid. In case of any failures in the update/insert due to the Model Validation, Grid handle them using the ActionFailure events.  
 
Refer to the following Help Document and demo for the RemoteSaveAdaptor. 
 
 
 
To handle the failures in the any server action, you can use the ActionFailure event. Refer to the following API Reference.  
 
 
We have achieved your requirements using the RemoteSaveAdaptor and ActionFailure event. RemoteSaveAdaptor handles the editing action in the Grid and updates the changes to the server whereas the ActionFailure events will handle the failures maintains the Editform. So, you can re-update the Grid even after failures. Refer to the following code example.  
 
@(Html.EJ().Grid<OrdersView>("Editing") 
         .Datasource(ds => ds.Json((IEnumerable<object>)ViewBag.dataSource).UpdateURL("/Home/NormalUpdate").InsertURL("/Home/NormalInsert").RemoveURL("/Home/NormalDelete").Adaptor(AdaptorType.RemoteSaveAdaptor)) 
                  .. .  
                              . . . 
              .ClientSideEvents(eve => { eve.ActionFailure("onFailure"); }) 
) 
 
<script> 
    function onFailure(args) { 
        var str = ""; 
        str = ($($(args.error.responseText).find('b')[0]).text() + ":" + $(args.error.responseText).find('i').text()); 
        window.alert(str)//alert message for the exception 
    } 
</script> 
 
Highlighted URLs will be triggered as the end of the client-side action and the server will be updated. In case, of any failures in the server-end, ActionFailure will be triggered and alert the user. This will never closed the editform before the users cancel/successful save action. 
 
We have prepared a sample that can be downloaded from the following location.  
 
 
Regards,  
Seeni Sakthi Kumar S. 



SO Samuel Otero August 11, 2017 08:21 PM UTC

Thank you guys

I think you completely misunderstood my question. I don't even know what do you meant with "We could see you would like to perform editing action along with the Model Validation in the server-end". Wait... what??? "Editing action"? No no no. The CRUD operations of my grid doesn't have anything to do with the server. I don't need server validation for the grid. 

This grid is part of another form and some parts of this forms are the ones who has server side validation. When I post the form, I convert the grid data to .json, assign the json to a hidden field and that's what I send to the server.

If some other part of the form makes the model invalid, I return to the same page, and that's where I need the data on my grid back. Because I have one string in the model holding the json of the data of the grid, I thought that I can bind that string to be the datasource of the grid someway.

I only need data to persists if the page is reloaded because other elements of the forms are invalid. I don't need validation on the grid. I only need the data to persist. 

So, how I achieve this? 

Thank you!




SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team August 14, 2017 10:02 AM UTC

Hi Customer,  
 
We are sorry for the inconvenience.  
 
We suspect that you would like to repopulate the Grid after unsuccessful form submission. From the given scenario, we could see the Grid data is returned in the form of string. You have to deserialize it to the JSON and assign them to the Grid using the dataSource method. 
 
@(Html.EJ().Grid<OrdersView>("Grid") 
    ..  .  
                . ..  
) 
 
<script> 
    $.ajax({ 
        url: "Home/submit", 
        success: function (data) { 
 
        }, 
        error: function (data) { 
            //deserializing 
            var src = ej.parseJSON(data.d.data); 
            //Create an instance 
            var gridObj = $("#Grid").ejGrid("instance"); 
            //Update dataSource 
            gridObj.dataSource(src); 
        } 
    }); 
 
</script> 
 
 
Since we didn’t receive any code example from your end, we have given the code example based on the discussed scenario with solution. This solution will update the Grid after failure event of the Grid. If you are still facing any problem, please share the complete code example of the Grid along with the following information  
 
  1. Code example of the Grid along with the form
  2. Explain the scenario for the form submission
  3. Graphical representation of the requirement.
 
Regards,  
Seeni Sakthi Kumar S. 



SO Samuel Otero August 15, 2017 07:15 PM UTC

Thank you for your reply.

I tried your steps, and I think that I am doing the right, but for some reason, when the page re-loads, the grid still doesn't have any data. 

Here is my Razor code:

 @(Html.EJ().Grid<object>("MultiplesImputacionesGrid")

.EditSettings(edit => { edit.AllowAdding().AllowDeleting().AllowEditing().RowPosition(RowPosition.Bottom); })

.ToolbarSettings(toolbar =>

{

toolbar.ShowToolbar().ToolbarItems(items =>

{

items.AddTool(ToolBarItems.Add);

items.AddTool(ToolBarItems.Edit);

items.AddTool(ToolBarItems.Delete);

items.AddTool(ToolBarItems.Update);

items.AddTool(ToolBarItems.Cancel);

});

})

.ClientSideEvents(clientevent => clientevent.ActionComplete("ActionCompleted").ActionBegin("ActionBegin"))


.Columns(col =>


{

col.Field("InfraccionId").HeaderText("ID").TextAlign(TextAlign.Center).IsPrimaryKey(true).Visible(false).Add();


col.Field("Infraccion").HeaderText("Infracción").TextAlign(TextAlign.Center).Add();


col.Field("Fecha").HeaderText("Fecha").Format("{0:dd/MM/yyyy}").TextAlign(TextAlign.Center).EditType(EditingType.Datepicker).Add();


col.Field("Periodos").HeaderText("Periodos").TextAlign(TextAlign.Center).Add();


col.Field("MultaAdministrativa").HeaderText("Multa Administrativa").Format("{0:C2}").TextAlign(TextAlign.Center).EditType(EditingType.Numeric).NumericEditOptions(new EditorProperties() { DecimalPlaces = 2 }).Add();


col.Field("GastosAdministrativos").HeaderText("Gastos Administrativos").Format("{0:C2}").TextAlign(TextAlign.Center).EditType(EditingType.Numeric).NumericEditOptions(new EditorProperties() { DecimalPlaces = 2 }).Add();


})


)

And, for the Javascript, I changed the place where you did the work in your post, because I don't submit the form via Javascript. What I do is, that because a hidden field holds the json string with the grid's data when the page reloads with errors, I get the json from that field. Here is my logic:

function ReloadGridData() {

var jsonString = $("#ImputacionesJson").val();

if (jsonString != "") {

var src = ej.parseJSON(jsonString);

//Create an instance 

var gridObj = $("#MultiplesImputacionesGrid").ejGrid("instance");

//Update dataSource 

gridObj.dataSource(src); 

}

}

When I debug the Javascript, it successfully parse the json, and "src" ends up been an object. I can see the right properties assigned with the values in Firefox debugger.

But... then, the page reloads, and there is no data whatsoever. 

What I am doing wrong?? Thank you!



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team August 16, 2017 08:43 AM UTC

Hi Samuel,  
 
You have quoted that the Grid still doesn’t have data after page load. Do the page loads after executing the below function? 
 
<script> 
    function ReloadGridData() { 
 
        var jsonString = $("#ImputacionesJson").val(); 
 
        if (jsonString != "") { 
 
            var src = ej.parseJSON(jsonString); 
 
            //Create an instance 
 
            var gridObj = $("#MultiplesImputacionesGrid").ejGrid("instance"); 
 
            //Update dataSource 
 
            gridObj.dataSource(src); 
 
        } 
 
    } 
</script> 
 
Can you present a video demo of the issue which would be easy for us to analyze the problem and get the flow? 
 
If you would like to persists the certain Grid properties after the page load or the browser refresh, you can use the EnablePersistence property of the Grid. Refer to the following sample and Help Document.  
 
 
To add the dataSource to be persisted in the Grid, you can use the addToPersist method. Refer to the code example.  
 
@(Html.EJ().Grid<OrdersView>("Grid") 
    .EnablePersistence() 
    .ClientSideEvents(events=>events.DataBound("onDataBound")) 
) 
 
<script> 
    //Since dataSource is not persisted.  
    //we need add them programatically as follows 
    function onDataBound(args){ 
        this.addToPersist("dataSource") 
    } 
</script> 
 
If you are not willing persist the entire Grid model, you can use the localstorage of the browser window. Refer to the following code example.  
 
@(Html.EJ().Grid<OrdersView>("Grid") 
    .EnablePersistence() 
    .ClientSideEvents(events=>events.Load("onLoad")) 
) 
 
<script> 
    function ReloadGridData() {//after failures 
        var jsonString = $("#ImputacionesJson").val(); 
        window.localStorage.setItem("gridData", jsonString); 
    } 
    function onLoad() { 
        if (!ej.isNullOrUndefined(window.localStorage["gridData"])) { 
            this.model.dataSource = ej.parseJSON(window.localStorage["gridData"]); 
            window.localStorage.clear(); 
        } 
    } 
</script> 
 
Since we suspect that you are reloading the entire page after the form submit, we recommended to use the browser localstorage or EnablePersistence of the Grid.  
 
If we misunderstood your requirement, please get back to us with the above requested details.  
 
Regards,  
Seeni Sakthi Kumar S. 



SO Samuel Otero August 16, 2017 03:10 PM UTC

Thank you for your reply

You said: "You have quoted that the Grid still doesn’t have data after page load. Do the page loads after executing the below function?"

That function resides and it's called inside the $(document).ready() function in jQuery, so it runs after the page loads. This is the right way to do it, or it should run BEFORE the page loads? For me, to run it before doesn't have any sense but please, enlighten me. 

If my simple Javascript code doesn't work, I don't really know how Model Persistance or Local Storage will work, as I think at the end, it will behave similar as my code. 

So, my Javascript function should run before or after the page loads? What do you think about this?

Thank you



SO Samuel Otero August 16, 2017 03:47 PM UTC

Ok. I was able to achieve what I were looking for using State Persistance. 

However I have a little problem. The date format in the table cell doesn't persist, while the number format of my other cells, does. 

Again, this is the razor code of my grid:

@Html.HiddenFor(model => model.ImputacionesJson, new { id = "ImputacionesJson" })


                    @(Html.EJ().Grid<Imputaciones>("MultiplesImputacionesGrid")


.EditSettings(edit => { edit.AllowAdding().AllowDeleting().AllowEditing().RowPosition(RowPosition.Bottom); })

.ToolbarSettings(toolbar =>

{

toolbar.ShowToolbar().ToolbarItems(items =>

{

items.AddTool(ToolBarItems.Add);

items.AddTool(ToolBarItems.Edit);

items.AddTool(ToolBarItems.Delete);

items.AddTool(ToolBarItems.Update);

items.AddTool(ToolBarItems.Cancel);

});

})

.ClientSideEvents(clientevent => clientevent.ActionComplete("ActionCompleted").ActionBegin("ActionBegin").DataBound("onDataBound"))


.EnablePersistence(true)


.Columns(col =>


{

col.Field("InfraccionId").HeaderText("ID").TextAlign(TextAlign.Center).IsPrimaryKey(true).Visible(false).Add();


col.Field("Infraccion").HeaderText("Infracción").TextAlign(TextAlign.Center).Add();


col.Field("Fecha").HeaderText("Fecha").Format("{0:dd/MM/yyyy}").TextAlign(TextAlign.Center).EditType(EditingType.Datepicker).Add();


col.Field("Periodos").HeaderText("Periodos").TextAlign(TextAlign.Center).Add();


col.Field("MultaAdministrativa").HeaderText("Multa Administrativa").Format("{0:C2}").TextAlign(TextAlign.Center).EditType(EditingType.Numeric).NumericEditOptions(new EditorProperties() { DecimalPlaces = 2 }).Add();


col.Field("GastosAdministrativos").HeaderText("Gastos Administrativos").Format("{0:C2}").TextAlign(TextAlign.Center).EditType(EditingType.Numeric).NumericEditOptions(new EditorProperties() { DecimalPlaces = 2 }).Add();


})


)

I marked yellow the format that doesn't persist, while I marked in bold the format that does persist. This is, after the page loads, the date shown should be, for example: "16/08/2017", but instead, it shows: "16/08/2017T04:00:00:000Z". Why this happens? Why some formats persists and some others doesn't?

Thank you



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team August 17, 2017 12:54 PM UTC

Hi Samuel,  
 
We are unable to reproduce the problem at our end. Could you please provide following details to analyze the problem at our end? 
 
  1. Complete code example of the Grid along with the Form submit and action handlers
  2. Screenshots with the replication procedure or video demo of the issue
 
Make sure that you are not updating the Grid dataSource without parsing them. 
 
Regards,  
Seeni Sakthi Kumar S. 



SO Samuel Otero August 17, 2017 03:04 PM UTC

I was in part, wrong in my last reply. The date format works. However after the page reloads, a strange string is part of the date, probably a time or something. For example:

1. How the date is shown in the cell before the page reloads (without clicking the cell to edit) -> 2017-08-09

2. How the date is shown after page reloads -> 2017-08-09T04:00:00.000Z

For now, I solved this problem with a piece of jQuery:

$('.e-rowcell').each(function (i, el) {

var txt = $(el).text();

$(el).text(txt.replace('T04:00:00.000Z', ''));

});

Now... I have another problem which is a priority.

Of both of your methods, only the State Persistance works. The second one, give me the same problem of my original post. When I do what you example shows, the grid still empty after reload. 

Considering that only "Enable Persistence" works for me, I want to get it right, but I have a problem with it. The data still shows up on the grid, even if you open a new tab and go to the form again. I want the data to persist only if I reload the page itself and not when I open a new tab in my browser. I tried window.localStorage.clear(); in the console and it seems to works (sometimes) but I am not sure how to know in my code when the page comes from a new tab or it is opening for the first time, in order to delete that local storage.

So, I should approach the behavior that I want?



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team August 18, 2017 11:26 AM UTC

Hi Samuel,  
 
We could see you would like to persist the Grid data only after refreshing the page or form submit after failures. So, we cannot achieve this using the EnablePersistence. However, we can achieve your requirement using the window.localStorage. We suggest to add the data to the localstorage to the after the form’s failure event has been triggered. In the following code example, jsonstring refers to the JSON.stringify(data). Later, the data has been retrieved from the localStoreage in the load event of the Grid. Refer to the following code example.  
 
 
@(Html.EJ().Grid<OrdersView>("Grid")  
 
    .ClientSideEvents(events=>events.Load("onLoad"))  
)  
  
<script>  
    function ReloadGridData() {//after failures  
        var jsonString = $("#ImputacionesJson").val();  
        window.localStorage.setItem("gridData", jsonString);  
    }  
    function onLoad() {  
        if (!ej.isNullOrUndefined(window.localStorage["gridData"])) {  
            this.model.dataSource = ej.parseJSON(window.localStorage["gridData"]);  
            window.localStorage.clear();  
        }  
    }  
</script> 
 
 
If you are still facing any problem, please share a video demo along with the complete code example of your view page and partial page (if any). 
 
Regards,  
Seeni Sakthi Kumar S. 



SO Samuel Otero August 21, 2017 08:07 PM UTC

Bah!

That code inside the onload event never works for me. I see the object well parsed in the debugger but when the code assign the object to the datasource, the grid stay empty anyway. Don't know what's wrong with that approach.



SS Seeni Sakthi Kumar Seeni Raj Syncfusion Team August 22, 2017 07:26 AM UTC

Hi Samuel,  
 
We have created a support incident under your directtrac account. Please visit the following page and logon to your account. You can track that support incident for further information. 
 
 
Regards,  
Seeni Sakthi Kumar S. 
 


Loader.
Up arrow icon