Switch in Grid Client Detail

0 Answers 160 Views
Switch
AP
Top achievements
Rank 1
Iron
Iron
Veteran
AP asked on 24 Feb 2022, 08:58 AM

I have a switch control, placed inside of a tab control, in a client detail template, as part of a grid.

I need to bind the switch checked property, to a value stored in the grids dataset, which is a Boolean. However, the code causes the error:-

Preprocessor directives must appear as the first non-whitespace character on a line

The code is:-

<script id="subsubdetailsTemplate" type="text/kendo-tmpl">

@(Html.Kendo().TabStrip().Name("Tabstrip_#=ReportID#")
         .Items(i =>
         {

         i.Add().Text("Report Details").Selected(true).Content(@<text>


    <div>

    <p> #=HideOnCatalogue#</p>

    Hide from Catalogue?:
     @(Html.Kendo().Switch()
                    .Name("switch_#=ReportID#")
                    .Events(e => e.Change("function(e){ switchChange(e, '#=ReportID#')}"))
        .Checked(#=HideOnCatalogue#)
        .Messages(c => c.Checked("YES").Unchecked("NO"))
        .ToClientTemplate()
    )


    </div>
    </text>);

       



         }).ToClientTemplate())


</script>

How can I bind the value to the switch?  I can display the value in a <p> tag without a problem, as well as passing the report ID to the function called when the switch is clicked.

Thanks

Anton Mironov
Telerik team
commented on 01 Mar 2022, 08:31 AM

Hi Andrew,

Thank you for the code snippet and details provided.

Could you please share more details for this structure, as I am not totally sure which component is part of another and wherein the picture is the Switch component?

I guess that if we have a collection of values from the Model to the Switch - the 2nd instance of #=HideOnCalalog# is within the C# range, so the compiler is treating it as a #region preprocessor directive.

Once I have the whole picture, will try my best to achieve the desired behavior locally.

Looking forward to hearing back from you.


Kind Regards,
Anton Mironov

AP
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 07 Mar 2022, 03:56 PM

Sorry for the late replay, I've been on leave.  The template is part of the grid, the code for which is:-


  @(Html.Kendo().Grid<PBIReportCatalogue.Models.ViewReport>
    ()
    .Name("catalogueGrid")

    .Columns(col =>
    {



        col.Bound(o => o.ReportName).Title("Name");
        col.Bound(o => o.WorkspaceName).Title("Workspace");
        col.Bound(o => o.DatasetName).Title("Dataset");
       
        col.Bound(o => o.WebURL).Title("Link").ClientTemplate("<a href='#=WebURL#' target='_blank' class='btn btn-info btn-sm'    data-toggle=\"tooltip\" data-placement=\"top\" title=\"Click to open the report url.\"  >View</a> ");

        col.Bound(o => o.ValidatedFlag).Title("Validated").ClientTemplate("#=ValidatedFlagGlyph#");
        col.Bound(o => o.FunctionalFlag).Title("Functional?").ClientTemplate("#=FunctionalGlyph#").Filterable(filterable => filterable.UI("functionalFilter"));
        col.Bound(o => o.FinanceSystems).Title("Fin Sys?").ClientTemplate("#=FinanceSystemsGlyph#");
        col.Bound(o => o.HasMetaData).Title("Has Tags?").ClientTemplate("#=HasTagsGlyph#");
        col.Bound(o => o.HasTags).Title("Has Meta Data?").ClientTemplate("#=HasMetaDataGlyph#");

        col.Bound(o => o.ReportID).Title("").ClientTemplate("#=EditButton#").Visible((bool)ViewBag.ShowEditbutton);



    })

    .ClientDetailTemplateId("subsubdetailsTemplate")
    .Events(e=>e.DataBound("onDB"))






        .DataSource(ds => ds
        .Ajax()
        .Model(m => m.Id(p => p.ReportID))
        .PageSize(25)
        .Read(rd => rd.Action("RD_Catlogue", "Catalogue").Data("antiForgery")

        ).Sort(s=>
        {

            s.Add("WorkspaceName").Ascending();
            s.Add("ReportName").Ascending();

        })
        //.Group(group => group.Add("Folder", typeof(string), System.ComponentModel.ListSortDirection.Ascending))
        )

        .Pageable(p => p.Refresh(true))
        .Sortable(s => s.SortMode(GridSortMode.MultipleColumn))
        .Filterable()
        .ColumnMenu()
        .HtmlAttributes(new {style= "font-size:small" })


                )

I've used templates in grids a lot successfully, but not with switches.

Eyup
Telerik team
commented on 10 Mar 2022, 02:08 PM

In similar scenarios the For() equivalent of the component is used: TextBoxFor, NumericTextBoxFor, etc.

The same is valid for the SwitchFor component as well:
https://github.com/telerik/kendo-ui-core/issues/4783

AP
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 10 Mar 2022, 02:17 PM

Unfortunately, SwitchFor doesn't work, as it's in a template bound to a Grid using AJAX binding. Do I need to log a support ticket for this?
Anton Mironov
Telerik team
commented on 15 Mar 2022, 10:33 AM

Hi Andrew,

Feel free to correct me if I misunderstood something. The requirement for the case is to use a Kendo UI Switch in a Kendo UI Grid using one of its boolean properties. If this is the case, I would recommend trying the following approach:

  1. Use the following ClientTemplate:
    columns.Bound(p => p.Discontinued).ClientTemplate("<input class='customClass' #if (Discontinued) { # checked='checked' # } # type='checkbox' /> ");
  2. In the DataBound Event handler, initialize the needed Switch components for the pointed field. Here is an example:
    // In the Grid:
    .Events(e => e.DataBound("onDataBound"))
    
    // The Event handler:
        function onDataBound() {
            this.tbody.find(".customClass").kendoSwitch()
        }

Attached is a sample project that I prepared for the case. It implements the approach above.

Make the needed tests locally with the project attached and let me know if further assistance is needed.

Looking forward to hearing back from you.


Best Regards,
Anton Mironov

AP
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 15 Mar 2022, 10:37 AM

Anton,  the switch isn't in the grid itself, but in a tab in a sub detail template. I've used this with many other controls, and only experienced this issue with the switch. I just need to be able to bind the switch checked value when it's in this template, inside a tab.
Anton Mironov
Telerik team
commented on 18 Mar 2022, 10:02 AM

Hi Andrew,

I am currently working on the case and will come back to you with an approach for achieving the desired behavior.

Thank you for your patience.

Kind Regards,
Anton Mironov

Anton Mironov
Telerik team
commented on 18 Mar 2022, 11:25 AM

Hi Andrew,

Attached is a sample project that implements the requirements:

  • A Kendo Grid with details template.
  • The details template includes a Kendo UI Tabstrip.
  • One of the tabs in the TabStrip implements a Kendo UI Switch as an input HTML element.

In order to achieve the desired behavior and bind every switch to a boolean property of the dataItem in the parent row of the Grid, I would recommend keeping the currently selected dataItem in a global scope variable. When a tab of the TabStrip is selected - get the input element and initialize the Switch with a value from the boolean property of the global scope saved dataItem.

Attached is a sample project that implements the approach above. Make the needed tests locally with the project attached and let me know if further assistance is needed.

In order to apply changes to the boolean property of the Model, handle the change event of the Switch and change the dataItem of the Grid.

Looking forward to hearing back from you.

Kind Regards,

Anton Mironov

 

 

AP
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 18 Mar 2022, 11:54 AM

Thanks for this, I'll take a look
AP
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 18 Mar 2022, 12:16 PM

I've tried this code, however it doesn't work for me, as I've defined the Switch using MVC, and have another event defined, as when the switch is changed, the flag is updated in the database. Also, I ahve the switch in the first tab of the tabstrip, so select isn't fired until the tabs  are changed.


  @(Html.Kendo().Switch()
                    .Name("switch_#=ReportID#")
                    .Events(e => e.Change("function(e){ switchChange(e, '#=ReportID#')}"))
        //.Checked(#=HideOnCatalogue#)
        .Size(ComponentSize.Small)
        .Messages(c => c.Checked("YES").Unchecked("NO"))
        .ToClientTemplate()
    )

This does seem to be a bug in the MVC wrappers not supporting binding properly.

Anton Mironov
Telerik team
commented on 23 Mar 2022, 11:30 AM

Hi Andrew,

Thank you for the additional details provided.

The fact that the Switch is in the first tab is actually great news. In this case, the Switch could be initialized in the "DetailExpand" Event of the Grid. Here is an example of the event handler:

    function onDetailExpand(e) {
        var dataItem = $("#grid").data("kendoGrid").dataItem(e.masterRow);
        var switchInstance = $("#switch_" + dataItem.OrderID).kendoSwitch().data("kendoSwitch");
        switchInstance.check(dataItem.IsSwitchChecked);
    }

The values shown in the switch are the expected ones, so the value binding is correct. The saving of a change could be set via the Change Event handler as you mentioned. Let me know if further assistance with the update of the boolean property is needed.

Attached is the re-worked sample project that includes the approach with the Switch in the first tab.

Looking forward to hearing back from you.

Best Regards,
Anton Mironov

AP
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 29 Mar 2022, 02:31 PM

Anton, thanks for this, but I also have an event bound via the switch, using the MVC wrappers.

Can't this be done using a switch defined in Razor syntax? 

Anton Mironov
Telerik team
commented on 01 Apr 2022, 07:36 AM

Hi Andrew,

Thank you for the kind words.

The problem is that the Name of the Switch component is actually its Id.

As we are trying to initialize the Switch in a TabStrip where the current Model is not selected, the needed information for the name of the component is not available for the wrapper(MVC Switch), but this could be achieved with the Kendo component as in the sample project from my previous reply.

In order to implement the needed Event for the Switch(it is probably the "Change" Event as it is the one in the API for the component), I would recommend trying the following approach:

I hope this information helps.

Let me know if further information or assistance is needed.

Kind Regards,
Anton Mironov

AP
Top achievements
Rank 1
Iron
Iron
Veteran
commented on 01 Apr 2022, 08:36 AM

Thanks for this, I've now got this working. It's still a shame this couldn't be done in teh MVC wrappers, and this seems strange when other controls work this way.
Anton Mironov
Telerik team
commented on 06 Apr 2022, 06:57 AM

Hi Andrew,

I am glad to hear that the desired behavior is now achieved.

If any further assistance or information is needed, do not hesitate to contact me and the team.


Best Regards,
Anton Mironov

No answers yet. Maybe you can help?

Tags
Switch
Asked by
AP
Top achievements
Rank 1
Iron
Iron
Veteran
Share this question
or