How can i append partial view result in to div? - asp.net-mvc-3

I have a div id="comments"
in this i am displaying 10 comments at a time.
when user want to view next comments, i have provided one button that will collect next 10 comments. for this next comment i have created partial view to display remaining 10 comments into another div morecomments.
My problem is when i am displaying next 10 comments its showing me all 20 comments but whole comments div is getting refreshed, how to prevent loading whole comment div.
My code is here:
<div id="comments">
// Display Comments
<div id="moreButton">
<input type="submit" id="more" class="morerecords" value="More Post" />
</div>
</div>
<div id="morecomments">
</div>
Jquery::
$('.morerecords').livequery("click", function (e) {
// alert("Showing more records...");
var next = 10;
var url = '#Url.Action("ViewMore", "Home")'
var data = { nextrecord: next};
$.ajax({
type: "POST",
url: url,
data: data,
success: function (result) {
$("#morecomments").html(result);
}
});
});
In above code i am getting 10 comments first time and when user click on More Post button it will show me above 10 comments plus next 10 comments. but whole div is getting refreshed.
What changes i have to do so that i can get user comments without affecting previous showing comments?
Suppose user having 50-60 post in his section then all comments should be display 10+ on More Post button click and so on...
How can i do that?

You need to filter your records and put it in comment div... Your code should like this:
$('.morerecords').livequery("click", function (e) {
var next = 10;
var url = '#Url.Action("ViewMore", "Home")'
var data = { nextrecord: next};
var older_records = $("#morecomments").text();
$.("comments").append(older_records); //When you will get next record data, older data will be filled in comment div.
$.ajax({
type: "POST",
url: url,
data: data,
success: function (result) {
$("#morecomments").html(result);
}
});
});

The error is in:
$("#morecomments").html(result);
.html("somevalue") deletes the content, then fills it with whatever parameter you supplied.
Try doing this:
$("#morecomments").html($("#morecomments").html() + result);
or even easier:
$("#morecomments").append(result);
I know this works if you're passing strings, and a partial view is basically a html string. I don't know if there will be any conflict issues with the tags brought along by partial views.
Either way, this is the easiest way to add to an element rather than write over it.

If you are using Entity Framework (which you do), you need to use something like below:
public JsonResult Get(
//this is basically giving how many times you get the comments before
//for example, if you get only one portion of the comments, this should be 1
//if this is the first time, this should be 0
int pageIndex,
//how many entiries you are getting
int pageSize) {
IEnumerable<Foo> list = _context.Foos;
list.Skip(PageIndex * PageSize).Take(pageSize);
if(list.Count() < 1) {
//do something here, there is no source
}
return Json(list);
}
This is returning Json though but you will get the idea. you can modify this based on your needs.
You can use this way for pagination as well. Here is a helper for that:
https://bitbucket.org/tugberk/tugberkug.mvc/src/69ef9e1f1670/TugberkUg.MVC/Helpers/PaginatedList.cs

Related

How to initialize select2 that uses a query for data when I already have a value

