Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

MVC.NET Modal Widget Helper

5.00/5 (7 votes)
4 Nov 2016CPOL2 min read 29.3K   431  
A reusable MVC popup message box with Ajax functionality - that can bind to any model

Introduction

I wanted to outline an widget-factory pattern for creating reusable MVC controls. In this example, I decided to create a reusable "MVC" modal pop-up widget. With the aid of the MVC HtmlHelper - I could easily create an extension off of the Razor "HTML" class to implement my own custom pop-control.

Background

You will need a good understanding on jQuery, MVC and C# code.

Using the Code

It is really easy to add the control to your View:

  1. Ensure to add the Widget control onto your page.
  2. Assign all the necessary properties. Defining these properties will help you to manage the behaviour of your modal pop-up.
CSS
 @(Html.HollowPoint().Window()
.Name("modalPopup")
.TemplateViewPath("~/Views/Shared/BootstrapModal.cshtml")
.Title("Hellow new world..!")
.Resizable(false)
.Draggable()
.IconUrl("~/Images/User_Male_Check.png")
)

Understanding your modal pop-up control's properties:

CSS
Need to define the title

`.Title("Hellow new world..!")

Provide a template you would like to re-use. The template is like the building blocks
of your client side control.
The template needs to implement the client side UI structure of the control you wish to see.
In this example I provide a "Bootstrap" modal HTML template.

.TemplateViewPath("~/Views/Shared/BootstrapModal.cshtml")

Control in Action

I have included an example where I list a bunch of "People" displayed in a gridview. In this example, I show how the pop-up can be used in conjunction with a Grid or List of items. This allows me to quickly edit these people's "details" from within the same page.

In my example, you can see I have added the modal popup control just under the foreach loop.

HTML
	List all the people included within the provided Model

@foreach (var item in Model)
    {
        < tr>
            < td>
                @Html.DisplayFor(modelItem => item.Value.Name)
            < /td>
            < td>
                @Html.DisplayFor(modelItem => item.Value.LastName)
            < /td>
            < td>
                @Html.DisplayFor(modelItem => item.Value.Address)
            < /td>
            < td>
                < a href="#" data-id="@item.Key" class="my-edit">Edit</a>
            < /td>
        < /tr>
    }

Now, we need to edit one of these people. When the "Edit" button in the Grid is clicked on - the Modal pop-up control will appear. We need to now "fetch" the particular details of the person we are trying to "Edit". In my example: The "/People/GetPerson" controller will be called via an Ajax call. Here, one could decide whether you want to call a Web API or a Controller Method.

JavaScript
      $(".my-edit").click(function () {
        //show the 'OK' button again
        $('.modal-footer').find('.btn-primary').first().show();
        clearContent();
        //the unique key found on this particular item
        var idx = $(this).attr("data-id");
        //store this unique 'key' away - as we will be needing it later
        $("#currentID").val(idx);
        //lets go and fetch this 'person'
        $.ajax({
            url: "/People/GetPerson?idx=" + idx,
            datatype: "application/json",
            type: "GET",
            cache: false,
            success: function (data) {
                //this call created a partial view for us = and returned the HTML
                //all we need to do is place it within the modal's internal content area            
                var dialog = $("#modalPopup")
                    .modalpopup("populateContent", data)
                    .modalpopup("show");       
            },
            error: function (e) {
                var test = e;
            }
        });
    });
}

The modal windows inner CONTENT is wrapped inside of a DIV - the content of the modal is populated based on the returning Ajax call, i.e., the contents "HTML" is retrieved from the server. In my example, I retrieve the content of a "Person", i.e., Binding the "Person" Model to the patial view: "_Person.cshtml".

C#
// Here the controller method is called. You can decide what to do with the incoming parameters.
public ActionResult GetPerson(string idx)
{
    Person person;
    if (p.GetPeopleDictionary().TryGetValue(int.Parse(idx), out person))
    {
        //let us return a partial view - passing through the "Person" model
        return PartialView("~/Views/Home/_Person.cshtml", person);
        //you could also pass a JSON object of the Person Model - if you so wished
        //you have to "AllowGet" to pass the security restriction
        //return Json(person, JsonRequestBehavior.AllowGet);
    }
    else
        return null;
}

Edit the Details

In order to update the selected Person's details, one has to keep track of which record (or "key") you would like to display for update purposes. One does this by ensuring that a key value is added as an "attribute" within the "edit" link.

HTML
< a href="#" <b>data-id="@item.Key"</b> class="my-edit">Edit< /a>

We now have the ability to update one any of the properties for this particular Person.

C#
[HttpPost]
    public ActionResult Edit(int id, Person person)
    {
        Person found;
        int key = int.Parse(id.ToString());
        if (p.GetPeopleDictionary().TryGetValue(key, out found))
        {
            found.Name = person.Name;
            found.Address = person.Address;
            found.LastName = person.LastName;
            return Content("Well done. " + found.Name + " - has now been updated!");
        }
        else
        {
            return Content("Nope! Something went wrong.");
        }
    }

That's it! We have successfully updated an item in the collection.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)