Sorted By: Tag (jquery)

JavaScript-Heavy, Maintainable Web Applications by a n00b: 101 - Leveraging Existing Libraries

I decided to dedicate this part of my life to JavaScript for a while and I will write my experience on JavaScript-heavy, maintainable web Applications as a n00b.
2013-01-08 00:07
Tugberk Ugurlu


Nearly every software developer dedicates a part of its time to improve him/herself on a particular area of expertise. Well, I dedicate this part of my life to JavaScript for a while. I have been writing JavaScript for approx. 3 years now but if anybody asks me if I know JavaScript, I tell them that I know JavaScript and I *don’t* know JavaScript at the same time. It’s probably because of the fact that I don’t get to work with it that much. One of the places I struggle most is the idea of maintaining big-ass JavaScript heavy web applications. That idea has been causing me to carry a psychic weight but now, at this very moment, I am committed to throw it away like a piece of garbage! And yes, it starts with a blog post Smile

A few months ago I talked to a brilliant developer about node.js, the platform built on Chrome's JavaScript runtime (V8) for easily building fast, scalable network applications, and asked his opinion about it. He was uncertain at the time but apparently he had more information about node.js than me. So, I expressed that I didn’t understand the need of JavaScript at the server side because it’s hard to maintain such a huge JS codebase. Then, he slapped me in the face with a follow-up sentence: "Well, the node community thinks that a big application codebase needs to be separated into small modules, components to be more maintainable". That was the nudge I needed to believe that the JavaScript codebase can be maintained.

Not long time later from that moment, I then started watching John Papa’s Single Page Apps with HTML5, Web API, Knockout and jQuery and I learnt lots of mind blowing stuff about JavaScript: new (at least new to me) libraries, well-known JavaScript patterns, which I had been aware of but didn’t know how to apply them most of the time, and many more. This was the start of my commitment to learn JavaScript (I mean really learning, going beyond the for loops and if statements) and I pulled out my JavaScript: The Good Parts book which I have bought in last June, but I thought that the best way to learn this stuff is to blog about it. So, here I am Winking smile In this post I am listing a few JavaScript libraries which make a lot of sense to be used in nearly every web applications. I have been working with some of this libraries for a while now and I am going to be working with some of those.

JQuery: The JavaScript framework we all know and fell in love at the time that we have noticed it. JQuery is especially helpful for DOM manipulation and Ajax interactions. If you don’t want to install JQuery, don’t worry; you eventually will have to because I am sure that at least of the libraries you are going to use will have a dependency on it.

KnockoutJS: KnockoutJS is one of the best things that can happen to a web developer. Starting to learn KnockoutJS gives you the equivalent feeling which you would feel at the very moment when you find a cup of hot chocolate in a freezing cold day. It enables your to have two way data-binding between your DOM elements and your view model which means when your data model's state changes, your UI updates automatically and vice versa. Check out its well-arranged documents and live tutorials.

Underscore.js: Underscore.js provides a utility suite which covers lots of useful functions. From the its official page: "Underscore provides 80-odd functions that support both the usual functional suspects:map, select, invoke — as well as more specialized helpers: function binding, javascript templating, deep equality testing, and so on. It delegates to built-in functions, if present, so modern browsers will use the native implementations of forEach, map,reduce, filter, every, some and indexOf". Don’t forget to watch this awesome presentation from Elijah Manor on Underscore.js.

RequireJS: I think RequireJS is the essential piece of library which makes it possible to have maintainable, well-designed JavaScript codebase. It’s a modular script loader which enables you to write small pieces of code in separate files and handle their dependencies and load order correctly. RequireJS also has a very nice documentation in its web site; definitely check that out.

Sammy.js: Last library I am considering for my every web application is Sammy.js. It gives us a nice way to handle page navigations without refreshing the page at all by providing a nice routing mechanism. Especially, if you are writing a Single Page Applications (SPA), this is the library that you want inside your suite. Don’t skip to check out its intro sample.

There are for sure other great libraries out there (e.g. Moment.js, AmplifyJS, JQuery UI, Breeze) but these are the ones I am in love at the moment. Go check them out and start exploring Winking smile

ASP.NET MVC Remote Validation For Multiple Fields With AdditionalFields Property

This post shows the implementation of ASP.NET MVC Remote Validation for multiple fields with AdditionalFields property and we will validate the uniqueness of a product name under a chosen category.
2011-10-24 06:44
Tugberk Ugurlu


why-wont-you-validate-me-hrrrr

I blogged about ASP.NET MVC Remote Validation couple of days ago by showing a simple scenario for how to use it. That blog post simply covers everything about remote validation except for properties of RemoteAttribute Class.

In that blog post, we covered validating user inputs uniqueness for one field in order to alert the user before the form is posted. This is a quite nice built-in feature which takes basically not more 5 minutes to implement.

But we as in all human beings tend not to be happy with the current situation and want more. It is in our nature, we can’t help that. So, as soon as I use this feature I ask myself "What if I would like to check the uniqueness of product name inside the chosen category?". Well, it turns out that ASP.NET MVC team asked this question themselves way earlier than me and added a support for this kind of situations.

RemoteAttribute.AdditionalFields Property gets or sets the additional fields that are required for validation. AdditionalFields property is string property and can be provided for multiple fields.

Probably another question pops up on your mind : "How does ASP.NET MVC Framework relate the fields, which we will provide for AdditionalFields property, with form elements and pass them our controller?" If we need to ask this question in plain English, that would be this : "How the heck does it know in which category I trying to check the uniqueness of the product name?". Here, ASP.NET MVC Model Binding feature plays a huge role here as much as JQuery.

Simple Scenario

Assume that we need to store products under a category inside our database and we need every each product name to be unique under the chosen category.

In order to stick with the topic here, I have already built the necessary stuff (database, repos, etc.). I used SQL Server Compact Version 4 here. As sample database, you won’t believe what I used : Northwind Winking smile I also used Entity Framework to reach out to the data. You can see all of the code from my GitHub Repo : https://github.com/tugberkugurlu/MvcRemoteValidationSample

Our create form looks like below :

image

The product model class looks like this :

public partial class Product
{
    public Product()
    {
        this.Order_Details = new HashSet<Order_Detail>();
    }

    public int Product_ID { get; set; }
    public Nullable<int> Supplier_ID { get; set; }
    public Nullable<int> Category_ID { get; set; }
    public string Product_Name { get; set; }
    public string English_Name { get; set; }
    public string Quantity_Per_Unit { get; set; }
    public Nullable<decimal> Unit_Price { get; set; }
    public Nullable<short> Units_In_Stock { get; set; }
    public Nullable<short> Units_On_Order { get; set; }
    public Nullable<short> Reorder_Level { get; set; }
    public bool Discontinued { get; set; }

    public virtual Category Category { get; set; }
    public virtual ICollection<Order_Detail> Order_Details { get; set; }
    public virtual Supplier Supplier { get; set; }
}

Here is my additional partial class under the same namespace of my Product class :

[MetadataType(typeof(Product.MetaData))]
public partial class Product {

    private class MetaData {

        [Remote(
            "doesProductNameExistUnderCategory", 
            "Northwind", 
            AdditionalFields = "Category_ID",
            ErrorMessage = "Product name already exists under the chosen category. Please enter a different product name.",
            HttpMethod = "POST"
        )]
        [Required]
        public string Product_Name { get; set; }
        
        [Required]
        public int? Supplier_ID { get; set; }

        [Required]
        public int? Category_ID { get; set; }

    }

}

As you see there, we have decorated Product_Name property with RemoteAttribute. What we need to point out here is AdditionalFields property of RemoteAttribute. Simply we are saying here that : 'Pass Category_ID value to the controller action when you try validate the Product_Name'. So, Ajax Request will send two form inputs to our action : Product_Name and Category_ID. As we have already seen on my previous blog post on ASP.NET MVC Remote Validation, Model Binder will bind those inputs to our action parameters in order to allow us to easily pick them.

Our main goal here is to check the uniqueness of the product name under the chosen category and that’s why we need Category_ID value inside our controller action. Check controller action code below and you will get what I am trying to say :

