Thursday, May 29, 2014

Step By Step How to create a Modal Form using JQuery UI and Partial Views

        By Carmel Shvartzman

In this tutorial we'll learn how to create a Modal Form using JQuery UI  and Partial Views. The jQuery UI is a set of user interface widgets, interactions, and themes built on top of the jQuery JavaScript Library. The Modal Form will be rendered as follows:



We'll follow this steps:
1) add a Create scaffolding template to your Controller - the Create View will be PARTIAL because we'll be rendering it INSIDE a JQueryUI Modal Dialog Form
2) insert  a JQueryUI Modal Dialog Form in your Index view, but REPLACE the Form HTML markup with a @Partial call
3) customize the HTTP POST Action method to REDIRECT the runtime to the Index Action, because we'll want to render again the Index View.


For the sake of using JQuery UI Widgets, like Accordion, Tabs, Portlets, Dialogs, and so on, we'll need to import a JQuery UI Theme, the jquery-ui.js and jquery-ui.css files. (and of course you'll need also a reference to the basic jquery.js file).

The present section is a sub-tutorial about importing the JQuery UI to our app: you can skip it if you already have done it, or you can see the complete step by step  in a former tutorial.

This is the BEGINING of the sub-tutorial section: -----------------------------------------------------
---------------------------------------------------------------------------------------------------

First of all, we need to download the Theme from the JQuery UI site, so browse to the site and go to the "Themes" tab:



Select from the "Gallery" the theme you like the most, and download it. I choose the "Le-Frog":




After you download it, extract all from the .ZIP file :



We'll use some of these files. But first , we need to update the javascript jQuery files in our project, because the files which comes with Visual Studio will be obsolete. Open the NuGet utility:



Make a search for the JQuery package and install it:



Do the same for the JQuery UI package:



Now open the Theme's folder we downloaded and copy the entire theme which is inside the "development-bundle" folder:




Paste the folder inside the "themes" folder inside your project:



It will show as follows:



We'll make use of the .CSS file jquery-ui.css. Open the BundleConfig file:




Take a look at these ScriptBundles, because we'll use them inside our app:



Replace the "base" folder by the "le-frog" folder, and add the jquery-ui.css file to the script:



Next, we'll call the bundles from the _Layout file:



Locate the Render "jquery" section and cut it:



Locate the render at the <head> section:



Paste there the "jquery" section , and add the "jqueryui" bundle:




We're done with the javascript and the style we'll need.
Now we'll add the Dialog widget to the Index View. Create a new View:



This is the END of the  sub-tutorial section --------------------------------------------------------
---------------------------------------------------------------------------------------------------



To get the markup of the Form, browse to the "Development" tab at the JQUERY UI site, and select  the "Dialog" Widget, and the "Modal Form" example:






Then go to the "View source", because we'll customize the SCRIPT and DIV sections of the Widget to make our own Modal Form:




Copy the <div> tag which represents the Form , from the JQuery UI site:


Now paste the <div> inside your Index View, but REPLACE the inner markup with this code:


<div id="dialog-form" title="Create new Post">
  <p class="validateTips">All form fields are required.</p>

                     @Html.Partial("Create", new AjaxMasterDetailsGrid.Models.Blog() { })

</div>


We're calling here the Html.Partial() method to render the Create partial view INSIDE the Modal Form. We MUST send a Blog empty object to the partial view, because if we don't, MVC will send the Index view Model  to the partial view, and that's not good: the partial expects a Blog model, while the Index view receives a List<Blog>.

Put  an <script> tag inside your Index file, and type the following code:



<script>

$(function () {   
         

    $( "#dialog-form" ).dialog({
        autoOpen: false,
        height: 500,
        width: 350,
        modal: true,
        buttons: {
        
              Cancel: function() {
                  $( this ).dialog( "close" );
              }
          }
    });

});
</script>

