MVC - Ajax - Inconsistency between Chrome and IE 9 - ajax

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.

Related

AJAX call with nodeJS and express successful, but not displaying data

I have recently migrated from a codeigniter framework, to a nodejs with an express framework. Our codeigniter site had a lot of JS as it was, and we made a lot of AJAX calls because it is a single page app. We are messing around with node and express now, and I cannot get a simple AJAX call to function. It could be a lack of understanding of node, it could be something else. We are using openshift to host. We are using hogan-express as a template.
server.js
var express = require('express');
var fs = require('fs');
var http = require('http');
var path = require('path');
var SampleApp = function() {
var self = this;
self.initializeServer = function() {
self.app = module.exports = express();
self.app.configure(function() {
self.app.set('views', __dirname + '/views');
self.app.set('view engine', 'html');
self.app.engine('html', require('hogan-express'));
//self.app.set('layout', 'layout') # use layout.html as the default layout
self.app.use(express.favicon());
self.app.use(express.logger('dev'));
self.app.use(express.bodyParser());
self.app.use(express.methodOverride());
self.app.use(express.session());
self.app.use(self.app.router);
self.app.use(require('stylus').middleware(__dirname + '/public'));
self.app.use(express.static(path.join(__dirname, 'public')));
});
require('./routes');
}
There is more code in this file, I am only including the relevant code (I think).
Ajax.html
<div id="button">
<button id="testbutton">Push Me!</button>
</div>
<div id="populate">{{title}}</div>
<div id="null">{{>part}}</div>
<script type='text/javascript'>
$(function(){
$('#testbutton').click(function (){
$.ajax({
url:'/test',
type: 'POST',
success: function(result){
alert('success!');
},
error: function(){
alert("well this is embarassing... if the problem persists please let us know at facebook.com/stembuds");
}
});
});
});
</script>
index.js
app = require('../server');
app.get('/', function(req, res){
res.render('ajax');
});
app.post('/test', function(req, res){
console.log('get');
res.locals = {title: 'Horray'};
res.render('ajax', {partials:{part:'part'}});
});
part.html
<p> pass me in!!</p>
So basically what I am trying to do is when the button is clicked I want the ajax call to show a partial view. The way we are going to structure the site is to have one single page, and have the ajax calls render different views based on the buttons that the user clicks. So here is the interesting part: I get the success alert from the ajax call, but the {{title}} and the {{>part}} never show up. However, when I go to the console and click 'network', and then click 'test' (the url to my ajax call), the response shows the divs populated with "Horray" and "pass me in!!". Sorry for the length, and thank you for any information you can provide us.
If you are calling your resources with ajax (as you are doing) then you get the response to your ajax function. After successful call you need to render the view in your client side JS code.
What I mean is that your code works as expected, but your backend cannot update your browsers view. You need to do it client side or load the whole page again from the server.
Your success hander could be something like this:
success: function(result){
renderTheResults(result);
},
You can just send the JSON. You need to send the json via send not render. Because render is supposed to deliver the full HTML page. May be .ejs file.
For example:
res.send({partials:{part:'part'}});
res.send should be used to pass json to your page. And on your page you have to use the JSON to populate the HTML dynamically.

Bootstrap popover and loading content with ajax and django

I know it has been given some answers but I will go for it :). As the title says i want to add popover bootstrap but with ajax loaded content. my html, but i want a Loading message to appear first and then the content.
<p class='entry' data-adjaxload = '/calendar/entry/1'>Title1</p>
<p class='entry' data-adjaxload = '/calendar/entry/2'>Title2</p>
<p class='entry' data-adjaxload = '/calendar/entry/3'>Title3</p>
my django view is the following
def entry_details(request, entry_id):
entry = get_object_or_404(Entry, pk=entry_id)
args = dict(entry=entry, user=request.user)
if request.is_ajax():
return render_to_response('mycal/ajax/entry_details.html', args)
else:
entry_form = EntryForm(instance=entry)
args.update(entry_form=entry_form)
return render_to_response('mycal/entry_details.html', args)
Pretty simple. I am using the same view to either load html content via ajax in the popover, or a details page via normal get request
the ajax details page:
<div class="entry">
<p>{{entry.title}}</p>
<p>{{entry.date}}</p>
<p>{{entry.customer}}</p>
</div>
and the script
$(document).ready(function(){
$('p.entry').each(function (){
var i = $(this);
$(i).bind('mouseenter', function(){
i.popover({
html:True,
title:i.html(),
content:'Loading'
}).popover('show');
$.ajax({
url:i.data('ajaxload'),
dataType:'html',
success:function (data){
i.popover({content:data}).popover('show');
}
});
});
$(i).bind('mouseleave', function(){
i.popover('hide');
});
});
});
But whilst it does run tha ajx and fetches the html, it won't load them onto the popover. How can I change that?
Just fiddled what you are looking for with popover content being updated dynamically using echo/json.
Just roll over the p element and wait for the 3 second delay.
If as you say, the data is being loaded properly then the only change needed is:
var popover = i.data('popover');
popover.options.content = data.text;
i.popover('show');