public JsonResult doesProductNameExistUnderCategory(int? Category_ID, string Product_Name) {

    var model = _entities.Products.Where(x => (Category_ID.HasValue) ? 
            (x.Category_ID == Category_ID && x.Product_Name == Product_Name) : 
            (x.Product_Name == Product_Name)
        );

    return Json(model.Count() == 0);

}

Inside this action, we are checking if the user name already exists under the chosen category or not. For the real purpose of this blog post, we only need to focus what we are returning here. The other part of this code mostly depends on your application’s business logic.

We are basically done here. I will run the app and see it in action but please firstly see the below screenshot :

image

This table show the list of products inside our database. On the first row, we see that there is a product named Chai under Category_ID 1 whose Category_Name is Beverages (you don’t see the Category_Name here but don’t worry, just trust me). We will demonstrate our sample with this product values.

First, select the category from the select list :

image

Then, type Chai for Product_Name :

image

Then, simply hit Tab key :

image

All done but I would like to go a little deeper here. Let’s put a break point on doesProductNameExistUnderCategory method and start a debug session.

image

When we follow the above steps again, we should end up like this :

image

Let’s look what we got here :

image

We have all the necessary values to check if the value is legitimate or not.

Again, you can see all of the code from my GitHub Repo : https://github.com/tugberkugurlu/MvcRemoteValidationSample

Hope you enjoy the post Smile

Check Instantly If Username Exists - ASP.NET MVC Remote Validation

This blog post will walk you through on implementation and usage of ASP.NET MVC Remote Validation. As a sample, we will validate the availability of the username for membership registration.
2011-10-19 04:07
Tugberk Ugurlu


On some of our web applications, we require users to register our site in order to perform some special actions. This feature kind of a no-brainer thing thanks to built-in ASP.NET Membership API. It works well with either ASP.NET Web Forms or ASP.NET MVC. In this path, on some cases, we also require each users to have unique username or unique e-mail. The implementation of this feature also does not require our concern either.

Let’s see it in action what I am getting at here.

I created an ASP.NET MVC 3 Web Application project with Visual Studio 2010 (It is also same for Visual Web Developer which is a free version of Visual Studio) and I fired it up by clicking Ctrl + F5. When I navigate to /Account/Register, I get the following view :

image

In order to stick with the topic here, I already registered a user with a username of user1. Look what happens when I try to create another user with a username of user1 :

image

So, the thing ASP.NET offers us out of the box is clever. But there is a little bit a problem here. Well, not a problem but how can I call it, hmmm… I can say lack of creativeness. When I push the register button here, it goes all the way to server to register the user. Inside our controller, built-in register action checks if user already exists or not.

Wouldn’t it be nice if user instantly sees if typed username is valid or not? It certainly would be!

Introduction to ASP.NET MVC Remote Validation

We know that ASP.NET MVC takes advantage of .NET Framework Data Annotations to validate user’s input. By this way, we can check for required fields with RequiredAttribute, length of a string with StringLengthAttribute and so on. Well, it turns out that there is another useful one called RemoteAttribute which we can use, for example, to validate e-mail and username in a registration form and alert the user before the form is posted.

