Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

MVC With Ajax - Push Start For Beginners(Part - 3)

0.00/5 (No votes)
31 Mar 2014 1  
This is quick tutorial how to start with ajax in mvx with all basic Add, Update, Edit and delete functionality in a sinlge page

Introduction

As I promised, this article is an advance step in MVC as per part-1 and part-2 of the series. Here we will include the Ajax/Jquery to implement the same we does earlier.

As we know, web is all about how fast is your service and the fastest ways to serve the client definitely requires the Ajax as it will reduces the exchange of data or we can say only necessary data is exchanged thus avoiding wastage of bandwidth and gives better performance. Additionally it also gives your application a much interactive interface. So let’s start MVC + Ajax.

Background

There are some new term/techniques we will be using in our project to impalement the Ajax. You will get brief information about these when you go through the article. So it will be good if you have some knowledge about them. These are 'Bundling' and 'PartialViews'.

Bundling and Minification: This is neither a new concept nor complex. In fact its very simple and i have explained this later in this article.

Partial Views: These are the razor view pages but they can be reused.If you want to reuse a view in your web application, you can go for the partial view concept. Partial view is like a regular view with a file extension '.cshtml'. We can use partial views in a situation where we need a header, footer reused for an MVC web application. We can say that it’s like a user control concept in ASP.NET.

So, having a very basic knowledge of these, you can proceed. Moreover, as the article progresses, you will get to know about them in details.

Using the code

Before we start MVC with Ajax, there are several points to be considered. As Ajax works with Jquery library, so have to include the Jquery library and there are some additional file you will find in your Scripts folder (see image below) i.e. ‘jquery.unobtrusive-ajax.js’ with its minified version which is responsible for all the Ajax post back in MVC using Ajax

So if you forget to add this file, your Ajax code block wouldn't be effective and will do the normal post backs.

Including Files in Bundling:

To include this JavaScript file there can be several ways, but choosing the most effective way without affecting the performance must be chosen. Till now all the files (css or js) are included from our ‘_Layout.cshtml’ page which acts as master page for our theme. It is located in the ‘Views/Shared’ folder. So open the page and you will see following lines at the bottom:

Here you can see we have added bundle of files under this namespace (we can say as this is logical separation only). Here comes the role of ‘Bundling and Minification’.

Bundling and Minification:

This is a process by which we create a bundle of files that are required throughout the application and register those when application loads, thus avoiding them loading again and again. This will avoid bandwidth wastage, better load time finally a better performance.

To add a file in bundle we have to follow the following steps:

1. Go to ‘App_Start’ folder which is in the root folder of the application folder.

2. Open the file named ‘BundleConfig.cs. This file contains the configuration for bundles we created

3. Add new bundle or modify the existing one. Now, if you are adding some files with some special case (like manual validations), you can create new bundle else it is good to add the files to best related bundle. Here in our application we will add the ‘ajax.unobtrusive.ajax.min.js’ file to our existing bundle. Below is the snapshot of this.

Here you can see that we haven’t added the full file path, instead we have just added ‘jquery.unobtrusive*’. This feature enables the application to avoid naming issues like in our case this will include the file that has the name beginning with ‘jquery.unobtrusive’.

One more thing you will notice here is ‘{version}’ word in second line of bundle block above. This is used to avoid the version issues. If you have two versions of the same file, it will automatically include the file with higher version.

This way we have added the js file or css or any file we want to register. Now we are ready to use the Ajax functionality in our first MC application. Now let’s start implementation of Ajax in MVC

DESIRED OUTPUT:

By using Ajax we will create a single page application where user can

  1. Add the records.
  2. Edit the existing records.
  3. Delete the existing records.

So below is the screenshot of what we will do in this article:

Here you can see that on left we have the same grid to view or edit or delete the saved records as we have added in the earlier part of series and on right we have the same view as we did in part-1 or series.

In short we will be merging the two pages to one and will use Ajax to communicate between those views to implement same on single page.

Add New Controller:

Add a new controller. Give it a appropriate name. I have named it FirstAjaxController’ so that it will be easy for us to identify that this will implement Ajax within this. By default you will have Index method in this and Index view for this method in your Views/FirstAjax folder.

Now, as I mentioned above that we will merge the two page views to single page, the question arise here is we have different type of Views for both case i.e. in part-1 series we have type cast the view to@model StartWithMVC.Models.Employee’ while in part -2 we have type casted (strongly typing) the view to @model List<StartWithMVC.Models.Employee>’. So how we will handle this in single page. For this we have some techniques. By using them we can implement our logic. One can choose any of the technique but again a Clear and Better approach is always preferred. To get in depth of these you can study the following article

