In my website I have a Facebook like chat page. I have implemented it with basic form submission method that will refresh the whole page when I post something. now I need to change it using ajax/jquery so that it should only refresh my partial views. I have written code for that and I changed my views by adding scripts.
My main Message view is like (sample):
@model myModel
<h2>
Message Board<small class="on-right"/>
</h2>
// Text box for Adding Message(post)
@Html.TextArea("Message", new { @placeholder = "Add a post", id = "Message" })
<input type="button" id="Post" value="Post"/>
// partial view that displays all the messages along with its comments
<div id="messagelist">
@{
Html.RenderPartial("_posts", Model.MessageList);
}
</div>
script for message page:
$('#Post').click(function () {
var url = "/MyController/Messages";
var Message = $("#Message").val();
$("#Message").val("");
$.post(url, { Message: Message }, function (data) {
$("#messagelist").html(data);
_post partial view:
@model IEnumerable<Model.MessageList>
//Foreach loop for displaying all the messages
@foreach (var item in Model)
{
<div >
@Html.DisplayFor(model => item.UserName)
@Html.DisplayFor(model => item.MessageText)
//Foreach loop for displaying all the comments related to each message
@foreach (var item1 in item.Comments)
{
@item1.UserName
@item1.MessageText
}
</div>
//partial view for adding comments each for messages
@Html.Partial("Comment", new ModelInstance { MessageId = item.MessageId })
}
Comment partial view (I am using ajax form submit):
@model ModelInstance
//form for submitting a message instance with parent message id for adding a comment to the parent message
@using (Ajax.BeginForm("Comment", "MyController", new AjaxOptions { UpdateTargetId = "messagelist" }))
{
@Html.AntiForgeryToken() @Html.ValidationSummary(true)
<div>
@Html.HiddenFor(modelItem => Model.MessageId)
@Html.TextBoxFor(modelItem => Model.CommentText, new { @placeholder = "leave a comment" })
<button class="btn-file" type="submit"></button>
</div>
}
Controller actions (sample):
public ActionResult Messages(string Message)
{
------------------------------
create messag object
---------------------
add to database
-------------------
fetch again for refreshing
------------------------
return PartialView("_posts", refreshed list);
}
public ActionResult Comment(StudiMessageDetails Comment)
{
------------------------------
create messag object
---------------------
add to database
-------------------
fetch again for refreshing
return PartialView("_posts", msgDetails);
}
Now the Posting message and posting comment is working perfectly. also when I post a message it only refreshes my main message view.
But when I post a comment it is giving me the refreshed partial view only. it is not getting bound to the 'div id=messagelist' and not giving me the full page. Can anybody tell where I am going wrong ? please help.
Your Ajax.BeginForm()
is replacing the contents of <div id="messagelist">
with the html from return PartialView("_posts", msgDetails);
. I suspect the model msgDetails
contains only the details of the comment's associated message so that's all your seeing.
I suggest to rethink your design, particularly the Messages()
method, which after saving the message is calling the database to get all messages and returning the complete list - you already have all the data on the page so this seems completely unnecessary and just degrades performance. You could simplify it with the following
Partial view (note the partial is for one message, not a collection)
@model Model.Message
<div class="message">
<div class=username">@Model.UserName</div>
<div class=messagetext">@Model.MessageText</div>
<div class="commentlist">
@foreach (var comment in Model.Comments)
{
<div class="comment">
<div class="username">@comment.UserName<div>
<div class="commenttext">@comment.MessageText<div>
</div>
}
</div>
<div>
@Html.TextBox("CommentText", new { placeholder = "Leave a comment", id = "" }) // remove the id attribute so its not invalid html
<button class="addcomment" data-id="@Model.MessageId">Add Comment</button>
</div>
</div>
Main View
@model myModel
...
@Html.TextArea("Message", new { placeholder = "Add a post" }) // no point adding the id - its already added for you
<input type="button" id="Post" value="Post" />
<div id="messagelist">
@foreach(var message in Model.MessageList)
{
@{ Html.RenderPartial("_posts", message); }
}
</div>
<div id="newmessage"> // style this as hidden
@{ Html.RenderPartial("_posts"); }
</div>
Scripts
// Add a model or ViewBag property for the current user name
var userName = JSON.parse('@Html.Raw(Json.Encode(ViewBag.UserName))');
$('#Post').click(function () {
var url = '@Url.Action("Message", "MyController")'; // dont hardcode!
var message = $('#Message').val();
$.post(url, { MessageText: message }, function (data) {
if(data) {
// clone the new message, update message id and add to DOM
var html = $('#newmessage').clone();
message.children('.username').text(userName);
message.children('.messagetext').text(message);
message.children('.newcomment').children('button').data('id', data);
$('#messagelist').perpend(html); // add at top of list
$('#Message').val(''); // clear message text
} else {
// something went wrong
}
});
});
$('.addcomment').click(function() {
var url = '@Url.Action("Comment", "MyController")';
var comment = $(this).prev('input');
var messageID = $(this).data('id');
var list = $(this).closest('.message').children('.commentlist');
$.post(url, { MessageID: messageID, CommentText comment.val() }, function (data) {
if (data) {
// add message
var html = $('<div><div>').addClass('comment');
html.append($('<div><div>').addClass('username').text(userName));
html.append($('<div><div>').addClass('commenttext').text(commentText));
list.append(html); // add to end of existing comments
comment.val(''); // clear existing text
} else {
// something went wrong
}
});
});
Controller
[HttpPost]
public ActionResult Message(string MessageText)
{
// create new message object and save to database
int ID = // the ID of the new message
return Json(ID); // if exception, then return null;
}
[HttpPost]
public ActionResult Comment(int MessageID, string CommentText)
{
// create new comment object and save to database
return Json(true); // if exception, then return null;
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments