How to get updated page content after a JS event using phantomjs? - javascript

I have a page with a simple form. This form has ONE input text.
I have this code:
page.open("http://www.example.com", function (status) {
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() {
page.evaluate(function() {
$('input[name=myText]').val('my content');
});
});
});
(as you can see i also loaded jquery)
Now, when i set the content of this input text, the page changes, the content of the page changes.
My question is: how can I get the updated content?
The problem is that i need to submit the form but i can not do it after:
$('input[name=myText]').val('my content');
because when i set it there is an JS event on the page that changes the content.
SO I must read the new content, find the form using JQuery and then submit it.
Could someone help me?
Thank you!

So your page.evaluate() call has a side effect and that changes the page. The question is whether this change occurs instantaneously. But you cannot assume that it does - particularly if it causes a fetch of new content from a remote webserver.
That being the case the best thing you can try is to sleep for a while and then assume your page has the new content. Or alternatively, when you feel more advanced, poll on a regular basis for a DOM object you are expecting to appear. But the beginner should try a sleep:
....
page.evaluate( function() { ... } );
window.setTimeout(
function() {
/* press submit button */
},
5000 /* wait 5 seconds (5,000ms) */
);
....

Related

How to fix: Ajax - Post request running multiple times

I have a table (formatted with Datatables script) and it has a column which contain few icons to manage actions. When user click on an icon, it load a modal and get the modal content using POST method.
Modal has a save button to complete the action after user make their choice. When they click save button, another post script complete the request and feedback to user.
This process working fine when the first time user load the page. There is a refresh button on the page which can reload the TABLE without reload the PAGE.
If user use this button to refresh the page and try above action. it open the modal and Save button trigger the post action 2 times. If the user refresh the page (using the refresh button) again and try one of the action icons, post script run 3 times... in other words if you refresh 10 times post script run 10 times...
if user use the browser refresh button, we don't get this repetition.
Just wondering whether we can fix this without get rid of the refresh button.
We tried different ways to place the script within the page. but still cannot understand what is triggering the multiple post request.
//javascript
//step 1 - load the modal with an action list
$("#proj_data tbody").on("click", ".update_job_progress", function () {
var pn = $(this).attr('mypn');
$.post('reports_job_progress.php', {proj: pn}, function (data) {
$('<div id="progress_update_modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"></div>').appendTo('#modal-container').html(data).modal();
});
});
//step 2 - save user choice
$('body #modal-container').on('click', '.btn_jobaction', function () {
var pn = $("#pn").val();
$.post("reports_job_progress_backend.php", $("#progress_list").serialize(),
function (res) {
if (res === 0) {
alert("There is a problem saving the information. please try again");
} else {
$("#prog" + pn).html(res);
$("#progress_update_modal").modal('hide');
}
}
);
});
//step 3 - destroy the modal
$("body").on("hidden.bs.modal", ".modal", function () {
$("#modal-container").empty();
});
Could you please help me to understand the issue with this code?
It looks like your problem is being caused by binding multiple onclick handlers to the element. Please try using off like this $("#proj_data tbody").off("click").on("click", ... and see if that fixes your issue.
#buffy solution worked. However just adding .off('click') was disabling other icons click event as all icons share the same class. after playing with the code i found adding $(this).off('click') does the trick. Now everything working perfect. Thanks #buffy for providing correct directions.
You will bind the click event multiple times. You could either reset the callback, check if the callback has been set or (much better) set the click listener in a part of your script, that will not be executed, whenever you refresh your page (with the mentioned refresh button) like:
$(document).ready(function() {
$('body #modal-container').on('click', ...
$('body #modal-container').on('click', ...
});

AJAX stop working on loading same site different PHP id

So i have a website that I'm doing for a school project. It's supposed to be like PasteBin. So on the right theres a different div (Uued koodid) that shows newest pastes. On click, they are supposed to show what they include using AJAX to refresh the left div. This only works for 4 times and then stops, but URL is still changing. After refresh it changes again and works again for 4 more times.
In main.js i have
...
$.ajaxSetup({ cache: false });
...
$(".uuedKoodid").click(function () {
$(".left-content").load(document.location.hash.substr(1));
});
...
EDIT:
Also other AJAX functions work. If I log in, I can switch between settings and profile perfectly but still cannot watch new codes
When you replace right menu with new code (from ajax call) you don't attach click event again on .uuedKoodid items so they don't do anything. You need to attach event again or attach it like this:
$(document).on('click', '.uuedKoodid', function () {
$(".left-content").load(document.location.hash.substr(1));
});
Edit:
As you noticed this will cause small problem. onclick event run before browser run standard link action. First you load ajax and then browser changes address. This way you are 1 action behind. Better solution than reading with delay (setTimeout) i think would be to read address directly from link:
$(document).on('click', '.uuedKoodid', function () {
var url = $(this).attr('href');
$(".left-content").load(url.substring(url.indexOf("#")+1));
});

JavaScript Setting property of a disabled button

PRE EDIT: It turned out that it was not about the disability of the button, but making some other actions after save. I debugged the page and found out that after making changes on a saved form, then page loses the javascript functionality in the (document).ready part. I've added the solution as an answer.
I have an entry page which has two buttons save and approve. The mechanism is something like, you can fill the form and save, then approve. You can also reach a saved page by refreshing the page or from the list of your saved pages.
The approve button is disabled if the form is not saved. I enable it from code behind after saving. Approve button also has a confirm button extender which takes its confirm text from javascript. I load it in (document).ready and its code is:
$(document).ready(function () {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_btnApprove").click(function () {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_lblMessage").text(GetConfirmTextForApprove());
});
});
,where GetConfirmTextForApproval() makes some calculations and returns the confirm text.
Now, my problem is, as the button is disabled when you open the form, the code above is not rendered at the first page load. This leads to the problem that, when I start to fill a form and save it, then approve it, I don't get any confirm text, because it does not run the function. But after refreshing the page or after I go to a saved form's page from another page, I get the proper confirm text.
So, how can I solve this problem? How can I get the proper confirm text even though the button is disabled at the first page load?
Note: I have to add that after saving, the url of the page is changed. The query string is added. That might also cause the problem.
You can use
// Disable #x
$( "#x" ).prop( "disabled", true );
// Enable #x
$( "#x" ).prop( "disabled", false );
But not when document ready, you need enable button when you want. Then you need create a event listener
$("#button").click(function(){
//Your code
if(GetConfirmTextForApproval()){
//You active the button and the text that you want show.
}
});
Solved my own problem:
As it was said in the pre edit of the question, the problem was caused because of making changes after the save. I've changed my function as:
$(document).ready(function () {
SetConfirmMessageForApproval();
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
});
function EndRequestHandler(sender, args) {
SetConfirmMessageForApproval();
}
function SetConfirmMessageForApproval() {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_btnApprove").click(function () {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_lblMessage").text(GetConfirmTextForApprove());
});
}
This helps, if anyone else needs it.