This Remote Validation thing is what we are looking for. In order to implement this for our scenario, we need to tweak the UserName property of RegisterModel class. Here is the whole RegisterModel class after the modification I made :

    public class RegisterModel {

        [Required]
        [Display(Name = "User name")]
        [Remote("doesUserNameExist", "Account", HttpMethod = "POST", ErrorMessage = "User name already exists. Please enter a different user name.")]
        public string UserName { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
    }

As you can see, we added Remote attribute for UserName property inside RegisterModel class. RemoteAttribute has several overloads but what we entered here is as follows :

  • doesUserNameExist : It is the name of the Action which will validates the user input by returning true or false as JSON format. We will see how we do that in a minute.
  • Account : It is the name of the controller which doesUserNameExist lives in.
  • HttpMethod : Simply we are telling the remote validation to communicate our mini service over Http POST method (This is not required but I’d like to do it this way).

How our controller action doesUserNameExist looks like is as follows :

[HttpPost]
public JsonResult doesUserNameExist(string UserName) {

    var user = Membership.GetUser(UserName);

    return Json(user == null);
}

As you see, it is a simple controller action which returns JsonResult. What we need to notice here is UserName paramater of this action. We put that parameter there to pick up the user input which will be sent through Ajax request to our action. Remote Validation will send the user input as Form Data which will have the same name as property. So, in this case it is UserName.

Before we give it a try, make sure that you have the following libraries referenced on your registration page :

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

Let’s build our project and fire it up to see it in action.

1. I loaded the page :

image

2. I enter user1 for UserName field (user1 is the username which is already inside our database) :

image

3. Then I just put the mouse cursor inside another text input field and see what happened :

image

Just what we needed. I thought showing this in action like that is a lame approach to do that so I recorded a short video in order to demonstrate this. In this video I also tried to show what is happening behind the scenes. See it below :

I also put the sample project on GitHub so you can get the working sample code if you want :

https://github.com/tugberkugurlu/MvcRemoteValidationSample

Note : 

But there is a donwside for this validation attribute. The remote validation does not validate the user input on server side. So, you need to make sure on the server side that it is valid as it is being done on our sample. We also make sure on the server side that username which is being passed to our controller is unique.

Hope this will help you even a little bit.

Working With JQuery Ajax API on ASP.NET MVC 3.0 - Power of JSON, JQuery and ASP.NET MVC Partial Views

In this post, we'll see how easy to work with JQuery AJAX API on ASP.NET MVC and how we make use of Partial Views to transfer chunk of html from server to client with a toggle button example.
2011-09-09 17:23
Tugberk Ugurlu


JQuery-logo

So, here it is. Nearly every blog I occasionally read has one JQuery related post which has JQuery ‘write less, do more’ logo on it. Now, I have it either Smile This is entirely not the intention of this blog post. What the real intention of this blog post is to lay down some useful stuff done with JQuery Ajax API on ASP.NET MVC 3.0 framework.

I am no expert on neither JQuery nor JavaScript but I am working on it and I hit the resources so hard nowadays. I am no expert on ASP.NET MVC either but I am sure I am pretty damn good at it. It is my favorite platform since v1.0.

ASP.NET MVC embraces the web (html, http, plain JavaScript) and enables you to move which direction you want on your layout. I mean you can real have your way. So, it is so important here to be able to use JavaScript (for most, it is not JavaScript anymore. It is JQuery. Don’t be surprised if you see Content-Type: text/jquery response header) as Ninja in order to get the most out of ASP.NET MVC’s V part (V as in View).

Easiest way to get JQuery package into your ASP.NET MVC 3.0 project is to do exactly nothing. No kidding, it is already there if you install the ASP.NET MVC 3 Tools Update

If you would like to get the latest version of it (which the below samples has been written on), simply type Update-Package JQuery inside PMC (Package Manager Console) and hit enter and you will be done !

Let’s get it started then.

Overview of the Process

Setting expectations correctly is the real deal. We need to set them correctly so that we will be as satisfied as we planned. In this quick blog post, I will walk you through a scenario: a basic to-do list application. We will:

  • Make AJAX calls to our server,
  • Display loading messages while processing,
  • Make use of partial views when we need to update our web page seamlessly.

File New > Project > ASP.NET MVC 3 Web Application > Internet Application > Razor View Engine > No thanks, I don’t want the test project > OK

So the mini title above actual explains what we need to do first, briefly Smile What I would like to do first is to set up my model, ORM (I will use Entity Framework for that) and database.

The main concern of this blog post is AJAX API usage on ASP.NET MVC so I am not go through all the steps of creation our model, database and all that stuff. I will put the sample code at the bottom of this blog post so feel free to dig into that

Then I will make sure to update my JQuery Nuget package to the latest one. I will tweak the default application a little bit as well.

Go get him tiger

Now we are all set up and ready to rock. Let’s begin.

imageOur database here is so simple as you can see on the left hand side. I have created the database with SQL Server Compact edition because database is not the point we are emphasizing on this post.

Our application will only consist one page and we will do all the work there.

First, I will create the JQuery structure. As I mentioned, we will display user friendly loading message to the end user. In order to do that, we will use JQuery.UI dialog api. We will have it inside our _layout.cshtml page (the reason why we do that is to be able to use it everywhere without writing it again. This app might contains only one page but think about multiple page apps for this purpose).

The code for that is really simple actually. We will only have a section defined as html code inside the DOM and we will turn that into a JQuery.UI dialog for loading messages.

Below is the html code for our loading box :

        <div id="ajax-progress-dialog">
            <div style="margin:10px 0 0 0;text-align:center;">
                <img src="@Url.Content("~/Content/img/facebook.gif")" alt="Loading..." />
            </div>
        </div>

Very simple html (please forgive me for putting the style code inline Smile). The below JQuery code will handle this html code :

        (function () {
            $(function () {
                //Global ajax progress dialog box
                //Simply run $("#ajax-progress-dialog").dialog("open"); script before the ajax post and
                //$("#ajax-progress-dialog").dialog("close"); on the ajax post complate
                $("#ajax-progress-dialog").dialog({
                    autoOpen: false,
                    draggable: false,
                    modal: true,
                    height: 80,
                    resizable: false,
                    title: "Processing, please wait...",
                    closeOnEscape: false,
                    open: function () { $(".ui-dialog-titlebar-close").hide(); } // Hide close button
                });
            });
        })();

With this approach, we set up an environment for ourselves to open this dialog when we start the AJAX call and close it when the action is completed.

Some of you guys probably think that .ajaxStart() and .ajaxComplate() would be a better fit here but I don’t. They will hook up the functions for all the AJAX calls but we might need separate loading messages. With the above approach we will call the global loading message only when we need it.

imageNow we can move up. I have added some items to the list manually and list then on the page and we have the result as the picture on the left side.

It is quite simple yet but don’t worry, it will get messy in a moment. First thing that we will do here is to add a functionality to enable toggling IsDone property of the items. When we click the anchor, the To-Do item will be marked as completed if it is not and vice versa.

Let’s look at the view code here before doing that because there is some fundamental structure for our main purpose here :

@model IEnumerable<JQueryAJAXToDoListMVCApp.Models.ToDoTB>

@{
    ViewBag.Title = "Tugberk's To-Do List";
}

@section Head { 
    <script>
        (function () {
            $(function () {
                //JQuery code will be put here
            });
        })();
    </script>
}

<h2>Tugberk's To-Do List</h2>

<div id="to-do-db-list-container">
    @Html.Partial("_ToDoDBListPartial")
</div>

As you can see have rendered a partial view here. The complete partial view code is as follows :

@model IEnumerable<JQueryAJAXToDoListMVCApp.Models.ToDoTB>

<table style="width:100%;">

    <tr>
        <th>Item</th>
        <th>Creation Date</th>
        <th>IsDone</th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>@item.Item</td>
        <td>@item.CreationDate</td>
        <td>@item.IsDone</td>
    </tr>   
}

