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

Action on Tab Selection

5 Answers 127 Views
PanelBar
This is a migrated thread and some comments may be shown as answers.
Joel
Top achievements
Rank 2
Iron
Iron
Iron
Joel asked on 05 Mar 2020, 11:07 PM

I have a multi-step UI that requires the user select a group from a TreeList.  That group selection must then be used to feed into a Grid that is populated by People that are in that selected Group.

How do I do this?  I've been using the PanelBar up to this point to perform multi-step processes.  However, I've never had to base the data selection in step 2 with the selection from step 1.  Can I late bind the Grid so it will go get its data when the host Tab is selected?

5 Answers, 1 is accepted

Sort by
0
Nencho
Telerik team
answered on 10 Mar 2020, 11:30 AM

Hello, Joel,

Straight to your question - yes you can bind the grid on a later stage. You can do that at a given time of the lifecycle, using the Client API of the component and by executing the read method on the DataSource instance of the Grid:

var grid = $("#grid").getKendoGrid()
grid.dataSource.read()

The above will trigger the request for data binding, and at this point, you can take into consideration the selection.

Hope this would help.

Regards,
Nencho
Progress Telerik

Get quickly onboarded and successful with Telerik UI for ASP.NET Core with the dedicated Virtual Classroom technical training, available to all active customers.
0
Joel
Top achievements
Rank 2
Iron
Iron
Iron
answered on 27 Mar 2020, 04:30 AM

I believe I'm close on this... but no cigar.  The TreeList:

@(Html.Kendo().TreeList<NameValueParent>()
      .Name("treelist")
      .Columns(columns =>
      {
          columns.Add().Command(c => { c.Custom().Text("Select")
              .Name("selectButton").ClassName("selectButton")
              .Click("goDetail"); })
              .Width(Glossary.Portal.ButtonWidth);
          columns.Add().Field(e => e.Name);
          columns.Add().Field(e => e.Description);
          columns.Add().Width(330).Command(c =>
          {
              c.CreateChild().Text("Add");
              c.Edit();
              c.Destroy();
          })
              .HtmlAttributes(new
              {
                  style = "text-align: center;"
              });
      })
      .Events(ev => ev.DataBound("onDataBound"))
      .Editable()
      .Selectable(s => s.Mode(TreeListSelectionMode.Single))
      .DataSource(dataSource => dataSource
          .Create(create => create.Action("Create", "Site"))
          .Read(read => read.Action("IndexJson", "Site").Data("getData"))
          .Update(update => update.Action("Update", "Site"))
          .Destroy(delete => delete.Action("Destroy", "Site"))
          .Model(m =>
          {
              m.Id(f => f.Id);
              m.ParentId(f => f.ParentId);
              m.Expanded(true);
              m.Field(f => f.Name);
          }).Events(events =>
          {
              events.Error("onError");
          })
      ).Height(540))

The goDetail script that stores the value in an id field tells the Grid to read:

function goDetail(e) {
    e.preventDefault();
    //alert("goDetail: " + e.toString());
    var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
    //alert("goDetail: " + dataItem.id);
    $('#itemId').val(dataItem.id);
 
    var grid = $("#grid").getKendoGrid();
    grid.dataSource.read();
}

The above script successfully tells the Grid to read.  My Grid:

@(Html.Kendo().Grid<NameValuePair>()
      .Name("grid")
      .Columns(columns =>
      {
          columns.Bound(p => p.Id);
          columns.Bound(p => p.Name);
          columns.Bound(p => p.Value);
      })
      .Pageable()
      .Sortable()
      .Scrollable()
      .HtmlAttributes(new { style = "height:550px;" })
      .DataSource(dataSource => dataSource
          .Ajax()
          .PageSize(20)
          .Read(read => read.Action("GridJson", "Site")
              .Data("getData"))))

When reading I need to get the selected value from the TreeList fed into the Controller's parameter list.  My attempt that is not working.  I tried to just return the raw value... this is an attempt to give the parameter.name:value.

function getData() {
    var id = document.getElementById("itemId").value;
    alert(id);
    if (id != null) {
        var str = "'id': '" + id + "'";
        alert(str);
        return str;
    } else {
        return 0;
    }
}

And finally my controller method.  The id parameter value is always 0:

