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

Custom css for conditionally editable columns

15 Answers 581 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Marc
Top achievements
Rank 1
Marc asked on 21 Dec 2017, 04:02 PM

Is there a nice clean solution for styling columns that may or may not be editable? So the user can tell without clicking in the cell if they can edit it.

I know its easy enough to add a css class to columns if you know they are always going to be editable or not. But in my case the editable fields will be different based on other values of the record and/or permissions of the user.

Thanks

15 Answers, 1 is accepted

Sort by
0
Preslav
Telerik team
answered on 22 Dec 2017, 12:26 PM
Hi Marc,

If the fields could be editable or not at any given time, there is no clean solution to apply a CSS class to the non-editable columns.

Could you please elaborate on the exact use case? When do we know if a column will be editable or not? After getting the data or runtime? This information will help me in understanding the case and I will be able to provide an approach that fits best the exact scenario.

I look forward to your reply.


Regards,
Preslav
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 22 Dec 2017, 06:22 PM
The exact use case is that different fields will be editable based on the status of the record and the permission levels of the user. These are also large datasets, so I suspect having a javascript based template to evaluate every record and style the cells individually would not be performant.
0
Ivan Zhekov
Telerik team
answered on 25 Dec 2017, 02:22 PM
Marc,

assuming the permissions are known as soon as the page is rendered and not determined by an asynchronous call, then you can go safely with adding the class names.

In addition, if the data is asynchronous, you could add the said class names during the databound event.

Regardless of the scenario, as long as the permissions data is available at any point in time, you could apply the styling from that moment onward, be it on page render, grid databount etc.

We would go into more details, but thus far we have noting concrete to cling to. If you could prepare a sample project and attach it to this thread, we could evaluate it and write back.

Just a minor note, this here is a forum thread and you are limited to the types of attachments you add. If you want, we could convert the forum thread to support thread, or if you prefer, you could start a new support thread.

Regards,
Ivan Zhekov
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 27 Dec 2017, 03:49 PM

The logic could be rendered on the server, but I'm struggling with the proper way to pass this to a kendo grid. Consider a grid with 25-30 columns, in the model section there could be code like this (using mvc wrappers)

 

model.Field(f => f.Name).Editable(Model.IsPurchaser || Model.IsRequester || Model.IsAdmin);
model.Field(f => f.Status).Editable(Model.IsRequester || Model.IsAdmin || or if status of the record is not closed );
model.Field(f => f.IsConsolidated).Editable(false);

 

I'd prefer this this business logic not to reside in the UI layer. Is there a suggested pattern that I might follow?

0
Marc
Top achievements
Rank 1
answered on 27 Dec 2017, 03:51 PM
Also InCell editing is a requirement here.
0
Ivan Zhekov
Telerik team
answered on 29 Dec 2017, 10:00 AM
Hello, Marc.

One way is to use the approach you described below.

Another way, using a similar approach, you could use a controller to generate all or some grid settings in json form and pass it to the grid:

<div id="grid1"></div>
 
<script>
$(document).ready(function() {
 
    var endPoint = ""; // some URL
 
    $.get( endpoint, function(data) {
        $("#grid1").kendoGrid(data);
    }, "json");
 
});
</script>

The above examples shows passing the entire options. You could patch certain settings e.g.:

$("#grid1").kendoGrid({
    dataSource: data
})

And since whether or not a column is editable is part of the datasource, you should definitely patch that one.

As for recommendations, the best way is the one that suits you and the project you work on. It's also important to be consistent with the rest of the project (or parts of it) for reducing future maintainability.

Finally, if your only concern is the location of the business logic, you can always use a delegate / external method to populate the fields of the model.

Regards,
Ivan Zhekov
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 03 Jan 2018, 06:17 PM

Ivan, thanks for your response, but I don't think we are on the same page.

 

I'm simply trying to understand if conditionally applying an editable boolean and css is supported at runtime. In reading some older posts, it looks like it wasn't 4-5 years ago.