Multiple Ajax loading indicators on 1 page

I have a page with 2 separate forms that can be submitted via Ajax (jQuery). For each of these forms I'd like to show a loading indicator to the user. I have found a nice piece of code that can easily show these icons, but it only works when there's 1 form.
$('.ajaxloader').hide().ajaxStart(function () {
$(this).show();
}).ajaxStop(function () {
$(this).hide();
});
ajaxloader is a class which shows the loading image as a CSS background image. To use it, I just need to add something like: <span class="ajaxLoader">Busy ...</span>
When I test this with my page (that has 2 forms), and I submit one of the two, then both loading indicators appear (which is quite obvious). Now my question is, how can I show the indicator that needs to be shown? I was thinking about giving the span-tag an id attribute, but then I don't know how to proceed. I want this to be as generic as possible, so I don't have to hardcode and duplicate code a lot.
Thanks!
You could attach the "show loading indicator" callbacks to the Ajax queries themselves, not do a 'catch-all' like your current solution.
Something like this in your $.ajax() call:
$.ajax("/form1/target", {
beforeSend: function() {
$(".ajax-loader-1").show();
},
complete: function() {
$(".ajax-loader-1").hide();
}
});
(And a similar one for your second form, wherever the Ajax call for that is defined)
Have you thought about starting it when your form is submitted and hiding the other.
$('.yourSubmitButton').click(function () {
$(this).parent().find('.ajaxLoader').show();
});
$('.ajaxloader').hide().ajaxStop(function () {
$(this).hide();
});
So the loader will show inside the form that has just been submitted (I assume you are doing a submit with a button or a link?) then both are hidden again when the ajax request stops.

jQuery replace all HTML

I'm trying to replace all the HTML (including the HTML tags) with another page. What I'm trying to do is having a website acting as an app even when navigating the another page.
Here is the code :
(function($) {
Drupal.behaviors.loadingPage = {
attach: function(context,settings) {
$('a').click(function(event) {
event.preventDefault();
// Create the loading icon
// ...
$.ajax({
url: $(this).attr('href'),
success: function(data) {
$('html').replaceWith(data);
}
});
});
}
};
})(jQuery);
I've tried several things. replaceWith() causes a jQuery error in jquery.js after deleting the HTML tag, I guess it is because it can't find the parent anymore to add the replacement.
The best result I got was with document.write(data). The problem is, the javascript code on the loaded page is not executed.
Anyone got a better idea ?
A better idea? Yeah, just load the new page normally by setting window.location instead of using AJAX. Or submit a form.
Otherwise, if you want to load something to replace all of the visible content of the current page but keep the current page's script going, put all the visible content in a frame sized to fill the browser window - which, again, you wouldn't populate using AJAX.
(I like AJAX, but I don't see why you'd use it to replace a whole page.)

Categories