public IActionResult GridJson(
    [DataSourceRequest] DataSourceRequest request,
    int id)
{
    NameValuePairList lst = new NameValuePairList();
    for (int i = 0; i < 5; i++)
    {
        lst.Add(new NameValuePair()
        {
            Id = $"{i}",
            Name = nameof(id),
            Value = $"{id}"
        });
    }
 
    var dsResult = lst.ToDataSourceResult(request);
    return Json(dsResult);
}

 

Thanks again for your help,

Joel

 

0
Accepted
Nencho
Telerik team
answered on 31 Mar 2020, 01:23 PM

Hello, Joel,

The Data function should return the key-value pair so that the controller can be aware of the parameter name to receive.  Check this forum thread, where this is described in details:

https://www.telerik.com/forums/pass-additional-parameters-to-read-ajax-datasource-method---mvc#6-wwFQboTECQByGUQYKKhw 

In other words, the getData function should look similar to the below implementation:

unction getData() {
    var id = document.getElementById("itemId").value;
    alert(id);
    if (id != null) {
        var str = "'id': '" + id + "'";
        alert(str);
    
    return {
           id: str 
    }
    } else {
        return 0;
    }
}

Also, the param in the controller should probably be in string type

Regards,
Nencho
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
Joel
Top achievements
Rank 2
Iron
Iron
Iron
answered on 13 Apr 2020, 08:57 PM

I finally got to work through this in detail.  TreeList Click Event puts the Item.Id value into a model.Item.Id field using the #itemId id on the form's input field.  I then capture the KendoGrid and tell it to read.  On Grid.Read, the Item.Id value is pulled out of the model and fed to the controller's parameter by "return { id: id }" (param name: param value) syntax.

 

$("#treelist").on("click", function (e) {
    //alert("click");
    var tree = $("#treelist").data("kendoTreeList");
    //alert(tree == null);
    var item = tree.dataItem($(e.target).closest("tr"));
    //alert(item == null);
    //alert(item.id);
    $('#itemId').val(item.id);
 
    var grid = $("#grid").getKendoGrid();
    grid.dataSource.read();
});

Controller (Note: param is defined as int)

public IActionResult GridJson(
    [DataSourceRequest] DataSourceRequest request,
    int id)
{
    NameValuePairList lst = new NameValuePairList();
    for (int i = 0; i < 5; i++)
    {
        lst.Add(new NameValuePair()
        {
            Id = $"{i}",
            Name = nameof(id),
            Value = $"{id}"
        });
    }
 
    var dsResult = lst.ToDataSourceResult(request);
    return Json(dsResult);
}

 

Script:

<script type="text/javascript">
 
    function getData() {
        // alert("grid.getData");
        var id = document.getElementById("itemId").value;
        // alert(id);
        if (id != null) {
            return { id: id };
        } else {
            return 0;
        }
    }
 
</script>

 

Grid:

<div class="col-sm-4">
    <form>
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <input type="hidden" id="groupId" asp-for="Item.Id" />
        <div class="form-group" style="margin-right: 5%">
            <label asp-for="Item.Id" class="control-label"></label>
            <input asp-for="Item.Id" class="form-control" id="itemId" readonly="true" />
            <span asp-validation-for="Item.Id" class="text-danger"></span>
        </div>
    </form>
 
 
    @(Html.Kendo().Grid<NameValuePair>()
          .Name("grid")
          .Columns(columns =>
          {
              columns.Bound(p => p.Id);
              columns.Bound(p => p.Name);
              columns.Bound(p => p.Value);
          })
          .Pageable()
          .Sortable()
          .Scrollable()
          .HtmlAttributes(new { style = "height:550px;" })
          .DataSource(dataSource => dataSource
              .Ajax()
              .PageSize(20)
              .Read(read => read.Action("GridJson", "Site")
                  .Data("getData"))))
</div>

 

0
Nencho
Telerik team
answered on 16 Apr 2020, 07:03 AM

Hello, Joel,

The solution seems great! Thank you for sharing it with the community as well.

Regards,
Nencho
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
PanelBar
Asked by
Joel
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Nencho
Telerik team
Joel
Top achievements
Rank 2
Iron
Iron
Iron
Share this question
or