I have the following code which loads via ajax contents to be appended:
$.get('http://mydomain.com/ajax1.php/', function(data){
var data_one = $(data).find('#ajax_editor_suggestion_container');
$('.ajax_editor_selection_container').append(data_one);
});
$.get('http://mydomain.com/ajax2.php/', function(data){
var data_one = $(data).find('#ajax_editor_suggestion_container');
$('.ajax_editor_selection_container').append(data_one);
});
My objective is to have the contents of ajax1.php appended first and then contents of ajax2.php appended after that. However sometimes the contents of ajax2.php gets loaded before that of ajax1.php and messes up the appended order.
So my question is, how do I ensure that the contents of ajax2.php are always appended after the contents of ajax1.php?
I'm using $.get() because it's easier for me but I'm open to any other jQuery ajax methods.
Thanks
I would use $.when:
$.when(
$.get('http://mydomain.com/ajax1.php/'),
$.get('http://mydomain.com/ajax2.php/')
).done(function (response1, response2) {
var data_one = $(response1).find('#ajax_editor_suggestion_container');
var data_two = $(response2).find('#ajax_editor_suggestion_container');
$('.ajax_editor_selection_container').append(data_one).append(data_two);
});
That will run the ajax requests at the same time, but won't call the callback until both have finished.
Related
I already have some data in the elements i just want to load and append something more,
I want to load and append on each element that has the atribute data-load.
I was doing this but isn't working. Can someone help me on this, thanks.
$(function(){
$("[data-load]").each(function(index){
var $tmp = $('<div>');
var valueData = $(this).data("load")
$tmp.load(valueData);
$(this).append($tmp.html());
});
})
load() is a shortcut convenience method for $.ajax().
AJAX is asynchronous so the http request won't have completed at the time when you are trying to get the returned html from inside $tmp
You need to use the complete callback of load() to do anything within the returned result
To continue using load() method Try:
$("[data-load]").each(function (index) {
var $tmp = $('<div>'),
$el = $(this);
var valueData = $(this).data("load")
$tmp.load(valueData, function () {
/* the ajax has completed here */
$el.append($tmp.html());
});
});
Another shortcut method of $.ajax is $.get which I think would make this code more readable and a little shorter by not needing to create a temporary storage element
$("[data-load]").each(function (index) {
var $el = $(this);
$.get($el.data("load"), function(response){
$el.append(response);
});
});
Both solutions assume that data-load attribute is a valid url that returns the html expected.
I have a page view that makes an ajax call and updates the contents of the page with renderPartial.
So page.php -> _pagePartial.php (ajax update)
in page.php I want to include the javascript files once, then have the DOM modifications apply after the ajax rendering happens. It doesn't make sense to have this JS file load on every AJAX refresh.
For example in page.php
$baseUrl = Yii::app()->baseUrl;
$basePath = Yii::app()->basePath;
$cs = Yii::app()->getClientScript();
$cs->registerScriptFile($baseUrl . '/js/jquery.ui.js'); // load one time!
then in pagePartial.php
// every ajax partial load
$('#sortable-list-left').sortable({
connectWith:'.productEntryCol',
placeholder: 'ui-state-highlight',
update: function(event, ui) {
var sortOrderLeft = getSortOrder('sortable-list-left');
var sortOrderRight = getSortOrder('sortable-list-right');
var projectId = '" . $project_id . "';
$.ajax({
data: { left: sortOrderLeft, right : sortOrderRight, id : projectId},
url: '/project/ajaxUpdateOrder',
type: 'POST',
success: function(response){
// process JSON response
var obj = jQuery.parseJSON(response);
}
});
}
});
The problem is after _pagePartial loads via AJAX, it can't use the .sortable() method.
What is the proper way to handle this ?
Thanks
The way I handle this is on the main view on the $.load or $.ajax or whatever it is, add your code on the success function.
So for example:
$.get('_pagePartial.php', null, function(html) {
$('#result').html(html);
$('#sortable-list-left').sortable({
//all your sortable code
});
});
Another option is to add your javascript on your ajax loaded page ('_pagePartial.php') into a function like so:
function firejs() {
$('#sortable-list-left').sortable({
//all your sortable code
});
}
Then on your successful ajax call on your main view ('page.php') simply add this:
$.get('_pagePartial.php', null, function(html) {
$('#result').html(html);
firejs();
});
You can bind to an object until it is added to the DOM and it isn't added to the DOM until the ajax call has finished successfully and the result is added to the DOM.
Also just an FYI yii has jqueryui built in you can simply say:
Yii::app()->clientScript->registerCoreScript('jquery.ui');
Yii::app()->clientScript->registerCoreScript('jquery');
For people like me who has the same issue, even with:
Yii::app()->clientscript->scriptMap['jquery.js'] = false;
in the renderPartial and still not work. I've found another solution, way more effective I think. The easiest solution is to set the 4th parameter of renderPartial.
RenderPartial-detail
public string renderPartial(string $view, array $data=NULL, boolean $return=false, boolean $processOutput=false)
It is about processOutput.If you put it to true, then Jquery will be loaded in your render Partial.
Hope this will help someone...
I'm trying to translate some phrases with jQuery. This code mostly works great:
changeText = function(text, newText){
var currentText = $('span.example').html();
$('span.example').html(currentText.replace(text,newText)); };
window.setTimeout(function(){changeText("TranslateMe", "Translation")}, 0000);
However, it's mostly useless when you wait for ajax generated results. To clarify - this is a search script with the following procedure:
When you click Search, you get a part of the page loaded "normally". I can change these text strings without any problems.
Afterwards there are results loaded dynamically through ajax I guess and there are div "blocks" getting loaded one after another. These phrases don't get translated.
A workaround is to wait for some time until everything gets loaded and then it does work for some parts. E. g.:
window.setTimeout(function(){changeText("TranslateMe", "Translation")}, 20000);
However, that's not a good solution, because users see untranslated strings that way for some time.
Therefore, I'm looking for a solution that would change strings as they get displayed. Is there a way to do that?
Thanks in advance!
EDIT:
Trying charlie's approach:
<script>
changeText = function(text, newText, $el) {
$el.html(function(i, currentText){
return currentText.replace(text, newText);
});
};
$(function(){
changeText(text, newText,$('span.example'));
});
$.ajax({
success:function(data){
var $changeEl=$(data).find('span.example');
changeText(text, newText,$changeEl);
var currentText = $('span.example').html();
$('span.example').html(currentText.replace(TranslateMe,Translation));
};
})
})
</script>
Your best/cleanest approach would be to add a callback from where the AJAX Call is being made and the content has been inserted in the divs.
If that is not possible for you there might be a possibility for you to get a callback if the DOM changes as asked here and here
I agree with Tyron that if you can, you should add or modify the callback function to the AJAX calls.
as for detecting the changes and translating without access to the ajax. something like this might help.
var c = document.getElementById('[ID OF CONTAINER FOR UNTRANSLATED BLOCKS]');
c.__appendChild = c.appendChild;
//this function catches the element before it is appended
c.appendChild = function(){
//this applies the change
c.__appendChild.apply(c, arguments);
var newBlock = $(c).children().last();
//this hides the newly added block
newBlock.hide();
// now perform your translations on the newBlock contents
//here
// and then make the block visible again
newBlock.show();
};
If you change the function to add a context argument you could do something like:
changeText = function(text, newText, $el) {
/* html method allows for function as argument to modify element*/
$el.html(function(i, currentText){
return currentText.replace(text, newText);
});
};
Then on page load:
$(function(){
changeText( text, newText,$('span.example'));
});
And in AJAX success look for the new elements and modify them:
$.ajax({
success:function(data){
var $changeEl=$(data).find('span.example');
changeText( text, newText,$changeEl);
/* your code that inserts the new html here*/
})
})
I'm trying to load a page using the load() function, the problem is that javascript code on that page is being executed when loading. I use this:
$('#itemid').load('thepage.php #selector', function() {
MY CODE HERE
});
how can i prevent the javascript code from being executed and load only the HTML part that i want?
Use .get() or .post() and process what you get back. Pull the script tags out of your returned code before you append it to the page, or just pull out the code you want:
$.post('thepage.php', {
data: myData
}, function(data) {
var myHTML = $(data).not('script');
$('#itemid').html(myHTML);
});
Or:
$.post('thepage.php', {
data: myData
}, function(data) {
var myHTML = $(data).filter('#selector');
$('#itemid').html(myHTML);
});
Demo: http://jsfiddle.net/jtbowden/wpNBM/
Note: As you mentioned, using a selector with load should accomplish the same thing, as you see in the example. So, if it isn't working this way, something else is going on.
Not sure if I have understood the problem correctly, but you could remove the javascript and just have the html. I assume you want to js bindings to happen on the new page though. So when you load the new page, in the callback, you could call a function that applies the needed bindings.
function applyAfterAjax(){
$(this).find('element').click(function(){alert('clicked');});
}
$('#itemid').load('thepage.php #selector',applyAfterAjax);
I'm trying to get my jQuery to work in this flow:
Parse json using $getJson
Loop through returned JSON and create divs for each JSON item
Once done, repeat but instead with another json file and append the results to the existing results.
But as of now I can't call another function AFTER the first loop is done, because the function gets called before the page is populated. How can I finish the populating loop, and then call another function?
I appreciate any help you can give me. Still learning as you can tell.
function test() {
var i;
for(i=0;i<=10;i++) {
$("div#test").append("<div id='"+i+"'></div>");
}
when_loop_is_done();
}
function when_loop_is_done() {
var i;
for(i=0;i<=10;i++) {
$("div#test div#"+i).append("<span>foo</span>");
}
}
Essentially I'm grabbing JSON from a separate page on my server, then looping through and populating the content using variables from that JSON object. The issue is no matter what I do, the second function always gets called before jQuery populates the content. So if I were to call an alert after the loop is done the page would pop up the alert and then load in all of the appended html.
Store your results in a variable or property. Then, use $(document).ready(fn) to wait for the page to finish loading and populate the page or finish your work when it has finished loading.
Your code should look something like this:
$.getJSON('/remote.json', function (response) {
// do the first loop using the response json
})
.done(function () {
// do the second json request and loop through the results
});
Any code you call inside the done() method's callback function will wait until the previous method in the chain is complete. You should definitely review the API documentation for $.getJSON: https://api.jquery.com/jquery.getjson/