Using CKEditor with NET MVC Razor

At work, we have a project coming up that requires content to be constructed by the user. For content entry, we will implement a WYSIWYG editor to give users a familiar set of tools to interact with. There are a plethora of WYSIWYG editors available on the web our chosen one is CKEditor
The CKEditor offers a rich tool set that can be tailored to meet the requirements for content entry. CKEditor comes with well written documentation on a well put together website which is a huge selling point.

Getting Started

To get started, and throw in a quick plug, I am going to use the default .NET MVC web project template to give us a head start. All you have to do is create the default project in visual studio. We have our project, the next step is to download the CKEditor. The current version at the time of writing is 4.7. Once downloaded, unzip the contents (should be a single directory called “ckeditor”) and copy to the root directory in the website.

Implementation

Lets just get the CKEditor loaded on a page in the website. Firstly the JS files for CKEditor need to be included on the web page, include the required JS files into the master page (or just onto the web page the ckeditor is required on) of the project for the moment as shown below.

<script src="ckeditor/ckeditor.js"></script>
<script src="ckeditor/adapters/jquery.js"></script>

ckeditor.js is the main JS file that holds all the code that makes up the CKEditor. I always utilise the JQuery framework to assist with JS coding on a website as it just makes things a lot easier. So in order to get the CKEditor working with JQuery the jquery.js adapter is required. In order to get the editor working, some JS is required in order to convert a DOM element into the CKEditor. You can use a div, p or textarea, I recommend using a textarea because the textarea is a reasonable fallback when the browser doesn’t have JS enabled.

<textarea id="my-textarea"></textarea>

Above is the textarea I have added to the web page so it can be converted into a ckeditor. I never use inline JS, so I have added the code below to the main external JS file (js/mylibs/boilerplate.js). The code is basically saying when the document had loaded, convert the specified selector into a ckeditor. If the selector doesn’t match any elements in the DOM, then nothing happens.

$(function () {
    $('#my-textarea').ckeditor();
});

Provided you have everything in place correctly, you should see something resembling the screenshot below. The textarea has been converted into a CKEditor offering a rich set of content formatting tools. Super!

installation

Sending Content to the Server

So we have our CKEditor on the page, next step is to send the content added by the user to the server so it can be stored or whatever needs to be done with it. With the .NET MVC framework, a process known as model binding is used to send data from the client to a method in a controller on the server. Model binding will take the form values or query string values and try to set those values on the properties of an object instance (the view model), that object is then passed to a method on a controller.

Lets create a view model that will hold the content that is created by the user via the ckeditor.

namespace CKEditorExample.ViewModels.Content
{
    public class ContentViewModel
    {
        public string Text { get; set; }
    }
}

The Text property will have the user content set on it automatically by MVC 3 before it is passed into a controller method. Next step is to modify the razor view page that shows the ckeditor to tell MVC to bind the textarea to the view model that we just created. Razor provides lots of useful helper methods, particular to do with setting up HTML form elements for model binding. The code for the razor view for the content submission is shown below.

@model CKEditorExample.ViewModels.Content.ContentViewModel

