views:

129

answers:

5

I am trying to add a simple comments/message box to a web page. When the user enters the comment and hits submit, I would like to save this message to the database and add the comment to the list displayed on the page, without refreshing the entire page.

However, I am not sure of the best way to do that these days. I am using ASP.NET MVC 2. I have been trying to read up on using JQuery for this type of functionality, but I am having problems getting a full picture of the correct approach that isn't also out of date (i.e. it is using an preview version of MVC 1 or older version of JQuery).

I can either find snippets of different pieces without the information of how they work together, or the information appears to be quite dated and no longer valid.

Can someone point me in the right direction for something like this?

Ideally, I am looking for a simple example of the JQuery code, a snippet of any key differences in an HTML form from a normal post method, and the basic method used in the MVC Controller. I need something to help the lightbulb of understanding to turn on. :)

Any help would be greatly appreciated!!

+1  A: 

There's a helper method that allows you to create an Ajax-enabled form. This article should help you get started:

http://msdn.microsoft.com/en-us/library/dd381533.aspx

Rob Windsor
eeek MicrosoftAjax....even their own devs have run for the hills from it
redsquare
+2  A: 

You should check out the jQuery Form plugin. You can POST the comment to your controller with ajax, persist the comment, and return a bool w/ JSON. In jquery, define a success handler (see the examples tab) and render the comment at the bottom of your page. You can also check out javascript templates (here is Microsoft's proposed implementation) if you want some formatting control over how to render the comment (without cluttering your JS).

Ryan
+4  A: 

I usually do something like

<form action="/controller/action" method="post" id="formID">
</form>

$("#formID").submit(function(){
  var form = $(this);
  $.post(form.attr("href"), form.serialize(), function(data){/*manipulate page*/}, "text")
  return false;
});

The MVC controller is just like it would be if you weren't using Ajax, except you probably return a different view--one that doesn't contain a full page of markup, depending on what data you want to get from the server. You might not need to return any data at all--your "manipulate page" code might have all the info it needs already.

joelt
Thanks. This is working great for me. Very simple and clean.
Swoop
A: 

For your comment system you can try a mechanism like this:

If you have a model like this

public class Message
{
    public int Id {get;set;}
    public string Text {get;set;}
    public Comment[] Comments {get;set;}
}

public class Comment
{
    public int Id {get;set;}
    public string Text {get;set;}
}

In your messageview

Message: 

<%: Model.Text%>
<div id="divComments">
    <% Html.RenderPartial("Comment",Model.Comments); %>
</div>
<% using(Ajax.BeginForm("AddComment", new{id=Model.Id}, new AjaxOptions{HttpMethod="POST",UpdatetargetId ="divComments" }))
   { %>
       <%: Html.TextArea("comment") %> 
       <input type="submit" value="Add comment" />      
<% } %>

In your comment partial view

<% foreach(var comment in Model) { %>
    <li><%: comment.Text %>
<%}

In your controller

public MessageController: Controller
{
    public ActionResult Message(int id)
    {
        using(MessageRepository messageRepo = new MessageRepository())
        {
            return View(messageRepo.SelectById(id));
        }
    }

    public ActionResult AddComment([Bind(Prefix="id")]int messageId, string comment)
    {
        using(MessageRepository messageRepo = new MessageRepository())
        {
            messageRepo.InsertComment(messageId,comment);

            if(this.Request.IsAjaxRequest())
                return View(messageRepo.SelectById(messageId).Comments));
            return RedirectToAction("Message", new{id=messageId});
        }
    }
}
Gregoire
A: 

I asked similar question some time ago.

Arnis L.