</table>

So why we did that is a good question in this case. When we need to make a change to our list view through an AJAX call, we will render this partial view on our controller method and send it back to the client as JSON result. This partial view will be our template here. When we make a change to this partial view, this change will be made all of the places that use this partial view which is kind of nice.

Also, this action will show us one of the main fundamentals of ASP.NET MVC which is separation of concerns. View doesn’t care how the model arrives to it. It will just displays it. The same is applicable for controller as well. It does not care about how the view will display the model. It will just pass it.

Let’s put the above paragraph in action. First, we need to make a little change to our partial view for toggle function :

@foreach (var item in Model) {
    <tr>
        <td>@item.Item</td>
        <td>@item.CreationDate</td>
        <td>
            @if (@item.IsDone) { 
                <a class="isDone" href="#" data-tododb-itemid="@item.ToDoItemID">Complated (Mark as Not Complated)</a>
            } else { 
                <a class="isDone" href="#" data-tododb-itemid="@item.ToDoItemID">Not Complated (Mark as Complated)</a>
            }
        </td>
    </tr>   
}

With this change, we make the DOM ready for the JQuery. Let’s look at the JQuery code for the toggle action :

        (function () {
            $(function () {

                function toggleIsDone(e, element) {

                    var itemId = element.attr("data-tododb-itemid");
                    var d = "itemId=" + itemId;
                    var actionURL = '@Url.Action("toogleIsDone", "ToDo")';

                    $("#ajax-progress-dialog").dialog("open");

                    $.ajax({
                        type: "POST",
                        url: actionURL,
                        data: d,
                        success: function (r) {
                            $("#to-do-db-list-container").html(r.data);
                        },
                        complete: function () {
                            $("#ajax-progress-dialog").dialog("close");
                            $(".isDone").bind("click", function (event) {
                                toggleIsDone(event, $(this));
                            });
                        },
                        error: function (req, status, error) {
                            //do what you need to do here if an error occurs
                            $("#ajax-progress-dialog").dialog("close");
                        }
                    });

                    e.preventDefault();
                }

                $(".isDone").bind("click", function(e) {
                        toggleIsDone(e, $(this));
                });

            });
        })();