jQuery(document).ready() won't work on AJAX loaded jQuery-UI widgets

I am loading some code with the jQuery.ajax() method. In this code I want to have some jQuery-UI Widgets (sliders and calenders) but they won't appear in IE.
Here some example code where you maybe can help me to understand where I am going wrong.
The Code which will load the jQuery-UI Widgets
<script>
jQuery(document).ready(function(){
jQuery.ajax({
type:'post',
url: 'file.php',
success: function (data) {
jQuery('.somediv').empty().html(data);
}
});
});
</script>
The Code which is loaded and SHOULD initialize the jQuery-UI Widgets
<script>
jQuery(document).ready(function(){
jQuery('.datepicker-div').datepicker(someoptions);
jQuery('.slider-div').slider(someoptions);
});
</script>
<div class="datepicker-div">
<div class="slider-div">
You can see that it should be very simple. For FF it works fine but not for IE.
Maybe it has nothing to do with the document-ready statement?
Just call the initializers in the success event:
<script>
jQuery(document).ready(function(){
jQuery.ajax({
type:'post',
url: 'file.php',
success: function (data) {
jQuery('.somediv').empty().html(data);
jQuery('.datepicker-div').datepicker(someoptions);
jQuery('.slider-div').slider(someoptions);
}
});
});
</script>
Of course, you should refactor that by having a function for initializations:
function Initialize(){
jQuery('.datepicker-div').datepicker(someoptions);
jQuery('.slider-div').slider(someoptions);
}
Then have your success call it, as well as the ready() ebent:
<script>
jQuery(document).ready(function(){
jQuery.ajax({
type:'post',
url: 'file.php',
success: function (data) {
jQuery('.somediv').empty().html(data);
Initialize();
}
});
});
</script>
Update
I have read your question more carefully and now I fully understand it. Your ready() is in the loaded code. Then you should be using jQuery's load():
Script Execution
When calling .load() using a URL without a suffixed selector
expression, the content is passed to .html() prior to scripts being
removed. This executes the script blocks before they are discarded. If
.load() is called with a selector expression appended to the URL,
however, the scripts are stripped out prior to the DOM being updated,
and thus are not executed. An example of both cases can be seen below:
Here, any JavaScript loaded into #a as a part of the document will
successfully execute.
$('#a').load('article.html');
Try removing the scripts prior to appending the html, then adding them back.
var outHTML = data.replace(/<script>/ig,"<div class='script'>").replace(/<\/script>/ig,"</div>");
outHTML = $(outHTML);
var script = outHTML.find("div.script").detach();
$(".somediv").html(outHTML);
var s = document.createElement("script");
s.textContent = script.text();
document.body.appendChild(s);
Edit:
.find("div.script") may need to be changed to .filter("div.script") based on what your ajax request is returning.
Ok, I didn't found out how i can solve the Problem, but i found a work around.
The work around is very simple. Because in every browser except for the IE the loading of the script via ajax works fine, we have to identify the IE and change the behaviour to not loading the script but redirect to the site I wanted to load. I am doing this all in Joomla 2.5, so there was a bit work to do but basically it was the following code wich solved the problem.
// preparing the url
// check for ie
if (jQuery.browser.msie) {
window.location(url);
} else {
// do the ajax
}

How can i append partial view result in to div?

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

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!

Resources