sending arguments from one function to another through event handler - javascript

I have two functions here, the first one is triggered by a button and it is meant to trigger a second function which will change the inner html of that first buttons accompanying html area.
My problem is how to pass the arguments from the first function INTO the second one to the button and textfield have the same idnumber.
function doLoad(idnumber, id) {
var file = _(id).files[0];
_("Btn1_QP_"+idnumber).style.display = "none";
_("Display_QP_"+idnumber).innerHTML = "Image uploading......";
var formdata = new FormData();
formdata.append("stPic", file);
var ajax = new XMLHttpRequest();
ajax.addEventListener("load", completeHandler, false);
ajax.open("POST", "pho_stem3.php");
ajax.send(formdata);
}
function completeHandler(event) {
_("Display_QP").innerHTML = 'wahooo';
}
}
In function doLoad idnumber is given by the button and used to identify the proper button with("Btn1_QP_"+idnumber)
how can i achieve this same selective ability in the second function completeHandler in the event listener.
I have tried
ajax.addEventListener("load", completeHandler(idnumber), false);
ajax.addEventListener("load", ("completeHandler"+idnumber), false);
both dont work. how can i preserve and transmit the original argument from doLoad...

You can pass the same id number in response of ajax like this:
function doLoad(idnumber, id) {
var file = _(id).files[0];
_("Btn1_QP_" + idnumber).style.display = "none";
_("Display_QP_" + idnumber).innerHTML = "Image uploading......";
var formdata = new FormData();
formdata.append("stPic", file);
var ajax = new XMLHttpRequest();
ajax.open("POST", "pho_stem3.php");
ajax.send(formdata);
ajax.onreadystatechange = function() {
if (ajax.readyState == 4) {
completeHandler(idnumber);
}
}
}
function completeHandler(idnumber) {
_("Display_QP_" + idnumber).innerHTM = 'wahooo';
}

Related

What is the best way to stop function from running multiple times in Js

var emps;
function GetEmps(){
const Http = new XMLHttpRequest();
const url='http://127.0.0.1:3001/GetEmployeeList';
Http.open("GET", url);
Http.send();
Http.onreadystatechange = (e) => {
e.preventDefault();
if(Http.responseText.length>0)
{
emps=JSON.parse(Http.responseText);
for(let i=0;i<emps.length;i++)
{
CreateElementsInPage(i);
}
}
}
}
function CreateElementsInPage(id) {
console.log(id);
var btn = document.createElement("BUTTON");
btn.innerHTML = emps[id].name;
document.body.appendChild(btn);
var newLine=document.createElement("br");
document.body.appendChild(newLine);
}
GetEmps();
i am trying to create buttons dynamically. for every item in emps array, I want a button to appear in the DOM, but the "CreateElementsInPage" functions get called 4 times instead of 2 (suppose I have 2 items in emps) and I get 4 buttons
You should check request state inside your callback:
Http.onreadystatechange = (e) => {
if(Http.readyState === XMLHttpRequest.DONE ) {
// Request is complete, do your logic
}
}
onreadystatechange event function is triggered/called whenever the state of the connection is changed (readyState).
So you need to make sure that you create your button only when the connection is successful (done).
function GetEmps(){
const Http = new XMLHttpRequest();
const url='http://127.0.0.1:3001/GetEmployeeList';
Http.open("GET", url);
Http.send();
Http.onreadystatechange = (e) => {
// Make sure that the request is done before calling your button creation method
if (Http.readyState === XMLHttpRequest.DONE) {
if(Http.responseText.length>0)
{
emps=JSON.parse(Http.responseText);
for(let i=0;i<emps.length;i++)
{
CreateElementsInPage(i);
}
}
}
}
}

How to know, when AJAX request is fully loaded in Native Javascript?