Let’s bring that code down into pieces. First, we bind toggleIsDone(e, element) as a click function to every element whose class attribute is ‘isDone’ and we know that they are our toggle anchors. On the toggleIsDone function, we will grab the itemId of the clicked item from data-tododb-itemid attribute of clicked anchor. Then, we will set the itemId as parameter on d variable.

Look at the actionURL variable. What happens there is that : we assigning the URL of toogleIsDone action of ToDo controller.

Before we begin our AJAX call, we simply fire up our loading dialog to display that we are doing some stuff.

On the AJAX call, we make a post request to actionURL and we are passing the d variable as data. We know that we will get back a JSON result which contains a data property and on success event of the call we simply change the content of to-do-db-list-container element with the new one which we have received from the server as JSON result.

Just before we step out the success event, we do very tricky stuff there. It is tricky in this case and hard to figure it out if you are new to JQuery. I will try to explain what we did there. We bind toggleIsDone(e, element) as a click function to every element whose class attribute is ‘isDone’. The weird thing is the fact that we have done the same just after the DOM has loaded. So, why the heck do we do that? We have bind the specified function to specified elements just after the DOM has loaded. That’s fine. Then, we have update the entire content of to-do-db-list-container div and the all click event that we have bind has been cleared out. In order not to lose the functionality, we have bind them again.

This kind of an Inception way is the best way that I come up with for this functionality and if you thing there is a better one, let me know.

On complete event, we made sure to close our loading dialog.

At the end of the code, we call a function called preventDefault() for the event. What this does is to prevent the anchor to do its default function which would be the append the # to the URL. Not necessary here but it is kind of nice to use here though.

So far, we have completed our work on client side code and lastly, we need to implement the server side function which updates the database according to parameters and sends a JSON result back to the client.

Before we do that we need to use Nuget here to bring down a very small package called TugberkUg.MVC which will have a Controller extension for us to convert partial views to string inside the controller.

image

image

The complete code of out ToDoController is as indicated below :

using System.Linq;
using System.Web.Mvc;
using TugberkUg.MVC.Helpers;
using System.Data.Objects;
using System.Data;

namespace JQueryAJAXToDoListMVCApp.Controllers
{
    public class ToDoController : Controller {

        private readonly Models.ToDoDBEntities _entities = new Models.ToDoDBEntities();

        public ActionResult Index() {

            var model = _entities.ToDoTBs;

            return View(model);
        }

        [HttpPost]
        public ActionResult toogleIsDone(int itemId) {

            //Getting the item according to itemId param
            var model = _entities.ToDoTBs.FirstOrDefault(x => x.ToDoItemID == itemId);
            //toggling the IsDone property
            model.IsDone = !model.IsDone;

            //Making the change on the db and saving
            ObjectStateEntry osmEntry = _entities.ObjectStateManager.GetObjectStateEntry(model);
            osmEntry.ChangeState(EntityState.Modified);
            _entities.SaveChanges();

            var updatedModel = _entities.ToDoTBs;

            //returning the new template as json result
            return Json(new { data = this.RenderPartialViewToString("_ToDoDBListPartial", updatedModel) });
        }

        protected override void Dispose(bool disposing) {

            _entities.Dispose();
            base.Dispose(disposing);
        }

    }
}

When you look inside the toogleIsDone method, you will see that after the necessary actions are completed, we will pass a model to our partial view which we have created earlier, render it and finally return it to the client as JSON. Why we return it as JSON instead of content is a totally subjective question in my opinion. For me, the advantage of JSON result is to be able to pass multiple values. For example, we would pass the result as follows if we needed :

            return Json(
                new { 
                    CustomMessage = "My message", 
                    data = this.RenderPartialViewToString("_ToDoDBListPartial", updatedModel) 
                });