Here we have the following code:
0) "autoOpen" : MUST be 'false'  because we want the Modal Form to be opened by demand, not when the view is loaded;
1) "modal" = true: to make MODAL the Dialog;
2) "buttons" : when the "Cancel" button is pressed, will close the Dialog;
3) a #btnOpenDialog : when the "Open..." button is clicked, show the Dialog using the dialog("open ") function.

Also, add a button to open the dialog from the Client side:


<a id="btnOpenDialog" href="#" 
    class="ui-state-default ui-corner-all" 
    onclick="$('#dialog-form').dialog('open');">
     Create new Post
</a>

Last but not least, we need to customize the style of the Form and the button:



<style>
    #btnOpenDialog {
        position: relative;
        left: 50%;
        width: 100px;
        margin-left: -50px;
        padding: 5px 5px;
        text-decoration: none;
        text-align:center;
        font: 900 12px georgia;
        color: #FFF;
    }

    #dialog-form {
    font:900 11px Georgia;
    
    }
    
  </style>

------------------------------------------------------------------------------------------------------
Optional Section: we'll create a WEBGRID for the Blogs List : this code REPLACES the default <TABLE> tag built by the scaffolding mechanism to render the LIST of ALL posts : 




@model IEnumerable<AjaxMasterDetailsGrid.Models.Blog>
@{    ViewBag.Title = "Index";    Layout = "~/Views/Shared/_Layout.cshtml";    WebGrid grid = new WebGrid(Model, rowsPerPage: 3, ajaxUpdateContainerId: "divGrid");}

<div id="divGrid" class="ui-widget ui-widget-content ui-helper-clearfix ui-corner-all">
    @grid.GetHtml(headerStyle: "ui-widget-header",      columns: new[] {        grid.Column("ID","",format:@<b>@item.GetSelectLink(item.BlogID.ToString())</b>),      grid.Column("Title","",format:@<b><a href='/Blog/Comments/@item.BlogID'></a></b>),      grid.Column("Text","",format:@<i>@item.Text</i>),      grid.Column("Post Date","",format:@<p>@item.DatePosted.ToShortDateString()</p>),      grid.Column("Picture","",format:@<a href='/Blog/Comments/@item.BlogID'>          <img src="/Images/@item.MainPicture" alt="@item.MainPicture"               style="width:100px;height:100px;"/></a>),      grid.Column("","",format:@<div>          @Html.ActionLink("Edit", "Edit", new { id=item.BlogID })          @Html.ActionLink("Details", "Details", new { id=item.BlogID })          @Html.ActionLink("Delete", "Delete", new { id=item.BlogID })      </div>)                  })
</div>


(End of the Optional Section)
------------------------------------------------------------------------------------------------------

Now, for the Controller, we add the following Action methods:





 private BlogEntities db = new BlogEntities();
        public ActionResult Index()
        {
            return View(db.Blogs.ToList());
        }
        public PartialViewResult Create()
        {
            return PartialView();
        }
     
        [HttpPost]
        [ValidateAntiForgeryToken]
        public RedirectResult Create(Blog blog)
        {
            if (ModelState.IsValid)
            {
                 blog.DatePosted = DateTime.Now;
                 db.Blogs.Add(blog);
                 db.SaveChanges();              
            }
            return Redirect("Index");
        }


Notice that the Http POST Action method REDIRECTS the runtime to the Index Action, to feed the WebGrid we have made.

Now we need TWO Views:
1) "Index" View: to render the List of ALL posts
2) "Create" View: partial view to render the Blog fields to create a new post.

Therefore, right click over the Index Action and add the following View:



Then right click over the Create Action and add the following Partial View:




Finally, let's run the application to see the Form in action. The Button when clicked will open the Form:





The Form remains opened in a Modal way:







Also you can set the Form in a non-modal way. If you don't want the Dialog to be Modal, just write "modal = false" in the script :





That's all!! 
In this tutorial we've learn how to create a Modal Form using JQuery UI  and Partial Views.  

Happy programming.....


כתב: כרמל שוורצמן