Came here again with lame questions as I am in process of learning/coding.
I would like to change a property of a disable value on button: During function performing its job, button should be disabled, once function finishes and return the values, button should be enabled again.
In function which creates a buttons I am calling update() function which loading php file via XMLHttpRequest. Then running the php code and return values on page. I want to have button disabled during this time. But everytime I call the function the button will not change. Or if changed it was so fast that I didnt even saw it.
here is a code:
global_button = document.createElement("button");
// let btn1 = document.createElement("button");
global_button.innerHTML = "UPDATE";
global_button.id = "update";
global_button.disabled = false;
document.body.appendChild(global_button);
document.getElementsByClassName("two")[0].append(global_button);
global_button.addEventListener("click", function () {
console.log("After CLICKED");
global_button.disabled = true;
update();
global_button.disabled = false;
console.log("AFTER FUNCTION RETURN VALUES");
update function:
var xmlhttp;
function loadFile(file, func){
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = func;
xmlhttp.open("GET", file, true);
xmlhttp.send();
}
function update(){
loadFile("update.php", function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("content").innerHTML = xmlhttp.responseText;
}
});
}
When I checked the console, it shows both console logs immediately: "After CLICKED" and "AFTER FUNCTION RETURN VALUES" messages. And couples seconds later, result of the function appear. But button wont change whatsoever.
I am suspecting the sync/async functions ? I read something for the .open method and vale true/false, but nothing changed if I switched from true to false. Also thinking if I should put it on the loop or something which will check the button clicked ? But I thought that listener would do the job.
Can anybody check and give me an advice ? or correct my thinking if it's wrong?
many thanks all of you. :)
The problem is indeed due to the asynchronous nature of thesend
method ofXMLHttpRequest
- and therefore of yourupdate
, which calls it.
When you callupdate()
, which itself calls this:
loadFile("update.php", function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("content").innerHTML = xmlhttp.responseText;
}
});
all that happens is that you set up anXMLHttpRequest
object and use itssend
method to send a request, telling it to call this function:
function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("content").innerHTML = xmlhttp.responseText;
}
});
as a "callback" when thereadyState
changes. (And in particular, when the request is complete and a response received.) But callingupdate
does not wait for that state change to happen and block your code from running - hence the next lines of code, which set thedisabled
state of the button to false and log to the console - are executed straight away. So the button gets disabled but then instantly un-disabled, and therefore you never see it disabled. (In fact the browser will never even "paint" the screen with a disabled button, since it doesn't get a chance to do this while your code is running, so even if you could in theory do a freeze-frame here you would never see a disabled button.)
To fix it, you have to work with the asynchronous code you're using. Anything you want to happen after the state change has to take place in the callback function you pass it. So you can simply fix your problem by changing theupdate
definition to this:
function update(){
loadFile("update.php", function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("content").innerHTML = xmlhttp.responseText;
global_button.disabled = false;
console.log("AFTER FUNCTION RETURN VALUES");
}
});
}
and delete those two lines of code from the place you've currently got them, after theupdate
call.
Although note that this will only work ifglobal_button
is in scope insideupdate
, which it might not be depending on how your code is structured (it probably shouldn't be to be honest). And even if it does, it's not good to hardcode yourupdate
to always undisable the button afterwards, with no guarantee the button will even be disabled first.
It's therefore better to defineupdate
to itself take a callback function:
function update(callback){
loadFile("update.php", function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("content").innerHTML = xmlhttp.responseText;
callback();
}
});
}
and then call it like this in your main code:
global_button.disabled = true;
update(function() {
global_button.disabled = false;
console.log("AFTER FUNCTION RETURN VALUES");
});
because this separates the concerns ofupdate
itself ("make this request and set thecontent
inner HTML to the response"), from whatever you might want to do afterwards, which could be different each time.
Finally, I can't not mention that this callback-based asynchronous code is very old-fashioned now.XMLHTTPRequest
itself is quite a cumbersome API. I highly recommend you look into its modern equivalent,fetch
, which is based on Promises - which while not without their mental gotchas are a much more understandable way to write asynchronous code. In particular withasync
andawait
you can write code that looks much like what you originally had: puttingawait update();
would actually do what you are waiting, and have the rest of your code wait forupdate
to complete. But you can't just make that change to your original code because that only works ifupdate
returns a Promise, which in turns would mean completely rewriting yourloadFile
to use a more modern, Promise-based approach.
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Find the answer in similar questions on our website.
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.
PHP (from the English Hypertext Preprocessor - hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/
JavaScript is a multi-paradigm language that supports event-driven, functional, and mandatory (including object-oriented and prototype-based) programming types. Originally JavaScript was only used on the client side. JavaScript is now still used as a server-side programming language. To summarize, we can say that JavaScript is the language of the Internet.
https://www.javascript.com/
HTML (English "hyper text markup language" - hypertext markup language) is a special markup language that is used to create sites on the Internet.
Browsers understand html perfectly and can interpret it in an understandable way. In general, any page on the site is html-code, which the browser translates into a user-friendly form. By the way, the code of any page is available to everyone.
https://www.w3.org/html/
Welcome to the Q&A site for web developers. Here you can ask a question about the problem you are facing and get answers from other experts. We have created a user-friendly interface so that you can quickly and free of charge ask a question about a web programming problem. We also invite other experts to join our community and help other members who ask questions. In addition, you can use our search for questions with a solution.
Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.
Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.