http://www.codeproject.com/Articles/687061/Using-Multiple-Models-in-a-View-in-ASP-NET-MVC-M

In our application to counter this we will use ‘Tuple’ technique. In this we will create a new class or Model we can say, which group multiple kinds of data types. So,

  1. Add new Model folder and give it appropriate name (i named it ‘AddUpdateEmployee.cs’)
  2. Write the following codes of line in that class/Model
public Employee EmpModel { get; set; }

public List<Employee> ListEmpModel { get; set; }

Here the line 1 includes the Employee Model object and line 2 includes the List type employee model object. Hence if we strongly typecast a view to this very object we can have the two models inherited into single model. You will see how we will use this Model in our application.

Here is screenshot of how it will go in case you face any problem/confusion.

Add/Update Index View:

Now go to the ‘index.cshtml ‘ by right click on the Index method in controller (FirstAjaxController.cs). Now write the following code in that

@model StartWithMVC.Models.AddUpdateEmployee

@{

    ViewBag.Title = "Index";

}


<h2>Employee</h2>

<div id="divListPanel" class="left_panel">

    @Html.Partial("_ViewAllRecords", Model.ListEmpModel)

</div>


<div id="divEditPanel" class="right_panel">

    @Html.Partial("_UpdateEmployee", Model.EmpModel)

</div>

Now as you can see here we have used the ‘AddUpdateEmployee’ tuple in this view and further we use this model to fetch the Employee and List<Employee> type object where ever it is required.

Why Partial Views ?

As ajax in response return the full page HTML and update the target div with whole page html thus page in a page will open up. So to avoid this we create a partial view for only that portion which we want to update on any particular action.

1.Partial View "_ViewRecord" :

 @model List<StartWithMVC.Models.Employee>

<div class="table_container">

    <table>

        <thead>

            <th>HR Emp Id</th>

            <th>Last Name</th>

            <th>First Name</th>

            <th>City</th>

            <td><b>Edit</b></td>

            <td><b>Delete</b></td>

        </thead>

        <tbody>

            @foreach (var item in Model)

            {

                <tr>

                    <td>@item.HREmpId</td>

                    <td>@item.LastName</td>

                    <td>@item.FirstName</td>

                    <td>@item.City</td>

                    <td>@Ajax.ActionLink("Edit", "EditRecord", new { recordID = @item.EmpId }, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "divEditPanel" })</td>

                    <td>@Ajax.ActionLink("Delete", "DeleteRecord", new { recordID = @item.EmpId }, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "divListPanel" })</td>

                </tr>

            }

        </tbody>

        </table>

</div>

As you can see this nothing just the same as we used in part-2 view. The only change we made are following:

As you can see here that we have used '@Ajax.ActionLink' instead of '@Html.ActionLink' thus introducing Ajax. Here we have added an attribute AjaxOption which will set the property of how the Ajax call will be handled. Here we are telling the Ajax that we want to replace the content of 'divEditPanel' on this Ajax call.

Similarly, on the delete link, we tell the Ajax that we wanted to update the content of 'divListPanel' i.e. left panel.

2.Partial View "_UpdateEmployee" :

@model StartWithMVC.Models.Employee
@using (Ajax.BeginForm("SaveEmployee", "FirstAjax", new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "divListPanel", OnComplete="resetFields();" }))
{
    <fieldset>
        @Html.HiddenFor(m => m.EmpId)
    <p>
        @Html.LabelFor(m => m.HREmpId)
        @Html.TextBoxFor(m => m.HREmpId, new { maxlength = 10 })
    </p>
    <p>
        @Html.LabelFor(m => m.FirstName)
        @Html.TextBoxFor(m => m.FirstName, new { maxlength = 30 })
    </p>
    <p>
        @Html.LabelFor(m => m.LastName)
        @Html.TextBoxFor(m => m.LastName, new { maxlength = 30 })
    </p>
        <p>
        @Html.LabelFor(m => m.Address)
        @Html.TextBoxFor(m => m.Address, new { maxlength = 30 })
    </p>
    <p>
        @Html.LabelFor(m => m.City)
        @Html.TextBoxFor(m => m.City, new { maxlength = 30 })
    </p>
    </fieldset>
    
    <input type="submit" name="btnSave" value="Submit" />
}

Here also we use he similar code we used in previously (part 1) but the only change we made is we introduced Ajax to the form by making it Ajax post form.

so, this will perform ajax request on click and it will call the 'resetFields()' JavaScript function to clear the fields from right portion. below is the JavaScript function

