how do i conditional set the visibility of the Command.Edit button on a row by row basis?

27 posts, 0 answers
  1. Atlas
    Atlas avatar
    97 posts
    Member since:
    Jun 2009

    Posted 29 Mar 2013 Link to this post

    I have the following grid:

    Html.Kendo().Grid<ABC>()
                                    .Name("grid")
                                    .Columns(columns =>
                                        {
                                            columns.Bound(p => p.Apply).Width(155);
                                            columns.Bound(p => p.Number).Width(155);
                                            columns.Bound(p => p.Paid).Width(155);
                                            columns.Bound(p => p.Note);
                                            columns.Bound(p => p.CompanyName);
                                            columns.Bound(p => p.ReferenceNumber);
                                            columns.Bound(p => p.ProcessedDate).Format("{0:d}");
                                            columns.Bound(p => p.ErrorMessage);
                                            columns.Command(command => command.Edit()).Width(100).Visible(???);
                                        })
                                    .Editable(editable => editable.Mode(GridEditMode.InLine))
                                    .Events(events => events.DataBound("onDataBound"))

    How do I set the visibility on a row by row basis? I want the edit button to be invisible if the ProcessedDate has a value.
    The edit command contains a visible property, but I don't see a way to write a lambda expression within the visible property to set it.
    There is also an DataBound event, but I can't find an example of how to use this or some other grid event to check the value of the ProcessedDate so that I can hide or show the edit button.

    The regular ASP.Net Grid has an onItemDataBound event, what is the equivelant in MVC?

  2. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 01 Apr 2013 Link to this post

    Hi Atlas,


    You could achieve this in several ways, depending on the dataSource binding, which is used in the current scenario. I'll cover both Ajax and Server binding.

    If a Server binding is used, you could use the RowAction method and assign a custom class to the rows, that will not be editable.
    E.g.
    .RowAction(row =>
    {
        if (row.DataItem.ProcessedDate != null)
        {
            row.HtmlAttributes["class"] = "custom";
        }
    })

    .custom .k-grid-edit
    {
        display: none;
    }

    If an Ajax binding is used, you could bind to the dataBound event of the Grid, traverse the items and hide the buttons manually.
    E.g.
    .Events(e => e.DataBound("onDataBound"))

    function onDataBound(e) {
        var grid = $("#grid").data("kendoGrid");
        var gridData = grid.dataSource.view();
     
        for (var i = 0; i < gridData.length; i++) {
            var currentUid = gridData[i].uid;
            if (gridData[i].ProcessedDate != null) {
                var currenRow = grid.table.find("tr[data-uid='" + currentUid + "']");
                var editButton = $(currenRow).find(".k-grid-edit");
                editButton.hide();
            }
        }
    }

    Wish you a great day!

     

    Greetings,
    Dimiter Madjarov
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Kendo UI is VS 2017 Ready
  4. Nick
    Nick avatar
    86 posts
    Member since:
    Mar 2008

    Posted 30 May 2013 Link to this post

    Ouch!  So I can't just put in a lambda to determine this?  Can I request this to be changed?   I'd love to be able to do something like this...
    @(Html.Kendo().Grid<MyProject.Web.Models.Scenarios.ClientGridClientViewModel>()
          .Name("ClientGrid")
          .Columns(c => {
            c.Bound(client => client.Name);
            c.Bound(client => client.ScenarioCount);
            c.Bound(client => client.ActiveScenarioName);
            c.Bound(client => client.LastModifiedBy);
            c.Bound(client => client.LastModifiedOn).Format("{0:G}");
            c.Command(cmd => cmd.Custom("Change").Click("showScenarios"));
            c.Command(cmd => cmd.Custom("Edit").Click("editScenario")).Visible(client => client.ScenarioCount > 0);
          })
          .Filterable()
          .DataSource(d => d
            .Ajax()
            .Events(e => {
              e.Error("datasourceError");
            })
            .Model(model => {
              model.Id(client => client.Id);
            })
            .ServerOperation(true)
            .Sort(x => x.Add("Name"))
            .Read("ClientGridRead", "Scenarios")
          )
    )

    I hope you could do something along these lines.

    Cheers,
    Nick
  5. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 31 May 2013 Link to this post

    Hello Nick,


    Currently the Grid does not support such configuration option. If you consider that it would be a useful addition, I would suggest you to post it as a feature request in our Kendo User Voice portal. If it gets popular among the community we will consider to implement it in future releases of Kendo UI.

     

    Regards,
    Dimiter Madjarov
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Tyrone
    Tyrone avatar
    13 posts
    Member since:
    Feb 2014

    Posted 12 Sep 2014 in reply to Dimiter Madjarov Link to this post

    Any idea why this would not work... after putting some console.log statements in, this code is executing down to the point of the hide.  It find the edit button, but when asked to hide the button, it does not.  Could this have to do with lockable columns?  I tried both putting my buttons in a locked column and an unlocked column, but no luck...
    <!-- BEGIN Grid -->
     
    @(Html.Kendo().Grid<CapacityPlanningStaffingResourceRecord>()
        .Name("grid")
     
        .Columns(columns =>
        {
            //Command Column
             
             
            columns.Bound(p => p.RecordID).Width(200).Locked(true).Lockable(false); ;
            columns.Bound(p => p.StaffingPlanRecordId).Width(200).Locked(true).Lockable(false); ;
            columns.Bound(p => p.RecordType).Width(100).Locked(true).Lockable(false);
            columns.Bound(p => p.HireDate).Format("{0:MM/dd/yyyy}").Width(140).Locked(true).Lockable(true).HeaderHtmlAttributes(new { style = "overflow: visible; white-space: normal" }).EditorTemplateName("Date");
            columns.Bound(p => p.JobProfile).Width(210).Locked(false).Lockable(true).HeaderHtmlAttributes(new { style = "overflow: visible; white-space: normal" }).EditorTemplateName("cJobProfile");
            columns.Bound(p => p.CountOfResources).Format("{0:N0}").Width(140).Locked(false).Lockable(true).HeaderHtmlAttributes(new { style = "overflow: visible; white-space: normal" }).EditorTemplateName("Integer");
            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(180).Locked(false).Lockable(false); ;
        })
         
        .ToolBar(toolbar => toolbar.Create())
        .Editable(editable => editable.Mode(GridEditMode.InLine))
        .Pageable()
        .Sortable()
        .Scrollable()
        .Filterable()
        .Events(events => events.DataBound("dataBound"))   
        .HtmlAttributes(new { style = "font-size:13px;width:1400px; height:700px" })
     
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(36)
            .Events(events => events.Error("error_handler").Change("onRequestEnd"))
             
            .Model(model => model.Id(p => p.RecordID))
                     
            .Model(model => model.Field("HireDate", typeof(DateTime)))
            .Model(model => model.Field("CountOfResources", typeof(int)))
            .Model(model => model.Field("RecordID", typeof(long)))
            .Model(model => model.Field("StaffingPlanRecordId", typeof(long)))
     
     
                  
            .Read(read => read.Action("ReadCapacityPlanningStaffingPlanRecord", "CapacityPlanningProcessor").Type(HttpVerbs.Post))
            .Create(update => update.Action("CreateCapacityPlanningStaffingPlanRecord", "CapacityPlanningProcessor").Type(HttpVerbs.Post))
            .Update(update => update.Action("UpdateCapacityPlanningStaffingPlanRecord", "CapacityPlanningProcessor").Type(HttpVerbs.Post))
            .Destroy(update => update.Action("DestroyCapacityPlanningStaffingPlanRecord", "CapacityPlanningProcessor").Type(HttpVerbs.Post))
                    )
            
        )
     
    <script type="text/javascript">
        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);
            }
        }
     
    function onRequestEnd(e) {
        var grid = $("#grid").data("kendoGrid");
        var gridData = grid.dataSource.view();
      
        for (var i = 0; i < gridData.length; i++) {
            var currentUid = gridData[i].uid;
            console.log(i + ' ' + gridData[i].RecordType);
            if (gridData[i].RecordType != "Model") {
                console.log("Model: " + i + ' ' + gridData[i].RecordType + " UID:" + currentUid);
                var currenRow = grid.table.find("tr[data-uid='" + currentUid + "']");
                var editButton = $(currenRow).find(".k-grid-edit");
                console.log(editButton);
                editButton.hide();
            }
        }
    }
    </script>
     
    <!-- END Grid -->
  7. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 15 Sep 2014 Link to this post

    Hello Tyrone,


    The code looks correct, but I would suggest to execute it in the dataBound event of the Grid instead of the change event of the dataSource.

    Let me know if this resolved the issue or I could provide further assistance.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  8. Tyrone
    Tyrone avatar
    13 posts
    Member since:
    Feb 2014

    Posted 15 Sep 2014 in reply to Dimiter Madjarov Link to this post

    I had wanted to use DataBound, but it was not available for use in my razor view.  I do not know why it is not available...
    But I do not think that would prevent my buttons from hiding, would it?
  9. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 15 Sep 2014 Link to this post

    Hi Tyrone,


    I am not sure what do you mean by "it is not available". It seems that you have bound to it in the provided sample code:
    Events(events => events.DataBound("dataBound"))
    The reason for using it is that the rows are not yet existing in the table before that.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  10. Tyrone
    Tyrone avatar
    13 posts
    Member since:
    Feb 2014

    Posted 15 Sep 2014 in reply to Dimiter Madjarov Link to this post

    The very simplicity of your questions solved my problem, thank you...
    I had actually put the event in the DataSource events, not the grid events.  That is why I did not have DataBound available and also why my code was not working.  By adding the event to the grid not the data source, it is hiding the buttons as it should.  

    I am sorry, I should have picked that up earlier...and thanks for taking the time to ask the question...
  11. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 15 Sep 2014 Link to this post

    Hello Tyrone,


    Thanks for the update.

    I wish you a great day!

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  12. Ziad
    Ziad avatar
    1 posts
    Member since:
    Mar 2013

    Posted 13 Apr 2015 in reply to Dimiter Madjarov Link to this post

    Hi Dimiter,

    The  post is very helpful for me. But I am confused where do I paste this chunk / in which CSS?

    .custom .k-grid-edit{    display: none;}

  13. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 14 Apr 2015 Link to this post

    Hello Ziad,

    The CSS should be added to the page where the Grid is displayed.

    Let me know if I could assist further regarding the case.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  14. ManniAT
    ManniAT avatar
    877 posts
    Member since:
    Nov 2003

    Posted 10 Aug 2015 in reply to Dimiter Madjarov Link to this post

    I have the following code (copied from above):

     

    ...
    ...
    ...
              columns.Command(command => command.Custom("Bestellung").Click("showDetails")).Width(100);
          })
          .Events(e => e.DataBound("onDataBound"))
          .Scrollable()
          .DataSource(dataSource => dataSource.Ajax()
                   
          .Group(grp => { grp.Add(a => a.WeekNumber); })
              .Model(model => {
                  model.Id(p => p.ID);
                  model.Field(p => p.Salads).DefaultValue(new List<EECanteen.Models.FoodItem>());
                  model.Field(p => p.WeekNumber).Editable(false); })
              .Read(read => read.Action("DaysMeals_Read", "Home"))
          )
    )
    <script>
        function onDataBound(e) {
            var grid = $("#grid").data("kendoGrid");
            var gridData = grid.dataSource.view();
            for (var i = 0; i < gridData.length; i++) {
                var currentUid = gridData[i].uid;
                if (gridData[i].CanOrder) {
                    var currenRow = grid.table.find("tr[data-uid='" + currentUid + "']");
                    var editButton = $(currenRow).find(".k-grid-edit");
                    editButton.hide();
                }
            }
        }
    </script>

    Although (checked with alerts) the code runs and "editButton" is a valid object the button is not hidden.

    What is wrong here?

     

    Manfred

  15. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 11 Aug 2015 Link to this post

    Hello,

    The sample code seems correct. You could debug it and assure that the editButton variable is set to the correct element. If the problem is still reproducing, please send small isolated runnable example, so we could inspect it locally.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  16. ManniAT
    ManniAT avatar
    877 posts
    Member since:
    Nov 2003

    Posted 12 Aug 2015 in reply to Dimiter Madjarov Link to this post

    I could isolate the problem - it has something to do with the grouping.
    As soon as I remove the .Group(grp => { grp.Add(a => a.WeekNumber); }) from the datasource the thing works...

    But I need it with grouping....

    How easy could it be with a property on the Column instead of fiddling around with script code...
    In my case something like columns.Command(command => command.Custom("Bestellung").Click("showDetails")).Hidden(a=>a.CanOrder)....

     

    Anyhow - I guess it is a simple "missing thing" to make the hidden button available even if grouping is active

  17. ManniAT
    ManniAT avatar
    877 posts
    Member since:
    Nov 2003

    Posted 12 Aug 2015 in reply to ManniAT Link to this post

    Ok - I got it - trial and error - frustrating....

     

    The "problem" - with the above suggested (from Nick)

         c.Command(cmd => cmd.Custom("Edit").Click("editScenario")).Visible(client => client.ScenarioCount > 0);

    such scenarios would work very simple (also "Disabled") would be an option in this case.

    I think "disabling / enab​ling" (show / hide) an element depending on the data is a very common task - such controls should implemt such functionallity.

    RAD - ​means "have options like this" - and not force us to write scripts which by the way change - dependig on "is grouped" or whatever...

  18. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 12 Aug 2015 Link to this post

    Hello ManniAT,

    I am glad the issue is resolved. Let us know if further help is required.

    Regarding the last suggestion, Kendo UI is not part of the Rad toolkit. It is a JavaScript framework and tends to not implement tasks, that could be achieved directly via jQuery.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  19. Jared
    Jared avatar
    6 posts
    Member since:
    Oct 2015

    Posted 28 Jan Link to this post

    Any possible way to do more than just to hide a button in a custom command column?  I'm hiding the button on certain rows but I'm worried someone with basic HTML knowledge could go into a browser's developer tools and unhide the button.  Therefore giving them access to what is behind the button, which is what I'm trying to avoid.  

     Yes, I can add a 2nd check to what's behind the button in case this happens and stop them.  But I'm wondering if I can avoid that.  

  20. Nick
    Nick avatar
    86 posts
    Member since:
    Mar 2008

    Posted 29 Jan in reply to Jared Link to this post

    Jared said:

     Yes, I can add a 2nd check to what's behind the button in case this happens and stop them.  But I'm wondering if I can avoid that.  

     

    Honestly, you should always be validating client input on the server side.  There's nothing stopping someone using a tool like Fiddler or Postman to just make up their own http calls and completely sidestep any UI you have constructed.

     

  21. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 29 Jan Link to this post

    Hello Jared,

    Indeed, even if the command is removed for some rows and not just hidden, a server side validation is always recommended.

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  22. Jared
    Jared avatar
    6 posts
    Member since:
    Oct 2015

    Posted 29 Jan Link to this post

    I agree with you guys and I already have this validation in place.  Both in the code click button and server-side.  But my question still remains.  Can you do more than just hide the button?  
  23. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 29 Jan Link to this post

    Hello Jared,

    Could you elaborate what exactly are you trying to achieve which is different, than the described approach?

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  24. Jared
    Jared avatar
    6 posts
    Member since:
    Oct 2015

    Posted 29 Jan in reply to Dimiter Madjarov Link to this post

    Instead of just calling .hide() on the button's HTML element, I'd rather the button not get created at all.  

    Or if there is no way to prevent it from being created, can we destroy the button instead of just hiding it.  This would be one more way to stop someone from someone just tweaking the CSS to show the button.  

  25. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 29 Jan Link to this post

    Hello Jared,

    You could directly remove the command instead of just hiding it or for example use a templated column with conditional logic that adds the command only to certain rows. This way the mark up will not be present in the DOM, if this is your concern. Keep in mind that this will also not stop someone from tweaking the DOM, manually copy/paste the command markup from the other rows and add to the current one, so a validation on the back end is always recommended.

    I hope this information helps. Have a great weekend!

    Regards,
    Dimiter Madjarov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  26. Mark
    Mark avatar
    4 posts
    Member since:
    Apr 2015

    Posted 25 Sep Link to this post

    In case it's helpful to someone I had a case where I was attempting the same with an ajax-bound grid that had grouped columns and had to modify the loop in the onDataBound function in Dimiter's solution to something like:

    for (var g = 0; g < gridData.length; g++) {
        for (var i1 = 0; i1 < gridData[g].items.length; i1++) {
            for (var i2 = 0; i2 < gridData[g].items[i1].items.length; i2++) {
                for (var i3 = 0; i3 < gridData[g].items[i1].items[i2].items.length; i3++) {
                    var currentUid = gridData[g].items[i1].items[i2].items[i3].uid;
                    if (gridData[g].items[i1].items[i2].items[i3].ProcessedDate != null) {
                        var currentRow = grid.table.find("tr[data-uid='" + currentUid + "']");
                        $(currentRow).find(".k-grid-Edit").hide();
                    }
                }
            }
        }
    }

  27. Maxime
    Maxime avatar
    1 posts
    Member since:
    Oct 2016

    Posted 26 Oct in reply to Mark Link to this post

    Hello everyone,

    I used the Events(events => events.DataBound("dataBound")) as suggested by Dimiter.

    for each user, I have 2 buttons (edit and delete) but for some of them i remove the delete one.

    But now, when i edit one of this un-deletable user. if i cancel the changes the cancel button reappears.

    Did someone know how can i delete the button again ?

  28. Dimiter Madjarov
    Admin
    Dimiter Madjarov avatar
    2153 posts

    Posted 27 Oct Link to this post

    Hello Maxime,

    You could attach a handler to the cancel event of the Grid

    http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-cancel

    and execute the same logic for hiding in a setTimeout() call inside of it.

    Regards,
    Dimiter Madjarov
    Telerik by Progress
     
    Build rich, delightful, *native* Angular 2 apps with Kendo UI for Angular 2. Try it out today! Kendo UI for Angular 2 (currently in beta) is a jQuery-free toolset, written in TypeScript, designed from the ground up to offer true, native Angular 2 components.
     
Back to Top
Kendo UI is VS 2017 Ready