0
Marc
Top achievements
Rank 1
answered on 03 Jan 2018, 10:33 PM

My current solution which I don't feel very good about is to define handler for both the template and the editable property along with an addition boolean property in the viewmodel for each field which may or may not be editable like below. I'm hopeful a better solution can be recommended preferrably without javascript.

in grid

columns.Bound(c => c.SomeProperty).ClientTemplate("#=editableTemplate(SomeProperty, SomePropertyEditable)#").Editable("SomePropertyEditable");

 

 

in js:

function somePropertyEditable(dataItem) {
    return dataItem.SomePropertyEditable;
}
 
function editableTemplate(fieldValue, isEditable) {
    if (isEditable) {
        return "<div class='editable'>" + fieldValue + " </div>";;
    } else {
        return fieldValue;
    }
}

 

 

0
Stefan
Telerik team
answered on 05 Jan 2018, 11:11 AM
Hello, Marc,

I'm glad to hear that you have found a solution.

Currently, the desired result can be achieved only using client-side JavaScript functions as the Editable property accepts only function string:

Editable MVC

https://docs.telerik.com/aspnet-mvc/helpers/grid/how-to/editing/conditionally-editable-columns

The ClientTemplate is also executed on the client that is why it does not have access to the server values from the model:

https://docs.telerik.com/aspnet-mvc/helpers/grid/configuration#clienttemplate

Let me know if you need additional information on this matter.

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 17 Jan 2018, 05:56 PM

I have a problem with the solution I described above. We are allowing users to persist the state of the grid so they can have custom views.

 

When they load a custom view via the kendo 'setOptions', all of the fields become editable rather than just the ones that were conditionally set on the initial load.

Is this a known issue?

 

 

 

0
Marc
Top achievements
Rank 1
answered on 18 Jan 2018, 12:12 AM

Reproduced here: http://dojo.telerik.com/@md1037/AWADA/5

 

 

0
Stefan
Telerik team
answered on 18 Jan 2018, 07:58 AM
Hello, Marc,

Thank you for the example.

The issue occurs because after assigning the function reference to the options the result is again stringified before passing it to the setOptions method which is causing the references to be lost. If the second kendo.stringify is removed the example is working as expected:

http://dojo.telerik.com/EnELA

This is described in the setOptions method documentation:

https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/methods/setoptions


Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 18 Jan 2018, 03:12 PM

Thanks for your reply. We are storing the grid options in a database, so the data needs to serialized/deserialized from a json string.

 

Can you advise on how we would persist the functions in a json string?

0
Marc
Top achievements
Rank 1
answered on 18 Jan 2018, 04:21 PM

In thinking about it I can probably add the function after retrieving the json from the database. Let me know if there may be a better approach. Here is the code I'm evaluating.

 

var originalOptions = grid.getOptions();
var savedOptions = jQuery.parseJSON(jsonFromDatabase);
 
 
if (savedOptions && savedOptions.columns && savedOptions.columns.length > 0) {
    for (var i = 0; i < savedOptions.columns.length; i++) {
        var col = savedOptions.columns[i];
        var editableFunction = originalOptions.columns[i].editable;
        if (editableFunction) {
            col.editable = editableFunction;
        }
    }
}
 
grid.setOptions(savedOptions);
0
Stefan
Telerik team
answered on 22 Jan 2018, 07:14 AM
Hello, Marc,

The provided approach looks good.

It is one of the approaches we recommend in our documentation as well:

"JSON.stringify() cannot serialize function references (e.g. event handlers), so if stringification is used for the retrieved Grid state, all configuration fields, which represent function references, will be lost. You have two options to avoid this limitation: use a custom implementation to serialize JavaScript functions, or add the function references back to the deserialized configuration object before passing it to the setOptions method."

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Grid
Asked by
Marc
Top achievements
Rank 1
Answers by
Preslav
Telerik team
Marc
Top achievements
Rank 1
Ivan Zhekov
Telerik team
Stefan
Telerik team
Share this question
or