addeventlistener even firing multiple times - javascript

I'm trying to ad an event to a form in on my page. The problem is that on the first click the event fires once after twice and after that three times and go on. Also the innerHTML is not being replaced after onload. I'm pretty sure that is because of the multiple event firing tho.
<form name="search" id="getForm" oninput="requestData();">
Search customer:<br>
<input type="text" name="user" id="name"><br>
<input type="submit" value="submit">
</form>
</div>
<script>
function requestData(){
document.getElementById('getForm').addEventListener('submit', ev);
function ev(e){
e.preventDefault();
var user = document.getElementById('name').value;
if (user !== ""){
var url = 'http://localhost:3000/users/'+user;
var xhttp;
if (window.XMLHttpRequest){
xhttp=new XMLHttpRequest();
}
else{
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onprogress = function(){
//this will print out on the 3rd ready state
//good for if the application is hanging
}
xhttp.onload = function() {
if (this.status == 200 || this.status == 304) {
var response = JSON.parse(xhttp.responseText);
var output = '';
if(response.data[0] != null){
for(var i in response.data){
output += '<ul>' +
'<li>Name: '+response.data[i].customer_name+'</li>' +
'<li>Parent: '+response.data[i].parent+'</li>' +
'</ul>';
}
document.getElementById('customer_name').innerHTML = output;
}
else {
alert('Customer does not exist.');
}
}
}
xhttp.onerror = function(){
console.log('Request error...');
}
xhttp.open("GET", url, true);
xhttp.send();
} else {
alert("Name must be filled out");
return false;
}
document.getElementById('getForm').removeEventListener('submit', ev);
}
}
</script>```

You're seeing the event fire multiple times because you're adding multiple event listeners - one every time the requestData() function runs as a result of the "oninput" event. And the removeEventListener command never fires because of the else { ... return... block just above it.
But I can't see why you need the "oninput" event at all. It doesn't do anything except add more and more event listeners. You can just declare the submit event directly, without this extra layer:
<form name="search" id="getForm">
Search customer:<br>
<input type="text" name="user" id="name"><br>
<input type="submit" value="submit">
</form>
</div>
<script>
document.getElementById('getForm').addEventListener('submit', ev);
function ev(e){
e.preventDefault();
var user = document.getElementById('name').value;
if (user !== ""){
var url = 'http://localhost:3000/users/'+user;
var xhttp;
if (window.XMLHttpRequest){
xhttp=new XMLHttpRequest();
}
else{
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onprogress = function(){
//this will print out on the 3rd ready state
//good for if the application is hanging
}
xhttp.onload = function() {
if (this.status == 200 || this.status == 304) {
var response = JSON.parse(xhttp.responseText);
var output = '';
if(response.data[0] != null){
for(var i in response.data){
output += '<ul>' +
'<li>Name: '+response.data[i].customer_name+'</li>' +
'<li>Parent: '+response.data[i].parent+'</li>' +
'</ul>';
}
document.getElementById('customer_name').innerHTML = output;
}
else {
alert('Customer does not exist.');
}
}
}
xhttp.onerror = function(){
console.log('Request error...');
}
xhttp.open("GET", url, true);
xhttp.send();
} else {
alert("Name must be filled out");
return false;
}
}
</script>
Here's a little minimised working demo to show the event handling part of this in action:
document.getElementById('getForm').addEventListener('submit', ev);
function ev(e) {
e.preventDefault();
console.log(document.getElementById('name').value);
}
<form name="search" id="getForm">
Search customer:<br>
<input type="text" name="user" id="name"><br>
<input type="submit" value="submit">
</form>

Related

Why does not the Ajax response shown in innerHTML and changes back to the original text?

I am trying to get a response from a local file and display it. However, the response text changes back to the original text. Any help would be appreciated.
<script>
function getMsg(text) {
if (text.length == 0) {
document.getElementById("msg").innerHTML = "";
return;
} else {
document.getElementById("msg").innerHTML = "sending request";
var xhttp = new XMLHttpRequest();
var filepath = "";
if (inputText == "File1") {
filepath = "file1.txt";
} else if (inputText == "File2") {
filepath = "file2.txt";
}
xhttp.open("GET", filepath, true);
xhttp.send();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.response);
document.getElementById("msg").innerHTML = this.responseText;
} else {
document.getElementById("msg").innerHTML = "failed";
}
};
}
}
</script>
<body>
<form onsubmit="getMsg(this.file.value)">
<label for="file">File:</label>
<input type="text" name="file" id="file">
<button type="submit">Get</button>
</form>
</body>
This is because you form submits normally along with your ajax and reload the page. You can prevent the form from submitting by returning false from your onsubmit handler.
<form onsubmit="getMsg(this.file.value); return false">
Welcome to Stackoverflow, by reading your code I noticed you got two main issues.
Avoid using innerHTML, it's a bad practice.
When you use innerHTML, even if your string variable is only text (no HTML tags, etc), the content is parsed by JavaScript which takes time, it might not be significant in a small app like this, but in bigger apps this has a big impact in performance.
Use innerText.
You are not preventing the default behavior of your form.
When using AJAX request, the best approach for this is to set an event listener to the form like this:
Your HTML:
<form id="file_select"><!-- Add an id to identify the form -->
<label for="file">File:</label>
<input type="text" name="file" id="file">
<button type="submit">Get</button>
</form>
<div id="msg"></div>
You can add an event listener in JavaScript like this:
document.querySelector("#file_select").addEventListener("submit",(event)=>{
event.preventDefault();
//Your code
});
The preventDefault() function prevents the window redirection to the action attribute of your form. (Default behavior)
Keeping code clean, reusable and simple.
This is the same function with cleaner code, you should try keeping your code easy to read so when you come back to it you understand everything perfectly.
const message = (text) =>{
document.querySelector("#msg").innerText = text; //The message div
};
document.querySelector("#file_select").addEventListener("submit",(event)=>{
event.preventDefault();
let fileValue = event.target.file.value; //The value of the file
if (fileValue != "") { //If value not empty
var xhttp = new XMLHttpRequest();
var filepath = (fileValue === "File1" ? "file1.txt" : (fileValue === "File2") ? "file2.txt" : "");
message("Filepath is: "+filepath);
xhttp.open("GET", filepath, true);
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
message.innerText = this.responseText;
} else {
message.innerText = "failed";
}
xhttp.send();
}
} else { //If input is empty
message("Invalid file.");
}
});
<form id="file_select">
<label for="file">File:</label>
<input type="text" name="file" id="file">
<button type="submit">Get</button>
</form>
<div id="msg"></div>
Note: You can use message("text") to output the result of your AJAX request. It's up to you how to fit this to your expected behavior. Hope this helps you.

javascript to check and open page

I'm trying to use a form with a single input, that will ask for a 4-letter "secret" code (eg "a123"). The script will check if the corresponding page exists (eg: https://example.com/a123). If it exists, the page opens (in _self). If it does not, an error message is displayed.
The code below does not produce the expected result, it just refreshes the page regardless if my code is a match or not, although the url gets an appended parameter (eg: https://example.com/secret-code/?code=a123).
Functions in head:
function checkUrl(url) {
var request = false;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest;
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHttp");
}
if (request) {
request.open("GET", url);
if (request.status == 200) { return true; }
}
return false;
}
function validateCode() {
var x = document.forms["secret"]["code"].value;
if (x == "") {
document.getElementById("alertmsg").innerHTML = "Enter a code.";
}
if (checkUrl("https://www.example.com/" + x))
{
window.open("https://www.example.com/" + x,"_self");
} else {
document.getElementById("alertmsg").innerHTML = "Invalid Code. Try again.";
}
}
Form in body:
<form name="secret" onsubmit="validateCode()">
Code secret : <input type="text" name="code" size="4" maxlength="4" text-transform="uppercase"/>
<div id="alertmsg" style:"color:red;font-weight:bold"></div>
<input type="submit" value="Validate" />
</form>
I'm stumped. Thanks for helping me find the issue...
Adding another answer.
Removed form tag.
Changed the button type to button from submit.
Added onclick event on button to call validateCode() function.
Changed the way to get the secret code value x;
There was another issue with the blank data (empty string), which should be in the else case. Now handled.
function checkUrl(url) {
var request = false;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest;
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHttp");
}
if (request) {
request.open("GET", url);
request.send();
if (request.status == 200) {
return true;
}
}
return false;
}
function validateCode() {
var x = document.getElementById('code').value;
if (x == "") {
document.getElementById("alertmsg").innerHTML = "Enter a code.";
} else {
if (checkUrl("https://www.example.com/" + x)) {
window.open("https://www.example.com/" + x, "_self");
} else {
document.getElementById("alertmsg").innerHTML = "Invalid Code. Try again.";
}
}
return false;
}
Code secret : <input id="code" type="text" name="code" size="4" maxlength="4" text-transform="uppercase" />
<div id="alertmsg" style: "color:red;font-weight:bold"></div>
<input type="button" value="Validate" onclick="validateCode()" />
I have made few changes but not tested the code because having cross origin problem.
I hope it works for you.
Added return in <form name="secret" onsubmit="return validateCode()">
Added return false; in validateCode() function. As you were facing the page reload problem due to form submission.
Added request.send();, As you were just setting the to open the link, but not sending the request.
function checkUrl(url) {
var request = false;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest;
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHttp");
}
if (request) {
request.open("GET", url);
request.send();
if (request.status == 200) {
return true;
}
}
return false;
}
function validateCode() {
var x = document.forms["secret"]["code"].value;
if (x == "") {
document.getElementById("alertmsg").innerHTML = "Enter a code.";
}
if (checkUrl("https://www.example.com/" + x)) {
window.open("https://www.example.com/" + x, "_self");
} else {
document.getElementById("alertmsg").innerHTML = "Invalid Code. Try again.";
}
return false;
}
<form name="secret" onsubmit="return validateCode()">
Code secret : <input type="text" name="code" size="4" maxlength="4" text-transform="uppercase" />
<div id="alertmsg" style: "color:red;font-weight:bold"></div>
<input type="submit" value="Validate" />
</form>

show alert when second input box filled data from first box

I have this code with me:
<input id="qfront" name="qfront" placeholder="Ketik Nama Kampus ..."
value="" type="text" onKeyPress="strQuery(this.value)"/> *<!--first inputbox-->*
<script>
function strQuery(str) {
if (str.length == 0) {
document.getElementById("valdata").value = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("valdata").value = xmlhttp.responseText;
}
}
xmlhttp.open("POST", "inc.php?q="+str, true);
xmlhttp.send(null);
}
}
</script>
<input id="valdata" name="valdata" value="" type="text" onChange="showalert()"/>*<!--2nd inputbox-->*
<script>
function showalert(){
var X =document.querySelector("#valdata").value;
alert(X);
}
</script>
When I run function strQuery(str) it works 100% and show the result in the second inputbox (#valdata). When second inputbox contains data (from 1st inputbox). the second box not show alert
Do I miss something? How can I do this? (pls not using jquery). many thanks
I've finally found the solution for my problem.
I fix the place of the second JS (showalert) into the first, as follows:
<input id="qfront" name="qfront" placeholder="Ketik Nama Kampus ..."
value="" type="text" onKeyPress="strQuery(this.value)"/>
<script>
function strQuery(str) {
if (str.length == 0) {
document.getElementById("valdata").value = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("valdata").value = xmlhttp.responseText;
showalert()
}
}
xmlhttp.open("POST", "inc.php?q="+str, true);
xmlhttp.send(null);
}
}
function showalert(){
var X =document.querySelector("#valdata").value;
alert(X);
}
</script>
<input id="valdata" name="valdata" value="" type="text"/>
Thanks so much for discussion.
It looks like there's a missing double quote after showalert();
But separately, I think that onchange may only fire in response to user input. If that's the case, simply change your code to:
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("valdata").value = xmlhttp.responseText;
document.getElementById("valdata").onchange();
}

jQuery how to trigger event after form post returns?

I have an expensive form action that builds a zip file on the server and returns it to the browser.
<form action='/download' method='post'>
<input type='submit' value='download'/>
</form>
I want to block the page on click of the button so that the user doesn't repeatably hit the button.
However I want to unblock the page after the form returns.
How can trigger an event on successful completion of the form?
(I know I can trigger this by changing the form to be an ajax submission but then the save file dialog does not appear...)
Any suggestions?
Thanks
One way you could handle this without using AJAX could be submitting the content of the form to an iframe element. If you attach an onsubmit function to the form that disables further submissions and attach an onload function to the iframe, you should be able to disable the user from submitting the form multiple times.
Example HTML:
<form action="/download" method="post" target="downloadFrame" onsubmit="return downloadFile();">
<input type="submit" value="download" />
</form>
<iframe style="width: 0px; height: 0px;" scrolling="no" frameborder="0" border="0" name="downloadFrame" onload="downloadComplete();"></iframe>
Example Javascript:
var downloading = false;
function downloadFile() {
var isDownloading = downloading;
downloading = true;
return !isDownloading;
}
function downloadComplete() {
downloading = false;
}
It appears no one has yet found a way to detect the post return in the browser itself, but there is another possibility using AJAX. It is a bit more involved though:
<script type="text/javascript">
$(function () {
$('#submitbtn').click (function () {
window.setTimeout (dldone, 100);
return true;
});
function dldone () {
$.get ("/downloadstatus?rand="+$('#rand').val (), function (data) {
if (data == 'done') {
// data generation finished, do something
} else {
window.setTimeout (dldone, 100);
}
});
}
});
</script>
<form action="/generatedata" method="post">
<input type="hidden" id="rand" value="[RANDOMVALUE]">
<input type="submit" id="submitbtn" value="Download Data">
</form>
On the server, you would have to do some inter-process-communication to signal when the data generation is done. Since I already have a database, I did it like this:
public function downloadstatusAction () {
if ($this->db->fetchOne ("SELECT rand FROM dlstatus WHERE rand = ?", (int) $_GET["rand"])) {
$db->delete ("dlstatus", array ("rand = ?" => (int) $_GET["rand"]));
print "done";
} else {
print "loading";
}
}
public function generatedataAction () {
// generate data
$this->db->insert ("dlstatus", array ("rand" => (int) $_POST["rand"]));
// output data
}
I am sure there are more elegant ways to do this, but you get the idea. This appears to work fine in all browsers I tested.
I used this:
function generatePdfZipViaWS_ajax(theUrl) {
//=========================
// testé avec Chrome 37.0.2062.124 m, Firefox 32.0.3
// ça block avec IE9 à cause du xmlHttp.overrideMimeType
//=========================
var xmlHttp = new XMLHttpRequest();
var alert = document.getElementById("alertError");
block_UI();
var url = "undefined";
xmlHttp.open("GET", theUrl, true);
xmlHttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xmlHttp.overrideMimeType("application/octet-stream");
xmlHttp.responseType = "blob";
xmlHttp.onload = function(oEvent) {
if (xmlHttp.status == 200) {
deblock_UI();
// a mettre apres un certain temps: window.URL.revokeObjectURL(url);
} else {
alert.style.display = "block";
deblock_UI();
// console.log("Error " + xmlHttp.status + " occurred downloading your file.<br \/>");
}
};
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == xmlHttp.DONE) {
if (xmlHttp.status == 200) {
var contentDisposition = xmlHttp.getResponseHeader("Content-Disposition");
var type = xmlHttp.getResponseHeader("Content-Type");
var reponseType = xmlHttp.responseType;
var pos1 = contentDisposition.indexOf("archive");
var pos2 = contentDisposition.lastIndexOf(".zip") + 4;
var fileName = contentDisposition.substring(pos1, pos2);
if (fileName === null) {
fileName = "archivexxxxxxxxxxxxxx.zip";
}
console.log("fileName:" + fileName);
var blob = xmlHttp.response;
url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.style = "display: none";
a.href = url;
a.download = fileName;
a.type = type;
document.body.appendChild(a);
a.click();
//a.delete();
deblock_UI();
} else {
var msg =" Une erreur " + xmlHttp.status +" est apparue pendant que votre demande était traitée.\n"
msg = msg + "Merci de réessayer plus tard!";
alert.innerHTML = msg;
alert.style.display = "block";
deblock_UI();
console.log(msg);
}
}
};
xmlHttp.send();
}
I don't have time to write a proper answer right now, but since nobody else has a good answer, I think a "Mutation Observer" would work... https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

URL Redirect based on input but if input url does not exist do not redirect cant get PHP to work

#themask
Hello and thanks for your help, I have tosed the php and now have just this code
<script>
document.forms[0].onsubmit =
function() {
var to = document.getElementById('myInput').value;
var ajax = new XMLHttpRequest;
ajax.onreadystate = function() {
if(this.readyState == 4 && this.status != 404) {
window.locaiton.replace(to);
} else {
window.location.replace('http://www.mysite.com/incontinence/protective_underwear/presto_protective_underwear/');
}
};
ajax.open('GET',to);
ajax.send(null);
};
</script>
<form onsubmit="location.href='http://www.mysite.com/coupons/' + document.getElementById('myInput').value; return false;" >
<input type="text" id="myInput" />
<input name="Submit" type="submit" id="Submit" />
</form>
But it is still sending me to incorrect urls if a bad code is used. Its like it is skipping the java all together.
Any additional help would be great.
Thank you,
Micah
Thank you,
Micah
Try using get_headers()
$headers = get_headers('http://www.activelifemed.com/incontinence/protective_underwear/presto_protective_underwear/')
if($headers[0] == 'HTTP/1.1 200 OK'){
//exists
}
else{
//doesn't exist
}
http://www.php.net/manual/en/function.get-headers.php
You can make this using JavaScript:
document.forms[0].onsubmit =
function() {
var to = document.getElementById('myInput').value;
var ajax = new XMLHttpRequest;
ajax.onreadystate = function() {
if(this.readyState == 4 && this.status != 404) {
window.locaiton.replace(to);
} else {
window.location.replace('http://www.mysite.com/incontinence/protective_underwear/presto_protective_underwear/');
}
};
ajax.open('GET',to);
ajax.send(null);
};

Categories