@{
    ViewBag.Title = "Content Entry";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Content Input</h2>

<form method="post" action="/Content/Submit">
@Html.TextAreaFor(x => x.Text)

<p><input type="submit" value="Submit" /></p>
</form>

At the top on the view the model is declared, so now the textarea can be binded to a property on our model. As you can see we are using the razor Html.TextAreaFor to bind a textarea to the Text property on our view model, so when the form is submitted the value in the textarea at the time of submission should be set on the Text property. You may notice that the form is being submitted to /Content/Submit, I have created another razor view / controller method to handle the form submission and display a web page showing the content from the ckeditor that was sent to the server. The ContentController has two methods now, Index which returns a view that displays the form, and Submit that takes care of the form submission.

using System;
using System.Web.Mvc;
using CKEditorExample.ViewModels.Content;

namespace CKEditorExample.Controllers
{
    public class ContentController : Controller
    {
        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Submit(ContentViewModel model)
        {
            ViewBag.Text = model.Text;
            return View();
        }
    }
}

Above the Submit method shown in the controller above are a couple of attributes. HttpPost stipulates that only POST requests are accepted. The second attribute ValidateInput is telling MVC not to validate the user input, without this when submitting the form you will see the error message shown below.

[HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client…” exception is thrown because there is HTML being sent to the server. The [ValidateInput(false)] attribute will prevent this error happening, however we are opening ourselves up to a security vulnerability. So, to handle this you can encode the HTML before it is saved a database, or run checks on the content to ensure there isn’t any malicious HTML, such as script tags for JS code blocks. This will allow all our properties on the model to have HTML passed to the server, if your not keen for that you can add [AllowHtml] above the property that is permitted to accept HTML, thus removing the need for the [ValidateInput(false)] attribute.

So submitting the form in the state as shown below.

content_submission

Will result in the web page shown below.

content_submitted

As you can see the HTML that is created by the CKEditor has been sent to the server and is now displayed in the response. This demonstrates creating a CKEditor and sending the content entered by a user to the server.

Advertisements

Are you an analytical thinker?

Are you an analytical thinker? i was in a meeting the other day and after the meeting, one of the executives completed me as being “analytical thinker”. I didn’t know what to say thn a simple “Thank you”.

But when i got home that evening, i began to research what it meant to be an analytical thinker. this is the result of my research.

1: Information addict

Analytical thinkers just can’t get enough information. They devour Web pages about everything from the weather to the latest high tech gadget. They are gluttons for online discussions, but they’re more often lurkers than participants. They have voracious appetites for facts and figures of any kind. They head straight for the specs page when shopping for anything more technologically sophisticated than an alarm clock. The siren call of the Internet cries out, “Step right up to the buffet — all the information you can eat for one low price”.

I can understand how this behavior might be really annoying to a family member. Please understand it is natural for humans to seek after information — just not as compulsively as the analytical thinker seeks it. Come to think of it, this propensity for information binging might explain the swelled heads of a few IT personnel I have encountered over the years.

2: Vacillatory

Most people see only one side of a controversial issue. Not the analytical thinker. To him, every issue has pros and cons. To him, the glass can be both half full and half empty at the same time. The analytical will inevitably be known as Dr. Doom to some and the eternal optimist to others. Being both a pessimist and an optimist gives the impression to friends that the analytical is wishy-washy, assuming he has any friends.

3: Indecisive

Because the analytical likes to gather as many facts as possible before making an informed decision, he may be perceived by others as being indecisive. The phrase “lead or get off the pot” could apply to the analytical manager who is so busy gathering information that he often overlooks the value of a quick, definitive decision.

4: Insensitive

I was once explaining parts of a client/server system to Mark, one of our mainframe guys. I pointed to the screen and said something like, “As you can see right here…” There was only one problem with that gesture and statement: Mark was totally blind. I was so embarrassed that I froze and said nothing. Had Mark been able to see he would have seen a flushed face with perspiration beginning to form at the hairline. This kind of “foot in mouth” behavior isn’t that unusual for an analytical. I now realize that I should have had the courtesy to acknowledge my gaffe and apologize, but words failed me at the time. It may be more than 15 years late, but Mark please accept this apology for my insensitivity.

5: Habitual

“You want me to do what– skip lunch? Are you kidding?” Missing lunch to complete some inane pet project for my manager was physically upsetting. My blood pressure rose. My stress hormones rose. Yes, I was angry. Stand well clear of a hypoglycemic logician when sustenance has been withheld!

It can be hard to for analyticals to break their habits. They prefer the predictable, daily routine and are resistant to change. A left-brain thinker may lack motivation when starting a new project, but once started, they are like a persistent bulldog working to complete the project. It’s not that they can’t accept change; analyticals would just prefer it not intrude upon their comfort zone

6: Socially inept

I once told a young lady who I was friends with that she was overweight. Well, she did ask. I never got a chance to tell her that it, the weight, was in all the right places. Analyticals take matters literally — too literally. It is not the intention of the analytical to be critical but rather to provide an honest assessment, although it is almost always perceived as criticism. Unfortunately for the well-intentioned analytical, people don’t like an “honest assessment” of their looks, behavior, general hygiene, or body fat index. The irony is that these socially oblivious, albeit honest assessors usually don’t take criticism well themselves.

7: Skeptical

“You can fool some of the people all of the time, and all of the people some of the time, but you cannot fool all of the people all of the time.” Abraham Lincoln is supposed to have said this. Politicians, of all people, know that it’s hard to fool a logical thinker. If you want to sell anything to left-brain thinkers, you’d better explain why they need it. An analytical needs facts, not feelings or persuasive platitudes.

If you are a manager trying to convince a team of programmers that a project can be completed two months ahead of schedule, you’d better come armed with facts to support how such a miracle can be achieved. The pushback you are almost certain to receive is a predictable response from the cynical analytical.

8: Poor marketers

The very thing that makes analyticals good product reviewers is what makes them poor at the sales pitch. They thoroughly and accurately note both the positive and negative attributes of the product they are reviewing. One of the important skills needed to land a job is self promotion. While others may exaggerate their positive traits, the analytical person does not. Stating that you prefer working with computers rather than people may be an honest and unbiased analysis but is perceived as a black mark by the interviewer. I know I am weak at promoting myself. I have worked at improving my marketing skills. But if I could get away with it, I would hire a marketing specialist for my next job interview!

9: Politically incorrect

When I write I try to address the very real possibility that there might actually be personages of the female persuasion reading my musings. I try to throw in at least one” he or she” in recognition of this. The truth is that I put readability ahead of political correctness. Right or wrong, I believe that including references to both genders is tedious for the patient reader. So ladies, please forgive my political incorrectness. I am indeed honored to have you as a guest.

10: Loners

We analyticals would rather spend time alone with a good book or movie than with people. It’s not that we dislike people, per se. We just find them boring, uninspiring, and mundane. To the all seeing and all knowing analytical, the average person is like the emperor in the story “The Emperor’s New Clothes“– there’s nothing there. I mean, really, when was the last time you found someone who wanted to discuss the theory of relativity or the law of diminishing marginal returns?
The bottom line

Sure, the analytical thinker can appear to be cold, insensitive, and logical, somewhat akin to the personality of Mr. Spock, but the world needs these attributes. After all, it would take only one analytical lemming to save the others from mythological disaster by telling his friends, “Hey guys, I don’t think this cliff diving idea is so good after all.”

Every curse is a blessing in disguise. Because analytical thinkers like information in tabular format, I give you the 10 blessings for the aforementioned curses:

Each curse can be viewed as a blessing.

Give your favorite analytical person a break the next time you want to scream at him. The characteristics you find so annoying do have positive benefits to society.

While these traits may apply in part or in whole to me and other analytical people, we are all complex creatures. It is not my intention to imply that such a simplistic view applies to all analytical thinkers.