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
close icon

Resetting Column Ordering

I'm working on a project that makes use of the Grid control setup through RAZOR. They've asked for a way to reset the column ordering with persistence enabled. After much fiddling with the JavaScript I found I could take the HTML5 data attribute that was used to unobtrusively setup the grid and iterate over that to put the columns in the original order. However, I found that sometimes the data in the attribute isn't proper JSON, it has a function call in it that isn't wrapped in quotes. The function call in question is "ej.isJSON". 

I have two questions:
  1. Is there a better way to reset the column ordering?
  2. If not, is there a way to parse the non-standard JSON into a JavaScript array that I can iterate over?

6 Replies

VA Venkatesh Ayothi Raman Syncfusion Team July 17, 2017 09:27 AM UTC

Hi Andrew, 
 
Thanks for contacting Syncfusion support. 


Query #1: “Is there a better way to reset the column ordering? 

If you want to reset the column ordering when we enabling the persistence feature in Grid, then we suggest you to add the columns properties in ignoreOnPersist method in Load event of Grid. If we add the columns property in ignoreOnPersist then columns re-ordering are doesn’t maintain while reloading the page.  
Please refer to the following code example and Help documentation for more information, 

Code example
@(Html.EJ().Grid<OrdersView>("Grid") 
 
                    .AllowReordering() 
 
         
                    .ClientSideEvents(e=>e.ActionBegin("actionBegin").Load("load")) 
                    .EnablePersistence() 
                    .Columns(col => 
                    { 
 
                    .   .   . 
                    }) 
) 
 
<script type="text/javascript"> 
     
//Load event  
    function load(args) { 
 
        //add the columns property to ignoreOnExport method 
        this.ignoreOnPersist("columns"); 
    }   
  
 
</script> 


If we misunderstood your requirement, then could you please provide more details about your requirement? 

Query #2: “If not, is there a way to parse the non-standard JSON into a JavaScript array that I can iterate over? 
We should assign standard JSON format array as data source. If any non-standard JSON format, then we can change JSON format by calling the ej.isJSON method. It is parsing non-standard JSON format to standard JSON format.  
For example, in JavaScript shows the Date using Date format. If the date value is string from server side like 2014-03-30T09:51” then we can parse the date string to date object to show the Date column with formatting. We can handle the parsing the date string using ej.isJSON method.  
 
We have also built-in Helper functions of ej.parseJSON. This method is used to parse the string to JSON format. Please refer to the following Help documentation for more information, 

Regards, 
Venkatesh Ayothiraman. 



AN Andrew July 17, 2017 04:02 PM UTC

Hi Venkatesh,

Thanks for the response. For number 1 that isn't an option, the users want column ordering to be persistent until a reset button is clicked to explicitly reset the column ordering. Additionally disabling a feature isn't a better way to accomplish something.

As for number two, I have tried that and it throws the exact same error. The code I'm trying to get to work is as follows:

var grid = $("#" + gridId);
grid.ejWaitingPopup("show");
//Get the grid object
var gridInstance = grid.data("ejGrid");
//Get the original columns from the unobtrusive settings
var originalColumns = ej.parseJSON(grid.data("ej-columns"));

The error I get, whether I use JSON.parse or ej.parseJSON is "JSON.parse: unexpected character at line 1 column 251 of the JSON data". At character 251 is some non-standard JSON, the call to isJSON. The JSON in question looks like this:

"dataSource":ej.isJSON([{"Id":5,"Name":"EPSI"}])

As you can see, that isn't standard JSON. I need a way to parse this so that I can properly reset the column order while maintaining persistence.



VA Venkatesh Ayothi Raman Syncfusion Team July 18, 2017 12:34 PM UTC

Hi Andrew, 
 
Thanks for the update. 
 
Query #1:” For number 1 that isn't an option, the users want column ordering to be persistent until a reset button is clicked to explicitly reset the column ordering. Additionally disabling a feature isn't a better way to accomplish something. 
 
We have achieved your requirement using Load event in Grid. In this event, we can store the initial Grid columns in some local storage variable and we can restore the original state of the Grid while we clicking the button. Please refer to the following sample and code example,  
 
Code example 
@Grid  
  
@(Html.EJ().Grid<object>("FlatGrid")  
             .Datasource((IEnumerable<object>)ViewBag.datasource)  
                     
            . . .  
           .AllowResizing()  
           .AllowReordering()  
          .EnablePersistence()  
            .PageSettings(p=>p.PageSize(5))  
             . . .  
                    .ClientSideEvents(eve => eve.Create("create").Load("onLoad"))  
  
        .Columns(col =>  
                             {  
                            
                         . . .  
                             })  
    )  
  
