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

Inline Edit - Make primary Key read only for edits not inserts

10 Answers 127 Views
Grid
This is a migrated thread and some comments may be shown as answers.
AP
Top achievements
Rank 1
Veteran
AP asked on 10 Dec 2020, 10:51 AM

I have a grid, with inline editing enabled, with a user entered value for the primary key. Obviously, for row edits, this value can't be updated. Unfortunately the Kendo Grid doesn't differentiate between edits and inserts.

I can set the field to non editable using :-

.Model(m=>{
                    m.Id(p => p.OPCS);
                    m.Field(p => p.OPCS).Editable(false);
                })

And this works for edits, as the key column remains as text, not a text box. However, this breaks inserts.

Alternatively I can set the field to read only using the grid edit event:-

function gridEdit(args) {
 
        if (args.model.isNew() == false) {
            // textbox
            $("#OPCS").attr("readonly", true);
 
             
        }
 
    }

This stops the value in the field from being changed, but still displays it in a textbox, giving the user the impression it can be changed.

How can I stop the field being shown in a textbox for edits, but allow inserting new values for new records?

10 Answers, 1 is accepted

Sort by
0
Anton Mironov
Telerik team
answered on 14 Dec 2020, 09:24 AM

Hi Andrew.

Thank you for the code snippet provided.

In order to achieve the desired behavior, I would recommend using the "Edit" Event of the Kendo UI Grid. In the event handler, check conditionally if the current model is a new one. This will provide the opportunity to confirm if the behavior should be for adding a new item or updating an existing one.

The following form answer demonstrates the pointed behavior:

Give the approach above a try and let me know if further assistance is needed.

Kind Regards,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
AP
Top achievements
Rank 1
Veteran
answered on 14 Dec 2020, 09:43 AM

Anton, thanks for your reply, but you seem to have misunderstood. I can trap the edit event, and make the field read only. However, what I want to happen, is that on an edit, the primary key field is not turned into a text box (as happens if the field is set to read only in the model part of the data source definition).

 

0
Anton Mironov
Telerik team
answered on 14 Dec 2020, 01:47 PM

Hi Andrew,

Apologize for the misunderstood.

In order to change the visualization of the read-only field, I would recommend hiding the numeric wrapper and appending the needed value to its parent. Here is an example:

          if (!e.model.isNew()) {
            // Disable the editor of the "id" column when editing data items
            var numeric = e.container.find("input[name=id]").data("kendoNumericTextBox");
              numeric.wrapper.hide();
            numeric.wrapper.parent().append(e.model.id);
          }

 The complete implementation could be found in the following dojo example:

After making the needed tests locally, let me know if this is the expected behavior.

Best Regards,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
AP
Top achievements
Rank 1
Veteran
answered on 15 Dec 2020, 08:09 AM
Anton, I'm afraid this doesn't work as my primary key field isn't numeric, but a string.
0
Anton Mironov
Telerik team
answered on 16 Dec 2020, 12:17 PM

Hello Andrew,

Thank you for providing this detail.

In order to achieve the desired behavior, I would recommend finding the needed field in the container by using the selector: "input[name=id]". After finding the element, hide it and append the id of the model to the parent of the element. Here is an example:

          if (!e.model.isNew()) {
            // Disable the editor of the "id" column when editing data items
            var idElement = e.container.find("input[name=id]");
            idElement.hide();
            idElement.parent().append(e.model.id);
          }

The complete implementation could be found in the following dojo example:

I hope this approach will work as expected. Let me know if the result is achieving the required behavior.

Greetings,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
AP
Top achievements
Rank 1
Veteran
answered on 16 Dec 2020, 02:12 PM

Anton, I'm afraid this didn't work. My key field isn't called id, it's called opcs. I tried the code both ways (using id and opcs), but the field was still a textbox and the contents were editable. 

The grid definition is:-