I have a view with 2 select boxes which are "cascading". A user selects a value from the first box and the second is populated based on the new value. This is done with Select2's query option, and works fine on the first load of the page. However, when I post the page and then render it, both select boxes already have values (say A and 1), but the dependent checkbox is not initialized. I have done a few things with initSelection and it didn't help much, sometimes just getting me into an loop.
What I am trying to do is this:
Link the two boxes
When the first box changes, reset the data in the second box and clear the value
When the page is re-drawn, and a value has already been selected (e.g. response to POST)
Go to server and get the data
Show the correct value for the existing <input type='hidden' value='xxx'>
if that value exists in the list, of course
if not, set value to blank (optionally fire jquery validation
Searching/constant querying is not needed. Just load once on change
I am thinking about changing this entire, so if this is really the wrong way to go about this, I'd be happy to know.
// caches ajax result based on `data`
// if data has been requested before, retrieves from the cache (nothing special)
// based on other code that did it all inside the `query` function directly
var locationsCache = new AjaxCacheClassThing( {
url: '...',
data: function() { return { masterId: $('#ParentBox').val(); } }
});
$(function() {
$('#ParentBox').change(function () {
$('#ChildBox').select2('data', null);
});
$('#ChildBox').select2({
query: locationsCache.queryCallbackHandler,
selectOnBlur: true,
});
});
The HTML uses the standard MVC helpers, and the HTML is rendered just fine.
#Html.DropDownListFor(m => m.ParentBox, SelectListOfStuff) // standard <select>
#Html.HiddenFor(m => m.ChildBox)
Here is how this scenario goes:
ParentBox is required (no empty option)
First Load: there is no value selected
Open the DependentBox
Ajax query issues correctly
Dropdown populates as expected
Second Load
Master box selects value just fine
ChildBox hidden input has value="xx" just fine
It does not show a selected item
Clicking dropdown populates the box as expected (from cache)
After some time spent, and lots of time on here and other places, I figured out how this all works (at least some parts of it!). Way simpler than I thought it was, but still surprised this isn't supported out of the box in some way. Seems like a really common request.
query and ajax and initselection aren't that useful in this scenario
They query each time a the search box changes (not desired)
They complicate everything
You need to init the select2 manually
If you use { data: ... } then you don't need query or ajax
Set the "value" on your hidden input if you have one, so the item gets selected
You have to recreate the box when you get new data
It is really simple. This is the simplest case, using no extra features or attributes
Javascript:
$(function() {
$('#ParentBox').change(createChildSelect2);
createChildSelect2();
});
function createChildSelect2() {
makeAjaxRequest( function( newData ) {
$('#ChildBox').select2( { data: newData } );
});
}
function makeAjaxRequest(callback) {
// calls a.jsp?parentId={?} and then the callback when done.
jQuery.ajax({
url: 'a.jsp', dataType: 'json',
data: function() {
return { parentId: $("#parentBox").val() };
}
})
.done(function (data) {
callback(data);
});
}
The HTML is all the same. A type=text and type=hidden both work:
<select id="ParentBox">
<option ... >
<option ... >
<select>
<input id="ChildBox" type="hidden" class="input-medium" value="1"/>
Or using Razor:
#Html.DropDownListFor(m => m.MasterBox, SelectListOfStuff) // standard <select>
#Html.HiddenFor(m => m.DependentBox)

MVC - Ajax - Inconsistency between Chrome and IE 9

I have an MVC view where I am doing some paging of data, using the PagedList component. My JavaScript to support this looks as follows:
$(function () {
var getPage = function () {
var $a = $(this);
var options = {
url: $a.attr("href"),
type: "get"
};
$.ajax(options).done(function (data) {
var target = $a.parents("div.pagedList").attr("data-ExchangeSite-target");
data: $("form").serialize(),
$(target).replaceWith(data);
});
return false;
};
$(".main-content").on("click", ".pagedList a", getPage);
});
My .cshtml file looks, in part, like this:
#model ExchangeSite.Entities.BicycleSearchSeller
<div id="itemList">
<div class="pagedList" data-ExchangeSite-target="#itemList">
#Html.PagedListPager(Model.BicycleSellerListingList, pageNumber => Url.Action("Index", new {pageNumber}),
PagedListRenderOptions.ClassicPlusFirstAndLast)
</div>
...
...
In IE9, this works perfectly. When I click on a specific page number, or the next/previous page, an asynch call is made to my controller to refresh the list of data ("itemList"). However, in Chrome, two calls are made to my controller. One is an Ajax call, the other is not. Can anyone tell me why, in Chrome, two calls are made to my controller? If you need to see more code, please let me know.
There seems to be some buggy line in your success callback:
data: $("form").serialize(),
It is terminated with a comma instead of semicolon. It also contains a colon after data. IE might be a little more tolerant towards broken javascript compared with Google Chrome.

Passing the signed_request along with the AJAX call to an ActionMethod decorated with CanvasAuthorize