It is my AJAX call with setTimeout
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
document.getElementById('mainContent').style.display = 'none';
if (this.readyState == 4 && this.status == 200) {
xhttp.onload = function(){
document.getElementById("mainContent").innerHTML = this.responseText;
setTimeout(function(
document.getElementById("mainContent").style.display = 'block';
),1000);
}
}
};
xhttp.open("POST", "system.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("lang="+lang);
I want detect when ajax is fully loaded and I have also solution here
I have solution here but I can't understand how it work.
var oldOpen = XMLHttpRequest.prototype.open;
function onStateChange(event) {
// fires on every readystatechange ever
// use `this` to determine which XHR object fired the change event
}
XMLHttpRequest.prototype.open = function() {
// when an XHR object is opened, add a listener for its readystatechange events
this.addEventListener("readystatechange", onStateChange)
// run the real `open`
oldOpen.apply(this, arguments);
}
Can you example me how it work or write full code how it work ?

Uniquely identify an upload

I'm uploading files using the following code:
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.open("POST", requestUrl, true);
xhr.send(f);
Note that I'm attaching a listener to upload progress:
function uploadProgress(evt)
{
// Which upload was it?
}
Here's the question, if I have multiple uploads happening at the same time, and they are sharing the same event handler, how can I figure out which upload triggered the event?
Try to wrap it as a Control?
var uploadProgress = function(uploadObj, event) {
// Do somthing about uploadObj
}
// Target maybe object or string, whatever you want
var Uploader = function(target) {
var xhr = new XMLHttpRequest();
var handler = uploadProgress.bind(this, target);
xhr.upload.addEventListener("progress", handler, false);
xhr.open("POST", target, true);
xhr.send(f);
}
The .bind will return a new function, when execute the new function, it'll:
Use this here, the Uploader as its context.
Execute uploadProgress and pass target as first argument, so the evt given by progess event will be passed to the 2nd param in uploadProgress.

wait till an upload is completed and then continue the script

How can I wait in an for Loop till an upload is completed and then continue the for Loop with the next number?
I have searched the Internet but there is only the setTimeout function and so on!
Here My code:
for(var f=0;f<4;f++){
var formdata = new FormData();
var id = f+1;
var file = _("filestyle-"+id).files[0];
formdata.append("file"+id, file);
var title = _("title"+id).value;
formdata.append("title"+id, title);
document.getElementById("uploadname").innerHTML=title+"is uploading<br>";
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "../swupload.php");
ajax.send(formdata);
}
in the completeHandler a variable is set to 1
You can set code you want to execute at different stages of ajax request as:-
readyState Holds the status of the XMLHttpRequest. Changes from 0 to 4:
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
However in your case you want to execute code after completion of upload, it may be achieve like that:
ajax.onreadystatechange=function()
{
if (ajax.readyState==4 && ajax.status==200)
{
// code to execute after upload
}
}
Ajax is asynchronous, so you can't expect your other synchronous code to wait for it. What you can do is replace your loop with a function, and recall it from your completeHandler callback.
post(1);
function post(id) {
var formdata = new FormData();
var file = _("filestyle-"+id).files[0];
formdata.append("file"+id, file);
var title = _("title"+id).value;
formdata.append("title"+id, title);
document.getElementById("uploadname").innerHTML=title+"is uploading<br>";
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "../swupload.php");
ajax.send(formdata);
function completeHandler() {
if (id < 5) post(id + 1);
}
}
If completeHandler must be defined outside of this function, you can preserve the id with a closure:
ajax.addEventListener("load", completeHandler(id), false);
function completeHandler(id) {
return function() {
if (id < 5) post(id + 1);
}
}

Managing Progress Bars for Multiple File Upload

So I am using a ajax to upload multiple files. Everything seems to be working like a charm... I just can't get to make my progress bars to work ...
Any help would be really appreciated. Thanks.
var images = document.getElementById('images');
for(var i=0;i<images.files.length;i++) {
var formData = new FormData();
var image = images.files[i];
formData.append('image', image);
formData.append('order_id', document.getElementById('order_id').value);
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","/pictures/uploadImage");
xmlhttp.send(formData);
xmlhttp.upload.addEventListener('progress', function(e){
document.getElementById("image_"+i+"_progress").value = Math.ceil(e.loaded/e.total)*100;
}, false);
}
I am basically uploading images individually .. I figured that would help me track the progress bars better ... Perhaps there's another approach.
According to [MDN][1]:
Note: You need to add the event listeners before calling open() on the request. Otherwise the progress events will not fire.
So, combining this knowledge with Engin's answer, you could do like this:
const images = document.getElementById('images');
const completedCount = 0; // added for loadend scenario
const length = images.files.length;
for (let i = 0; i < length; i++) {
const formData = new FormData();
const image = images.files[i];
formData.append('image', image);
formData.append('order_id', document.getElementById('order_id').value);
const xmlhttp = new XMLHttpRequest();
(elId => {
xmlhttp.upload.addEventListener('progress', e => {
document.getElementById('image_' + elId + '_progress').value = Math.ceil(e.loaded / e.total) * 100;
}, false);
})(i); // to unbind i.
// --- added for loadend scenario. ---
xmlhttp.addEventListener('loadend', () => {
completedCount++;
if (completedCount == length) {
// here you should hide your gif animation
}
}, false);
// ---
xmlhttp.open('POST', '/pictures/uploadImage');
xmlhttp.send(formData);
}
UPDATE:
To catch the event when all files are uploaded you may use loadend events. I've updated my code (see comments), I'm not sure this is a correct way though.
[1]: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress
i did not try but i think it works, because for loop finished before your post and "i"s value equal to images.files.length. sorry for terrible english
try this:
var images = document.getElementById('images');
for(var i=0;i<images.files.length;i++) {
getProgress(images.files[i],i);
}
function getProgress(image,order){
var formData = new FormData();
formData.append('image', image);
formData.append('order_id', document.getElementById('order_id').value);
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","/pictures/uploadImage");
xmlhttp.send(formData);
xmlhttp.upload.addEventListener('progress', function(e){
document.getElementById("image_"+order+"_progress").value = Math.ceil(e.loaded/e.total)*100;
}, false);
}
You can include another function.
function upload(ProgressbarId){
/*
.
.
.
some code
*/
xmlhttp.upload.addEventListener("progress", function(evt){uploadProgress(evt,ProgressbarId);}, false);
}
function uploadProgress(evt,ProgressbarId) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
set_Progressbar(ProgressbarId,percentComplete);
}
}
}

Categories

Resources