<script type="text/javascript">
    function resetFields() {
        $('input[type=text]').val('');
    }
</script> 

This is all from views, now we will see changes in controller.

Controller Action Code Block:

1. Index Action :

write the following lines in the index method of the controller.

 StartWithMVCEntities db = new StartWithMVCEntities();
            var tempModel = new AddUpdateEmployee();
            tempModel.EmpModel = new Employee();
            tempModel.ListEmpModel = db.Employees.ToList();
            return View(tempModel); 

As you can see i have used tempModel tuple model here and assigned an Employee model object and List <Employee> object and passed this to the view. Now check above 'Index.cshtml' view code above , there we have used this. So this we can serve a View by multiple Models.

2. Save/Update Employee Action:

Write the following code to save employee. You will notice some changes in this method from the method written in part-2 of article series.

 public ActionResult SaveEmployee(Employee objEmployee)
        {
            StartWithMVCEntities db = new StartWithMVCEntities();
            if (objEmployee != null && objEmployee.EmpId != 0)
            {
                //TODO : your entity framework code for updateing the employee details
                //fetch object for the editted employee record
                Employee objEmp = db.Employees.ToList().Find(m => m.EmpId == objEmployee.EmpId);
                //Assign the edited value to getch object
                objEmp.HREmpId = objEmployee.HREmpId;
                objEmp.FirstName = objEmployee.FirstName;
                objEmp.LastName = objEmployee.LastName;
                objEmp.Address = objEmployee.Address;
                objEmp.City = objEmployee.City;
                //finally save the chagne to database
                db.SaveChanges();
                //this line will reset the default model state or properties
                ModelState.Clear(); 
                List<Employee> listEmpModel = db.Employees.ToList();
                return PartialView("_ViewAllRecords", listEmpModel);
            }
            else
            {
                //TODO : your entity framework code for saving the employee details
                db.Employees.AddObject(objEmployee);
                db.SaveChanges();
                //this line will reset the default model state or properties
                ModelState.Clear();
                List<Employee> listEmpModel = db.Employees.ToList();
                return PartialView("_ViewAllRecords", listEmpModel);
            }
        } 
Things to notice:

Now its clear that if we save or Update any employee than it should come/reflect the changes on the view records list on the left side. Hence we need to update the that part only and reset the fields once done. So for that following lines are important:

ModelState.Clear(); and return PartialView("_ViewAllRecords", listEmpModel);

modelstate.clear(): This will reset the model state and reinitialize the for on save and update so that save and update action remains isolated. So in case of Add the primary key value we used to compare in save function will be Zero and for update case it will be Non-Zero.

In line 'return PartialView("_ViewAllRecords", listEmpModel);' i am returning the view generated by this partial view also i pass the listed model required by this partial view.

Hence we have the required output without fully loading the page and only required portion/section is update thus increase the performance.

Now to reset the fields, i called the JavaScript function as written above. This is very simple.

3. Edit Records (Make record editable):

Now, on click of 'Edit' link in out view record grid we requires the values to appear in the fields, so it is clear that we need to update the right part or we can say '_UpdateEmployee' view. So below is the code for that with similar changes.

public ActionResult EditRecord(int recordID)
        {
            //TODO : your entity framework code for showing the employee details
            StartWithMVCEntities db = new StartWithMVCEntities();
            Employee objEmp = db.Employees.ToList().Find(m => m.EmpId == recordID);
             
            return PartialView("_UpdateEmployee", objEmp);
        }  

4. Delete Record:

Now, When we delete the record from grid, we need to update the left portion only or we can say the '_ViewRecords' view only and we will do the same. Below is the code for that:

 public ActionResult DeleteRecord(int recordID)
        {
            //TODO : your entity framework code for showing the employee details
            StartWithMVCEntities db = new StartWithMVCEntities();
            Employee objEmp = db.Employees.ToList().Find(m => m.EmpId == recordID);
            db.Employees.DeleteObject(objEmp);
            db.SaveChanges();
            List<Employee> listEmpModel = db.Employees.ToList();
            return PartialView("_ViewAllRecords", listEmpModel);
        } 

Run The Project:

Now we are ready to run the application. You will the similar view as i have mention in the beginning. Hence we have achieved our goals.

Note: There might be some design changes in you view as image i included which is due to some css 'style sheet' only. That was not the part of our discussion, so i haven't included that. If you wish to have that, please download it in source code attached above.

Points of Interest

So we just see how we can use Ajax with MVC to implement all Add, Update and delete record on the same which that is with minimum load over the server. Now as already mention above things of interest are

  • Partial View
  • Bundling and Minification
  • Ajax Js file

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here