I have an ajax call that looks like this,
$('campaignType').addEvent('change', function(){
alert($('campaignType').value);
var request = new Request({
method: 'get',
url: '/admin/admin_' + $('campaignType').value + '.php',
onRequest:function() {
alert('Request has been made, please be patient')
},
onComplete:function(response) {
$('campaignForm').append(response);
}
}).send();
});
Essentially what happens is depending on what the value of `$('campaignType') some HTML is returned from another file, however I cannot seem to get the HTML to append on to my container. Any one care to give me some advice?
Thanks
Dimitar's solution is close but is a bad solution as it recreates the whole element contents and destroys attached event handlers. A better solution would be:
Element.implement({
append: function(newhtml) {
return this.adopt(new Element('div', {html: newhtml}).getChildren());
}
});
this is actually what Request.HTML internally does.
.append is not a valid element prototype in mootools.
if you want to append html to an existing one, then you can either MAKE .append valid by defining in your site lib/core bit (I would consider this if you use it a lot):
Element.implement({
append: function(newhtml) {
// silly name, does not say to me you are appending html. rename to appendHTML
return this.set("html", this.get("html") + newhtml);
}
});
or in your onComplete do:
var cf = $('campaignForm');
cf.set("html", cf.get("html") + this.response.text);
have fun :)
If you're using mootools 1.2.4 you can change Request to Request.HTML and use append option. (Not sure that append option was in older versions)
$('campaignType').addEvent('change', function(){
new Request.HTML({
method: 'get',
url: '/admin/admin_' + $('campaignType').value + '.php',
append: $('campaignForm')
}).send();
});
I think you like to use onSuccess instead of onComplete
Related
I use $http service to get data and generate DOM elements.
How can I in jQuery/AngularJS call a method (example .slideToggle()) on dynamic element? I need to do this when page is loaded (not on click event etc.).
To do this one $('#test').slideToggle() (#test is generated element) i need use timeout.
It's difficult to know for sure from your description, but if you're creating the element from data you retrieve remotely, you should ensure that element's creation/insertion are completed before you attempt to scroll to it.
The following code is an example of how you may do this:
$http({
method: 'GET',
url: '/someUrl'
})
.then(createAndInsertYourElement)
.then(scrollToElem);
function createAndInsertYourElement(data) {
var $elem = $('<div id="test">' + data.whateva + '</div>');
$('#someElement').append($elem);
return $elem;
}
function scrollToElem($elem) {
$elem.slideToggle();
}
Note the .thens. These are an option because Angular's $http returns a promise. If you're not familiar with promises, yet, they are awesome, and you should check 'em out: http://www.dwmkerr.com/promises-in-angularjs-the-definitive-guide/
I have setup a search funtionality that will search in an XSLT file. This works flawlessly but I have a little trouble returning the search results dynamically with ajax.
This is my JS:
var SearchHandler = function(frm) {
frm = $(frm);
var data = frm.find(".search-field").val();
$.ajax({
method: 'GET',
url: '/',
data: { query: data },
dataType: 'xml',
success: SearchSuccessHandler,
error: SearchSuccessHandler
});
};
var SearchSuccessHandler = function(html) {
};
What I want is the SearchSuccessHandler to dynamically load the search result from index.php?query=searchword
I just can't seem to figure out the right way to handle it.
Based on your comment:
Bah.. Sorry... The ajax call will return some new html based on the
query ... I want the existing html to be replaced I have tried
$('body').html(html.responseText); but then I cannot search again
because javascript is not loaded correctly
It's not the AJAX which is the issue but rather event delegation
When you bind a function to an element directly like this:
$('.my-element').on('whatever', function() { ... })
the handler will work as long as the element exists however if you replace the contents of the entire body you'll run into trouble as your original .my-element no longer exists.
You can overcome that by using event delegation to make sure your function keeps searching e.g.
$(body).on('whatever', '.my-element', function() { ... })
This basically says: "If I click on body and the target is .my-element then execute this function"
Instead of a directly bound handler which says: "If I click on this specific element then execute this function"
the body will always exist and therefore you'll always be able to delegate down from the body but if you can do it on some more specific element that would obviously be better since then you won't have an onclick handler on the entire body.
I think this is what your issue is since you're replacing the entire body.
Try this
success:function(data) {
// do your stuff here
}
Of course, you need to be sure your function is returning some values.
To make it easier for your, encode the values as json on your index.php
return json_encode($values)
Then, inside your success function, just parse it with eval()
I got this code from some template, it gets executed by clicking on the tabs to fetch posts into the page. All I want is to have an edited copy of this code to fetch posts by timer aside from clicking on the tabs. I have tried the setInterval but it didn't work, I appreciate any help I am so new to Ajax and JQuery.
jQuery(document).ready(function($) {
setInterval(function(){
e.preventDefault();
var bt = $(this);
var bts = bt.parent().parent();
var where = $(this).parent().parent().parent().next();
var nbs = bt.parent().parent().data('nbs');
var nop = bt.parent().parent().data('number_of_posts');
cat = bt.data('cat_id');
if (cat === '') {
cat = bt.data('parent_cat');
}
where.parent().find('.show-more').find('.nomoreposts').remove();
jQuery.ajax({
type: "post",
url: nbtabs.url,
dataType: 'html',
data: "action=nbtabs&nonce="+nbtabs.nonce+"&cat="+cat+"&nbs="+nbs+"&number_of_posts="+nop,
cach: false,
beforeSend : function () {
where.parent().append('<i class="nb-load"></i>');
},
success: function(data){
where.hide().html(data).fadeIn('slow');
bts.find('li').removeClass('active');
bt.parent().addClass('active');
where.parent().find('.nb-load').remove();
}
});
}, 5000)
})
You have to get started to some degree before we can really help you code-wise. We can't just write the code for you because we do not know what elements you want updated and how.
All I can advise you is the Jquery Ajax method is how this code retrieves url responses:
jQuery.ajax({
type: "post",
url: "<name of your url or maybe servlet>"
success: function(data){
// data is the response from your url
// in the code sample, data was html that was inserted to an element
}
});
You can put this ajax call in a function and use setInterval. You can place the setInterval call on your Jquery.ready() function.
Your first issue is that you're trying to call jQuery.setInterval, not setInterval. jQuery.setInterval is not a function, so calling it will just give you an error.
The next issue is that your script tries to alter a bunch of elements, using the clicked element as a starting point. This is bad practice because of situations like this, where changing how to function is invoked can completely break the script. Without knowing what all of this:
var bt = $(this);
var bts = bt.parent().parent();
var where = $(this).parent().parent().parent().next();
var nbs = bt.parent().parent().data('nbs');
var nop = bt.parent().parent().data('number_of_posts');
is, it's pretty difficult to give advice. The safest bet is to replace $(this) with jQuery(".nb-tabbed-head li a"), but that might cause issues because $(this) refers to only one element, whereas jQuery(".nb-tabbed-head li a") may refer to multiple.
Really the biggest issue is that you're trying to use code that a) is poorly-written and b) you don't understand yet. I highly recommend learning about AJAX, events, the DOM, and jQuery before you make a serious attempt at this. It's almost impossible to create a good product when you're gluing together pieces of code that you don't understand that were written by someone that you don't know.
I am doing an ajax navigation for a wordpress website. I update the #content with fade, this is ok, but I want to just update my head with my new page head, I don't find!
$(document).ready(function () {
//hash change
$(window).hashchange(function () {
//on retrouve le vrai lien
var arg = window.location.hash.substring(3);
var link = 'http://ladresse.graphsynergie.com/' + arg;
$.ajax({
url: link,
processData: true,
dataType: 'html',
success: function (data) {
data = innerShiv(data, false);
var contenu = $(data).find("#contenu");
//problem part
var head = $(data).find('head').text();
document.head = head;
//problem part end
$('#contenu').fadeOut('200', function () {
$(this).html(contenu.html()).fadeIn('200');
});
}
});
});
//end
//détection d'un hash onload
if (window.location.hash.substring(3) != '') {
$(window).trigger('hashchange');
}
});
Have in consideration that .text() will only retrieve the "text" contained inside the html tags, review the jQuery documentation. I think that what you actually want is to use the .html() method.
So, I think that you may want to replace those 2 problematic lines of code with this:
$("head").html($(data).find("head").html());
Update:
Apparently all browsers strip out anything that it's not inside the "body" when they create the DOM object. The thing is that when you do: "$(data)" jQuery creates a DOM object with the content of the "data" variable, and your browser decides to ignore all the elements that are not inside the "body" tag, therefore in the internal DOM object that jQuery handles the "head" element is not there anymore. So you will have to find a workaround.
Try this, put these lines of code just after the line "success: function (data) {":
var headIni = data.toLowerCase().indexOf("<head");
var headEnd = data.toLowerCase().indexOf("</head>");
headIni = data.indexOf(">", headIni + 1) + 1;
var headHTML = data.substring(headIni, headEnd);
And then, replace the line that I initially suggested for this one:
$("head").html(headHTML);
This should do the job. I'm sure that there must be more elegant ways to do it, but hopefully this will be good enough for you.
Update 2:
If you follow this link you will find a much better way to do it. Just add the library "jquery.ba-htmldoc.js" that you will find there, and then do this:
$("head").html($.htmlDoc(data).find('head').html());
To overwrite the content of your "< head >" tag use
$("head").html('NEW STUFF IN HEAD');
I have a problem when calling a ajax call that after the ajax data is appended into the DOM, any Javascript referring to the appended html returns that the object is undefined.
The forms use tags with Javascript submits and some Javascript to modify hidden fields, thats why the eval() is in there.
edit: This is an example of a 'href' tag and why I have the eval in there:
javascript:document.faultList.sortBy.value='4';document.faultList.sortByPrev.value='3';document.faultList.Action01.value='SetMyRequestItem';
Its how the previous developer has created this software/website before my time instead of using a REST style system.
This is my code:
function ajaxFormUpdate(formID,linkClass){
$(formID+' '+linkClass).click(function(){
eval($(this).attr('href'));
serialised = $(this).closest(formID).serialize();
$.ajax({
type: "POST",
url: 'jadehttp.dll?EbdMulti_www_01',
data: serialised,
success: function(data) {
//console.log(data)
$(formID).html($(data).find(formID));
loadHandlers();
}
});
return false
});
}
function loadHandlers(){
ajaxFormUpdate('#faultList','.ajaxLink');
ajaxFormUpdate('#accessCardList','.ajaxLink');
ajaxFormUpdate('#facilityList','.ajaxLink');
ajaxFormUpdate('#carParkingList','.ajaxLink');
ajaxFormUpdate('#visitorList','.ajaxLink');
}
loadHandlers();
Resolved this by changing .html() to .replaceWith() (thanks jgauffin for putting me on the right track) and using the following click handler instead of the standard .click()
$(".selector_class").live('click', function() { alert("new element clicked"); });