@load event  
  
function onLoad(args) {  
        if (window.localStorage.getItem("Columns") == null)  
        window.localStorage.setItem("Columns", JSON.stringify(this.model.columns));//store the grid columns in local storage variable  
    }  
  
@button click event  
  
$("#restore").ejButton({  
        click: function () {  
  
            var gridobj = $("#FlatGrid").ejGrid("instance"); // Create a instance for Grid    
            gridobj.deleteState();// Delete the persistence State    
  
            gridobj.destroy();// Destroy the grid    
            var gridModel = JSON.parse(window.localStorage.getItem("GridModel"));  
            gridModel.columns = JSON.parse(window.localStorage.getItem("Columns")); // get the initial grid columns from local storage and assign into gridmodel which is previously stored in the create event  
           $("#FlatGrid").ejGrid(JSON.parse(window.localStorage.getItem("GridModel")));//rerender the grid which is intially loaded    
  
        }  
  
    })  
 
Please let us know, if you have any further assistance on this.  
  
Query #2:” for number two, I have tried that and it throws the exact same error. 
 
We went through your code example that you have shared for us and found that you are tried to parse the columns object to JSON array for reset the column ordering from unobtrusive settings. There is no need to parse this object to JSON object, because we can directly bound the object for columns via columns method. 
Only we are bounded JSON array object for data source. So, we have bounded the columns object from $(“#GridID”).data(“ej-columns”). Please refer to the following code example, Help documentation and screenshot, 
Code example: 
function buttonClick(args) { 
 
        var grid = $("#Grid"); 
        grid.ejWaitingPopup("show"); 
        //Get the grid object 
        var gridInstance = grid.data("ejGrid"); 
 
        //Get the original columns from the unobtrusive settings 
        var originalColumns = grid.data("ej-columns"); 
 
        gridInstance.columns(originalColumns);//bound the original columns through grid columns method 
 
    } 
 
 
 
Screenshot: 
 

Note: ej.parseJSON method is used to parse the non-standard JSON array to standard array object. Refer to the following Help documentation, 


Please let us know if you have any further assistance on this. 

Regards, 
Venkatesh Ayothiraman. 




AN Andrew July 19, 2017 04:08 AM UTC

Thanks for the answers, unfortunately I've tried both of these before and had issues with them. 

For option one, if I reorder the columns then return to the page and check the columns array returned by 'this.model.columns' the columns are not in the original order but rather in the last ordered state.

For example: If my set of columns is [Column_1, Column_2, Column_3] and I reorder them to be [Column_2, Column_1, Column_3] and I reload the page, the array I get in the load event is [Column_2, Column_1, Column_3].

For the second option, I tried this on a page that didn't have the strange non-standard JSON and sometimes I ended up causing the grid to render incorrectly and lose columns. Not sure why that happened. When I tried this method with the non-standard JSON it would just dump the whole string into the column header.

Just so you can see exactly what I'm looking at I've attached a zip file with the screenshot of the column header being populated with the JSON and a dump of the string that I get back from 'var originalColumns = grid.data("ej-columns");'

Any ideas on how I can get this working would be greatly appreciated, this issue is holding up releasing the persistence feature.


Attachment: Documents_aed220a.zip


AN Andrew July 19, 2017 02:40 PM UTC

I took a look at the ej.unobtrusive.js file and finally figured out how it parses this non-standard JSON. It turns out that it just runs `exec` on the string. Kind of dirty but it works. I got my code working by simply adding:

if(typeof(originalColumns) === "string")

     originalColumns = exec(originalColumns);

Again, this seems really dirty and asking for someone to inject malicious code but it gets the job done.



VA Venkatesh Ayothi Raman Syncfusion Team July 20, 2017 03:19 PM UTC

Hi Andrew, 
 
Thanks for the update. 
 
For option one, if I reorder the columns then return to the page and check the columns array returned by 'this.model.columns' the columns are not in the original order but rather in the last ordered state. 
While rendering the grid initially, then we can get the original columns( from this.model.columns”) order in Grid Load event. If we reorder the columns after rendering the grid and persistence is enabled then we can get the re-ordered columns(from this.model.columns”) only in Grid load event while refreshing/reloading the page again. 
We can achieve your requirement by stored the original columns ordered in window.localstorage  like as follows, 

<input type="button" id="restore" value="ResetColumns" /> 
<input type="button" value="unobtrusive" onclick="uClick()" /> 
 
@(Html.EJ().Grid<OrdersView>("FlatGrid") 
                     
                    .Datasource((IEnumerable<OrdersView>)ViewBag.datasource) 
                    .AllowReordering() 
                    .AllowPaging() 
                     .EnablePersistence() 
                    .ClientSideEvents(e=>e.Load("onLoad")) 
 
                    .Columns(col => 
                    { 
                        . . . 
                    }) 
) 
function onLoad(args) { 
        
        if (window.localStorage.getItem("Columns") == null)   
            window.localStorage.setItem("Columns", JSON.stringify(this.model.columns));//store the grid Original ordered columns in local storage variable  while initial rendering 
    }   

After re-ordering the columns we can restore the original state of the columns by clicking the external button. Please refer to the following code example, 

$("#restore").ejButton({   
        click: function () {   
               
            var gridModel = JSON.parse(window.localStorage.$ej$ejGridFlatGrid); //get the grid Model  
 
            gridModel.columns = JSON.parse(window.localStorage.getItem("Columns")); // get the initial grid columns from local storage and assign into gridmodel which is previously stored in the create event   
 
            $("#FlatGrid").ejGrid(gridModel);//rerender the grid which is intially loaded  columns   
   
        }   
   
    })   
Note: Here $ej$ejGridFlatGrid means $ej-common, $ejGrid-controlName/pluginName and FlatGrid-control id 
For the second option, I tried this on a page that didn't have the strange non-standard JSON and sometimes I ended up causing the grid to render incorrectly and lose columns. Not sure why that happened. When I tried this method with the non-standard JSON it would just dump the whole string into the column header. 
 
We were unable to reproduce the reported issue at our end and we can get the columns object from unobtrusive settings only. Please refer to the following screenshot, 
 

We have also reset the column order from unobtrusive settings. Please refer to the following code example, 
 
 
<input type="button" value="unobtrusive" onclick="uClick()" /> 
 
@(Html.EJ().Grid<OrdersView>("FlatGrid") 
                    //.Datasource(ds => ds.URL(@Url.Action("DataSource")) 
                    //.Adaptor(AdaptorType.UrlAdaptor)) 
                    .Datasource((IEnumerable<OrdersView>)ViewBag.datasource) 
                    .AllowReordering() 
                     
                    .AllowPaging() 
                     .EnablePersistence() 
                    
 
                    .Columns(col => 
                    { 
. . . 
                    }) 
) 
 
<script type="text/javascript"> 
    
    . .  . 
     
 
   
     
    function uClick() { 
 
        var grid = $("#FlatGrid"); //GridID 
        var gridObj = grid.ejGrid("instance");//Grid Instance 
         
        var originalColumns = grid.data("ej-columns"); 
 
        var  gridModel= JSON.parse(window.localStorage.$ej$ejGridFlatGrid) 
 
        gridModel.columns = originalColumns; 
        $("#FlatGrid").ejGrid(gridModel); 
    } 
 

We have also prepared a sample for your convenience which can be downloaded from following link, 


In this sample, we have rendered the Grid with EnablePersistence property and we have also rendered the two HTML buttons before the Grid. One for reset the columns using load event and another button for reset the columns from unobtrusive settings
 
For your kind information, if you are modifying the grid layout from the design/view, then it will be persisted based on the changes recently made to the layout.  

But if the initial settings of the grid model is changed in the project application, it won’t be reflected in the view page. So everytime, you make a change in the grid model from the application, you may have to clear the browser cache which is the default behavior.  

To overcome the above problem, we have provided the version based storage support such that we invalidate the previously stored data from local storage and the newly stored item will be based on the version specified. We can define this using the ej.persistStateVersionproperty which accepts a string value. Please refer to the below code example.  
 
<script type="text/javascript">  
    ej.persistStateVersion = "test";//any string value can be set  
</script>  
 
Note: Whenever you modify the grid model from application, we suggest you to change the persistStateVersion such that it invalidates the previously stored data and render grid based on newly defined model. And, please use the above code only when changing the grid model in application. It is not necessary to use this property when modifying the grid layout in browser view page.  
Please refer to the above sample and if you still face the same issue, then could you please provide the following information? 
1)      Share the Full Grid code example. 
2)      Share the scenario for replicate the issue. 
3)      A sample if possible or modified the given sample as issue reproducible. 
It would be helpful for us to find the problem and provide the better solution as earliest. 

Regards, 
Venkatesh Ayothiraman. 


Loader.
Live Chat Icon For mobile
Up arrow icon