@(Html.Kendo().Grid<UHB_Waiting_Times_Portal.Models.REF_Diagnostic_Procedures>()
           .Name("Grid")
           .Columns(col =>
           {
               col.Bound(o => o.OPCS).Title("OPCS Code");
               col.Bound(o => o.Area).Title("Area");
               col.Bound(o => o.OPCS_Description).Title("Description");
               col.Command(command => { command.Edit(); command.Destroy(); });
 
           })
           .ToolBar(commands => commands.Create())
           .Editable(editable => editable
                .Mode(GridEditMode.InLine))
 
               .DataSource(ds => ds
               .Ajax()
              .Events(e=>e.Error("errorH"))
 
 
 
               .Model(m=>{
                   m.Id(p => p.OPCS);
                   //m.Field(p => p.OPCS).Editable(false);
               })
 
 
 
 
               .PageSize(20)
               .Read(rd => rd.Action("RD_Procedures", "DiagnosticProcedures")
 
               )
                .Create(create => create.Action("InsertProcedure", "DiagnosticProcedures"))
                .Update(update => update.Action("UpdateProcedure", "DiagnosticProcedures"))
                .Destroy(delete => delete.Action("DeleteProcedure", "DiagnosticProcedures"))
 
               )
               .Events(e=>e.Edit("gridEdit"))
               .Pageable()
               .Sortable()
               .Filterable()
           )

The commented out line is what I'm trying to replicate, but just for edits

My function is:-

function gridEdit(args) {
 
        if (args.model.isNew() == false) {
           
            //$("#OPCS").attr("readonly", true);
        
 
            var idElement = args.container.find("input[name=opcs]");
            idElement.hide();
            idElement.parent().append(args.model.opcs);
             
        }
 
    }

This doesn't work, and neither does using 'id'. The only thing that comes close is simply setting the textbox to readonly (the commented out line), but that still leaves the data shown in a textbox.

 

0
Anton Mironov
Telerik team
answered on 18 Dec 2020, 11:11 AM

Hi Andrew,

Thank you for providing the code implementation.

I tried to implement the pointed behavior and consider that the needed element to be hidden is actually the parent of the input (the span element). After hiding the span element, append the value of the model to the "grandparent" of the input (the td element). Here is an example:

// Grid

.Events(e => e.Edit("onEdit"))

// JavaScript

    function onEdit(e) {
        if (!e.model.isNew()) {
            var idElement = e.container.find("input[name=OPCS]");

            idElement.parent().hide();
            idElement.parent().parent().append(e.model.OPCS);
        }
    }
Furthermore, I noticed that the bounded property is "OPCS", but in the function is used "opcs". This is a case-sensitive functionality and the property of the model needs to be in the same case as initialized(with capital letters).

Find attached a sample project with the needed implementation included. 

After making the needed tests locally, let me know if further assistance is needed.

 

Kind Regards,
Anton Mironov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
AP
Top achievements
Rank 1
Veteran
answered on 30 Dec 2020, 08:44 AM

Sorry for the delay in responding. I've tried your solution, and whilst it does make the field read-only, it also changes the column layout, and the headers no longer match.

I've attached a screenshot.

 

0
Accepted
Georgi Denchev
Telerik team
answered on 31 Dec 2020, 01:24 PM

Hello Andrew,

My name is Georgi and I'll be covering for my colleague Anton in his absence. Thank you for the provided screenshot.

You could utilize the BeforeEdit event alongside the Column.Editable method in order to enable/disable the editing functionality based on the state of the item.

col.Bound(o => o.OPCS).Title("OPCS Code").Editable("isEditable");

.Events(e => e.BeforeEdit("onBeforeEdit"))
<script>
    let editable = true; // Set a default value for editable.

    function isEditable() {
        return editable; // Return the value of the editable variable to the column.
    }

    function onBeforeEdit(e) {
        editable = e.model.isNew(); // If the item is new, edtiable = true. If we are editing an existing item, edtiable = false.
    }
</script>

Let me know if this approach is acceptable.

Best Regards,
Georgi Denchev
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
AP
Top achievements
Rank 1
Veteran
answered on 04 Jan 2021, 09:45 AM

Georgi,  Thanks for this - It's worked exactly as I wanted.

Tags
Grid
Asked by
AP
Top achievements
Rank 1
Veteran
Answers by
Anton Mironov
Telerik team
AP
Top achievements
Rank 1
Veteran
Georgi Denchev
Telerik team
Share this question
or