Introduction
What is CKEditor?
CkEditor is a ready-for-use HTML text editor, which is designed to simplify Web content creation.The best Browser-based rich text editors are usually called WYSIWYG editors. It is very easy to use in any type of project.
In this article, we are going to learn how to implement CKEditor in ASP.NET MVC. In this example, we will cover how to use it, how to post a simple blog or article & how to retrive the data from the database.
Here, I am going to use just three tables as Technology (used to retrive Id of technology), Users (used to retrive the users information), and UserPost (used to retrive the article details).
Step 1
First, I am going to create tables by using the script given below.
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- CREATE TABLE [dbo].[Technology](
- [Id] [bigint] IDENTITY(1,1) NOT NULL,
- [Technology] [nvarchar](500) NULL,
- CONSTRAINT [PK_Technology] PRIMARY KEY CLUSTERED
- (
- [Id] ASC
- )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- ) ON [PRIMARY]
- GO
-
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- CREATE TABLE [dbo].[Users](
- [Id] [bigint] IDENTITY(1,1) NOT NULL,
- [FirstName] [nvarchar](100) NOT NULL,
- [LastName] [nvarchar](100) NOT NULL,
- [Email] [nvarchar](50) NOT NULL,
- [Mobile] [nvarchar](50) NULL,
- CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
- (
- [Id] ASC
- )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- ) ON [PRIMARY]
- GO
-
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- CREATE TABLE [dbo].[UserPost](
- [Id] [bigint] IDENTITY(1,1) NOT NULL,
- [UserId] [bigint] NOT NULL,
- [TechnologyId] [bigint] NOT NULL,
- [Title] [nvarchar](200) NOT NULL,
- [Description] [nvarchar](500) NULL,
- [Contents] [nvarchar](max) NOT NULL,
- [CreationDate] [datetime] NULL,
- CONSTRAINT [PK_UserPost] PRIMARY KEY CLUSTERED
- (
- [Id] ASC
- )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- ) ON [PRIMARY]
- GO
Step 2
Create an empty MVC project by using Visual Studio. Download the latest version CKEditor from
here & add the folder into the Application.
Step 3
I am going to use font-awesome css, bootstrap css, bootstrap js & ckeditor.js. Add all the references into a BundleConfig file, as given below.
- public static void RegisterBundles(BundleCollection bundles)
- {
- bundles.Add(new ScriptBundle("~/bundles/headerJS").Include(
- "~/Scripts/External/jquery.min.js",
- "~/Scripts/External/bootstrap.min.js",
- "~/Scripts/ckeditor/ckeditor.js",
- "~/Scripts/ckeditor/samples/js/sample.js"
- ));
-
- bundles.Add(new StyleBundle("~/Content/css").Include(
- "~/Content/css/bootstrap.min.css",
- "~/Content/css/custom.css",
- "~/Content/css/font-awesome.css",
- "~/images/favico.ico",
- "~/Content/css/bootstrap-datetimepicker.min.css"
- ));
-
- bundles.Add(new ScriptBundle("~/bundles/footer").Include(
- "~/Scripts/External/jquery.min.js",
- "~/Scripts/External/bootstrap.min.js",
- "~/Scripts/External/bootstrap-datepicker.js",
- "~/Scripts/External/bootstrap-datetimepicker.min.js",
- "~/Scripts/Custom/Shared/Layout.js"
- ));
-
- }
Now, add the reference of above headerJS, CSS, footer into a _Layout.cstml.
Step 4
Create a view model ContributeViewModel, which conatins some properties, as given below.
- public class ContributeViewModel
- {
- public long UserId { get; set; }
- public string TechnologyId { get; set; }
- public string Title { get; set; }
- public DateTime Date { get; set; }
- public string Description { get; set; }
- public string Contents { get; set; }
- }
Step 5
Now, create controller Contribute, where action method Contribute() will return a View, which will take user inputs like article title, article description, technology name, and Content by using an editor. For technology names, we are using checkboxes.
On submit button we are going to save these data into a database by using repository pattern. Read my article for reference of
CRUD operation using repository pattern unit of work,
- @model CoderFunda.ViewModel.Contribute.ContributeViewModel
- <div class="mainContent">
- <div class="col-sm-12"><span class="pageText1">Contribute your </span><span class="pageText2">Blog</span></div>
- <div class="col-sm-12">
- <div class="col-sm-12 col-md-6">
- <dl class="dl-horizontal dlCustom">
- <dt>@Html.LabelFor(x => x.Title) :</dt>
- <dd>
- @Html.TextBoxFor(x => x.Title, new { @class = "form-control", @placeholder = "Enter Title" })
- </dd>
- <dt>@Html.LabelFor(x => x.TechnologyId,"Techonlogy") :</dt>
- <dd>
- <div class="checkbox customCheckbox" id="chkTech">
- <label>
- <input type="checkbox" name="blankCheckbox" id="blankCheckbox" value="Asp.NET">ASP.NET
- </label>
- <label>
- <input type="checkbox" name="blankCheckbox" id="blankCheckbox" value="C#">C#
- </label>
- <label>
- <input type="checkbox" name="blankCheckbox" id="blankCheckbox" value="MVC">MVC
- </label>
- <label>
- <input type="checkbox" name="blankCheckbox" id="blankCheckbox" value="SQL">SQL
- </label>
- <label>
- <input type="checkbox" name="blankCheckbox" id="blankCheckbox" value="Other">Other
- </label>
- </div>
- <label id="lblContributeTechErrorMsg" style="display:none;color:red"></label>
- </dd>
- </dl>
- </div>
- <div class="col-sm-12 col-md-6">
- <dl class="dl-horizontal dlCustom">
- <dt>@Html.LabelFor(x => x.Description) :</dt>
- <dd>@Html.TextAreaFor(x => x.Description, new { @class = "form-control", @placeholder = "Description" })</dd>
- </dl>
- </div>
- <div class="col-sm-12">
- <dl class="dl-horizontal">
- <dt>@Html.LabelFor(x => x.Contents) :</dt>
- <dd>
- <div id="editor">
- </div>
- <label id="lblContributeContentErrorMsg" style="display:none;color:red"></label>
- </dd>
- </dl>
- <div class="text-center">
- <a href="@Url.Action("Home","Account")" class="customSubmit">BACK</a>
- <input type="button" class="customPurple btnSubmit" id="btnSubmit" value="SUBMIT">
- </div>
- </div>
- </div>
- <div class="clearfix"></div>
- </div>
Now, write the code on submit button, click event, which will execute an action method using AJAX call in JavaScript, as given below.
- $('.btnSubmit').click(function () {
- if (ValidateContribute()) {
- var Title = $("#Title").val();
- var TechnologyId = "";
- $('input[name="blankCheckbox"]:checked').each(function () {
- if (this.value != '')
- TechnologyId = this.value;
- });
-
- var Description = $("#Description").val();
- var Content = CKEDITOR.instances['editor'].getData();
- var ContributeModel = {
- Title: Title,
- TechnologyId: TechnologyId,
- Description: Description,
- Contents: Content,
- }
-
- $.ajax({
- url: 'Contribute/Contribute',
- type: 'POST',
- data: JSON.stringify(ContributeModel),
- contentType: 'application/json;charset=utf-8',
- success: function (data) {
- if (data.success == true) {
- window.location.href = "../Account/Home";
- }
- else if (data.success == false) {
- alert("Error occured..!!")
- }
- },
- error: function () {
- alert("Error occured..!!");
- },
- });
- }
- });
Step 6
Create an action method in contribute controller, which will insert the data into a databse, if the data is inserted successfully, it will return JSON result as true, else it returns false. In this action method from GetLoggedInUserId() method, we get the current user id who is logged into an Application.
- [HttpPost]
- public ActionResult Contribute(ContributeViewModel ContributeViewModel)
- {
- try
- {
- var technologyId = UnitoffWork.TechnologyRepository.GetSingle(x => x.Technology1 == ContributeViewModel.TechnologyId).Id;
- int userId = Helper.UserHelper.GetLoggedInUserId();
- UserPost userPost = new UserPost();
- userPost.UserId = userId;
- userPost.TechnologyId = technologyId;
- userPost.Title = ContributeViewModel.Title;
- userPost.Description = ContributeViewModel.Description;
- userPost.Contents = ContributeViewModel.Contents;
- userPost.CreationDate = DateTime.UtcNow;
- UnitoffWork.UserPostRepository.Insert(userPost);
- UnitoffWork.Save();
- return Json(new { success = true }, JsonRequestBehavior.AllowGet);
- }
- catch
- {
- return Json(new { success = false }, JsonRequestBehavior.AllowGet);
- }
- }
Step 7
Create a View Model named as ArticleViewModel, as given below.
- public class ArticleViewModel
- {
- public ArticleViewModel(UserPost userPost, IEnumerable<PostLike> postLikes, List<UserComment> userComment)
- {
- Image = userPost.User.UserDetails.Count == 0 ? string.Empty : userPost.User.UserDetails.FirstOrDefault().Image == null ? string.Empty : userPost.User.UserDetails.FirstOrDefault().Image;
- FirstName = userPost.User.FirstName;
- LastName = userPost.User.LastName;
- Title = userPost.Title;
- Description = userPost.Description;
- PostId = userPost.Id;
- UserId = userPost.UserId;
- CreationDate = userPost.CreationDate.Value;
- Contents = userPost.Contents;
- Technology = userPost.Technology.Technology1;
- }
-
- public string Image { get; set; }
- public long PostId { get; set; }
- public long UserId { get; set; }
- public string Title { get; set; }
- public string Description { get; set; }
- public string Contents { get; set; }
- public string Technology { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public DateTime CreationDate { get; set; }
- }
-
In an Index method of controller, I am going to show a list of all the articles with Title, Description, Author Nam and Date etc. If we click on any record (the user would like to read any article from this list), then it will redirect to another action, which will show an article in the detail. For this, I have created an action method, as shown below.
- public ActionResult Article(long Id)
- {
- int userId = Helper.UserHelper.GetLoggedInUserId();
- Expression<Func<UserPost, object>> parames1 = v => v.User;
- Expression<Func<UserPost, object>> parames2 = v => v.User.UserDetails;
- Expression<Func<UserPost, object>> parames3 = v => v.PostLikes;
- Expression<Func<UserPost, object>> parames4 = v => v.UserComments;
- Expression<Func<UserPost, object>>[] paramesArray = new Expression<Func<UserPost, object>>[] { parames1, parames2, parames3, parames4 };
- var userPost = UnitoffWork.UserPostRepository.GetAllSingleTracking(x => x.Id == Id, navigationProperties: paramesArray).Select(u => new ArticleViewModel(u, u.PostLikes.Where(x => x.UserId == userId && x.PostId == Id), u.UserComments.ToList()));
- ViewBag.Techonology = userPost.FirstOrDefault().Technology;
- return View(userPost);
- }
Note
Here, I have used two more tables PostLikes & UserComments, which are used to get the count of likes & comment details. In the above action method, I used LINQ expression, using parameter array to get the record from the database on the basis of PostId.
Step 8
Now, create a View to show an article details for the above action, as given.
Step 9
Now, run the Application.
Access Contribute action method from the URL & you will see the view given below in which the user can enter the details, as given below.
Click Submit button. Now, open Index method on which you will get the article list, as given below.
If a user would like to read any article from this list, click on any article and the result is given below
Summary
In this article, you learned the basics of how to implement CKEditor in ASP.NET MVC.