This is a follow-up to AJAX Call Does Not Trigger Action Method When Decorated With CanvasAuthorize
So I found the following links and it seems that this is a common problem:
http://facebooksdk.codeplex.com/discussions/251878
http://facebooksdk.codeplex.com/discussions/250820
I tried to follow the advice by prabir but I couldn't get it to work...
Here's my setup:
I have the following snippet in the page where the button that triggers the whole post to facebook is located:
#if (!string.IsNullOrEmpty(Request.Params["signed_request"]))
{
<input type="hidden" id="signedReq" value="#Request.Params["signed_request"]" />
}
And then I have this snippet (inside a script tag inside the same page):
var signedRequest = $('#signedReq').val();
$('.facebookIcon').click(function () {
var thisItem = $(this).parent().parent();
var msg = thisItem.find('.compItemDescription').text();
var title = thisItem.find('.compareItemTitle').text();
var itemLink = thisItem.find('.compareItemTitle').attr('href');
var img = thisItem.find('img').first().attr('src');
postOnFacebook(msg, itemLink, img, title, signedRequest);
});
And finally, inside an external js file I have the following function:
/*Facebook post item to wall*/
function postOnFacebook(msg, itemLink, pic, itemTitle, signedReq) {
console.log(signedReq);
var siteUrl = 'http://www.localhost:2732';
$.ajax({
url: '/Facebook/PostItem',
data: {
'message': msg,
'link': siteUrl + itemLink,
'picture': siteUrl + pic,
'name' : itemTitle,
'signed_request': signedReq
},
type: 'get',
success: function(data) {
if(data.result == "success") {
alert("item was posted on facebook");
}
}
});
}
But signedReq is always undefined. And I'm not really sure I should be passing the 'signed_request' field inside the data object. Any thoughts?
Make sure you hidden input field is being populated.
Also, when you try to pull the ID of the input field via JQuery, you might not be referencing the proper element since .NET butcher's ID's of anything that's run on the server.
When I use the hidden input field trick, I set the jquery value like so:
var signedRequest = $('#<%=signedReq.ClientID %>').val();
This way, I'm getting the identifier that .NET is giving to the HTML element.
Hope that helps.
Just a guess - in your hidden field: id="signed_request" instead of id="signedReq"

CI + AJAX, Double posting + refreshing of page

So I have a normal form with 1 textarea and two hidden inputs, which I would like to post via AJAX to a CI controller I have that inserts the information into the database.
The problem I'm having is that a) the page action is still called and the output of the controller is displayed and b) because the initial AJAX request is still processed plus the extra loading of the action target the information gets inserted twice.
This is my javascript code:
$(document).ready(function() {
$("#submit-comment").click(function(){
var post_id = <?=$p->id?>;
var user_id = <?=$user->id?>;
var content = $("textarea#content").val();
if(content == '') {
alert('Not filled in content');
return false;
}
$.ajax({
type: "POST",
url: "<?=site_url('controller/comment')?>",
data: "post_id="+post_id+"&user_id="+user_id+"&content="+content,
success: function(msg){
alert(msg);
}
});
});
});
I have tried doing
...click(function(e)... ... e.preventDefault
with no luck.
What am I doing wrong? :P
Thanks
Ps. All the information is processed properly and accessed, it's just the preventing the form which is screwing it up..
Just realised I was using a input type="submit", rather than input type="button".
Doh!

Update using Prototype and Ajax

I am using Ajax and Prototype. In my code, I need to update the contents of a div.
My div:
<div id="update">
1. Content_1
</div>
My code:
Element.update($("update"),"2.Content_2");
Expected output:
<div id="update">
1.Content_1
2.Content_2
</div>
How can I do this in Ajax and Prototype?
AJAX usually means you are executing a script on the server to get this result.
However, in your example it looks like you simply want to append some text.
To append text you could simply add the text to the end of the innerHTML:
$("update").innerHTML = $("update").innerHTML + "2.Content_2";
If you are wanting to execute a server script, I'd do this: (I haven't used Prototype for a while, things might have changed)
function getResult()
{
var url = 'theServerScriptURL.php';
var pars = '';
var myAjax = new Ajax.Request(
url,
{
method: 'post',
parameters: {},
onComplete: showResult
});
}
function showResult(originalRequest)
{
$("update").innerHTML = originalRequest.responseText;
}
This code will call 'theServerScriptURL.php' and display the result in the div with id of 'update'.

Resources