Ajax Based Display Not Accurate - javascript

I'm building a Joomla module that uses slideDown and ajax of jQuery.
The way it works is that it populates the slideDown div, compute the div child element with highest height, and resizes the containing div height for display.
Problem is if the page is not cached (i.e. if it is on first load of the page) the height is not displayed properly as below
But on second click and so on, it displays correctly as follows
I'm thinking it is because the contents of the div child element are not completely populated before the height is computed, hence a false height is generated. I've tried some things to ensure that does not happen - right now I'm using a callback function along with the function that populates the div tag.
Quick help will be highly appreciated, thanks!
Edit - here's the code that populates
menuItemAjax: function (urlContent, dataContent) {
jQuery.ajax({
type: "POST",
url: urlContent,
data: dataContent, // data to send along with url
complete: function () {
//console.log("Process completed");
},
success: function (returnedData) {
WetvCreateHtml.popDropDownDiv(returnedData, function() {
var ddChildren = dropdownDiv.children(), highestHeight = 0;
ddChildren.each(function(){
if (jQuery(this).height() > highestHeight) {
highestHeight = jQuery(this).height();
}
});
dropdownDiv.animate({ height: highestHeight });
});
},
error: function () {
//console.log("Error occured");
},
statusCode: {
404: function() {
//console.log("Page not found");
}
}
});
},
popDropDownDiv: function(returnedData, callback) {
dropdownDiv.html(returnedData);
if (typeof(callback) == "function") {
callback();
}
}

Related

Stopping a scroll function from triggering multiple times?

So I have a script that pulls data from the database and displays it when the user nears the bottom of the page.
The problem:
When the user reaches the bottom, the script should only return one post back, but instead, multiple requests are being made, causing all of the posts to be being pulled from the database at a rapid pace, which in turn returns them in the wrong order.
My question is, is there anyone who knows how to stop it from going haywire and prevent the spamming of articles?
Note:
I'm not looking to completely cut the AJAX requests off once one has been made, as this script is an 'infinite scroll', pulling articles one by one from the database when the user reaches the bottom.
Thanks in advance, Rich.
$(document).ready(function() {
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
$('div#loadMoreArticles').show( function(){
$.ajax({
url: "loadMoreArticles.php?lastArticle="+ $(".postedArticle:last").attr('id') ,
success: function(html) {
if(html){
$("#postedArticle").append(html);
$('div#loadMoreArticles').hide();
} else {
$('div#loadMoreArticles').replaceWith("<p>There are no more articles.</p>");
}
}
});
});
}
});
});
Hope this helps
$(document).ready(function() {
var AjaxRequestOn;
$(window).scroll(function() {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
$('div#loadMoreArticles').show(function() {
if (!AjaxRequestOn) {
AjaxRequestOn = $.ajax({
url: "/",
success: function(html) {
}
});
}
});
}
});
});
Just use a variable to set the ajax request , when the first ajax is set then if user again scroll up and comes down then the variable has some value so we should not do the call again(check if loop before ajax call). If the variable is not defined then we have to make the call to server. so this results in only one call to server.
Try defining handler as named function , using .off() to detach scroll event before $.ajax() call , reattach scroll event after $.ajax() completes
function scroller() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
$(this).off("scroll.ajax");
$('div#loadMoreArticles').show( function(){
$.ajax({
url: "loadMoreArticles.php?lastArticle="+ $(".postedArticle:last").attr('id') ,
success: function(html) {
if(html){
$("#postedArticle").append(html);
$('div#loadMoreArticles').hide();
} else {
$('div#loadMoreArticles').replaceWith("<p>There are no more articles.</p>");
};
// setTimeout(function() {
$(window).on("scroll.ajax", scroller)
// }, 500)
}
});
});
}
}
$(window).on("scroll.ajax", scroller);

Jquery AJAX Post not hitting method in code behind

