I am new to javascript and the whole front-end side of development.
Here is what I am using:
Java servlet running on Tomcat7
twitter-bootstrap for the layout/theme
Pubnub to keep track of how many times a form is submitted
Javascript/jquery to display this value on a webpage.
I have added the PUBNUB.subscribe callback which updates the value on the webpage just fine. However, when I first load the webpage, I don't know what value I should display.
Here is what I did to overcome this issue:
I added a method to the servlet that, when passed in the correct parameter in a POST request, it will send out a pubnub message with the amount to be displayed which is working fine.
Next, I tried to call a POST request using jquery like this:
$.post("../servlets/theservlet",
{
update : "true"
});
I tried placing that inside a $(window).load function but when I loaded the webpage, it did not do what I expected.
I expected it to do the POST after everything was loaded, which would cause the pubnub message to be published from the servlet, which would activate the callback method in the PUBNUB.subscribe function. However, the value didn't change, it stayed as the placeholder that is hardcoded in the html.
Currently, I am now calling setTimeout("updateUses()", 1500); from within the $(window).load function. updateUses() is the exact same $.post call I showed earlier.
Now when I load the page, the placeholder value is there for a little bit (seems longer than 1.5ms) and then it is updated to the correct value. If I remove the setTimeout and just call updateUses() directly, then nothing happens again.
What do I need to change so that it loads the value instantly (or at least without a noticeable delay)?
If the page builder is JSP and what I have just read is correct then you should be able to do something like this:
RequestDispatcher rd=application.getRequestDispatcher("path/to/pubnub/servlet");
rd.include(request,response);
If you choose to stick with the ajax approach then the javascript should look something like this:
$(function(){
$.post("path/to/pubnub/servlet", {update:"true"}, function(response){
//do whatever is necessary with the response here, eg.
//$("#myElementId").html(response);
});
});
The $(function(){...}) wrapper ensures the code inside it is executed at the earliest opportunity after the DOM becomes ready. Hence no need for a timeout. jQuery is typically written inside such a wrapper.
Related
Anytime I click on a link/button anywhere on my site that performs/calls a GET or POST (Ajax and non-Ajax), if it takes more then a few seconds I would like to display a loading gif. I know how to do this on an individual basis, but I would like to know if it is possible to create a function that will do this automatically and then hide the gif when finished (assuming it does not redirect to a new page).
I found this but this does not work with the post method for spring security for example.
It may be a case where it is not possible or requires more effort than it's worth. I would just like to know if it is possible and if so how might it be approached.
The only constraint is that any methods calling the post or get should not need to be aware of this so called "listener".
This is tagged jQuery so I'm giving a jQuery answer for simplicity. This is also solvable in a relatively simple manner without it.
Hooking on every request:
Let's say your method is called myMethod.
GET/POST requests may be triggered the following ways:
Form submits, in which case you can select the form $("#formID").submit(myMethod); . Note that if myMethod returns false it will cause your form to not submit
AJAX in which case you can use $.ajaxStart with $.ajaxStart(myMethod)
"a" tag clicks, and other click handlers, in which case you can perform $("a[href]").click(myMethod) , note that this selects all a tags with an href attribute, you might want to change the selector to suit your needs
Image loads which you can handle like explained in this question.
Script loads which you can detect like explained in this question.
Stylesheet/Link loads, which is explained in this blog post. You can add a hidden element to the CSS and check if the style was applied in an interval, and when it does call myMethod
What you can't do:
If your page has a plugin like Flash, or in general anything your JavaScript does not have access to, you can't hook on requests it makes.
The case of displaying a 'loading' gif.
From what you're asking it seems like you only care about image requests, and AJAX requests (correct me if I'm wrong), since external pages that take a long time to load NOT in an AJAX requests can (should) implement that .gif logic on the new page. This could be handled as I explained above.
Although you can hook every case, I would not do so. I would create a method that loads the 'loading' gif into a place and accepts a url. If that url is an image (for example, by file extension if that's ok with your mapping) use the logic in the image load detect linked question, if it's AJAX load the loading gif to where the data will be loaded, and replace it with the data on a .done() handler.
Here is a question about how to do this for an image, here is how to do it for AJAX . The two can be easily combined into a method which is what I believe you should use.
My question is about using Back and Next buttons (of the browser) on an AJAX (dynamical) webpage.
The solution I self came up with:
setInterval(function(){
if (location.hash != hash)
{
hash = location.hash;
app.url = window.location.href.toString().replace('http://xxxxx.nl/xxxx/#!/','')
app.handleURL();
}
}, 500);
this function reads the url(hash) and compares it with the last stored url(hash), every 0.5 second. If url has changed (back/next is pushed) it runs handleUrl() which runs more functions to dynamically build my page.
the problem is, this sort of works BUT when I click an html [A] element or when I change the url in an other way (javascript), that content will be loaded TWICE because of the setInterval()... functionality.
How can I build my HTML/Javascript in such way that my content will always be loaded once,
once when I push back/next
once when I click on an HTML element/use Javascript functions on
runtime
I searched the sh*t out of google for a solution, plz help!
You don't need a timer to check it. Just use the onhashchange event, and fire your AJAX calls when the event is called. This event isn't supported in IE versions below 8, though, so your method seems fine if you need IE support.
Also, it doesn't make sense that they're being called twice for a elements, since there's no reason for the interval to call your AJAX loader twice just because the hash was changed using an a element. You probably have an event listener attached to the a element which causes it to load the AJAX content, which wouldn't be needed since you're detecting any change in the hash, no matter how it was changed.
I suggest using a library for that. It will be tricky to make your own solution. Take a look at these:
http://www.asual.com/jquery/address/docs/#sample-usage
http://benalman.com/projects/jquery-bbq-plugin/
Here's the case:
We have a file upload page. We didn't want to reload the page once the upload is done, so we put the form inside of an iframe. The form inside of an iframe posts to itself and returns json when it's done. How can we capture that response? When upload is done, the iframe reloads, so in other words, how do we capture when the iframe is reloaded?
Assume these:
we cannot print/return anything except the json object (so no js code to call the function in a parent document.)
we cannot use ajax since you cannot post files using ajax
we cannot append javascript code inside of iframe, because once the form inside of iframe is submitted, the page gets reloaded and we lose the appended js code.
Any ideas?
UPDATE - Seems like the solution is super simple (found it somewhere online):
<iframe onload="alert(window['upload_iframe'].document.body.innerHTML);" ...></iframe>
This way, it will fire the alert whenever page inside of an iframe is reloaded. Now it's just matter of differentiating JSON object from HTML code, which is pretty simple. Thanks for everyone for a great advises!
Have you tried appending an "onload" listener to the iframe element to see if when the iframe source is changed it's triggered? That might be a solution. If it doesn't work, then I don't think you have a choice but to execute a top level function from the iframe result.
update
Since you don't have control over the response from the servlet, perhaps you could build a PHP median that communicates with the servlet and takes the raw json it gets and then returns what it needs to execute a parent window javscript function and passing the json to that function.
This way you control the output.
You could check whether the content of the iFrame has changed by performing a timed check of the inner text of the iFrame document against whatever it was last time you checked ( or a hash of it if the document is large ) and then once it has changed you could try parsing the content as JSON to check it is the expected response.
Alternately you could use AJAX to check whether the upload has completed on the server side and once the server confirms that it has finished uploading you can then check the iFrame content.
I am submitting multiple data multiple times on one button click.
First I submit data to a variable number of hidden iframes (the form is enctype="multipart/form-data"). Then I would like to run the normal submit button/function which redirects the main page.
If i do this all in one function though, I don't end up recieving all the data I send to the hidden iframes. I believe the redirect begins before the other forms finish sending (sometimes I receive the first data submitted, most of the time I receive none).
I have hacked a solution using setTimeout(function(){$("#submitbtn").click()},3000)... but clearly this won't always take 3 seconds. I want a way of detecting when it finishes so I can start the submit.
Sorry if this is hard to understand, if you need more info just comment/ask.
I'm not sure how you are submitting that data to the iframes but if you are using $.ajax you can set async : false which will pause every jQuery event, animation, etc. There may be something similiar if you are using a different method.
If you are using AJAX I recommend using the success callback of jQuery's $.post.
e.g.
$.post('/process', form_data, function(data) { document.location = '/thankyou'; false})
In this example after the post data has been successfully submitted the user will be redirected to /thankyhou
You can also use $("#submitbtn").click() in the callback.
I managed to do it by using the IFRAME.load, to detect changes to the target iframes. Once all iframes.load()'s fired I fired the last submit (the one that redirects the main page).
I have a website that I'm working on. I'm using jquery to animate and display content. This content is stored in vars. I need to know how to load the content before displaying it.
For clarification, you click a link, a "loading..." window fades in, and once it loads everything, it fades out and fades in the loaded content that is stored in vars.
Thank you
Are you looking for how to request HTML content via AJAX, know when it is finished, and then insert it into the DOM? If so, jQuery's load method may be what you're after.
Steve
AJAX event will not tell you how many percent was loaded, in fact, in most cases, it has no idea how long is the response will be. But it will inform you when the response is completed, or error occured.
Take a look at the official reference AJAX of JQuery. My original answer was wrong, coz I suppose you already have the data. A simplified use case for your ajax request would be:
> Initiate the Request, and set the handler for ajax complete (thru something like $.Ajax)
> Hide the content pane and show the loader
> When ajax complete, you display your content, and hide the loader
Following is the original answer.
I think you are talking about something that's already in the client computer's memory, but you want to display all immediately once it's completed loading. Sounds like those "double buffering" in offline media.
What you can do, is:
// Display the loading screen, you can put any animation
$("#loader").fadeIn();
$("#contentPlaceHolder").hide();
// attach the DOM of the contents to placeholder.
$("#contentPlaceHolder").append(CONTENTS);
// .... similar statements follows.
// and finally..
$("#contentPlaceHolder").show();
$("#loader").fadeOut();