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

4 Answers 182 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? 

 

4 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.
0
Tony
Top achievements
Rank 1
Iron
Iron
Iron
answered on 27 May 2021, 02:08 PM

Hi Marin Bratanov,

I have a kendo grid where there's a toolbar with a custom button used for inserting a record. when clicked. it pops up a kendo window inside with kendotabstrip. 3 tabs

the last tab has a submit button. now the problem comes when i want to have something like a summary of all the values from tab1 and tab2 to be on tab3.

how would you pass those values to the last tab which consist of partial views?

i have tried it on my side like below...


 //ajax call from the kendo button
   function onNextClickSummary(e) {
        debugger;
        e.preventDefault();
        tabs.select(getTabAtIndex(currentIndex + 1));
        var formData = $("#SiteCodeform").serialize();
       
      
        $.ajax({
            type: "GET",
            url: '/SiteCodes/SiteCodes/_SiteCodeComplete',
            data: formData,
            contentType: 'application/html; charset=utf-8',
            dataType: "html",
           success: function (result) {
            
                $("#checksummary").html(result);
                
                },
            error: function (result) {

                alert("an Error occured while processing the request.");


            }
        });

    }
and my controller action looks like this 

  public ActionResult _SiteCodeComplete(SiteCodeModelView formData)
        {
            return PartialView(formData);
        }

my partialview 


@model SiteCodes.Models.SiteCodeModelView
<h2>Submit</h2>

<table id="checksummary">
    <tr>
        <th style='color:dodgerblue;'>SiteCodeType</th>
        <th style='color:dodgerblue;'>SiteCodeNumber</th>
        <th style='color:dodgerblue;'>SiteCodeAbbreviation</th>
    </tr>
    <tr>
        @if (Model != null)
        {
            <td>

                @Model.SiteCodeType
            </td>
            <td>

                @Model.SiteCodeNumber
            </td>
            <td>

                @Model.MineCode
            </td>
            <td>

                @Model.Country1
            </td>
        }

    </tr>
</table>



<p>
    Click submit to save to the database.
</p>

<footer class="col-xs-12 form-group text-right">



    @(Html.Kendo().Button()
                .Name("Previous4")
                .Content("Previous")
                .Events(ev => ev.Click("onPreviousClick")).ToClientTemplate()
                )
    @(Html.Kendo().Button()
                .Name("submit")
                .Content("submit")
                .Events(ev => ev.Click("onSaveSubmitNewEntry"))
                .HtmlAttributes(new { @class = "k-primary" }).ToClientTemplate()
                )
</footer>

another problem is that it also creates a duplicate html  see attached 

would i appreciate your help,

kind regards

Tony

Asked by
Don
Top achievements
Rank 1
Answers by
Marin Bratanov
Telerik team
Neil
Top achievements
Rank 1
Aleksandar
Telerik team
Tony
Top achievements
Rank 1
Iron
Iron
Iron
Share this question
or