I have an ASP.NET website which uses jQuery 1.8.2. I have a dialog box which lists UserReporting Settings from a DB whether a column is displayed or not. The User can change this by clicking the change columns buttons which open the dialog box - there are then a list of Available Columns and Current Columns and the User can drag and drop from one side to the other.
The code in the Update button off the dialog button is what is not working - the 'Hello' alert fires but if I set a breakpoint in my ashx Handler it never gets hit?
$("#UserReportSettings").dialog({
resizable: false,
autoOpen: false,
height: 600,
width: 525,
modal: true,
buttons: {
"Update Columns": function () {
var columns = [];
$('#currentColumnsList').each(function () {
// this is inner scope, in reference to the .phrase element
var column = '';
$(this).find('li').each(function () {
// cache jquery var
var current = $(this);
// check if our current li has children (sub elements)
// if it does, skip it
// ps, you can work with this by seeing if the first child
// is a UL with blank inside and odd your custom BLANK text
if (current.children().size() > 0) {
return true;
}
// add current text to our current phrase
column += (current.text() + ',');
});
// now that our current phrase is completely build we add it to our outer array
columns.push(column);
});
$.ajax({
type: 'POST',
url: '/MyWebsite/Handlers/UpdateUserReportingSettings.ashx',
data: { reportingSettings: columns.join() },
beforeSend: function (xhr, opts) {
},
success: function (data) {
alert("Hello");
window.top.location.href = "landing.aspx";
},
error: function (xhr, ajaxOptions, thrownError) {
alert('error' + xhr.responseText);
}
});
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
EDIT - Following Archers comment
If I paste localhost/Handlers/UpdateUserReportingSettings.ashx into the browser I can hit break point in my Handler.
So changed my URL in ajax call to :
url: '/MyWebsite/Handlers/UpdateUserReportingSettings.ashx',
and did a shift refresh to reload the js for page and hit the breakpoint.

Appending item to list with Ajax after post - layout related

I have an activity stream for both users use, and site-wide view. Currently when a user posts an update, I have it displaying a default bootstrap success alert. I have seen other websites append the new post to the list by sliding down the existing items, and appending the newest post to the top of the list.
I am attempting to do just that, but I am not sure how to add it with all the proper styling. (code below). I am tried adding all the <div> tags that make up one activity item in my feed, but without success.
TL;DR - Is there a way to have ajax look at the current top activity item, clone it, and append it to the top? It would make the code more dynamic for my use, and avoid having to place CSS inside the .js file.
jQuery(document).ready(function ($) {
$('form#postActivity').submit(function (event) {
event.preventDefault();
$postActivityNow = (this);
var subject = $('#activity_subject').val();
var message = $('#activity_content').val();
var data = {
'action': 'postAnActivity',
'subject': subject,
'message': message,
}
$.ajax({
type: 'post',
url: postAnActivityAjax.ajaxurl,
data: data,
error: function (response, status) {
alert(response);
},
success: function (response) {
if (response.success) {
bootstrap_alert.success('Activity Added');
} else {
if (response.data.loggedIn == false) {
bootstrap_alert.warning('you are NOT logged in');
console.log('you are not logged in')
}
if (response.data.userExists == false) {
console.log(response);
bootstrap_alert.warning(response.data.alertMsg);
console.log(response.data.alertMsg)
}
}
}
});
});
});
you can also use .prependTo()
var newActivity = $( ".activity" ).first().clone();
newActivity.prependTo( ".parentDiv").hide().slideDown();
FIDDLE
To clone an element: jQuery.clone()
var newItem = $("#myDiv").clone();
To append it as first child: jQuery.prepend()
$("#parentDiv").prepend( newItem );
Regards,
hotzu
I have already done in the past using $.prepend()
Check this url for more information jquery append to front/top of list

optimizing colorbox and adding extra jquery

I have two problems
I am trying to open a jQuery colorbox and it is very slow. The reason is I am trying to get html content from a different page (I cannot use iframe because I just need a part of this page). The following code works but it takes time after the button is clicked:
$(document).ready(function() {
$(".cart-link a").click(function(event) {
$(this).colorbox.close();
});
$(".rest-menuitem a").click(function(event) {
event.preventDefault();
var result = null;
var sURL = $(this).attr("href");
$.colorbox({
html: function() {
$.ajax({
url: sURL,
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
result = data;
}
});
return $(result).find('.product');
},
width: '650px',
height: '10px',
onComplete: function() {
$(this).colorbox.resize();
}
});
});
});
I want to know if there is a alternative way to do it. I dont mind if the colorbox popup and then takes time to load the content. The above version can be fount at this url (http://delivery3.water-7.com/index.php/restaurants/manufacturers/3/Barcelona-Restaurant-&-Winebar/products).
I am also trying to close the colorbox when a user clicks on add to cart. But some reason it is not triggered. $(".cart-link a").click is not triggered when I click on add to cart. Is there a special way to add jquery to colorbox content?
Try this instead:
$(".rest-menuitem a").colorbox({
href: function(){
return $(this).attr('href') + ' .products';
},
width: '650px',
height: '10px',
onComplete: function() {
$(this).colorbox.resize();
}
});
ColorBox uses jQuery's load() method for it's ajax handling, so you just need to add the desired selector to the link's href.
For your question 2 can you try this ?
$(document).ready(function() {
$(".cart-link a").live('click',function(event) {
$(this).colorbox.close();
});
});
For your question 1..it will be slow since you are fetching it from different page.Use a different logic for that
For your question no 1
$('selector').colorbox({onLoad: function() { /*Intially load a empty color box with only <div id="contenttoload"></div> (No other html content */
$.ajax({
url :'Your url',
data : {}, //data to send if any
type : "POST" //or get
success:function(data){ /*data means the stuff you want to show in color box which you must return from the other page*/
$('#contenttoload').html(data); //data should be well formatted i mean add your css,classes etc from the server itself */
}
});
}});

jQuery: How to apply a function to all elements including some which are loaded later via Ajax?

I have a simple jQuery function that resizes text areas, and I want it to apply to all text areas.
For the most part, this works great:
$(document.ready(function(){$("text_area").resizer('250px')});
However, because it is only called once when the document is ready, it fails to catch text areas that are later added onto the page using Ajax. I looked at the .live() function, which seems very close to what I'm looking. However, .live() must be bound to a specific event, whereas I just need this to fire once when they're done loading (the onLoad event doesn't work for individual elements).
The only thing I can get working is a really obtrusive inclusion of the JavaScript call directly into the Ajax. Is that the recommended way to be doing this?
Edit: Here is the rails source code for what it does for Ajax requests:
$('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
var link = $(this);
if (!allowAction(link)) return false;
if (link.attr('data-remote') != undefined) {
handleRemote(link);
return false;
} else if (link.attr('data-method')) {
handleMethod(link);
return false;
}
});
// Submits "remote" forms and links with ajax
function handleRemote(element) {
var method, url, data,
dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
if (element.is('form')) {
method = element.attr('method');
url = element.attr('action');
data = element.serializeArray();
// memoized value from clicked submit button
var button = element.data('ujs:submit-button');
if (button) {
data.push(button);
element.data('ujs:submit-button', null);
}
} else {
method = element.attr('data-method');
url = element.attr('href');
data = null;
}
$.ajax({
url: url, type: method || 'GET', data: data, dataType: dataType,
// stopping the "ajax:beforeSend" event will cancel the ajax request
beforeSend: function(xhr, settings) {
if (settings.dataType === undefined) {
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
}
return fire(element, 'ajax:beforeSend', [xhr, settings]);
},
success: function(data, status, xhr) {
element.trigger('ajax:success', [data, status, xhr]);
},
complete: function(xhr, status) {
element.trigger('ajax:complete', [xhr, status]);
},
error: function(xhr, status, error) {
element.trigger('ajax:error', [xhr, status, error]);
}
});
}
So in my particular case, I've got a link, that has data-remote set to true, which points to a location that will return JavaScript instructing a form containing a text area to be appended to my document.
A simple way to do this would be to use ajaxComplete, which is fired after every AJAX request:
$(document).ajaxComplete(function() {
$('textarea:not(.processed)').resizer('250px');
});
That says "every time an AJAX request completes, find all textarea elements that don't have the processed class (which seems to be added by the resizer plugin -- terrible name for its purpose!) and call the resizer plugin on them.
You may be able to optimise this further if we could see your AJAX call.
Generally speaking, I would do it this way..
$.ajax({
type : "GET",
url : "/loadstuff",
success: function(responseHtml) {
var div = $("#containerDiv").append(responseHtml);
$("textarea", div).resizer("250px");
}
});
Wondering if you could use .load for this. For example:
$('text_area').load(function() {
$("text_area").resizer('250px');
});

Categories

Resources