I am ganging my head against the wall for 3 hours now. I have this code:
function showpctask() {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
var xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("pcactivitytask").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.open("GET","showpctask.php"+,true);
xmlhttp.send();
}
that opens up a php file inside a div (id = pcactivitytask). That php file builds a 'select'
I also have this function right here:
function setpctaskwidth() {
var maxtaskwidth = 0;
$("div .pcactivitytask").each(function(){
c_width = parseInt($(this).width());
if (c_width > maxtaskwidth) {
maxtaskwidth = c_width;
}
});
alert (maxtaskwidth);
}
that will show me the max width of all elements with the the class of "pcactivitytask". Yes, the select created by the previous script has that class. If I call both these function it will NOT include the width of the NEWLY created select..... I need to run it AGAIN 'manuall'. I need my script to "onclick" BOTH build the NEW select AND include it in finding the max width by the second script. Thank you.
XMLhttprequest works asynchronously, meaning it does not happen in order.
that is why you have the xmlhttp.onreadystatechange callback function, that only runs once the request is finished
you do not specify how you call these two functions but I would expect to see the call to setpctaskwidth() inside the onreadystatechange function like this:
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("pcactivitytask").innerHTML = xmlhttp.responseText;
setpctaskwidth();
}
};
be advised that if the response includes images or other external resources (fonts etc) that don't already exist in the page you might get a different size than the actual final size (it will measure the size before the image is loaded)
Related
This is my first php project. I have imlemented partial ajax postback by refering to this article: PHP AJAX SQL reference article
Now, I am trying to show a loading gif when the partial loading starts and hide it when the partial loading completes. Here is the code that I am using in Javascript:
function showUser1(str)
{
if (str == "")
{
document.getElementById("mems").innerHTML = "I caanot fetch: " + str;
return;
}
else
{
document.getElementById("loadgif").style.visibility= "visible";
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else
{
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("outerpicwrapper").innerHTML = "";
document.getElementById("mems").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.open("GET","getmembers.php?q2="+str,true);
xmlhttp.send();
document.getElementById("loadgif").style.visibility= "hidden";
}
}
In the first line of body, I have written:
<img id="loadgif" src="img/loading.gif" class="loadinggif" />
In the CSS file, i have written:
.loadinggif
{
position: absolute;
z-index: 200;
visibility: hidden;
}
The code is working fine and shows the data but, loading gif is not shown.
I have even tried display:none and display:block in place of visibility.
Kindly help.
The problem is AJAX is asynchronous. Thus your code doesn't wait for the data to be fetched and
document.getElementById("loadgif").style.visibility= "visible";
document.getElementById("loadgif").style.visibility= "hidden";
These lines are executed simultaneously.
To prevent this from happening you can put
document.getElementById("loadgif").style.visibility= "hidden";
inside the callback as well
function showUser1(str)
{
if (str == "")
{
document.getElementById("mems").innerHTML = "I caanot fetch: " + str;
return;
}
else
{
document.getElementById("loadgif").style.visibility= "visible"; // This line displays the loading gif
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else
{
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("outerpicwrapper").innerHTML = "";
document.getElementById("mems").innerHTML = xmlhttp.responseText;
document.getElementById("loadgif").style.visibility= "hidden"; // This line hides the loading gif
}
};
xmlhttp.open("GET","getmembers.php?q2="+str,true);
xmlhttp.send();
}
}
Finally, I made my issue work out using JQuery.
I just made display:none in CSS and called the show() function of jquery on the loading gif div. This show function was written inside the javascript code.
I have a button calling an ajax function which loads a PHP script returned as innerHTML. It does return the output to the screen but the problem looks to be that it is not implementing javascript to format the outputted HTML. So I should have 6 boxes per line (dictated by salvattore.js) but instead it stretches 1 div across the screen. I can also tell my own js is not initialised until I do a window resize. Heres the script..
function submitForms() {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("searchResults").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET","ideasSearch.php?",true);
xmlhttp.send();
}
and HTML
<div id="searchResults"></div>
i have a span with the same value..
echo "<span id='msgNotif1' class='badge' style='position:relative;right:5px;bottom:10px;'>".$number."</span>";
where $number have a value..
and my js code is..
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var val = xmlhttp.responseText;
//alert(val);
document.getElementById("msgNotif1").innerHTML = val;
//document.getElementById("msgNotif2").innerHTML = val;
alert(val);
//document.getElementById("msgNotif3").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "some page", true);
xmlhttp.send();
the problem is the value still remains and do not change,
trying to uncomment the first alert shows an alert with the right value, but when i try to comment it the second alert never executed, giving me an idea that the document.getelementbyid().innerhtml is the one that is not working, been with this for a few hours,
any help will be appreciated.
thanks in advance
Your error message Cannot set property 'innerHTML' of null" means that:
document.getElementById("msgNotif1")
is returning null. That can happen for several possible reasons:
There is no element in your page with id="msgNotif1".
You are calling this code before your document has finished loading and thus the element with id="msgNotif1" has not yet loaded. This can commonly happen if you execute your code in the <head> section of the document rather than at the very end of <body> or in response to the DOMContentLoaded event.
Your content is dynamically loaded (not in the original page HTML) and you are calling document.getElementById("msgNotif1") before your dynamic content has been loaded.
You have some HTML errors which are preventing the proper parsing of your HTML that contains the element with id="msgNotif1".
For a general purpose description of how to run Javascript after the current page has been loaded without using a framework like jQuery, see this answer: pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it
You are receiving this error in your console because it doesn't exist at the time your script is running. This can be caused if the element hasn't been loaded when your script is running, if your IDs aren't the same, or if the element doesn't exist in your html. If you are referencing the element before it loads, add a function that executes when your page loads.
You can use JQuery
$(document).ready(function(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var val = xmlhttp.responseText;
//alert(val);
document.getElementById("msgNotif1").innerHTML = val;
//document.getElementById("msgNotif2").innerHTML = val;
alert(val);
//document.getElementById("msgNotif3").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "some page", true);
xmlhttp.send();
});
or with pure Javascript to create the event.
window.onload = function(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var val = xmlhttp.responseText;
//alert(val);
document.getElementById("msgNotif1").innerHTML = val;
//document.getElementById("msgNotif2").innerHTML = val;
alert(val);
//document.getElementById("msgNotif3").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "some page", true);
xmlhttp.send();
};
Valid points have been brought up in that doing Ajax requests with pure Javascript takes much more code than if you were to use JQuery. This is the reason why I (and many others) use JQuery for all the Ajax requests performed. JQuery has many methods for Ajax that will save a lot of time and code and in the long run will reduce your file size by a few bytes since, with JQuery, the code is reused.
I understand that jQuery will not run when the DOM content is being loaded via AJAX. But I'm confused as to the reason why. My understanding was that the DOM elements didn't exist at the time the jQuery was initiated therefore it won't find the correct IDs or classes.
But I have a situation where the jQuery is only called AFTER all the content has been loaded via AJAX. yet it still does not work.
Here is my code. I am trying to get the function decorateGains() to run after AJAX completes.
loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type){
var xmlhttp;
if (window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}
else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200){document.getElementById("home-table").innerHTML=xmlhttp.responseText;}
}
xmlhttp.open("GET","actions/get-data-"+type+".php",true);
xmlhttp.send();
decorateGains();
}
You can see that I am including a call to the function decorateGains() right at the end of the loadData() function.
The decorateGains() function does run, as I can see my console message. However it does not do the task that it should.
function decorateGains() {
console.log('here');
$(".gains").each(function() {
var num = +($(this).text());
if (num > 0) {
console.log('here');
$(this).addClass("positive");
}
if (num < 0) {
console.log('here');
$(this).addClass("negative");
}
});
}
(The script searches for all elements with a class of .gains and adds a new class of positive or negative depending on the content of the element. Essentially it decorates the .gains element to be red or green depending on whether the number is negative or positive).
This is because the AJAX call is asynchronous. The request has not been completed (and therefore the new content has not been appended to the DOM) when you call your decorateGains() function. You need to place the call to the function inside the onreadystatechange handler, after setting the innerHTML:
loadData('7-days'); // Runs the default AJAX for 7 days
function loadData(type) {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("home-table").innerHTML = xmlhttp.responseText;
decorateGains(); // <-- move this in here
}
}
xmlhttp.open("GET", "actions/get-data-" + type + ".php", true);
xmlhttp.send();
}
I want to write a JavaScript code that load HTML contents of a given URL and place the loaded HTML code exactly where the script is placed. (maybe this looks like functionality of the iframe tag, but i dont want "iframe tag" become a medium. i just want to load the html code and place it there without adding any container or extra parent)
something like this:
var url = "http://example.com/";
var html = loadhtmlcontents(url); // something like simplexml_load_file($url) for php and xml
document.write(html); // somthing like saveHTML() in DOMDocument class of php
I've tried AJAX approach but it doesn't work:
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.wirte( xmlhttp.responseText);
}
}
xmlhttp.open("GET", Url, false );
xmlhttp.send();
could you please give me an equivalent or correction to these? (pure JS approach is preferred to JQuery for me in this situation)
Getting the current script tag is possible, but here's another approach (keep in mind it replaces the entire element with the id tag):
In the body tag:
<script id='test'>docWrite('test', '/echo/html')</script>
Javascript declaring a new function:
function docWrite(id, url) {
var xmlhttp = new XMLHttpRequest(),
_id = id;
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState == 4
&& xmlhttp.status == 200) {
var el = document.getElementById(_id),
textnode = el.firstChild,
div = document.createElement('div');
div.id = _id;
div.appendChild(textnode);
el.parentNode.insertBefore(div, el.nextSibling);
el.parentNode.removeChild(el);
console.log(xmlhttp.responseText);
}
}
xmlhttp.open("GET", url, false );
xmlhttp.send();
}
http://jsfiddle.net/dpgk1Lx2/
Here, all I'm doing is copying the contents of the id-related tag (there is no responseText to display). In your usage, you would do this instead:
function docWrite(id, url) {
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState == 4
&& xmlhttp.status == 200) {
var el = document.getElementById(_id)
div = document.createElement('div');
div.id = _id;
div.appendChild(xmlhttp.responseText);
el.parentNode.insertBefore(div, el.nextSibling);
el.parentNode.removeChild(el);
}
}
xmlhttp.open("GET", url, false );
xmlhttp.send();
}
I know you are looking for a jQuery-less version... but I'm going to post this first... just to indicate how simple it is (and it works around browser differences in making AJAX calls, handling callbacks etc. for you).
<div id="someID"></div>
<script>$('#someID').load('someurl.html');</script>