This is a migrated thread and some comments may be shown as answers.
How to read and submit data for MainView and data in PartialView inside Kendo TabStrip
3 Answers 50 Views
This is a migrated thread and some comments may be shown as answers.
Don
Top achievements
Rank 1
Don asked on 13 Dec 2018, 04:12 AM

I use a kendo Splitter with 2 vertical panes (top-pane and bottom-pane).
Inside the top-pane .Content( ), I have a Kendo TabStrip with 3 tabs. Inside the bottom-pane .Content( ), I have a DropDownList / textbox controls and one input button "Save".
When the Main View page loads, my Main Controller Action retrieves the data and return the MainViewModel for my DropDownList / textbox controls and determines which Tab to select (ie show) to the user.

Here is my Kendo TabStrip on my main view with the MainViewModel

 

01.@(Html.Kendo().TabStrip()
02.    .Name("WorksheetTabStrip")
03.    .Items(tabstrip =>
04.    {
05.        tabstrip.Add().Text("Condition 1")
06.            .Selected( Model.ConditionSelection == 1 ? true : false)
07.            .LoadContentFrom("ConditionAction", "Worksheet", new { invoiceID = Model.InvoiceID, tabNum = 1 })
08.            .ContentHtmlAttributes(new { style = "height:580px;" });
09. 
10.        tabstrip.Add().Text("Condition 2")
11.            .Selected(Model.ConditionSelection == 2 ? true : false)
12.            .LoadContentFrom("ConditionAction", "Worksheet", new { invoiceID = Model.InvoiceID, tabNum = 2 })
13.            .ContentHtmlAttributes(new { style = "height:580px;" });
14. 
15.        tabstrip.Add().Text("Condition 3")
16.            .Selected(Model.ConditionSelection == 3 ? true : false)
17.            .LoadContentFrom("ConditionAction", "Worksheet", new { invoiceID = Model.InvoiceID, tabNum = 3 })
18.            .ContentHtmlAttributes(new { style = "height:580px;" });
19. 
20.    })
21. 

 

Each of the tabStrip .LoadContentFrom( ) calls the action "ConditionAction" to load data in the tab's corresponding PartialView.

 

public ActionResult ConditionAction(int invoiceID, int tabNum)  {
      // ... get data for the corresponding Tab from database
      ConditionViewModel model = getDBdata();
      if (tabNum == 1)
             return PartialView("_Condition1", model);
      else if (tabNum == 2)
             return PartialView("_Condition2", model);
      else if (tabNum == 3)
             return PartialView("_Condition3", model);
       else
             return View("Error");
}

 

With the codes that I have so far,  displaying the right data for the appropriate tab contents works.

My problem is when user clicks on the "Save" button (at the bottom-pane), how do I read from the form data of the Tab that I want.

For example, user clicks "Tab 2" and types some inputs in Textboxes, then clicks the Save button. I just want to read the form in Tab2 and save its data. (form in Tab1 and Tab 3 are ignored) and additionally read the main form controls (DropdownList etc) and save as well all at the same time.

I was planning to do an Ajax call onClick of the Save button. But don't know how to read and pass the PartialViewModel to my Controller.

 

<input type="button" id="btnSave" name="btnSave" value="Save" class="btn btn-danger btn-default" style="width:100px;" />
 
<script type="text/javascript">
 
    $("#btnSave").click(function () {
        var formData = $("#formWorksheet").serialize();
 
        $.ajax({
            url: '@Url.Action("SaveWorksheet", "Worksheet")',
            type: "POST",
            cache: false,
            contentType: "application/x-www-form-urlencoded",
            data: formData,
            datatype: "json",
            success: function (response) {
                if (response.ok) {
                    alert(response.message);
                }
                else {
                    window.alert("Error: " + response.message);
                }
            },
            error: function (request, status, error) {
                alert("Unexpected Error! Please contact the Administrator.");
                alert(error);
            }
        });
    })
 
</script>

 

Any suggestion? 

 

3 Answers, 1 is accepted

Sort by
0
Marin Bratanov
Telerik team
answered on 14 Dec 2018, 10:06 AM
Hi Don,

The tab strip makes the AJAX request for you and puts the returned HTML in its container. It does not know about the models, or the forms and its purpose is to load content and show/hide it from the user based on the clicked tab.

With this in mind, I suggest you devise the desired form submission/serialization logic by loading the partial views in simple divs with jQuery upon button clicks. Then, the same logic will work with the tab strip.

Perhaps you can use the same model for the main view and the partial views and the partial views can render only specific fields (e.g. through EditorFor() helpers). Then, you could wrap the entire splitter in a form whose submission will post the entire model to the controller. If you want to avoid including some fields in it, you could remove them from the DOM before submitting the form or set their disabled attribute. You could remove the items from the DOM if you use the tab strip API and events and when a new tab is selected you can .clear() the contents of the previous tab so only one tab is actually loaded at any given time (note that this will invoke requests for the previously selected tabs if they get selected again, effectively removing cache, and will wipe out user input in them).

Another approach would be to have a form around each individual set of inputs (e.g., one in the bottom pane, and one for each partial view you put in the tabs). Then you could submit more than one form to its respective action with the same button click. This will allow each view to use a different model.

Considering that you are serializing the data yourself, you may want to skip elements from unwanted tabs - you can easily traverse the DOM and, for example, set certain classes to them so you can avoid collecting them for serialization, or to remove them from the serialized object.


Regards,
Marin Bratanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Neil
Top achievements
Rank 1
answered on 27 Jan 2020, 07:57 AM
Here's my issue, i've managed to make a tabstrip based on the users activity.
If he clicks "Create Tab Strip", a tabstrip will be rendered.. Now my issue is
i want to render a certain Action from the controller, and with that, i would like
to pass viewmodel parameter, which is generated in javascript. How do I can
pass this value to action? Just look at the "CONTENT" part of the code.

 
tabstrip.append([<br>            {<br>               
text: dataItem.transDesc,<
br>               
encoded: false,<br>               
content: '#= @Html.Action("SaveMenuEdit", "Setting", new{@model=}) #>'<br>            }<br>        ]);
0
Aleksandar
Telerik team
answered on 28 Jan 2020, 02:41 PM

Hello Neil,

To achieve the desired result you could use the contentUrl property. This represents the field of the data item that provides the URL for the Ajax loaded tab content. Note however that The @Html.Action() method is processed on the server-side, so you cannot pass a client-side value to this function as a parameter. You can concatenate the client-side variables with the server-side url generated by this method, which is a string on the output. You could generate the url like this:

$("#appendButton").click(function () {
            tabstrip.append({
                text: 'Item ' + (++tabCounter),
                encoded: false,
                contentUrl: '@Url.Action("AddTab","Home")?id=' + tabCounter + '&city=' + city
            });
        });

Attached is a sample solution demonstrating the above approach. Let me know if you have further questions.

Regards,
Aleksandar
Progress Telerik

Get quickly onboarded and successful with your Telerik UI for ASP.NET MVC with the dedicated Virtual Classroom technical training, available to all active customers.
Asked by
Don
Top achievements
Rank 1
Answers by
Marin Bratanov
Telerik team
Neil
Top achievements
Rank 1
Aleksandar
Telerik team
Share this question
or