5

Learning mvc and I am trying to implement a page with 3 fields Name-Surname-Description So in my learning example I am loading employees and I should be able to create and edit them.

The description should use CKEditor .

  • I can load employees
  • I can save them

However I cannot seem to be able to save the description,such as whatever the user types in the description field. I have seen few examples on the net but none with a solution to download,as I cannot seem to put together. I have found this guy with a cool html helper but cannot seem to be able to put an example together http://www.andrewbarber.com/post/CKEditor-Html-Helpers-ASPNET-MVC-Razor-Views.aspx

The problems are :

  1. How do you get the value that is typed inside the ckEditor.
  2. In my viewModel the description is null all the time
  3. the ckEditor slow down the creation of the page quite a lot.How can I make it faster? I dont need all the options.
  4. Is there an example using mvc3 out there that I can use as a template.

I have done all the plumbing as follows:

Create.chtml

            @model MvcApplicationCKEditorIntegration.Models.EmployeeViewModel
        @{
            ViewBag.Title = "Create";
        }
        <h2>
            Create</h2>
        <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>
        @using (Html.BeginForm())
        {
            @Html.ValidationSummary(true)
            <fieldset>
                <legend>EmployeeViewModel</legend>
                <div class="editor-label">
                    @Html.LabelFor(model => model.FirstName)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.FirstName)
                    @Html.ValidationMessageFor(model => model.FirstName)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.LastName)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.LastName)
                    @Html.ValidationMessageFor(model => model.LastName)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.Email)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.Email)
                    @Html.ValidationMessageFor(model => model.Email)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.PhotoPath)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.PhotoPath)
                    @Html.ValidationMessageFor(model => model.PhotoPath)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(model => model.Description)
                </div>
                <div class="editor-field">            
                    <textarea class="ckeditor" id="ckeditor" rows="10"></textarea>            
                </div>
                <p>
                    <input type="submit" value="Create" />
                </p>
            </fieldset>
        }
        <div>
            @Html.ActionLink("Back to List", "Index")
        </div>
         <script type="text/javascript" src="../../ckeditor/ckeditor.js"></script>

EmployeeController

         public class EmployeeController : Controller
            {
                public ActionResult Index()
                {
                    var employeeRepository=new EmployeeRepository();
                    var employees = employeeRepository.GetAll();
                    var employeeList = employees.Select(employee => new EmployeeViewModel
                                                                        {
                                                                            EmployeeId = employee.EmployeeId,
                                                                            FirstName = employee.FirstName,
                                                                            LastName = employee.LastName,
                                                                            PhotoPath = employee.PhotoPath,
                                                                            Email = employee.Email,
                                                                            Description = employee.Description
                                                                        }).ToList();

                    return View(employeeList);
                }

                public ActionResult Create()
                {

                    return View(new EmployeeViewModel());
                } 

                [HttpPost]
                public ActionResult Create(EmployeeViewModel vm)
                {
                   if(ModelState.IsValid)
                   {
                       var employeeRepository=new EmployeeRepository();
                       var emp=new Employee
                                        {
                                            FirstName = vm.FirstName,
                                            LastName = vm.LastName,
                                            Description = vm.Description,
                                            Email = vm.Email,
                                            PhotoPath = vm.PhotoPath
                                        };
                       employeeRepository.Insert(emp);
                       return RedirectToAction("Index");

                   }
                    return View(vm);
                }




            }
        }

Thanks for any suggestions!!!

EDITED EXAMPLE USING CKEditor helper

    @using MvcApplicationCKEditorIntegration.Helpers
    @model MvcApplicationCKEditorIntegration.Models.EmployeeViewModel
    @{
        ViewBag.Title = "Create";
    }
    <h2>
        Create</h2>
    <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>
    @Html.CKEditorHeaderScripts()
    @using (Html.BeginForm())
    {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>EmployeeViewModel</legend>
            <div class="editor-label">
                @Html.LabelFor(model => model.FirstName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.FirstName)
                @Html.ValidationMessageFor(model => model.FirstName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.LastName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.LastName)
                @Html.ValidationMessageFor(model => model.LastName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Email)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Email)
                @Html.ValidationMessageFor(model => model.Email)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.PhotoPath)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.PhotoPath)
                @Html.ValidationMessageFor(model => model.PhotoPath)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.Description)
            </div>
                @Html.CKEditorFor(model=>model.Description)
            <p>
              <input type="submit" value="Create" onclick="@Html.CKEditorSubmitButtonUpdateFunction()" />
            </p>
        </fieldset>
    }
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
     <script type="text/javascript" src="../../ckeditor/ckeditor.js"></script>
Cœur
  • 37,241
  • 25
  • 195
  • 267
user712923
  • 1,515
  • 2
  • 16
  • 19

2 Answers2

7

You aren't actually using the CKEditor helper at all like is described on that blog page (which is my own blog)

The purpose of that helper is that once you have included the code correctly into your project, you can simply do this:

@Html.CKEditorFor(model=>model.Description)

However, you seem to simply be creating a plain-old text area and working with it 'manually' after that. There isn't anything to bind it to your property, as would exist if you had used the helper described in that post.

Also note that you aren't using the code that Updates the text area behind the scenes; so if your model has Required set on the Description field, you will get a client-side validation error the first time you submit an otherwise properly-configured CKEditorFor() This isn't unique to my helper; any bound property that is 'required' needs the bit of Javascript that is mentioned in that blog post, too. I do it as an onclick off the submit button, but you can run that same code anywhere. You just need to include it in the page, which you haven't done.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
  • Hi,thanks for your reply.I have not used your code above because I could not understand how you save the contents of the ckeditor,it definetely looks good.I am going to try now.Do you have a solution I can download? – user712923 Jun 13 '11 at 18:29
  • You don't do anything special to 'save' the contents; It works just like any other bound property. – Andrew Barber Jun 13 '11 at 18:31
  • is @HtmlCKEditorFor doing all the work and saving it to the description field? – user712923 Jun 13 '11 at 18:31
  • It does exactly what the other helpers, like `Html.TextareaFor()` or `Html.EditorFor()` do. It just does it with a CKEditor instance. – Andrew Barber Jun 13 '11 at 18:32
  • Just be sure you follow the steps for using the helper; There are three helpers there; one for the 'plumbing', one for the CKEditor itself, and one to call the 'update' on the client-side. Do those three, and it binds automatically. – Andrew Barber Jun 13 '11 at 18:38
  • @Andrew really appreciate your help,going through your blog and following it through.The thing is I am learning asp.net mvc at the same time so it makes a bit trickier. – user712923 Jun 13 '11 at 19:04
  • @andrew i have updated my question I get an error "A potentially dangerous Request.Form value was detected from the client" .Really appreciate if you could help.Spent all day on it.thanks – user712923 Jun 13 '11 at 19:17
  • For that part, you'll need either to mark the property in question as allowing HTML, or decorate the controller method not to perform request validation. The Attribute names escape me at the moment. – Andrew Barber Jun 13 '11 at 20:07
  • @Andrew Barber: Hi! Could you tell the URL of your blog post? Thanks. – Miguel Angelo Sep 09 '11 at 13:37
  • Already figured out... it is in the question. But I did't see it! =) – Miguel Angelo Sep 09 '11 at 13:42
3

You might want to try setting the name attribute of the textarea to "Description"

so:

<div class="editor-field">            
    <textarea class="ckeditor" id="ckeditor" rows="10" name="Description"></textarea>
</div>

if that doesn't work then you might have to use javascript to get the value of what's in the editor and set it in a hidden field before the post.

jeffsaracco
  • 1,259
  • 12
  • 21