Now when we compile our project and run it, we will see a working application :

image image image

Also, here is a quick video of a working example :

Summary

What we need to get out of from this blog post is to see that what we are capable of doing with a little effort for very usable and user friendly web pages. Also, we can visualize how things fit together and flow on your project. There are lots of way of making calls to your server from client side code and lots of them have its own pros and cons.

I hope that this blog post helps you, even a little, to solve a real world problem with your fingers Smile

TinyMCE HTML Text Editior & ASP.NET MVC - Setting It Up Has Become Easy With Nuget

One of the best Javascript WYSIWYG Editors TinyMCE is now up on Nuget live feed. How to get TinyMCE through Nuget and get it working is documented in this blog post.
2011-09-07 06:15
Tugberk Ugurlu


tinymce-logoOverview of the Process

Couple of weeks ago, I was setting up a new project and I have created a folder called ‘lib’ inside the $(SolutionDir) as usual to put all the dependencies that I am going to be using for my project (.Net libraries, JavaScript libraries, etc.).

Then, I go to http://www.tinymce.com/ to grab the latest version of TinyMCE which is an awesome Javascript WYSIWYG Editor. This action popped up a balloon inside my head that tells me I had been doing this stuff over and over again for 80% of the projects that I have created. So this hits me hard and I thought I should automate this process. In order to do that, I’ve created an internal Nuget package just for myself to pull the TinyMCE package with plugins. Even, I have created EditorTemplates so that I could just give my model a hint to use the template.

That worked pretty well for me but don’t miss the point here. That worked pretty well only for me. Not for John, Denis, Adam and so on. After I thought this, I have come across a blog post about TinyMCE integration on ASP.NET MVC 3 (The blog post is in Turkish). Remember the balloon which popped up inside my head? This blog post widened that balloon and it hit me harder this time. The process which has been documented there is a very well working sample but well…, it looked more like a poor man’s TinyMCE integration for me. (The article was nice but it wasn’t following the DRY way)

After that, I have decided to enhance my packages to push them to live Nuget feed. So, I have contacted with the package admins on their forum :

TinyMCE Nuget Package

@Spocke has replied my post in a short time and gave me a go ahead to push the package to live Nuget feed. I am not going to get into details of how I created the package. Mostly, I will show how to set up your environment to get TinyMCE working in a short time.

TinyMCE into an ASP.NET MVC project

tinymce-Nuget-packages-of-mine

It is now easy to get TinyMCE package to your project with Nuget. It’s even easier to get it working with ASP.NET MVC. In this post, I am going show you the easiest way to get it work ASP.NET MVC but I hope I am going to cover for Web Forms as well in near future.

There are several packages which are related to TinyMCE that I have pushed to live Nuget feed as you can see in the picture left hand side. (This list might extend in the future) Briefly the packages are :

TinyMCE : The main package which holds the infrastructure .js files of the library and plugings. This package has no dependency at all.

TinyMCE.JQuery : Holds the JQuery integration files for TinyMCE. This package depends on TinyMCE and JQuery packages.

TinyMCE.MVC : This package holds the ASP.NET MVC EditorTemplates for TinyMCE. This package depends on TinyMCE package.

TinyMCE.MVC.JQuery : Holds the ASP.NET MVC EditorTemplates for TinyMCE.JQuery. This package depends on TinyMCE.JQuery package.

TinyMCE.MVC.Sample : Holds a sample ASP.NET MVC mini Application (it is all just a model, a controller and a view) for TinyMCE. This package depends on TinyMCE.MVC package so it uses EditorTemplates to illustrate a sample.

TinyMCE.MVC.JQuery.Sample : This package holds a sample ASP.NET MVC mini Application (it is all just a model, a controller and a view) for TinyMCE.JQuery. This package depends on TinyMCE.MVC.JQuery package so it uses EditorTemplates to illustrate a sample.

How to get TinyMCE work on and ASP.NET MVC project

