Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery tabs with MVC4 content

I'm trying to get some MVC4 views to display in jQuery tabs. Here's my code:

<div id="tabs">
    <ul>
        <li><a href="#appone">App One</a></li>
        <li><a href="#apptwo">App Two</a></li>
    </ul>
    <div id="appone">
        @{ Html.RenderPartial("~/Views/AppOne/Index.cshtml"); }
    </div>
    <div id="apptwo">
        @{ Html.RenderPartial("~/Views/AppTwo/Index.cshtml"); }
    </div>
</div>

The problem is that the first tab content displays just fine- but the second is empty. It seems the partial view is not rendered.

Is there a way to either force jQuery tabs to update content for ALL tabs when the page is loaded, or a way to force my partial view to render on page load?

like image 837
Nicros Avatar asked Oct 05 '22 09:10

Nicros


1 Answers

Here's code I'm actively working on that is working just fine:

Login.cshtml

@{
    AjaxOptions optsLogin = new AjaxOptions { UpdateTargetId = "login-tab-login" };
    AjaxOptions optsRegister = new AjaxOptions { UpdateTargetId = "login-tab-register" };
}
<section id="login-tabs">
    <ul>
        <li><a href="#login-tab-login">Returning Customers</a></li>
        <li><a href="#login-tab-register">New Customers</a></li>
    </ul>
    @using (Ajax.BeginForm("Login", "Account", optsLogin, new { id = "form-login" }))
    {
        <div id="login-tab-login">
            @Html.Partial("Account/_Login")
        </div>
    }
    @using (Ajax.BeginForm("Register", "Account", optsRegister, new { id = "form-register" }))
    {
        <div id="login-tab-register">
            @Html.Partial("Account/_Register")
        </div>
    }
</section>
<script type="text/javascript">
    $(function() {
        $('#login-tabs').tabs();
    });
</script>

My partial views are in the Shared folder in an Account subfolder. In addition, each partial view has its own model. Other than that, the implementation is nothing special...

UPDATE

I've added code to implement Ajax calls on the two tabs. The code block above the tabs section holds the AjaxOptions objects for the two <form> elements. Your controller needs to look something like this:

AccountController.cs

public class AccountController : Controller
{
   ...
   [HttpGet]
   public ActionResult Login()
   {
       ...
       return View();
   }

   [HttpPost]
   public ActionResult Login(LoginModel model)
   {
       ...
       if (ModelState.IsValid)
           return RedirectToAction("Index", "Home")
       else
           return PartialView("/Account/_Login", model);
   }

   [HttpPost]
   public ActionResult Register(RegisterModel model)
   {
       ...
       if (ModelState.IsValid)
           return RedirectToAction("Index", "Home")
       else
           return PartialView("/Account/_Register", model);
   }
}

The Login GET action method renders the entire page, including the _Layout.cshtml and _ViewStart.cshtml views. My partial views, _Login.cshtml and _Register.cshtml, hold the HTML elements for the entry forms. Each partial view has its own submit button:

<input type="submit" value="<Whatever you want to display>" />

Because each partial view call is encased in its own using (Ajax.BeginForm(...)) block and I have given each <form> its own id attribute, I can add JavaScript code to hijack the submit event. Depending on which submit is pressed, it will execute the action method associated with the specified action and controller in the Ajax.BeginForm(...) call. In my case, if the form data passes validation, the controller will automatically redirect to /Home/Index.

However, if validation fails, the action method will simply send back the rendered version of my partial view to the browser and place it in the element specified in the UpdateTargetId property in the AjaxOptions object associated with the <form>. Since the default InsertionMode is Replace, the view engine will simply replace the old version of the partial view with the new version, complete with form data and validation messages, if included.

The only code-related items I haven't included are my partial views, which really don't matter as far as the jQuery tabs functionality goes. I don't have any additional JavaScript in my partial views, and the additional code in the AccountController I didn't include is specific to calling my external Web API console application and setting the authorization cookie. I am using Google's CDN for my jQuery and jQuery UI declarations, rather than hosting the JavaScript locally.

It takes a while to wrap your head around what you have to do. Once you've got it, though, you've got it and the knowledge is transferable. This is not WebForms, thank goodness.

like image 187
Neil T. Avatar answered Oct 12 '22 21:10

Neil T.