I would like set the boundaries here :

  • This will demonstrate the process of integrating TinyMCE to an ASP.NET MVC application.
  • I will use the JQuery one because it has more downloads on Nuget Smile
  • I will work with the TinyMCE.JQuery.MVC package to pull down all the TinyMCE stuff along with ASP.NET MVC EditorTemplates.

Always first thing to go is File > New Project > ASP.NET MVC 3 Web Application.

In order to make it more clear, I have created a very simple BlogPost model to work with. First, I am going to show you the way without TinyMCE then later we will bring it down through Nuget.

The model looks like as below :

    public class BlogPost {

        public string Title { get; set; }
        public DateTime PostedOn { get; set; }
        public string Tags { get; set; }
        public string Content { get; set; }

    }

Then I created a controller to create a new blog post (assume here this model is related to database). The controller is simple :

using System.Web.Mvc;
using TinyMCEJQueryMVCNuget.Models;

namespace TinyMCEJQueryMVCNuget.Controllers {

    public class BlogPostController : Controller {

        public ActionResult Create() {

            return View();
        }

        [HttpPost, ActionName("Create")]
        public ActionResult Create_post(BlogPost model) {

            ViewBag.HtmlContent = model.Content;

            return View(model);
        }

    }
}

It basically does noting. Just getting the model on the http post event and pushing it back to the view with a ViewBag property.

Here is what some portion of our view looks like :

@using (Html.BeginForm()) {
    
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>BlogPost</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PostedOn)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.PostedOn)
            @Html.ValidationMessageFor(model => model.PostedOn)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Tags)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Tags)
            @Html.ValidationMessageFor(model => model.Tags)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Content)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Content)
            @Html.ValidationMessageFor(model => model.Content)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>

        <p>
            Posted Content : @ViewBag.HtmlContent
        </p>

    </fieldset>
}

When we open it up, we will see nothing fancy there :

image

When we post it, we will get this result :

image

So, we got this baby working. Let’s improve it. What we need here is to give the blogger a real blogging experience. In order to do that, we need a text editor so that we could enter our content pretty easily.

First thing is to pull down the TinyMCE.JQuery.MVC package over the wire.

install-package

When you start installing the package, your solution will have a movement so don’t freak out Smile

image

imageSo now we have our package installed, we are ready to make some changes on our model. When you go to ~/Views/Shared/EditorTemplates folder on your solution, you will see that there is a cshtml file there called tinymce_jquery_full.cshtml. This partial view enables you to view your model property with TinyMCE editor.

I am not going to go inside this file and explain how to do this (however, it is pretty simple). It is entirely an another topic.

What I would like to point out here is this : if you are working with this package (TinyMCE.JQuery.MVC), you need to have JQuery referenced on your file. We have our JQuery referenced on our _Layout.cshtml file so we do not need to do anything else.

As I got the information from the project admins, TinyMCE can work with JQuery 1.4.3 and after. You don’t need to worry about that as well. Nuget will resolve the dependency without you knowing.

Change to Our Model

To get it work, we need to change our model as follows :

using System;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace TinyMCEJQueryMVCNuget.Models {

    public class BlogPost {

        public string Title { get; set; }
        public DateTime PostedOn { get; set; }
        public string Tags { get; set; }

        [UIHint("tinymce_jquery_full"), AllowHtml]
        public string Content { get; set; }

    }
}

What UIHint attribute does here is to tell the framework to use tinymce_jquery_full editor template instead of the default one. AllowHtml is also there to allow html string to pass from your browser to the server. Build you project and run it again and then you should see a page similar to following one:

image

If you are unable to see this when you run your application, this can be related to several things. First thing I would do is to check if the Content property is used with EditorFor instead of another Html Helpers :

        <div class="editor-label">
            @Html.LabelFor(model => model.Content)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Content)
            @Html.ValidationMessageFor(model => model.Content)
        </div>

The second thing would be a JavaScript error related to misconfiguration or a wrong library reverence. Check your browser console for any JavaScript errors for that.

Now when we post it back to server, we will get it back as :

image

Very nice. Html has been created for us behind the scenes.

It displays it as encoded html because we didn’t specify to view as raw html. In order to do that, just use @Html.Raw.

I hope this will help you to automate some portion of your project as well.

Tags