Unable to set the onclick property of a button - javascript

I have a button calling a js function. Everything in the function runs but at the end I try to set the onclick value for the button and nothing happens. The catch block doesn't even generate an error
var nextButton = document.getElementById("next");
try{
if(tvalue == "trend"){
nextButton.onclick = "generateLocations()";
}
else if (tvalue == "stats"){
nextButton.onclick = "generateCategories()";
}
}
catch(err) {
document.getElementById("demo").innerHTML = err.message;
}
I have also tried setting the onclick value these ways
nextButton.onclick = function () { generateCategories(); };
nextButton.onclick = generateCategories;
the tvalue variable is set like this:
var t = document.getElementById("type");
var tvalue = t.options[t.selectedIndex].value;
Other test outputs have shown that this retrieves the value no problem
The relevant HTML:
<form id='fieldsets' action="../scripts/reportParse.php">
<fieldset>
<legend> Select Report Type </legend>
<select id="type" name="type">
<option value="trend"> Waitlists over Time </option>
<option value="stats"> Region Statistics </option>
</select>
</fieldset>
<button id="next" onclick="generateRegions()"> Next </button>
I've been trying solutions based on the following page:
Change onclick action with a Javascript function
and w3schools.com
Thanks for any help. I've been hung up on this for a little bit now
Edit: I've tried useing event listeners based on a comment below and am now getting the error "i is not defined'. which seems odd since i is not referred too inside the try block.
The whole function in case i've missed something stupid:
function generateRegions(){
var t = document.getElementById("type");
var tvalue = t.options[t.selectedIndex].value; // The value of the selected option
var names = ["Downtown", "Glenmore", "Mission", "Rutland"];
var regions = document.createElement("FIELDSET");
regions.setAttribute("id","Region");
var temp = document.createElement("LEGEND");
temp.innerHTML = "Select Region:";
regions.appendChild(temp); //creating the fieldset div and assigning its legend
for(var i = 0; i < 4; i++){
var templ = document.createElement("LABEL");
var str1 = "chk";
var str2 = i.toString();
var id = str1.concat(str2); //creating a dynamic ID so each checkbox can be referred to individually
templ.setAttribute("for",id);
temp = document.createElement("INPUT"); //creating the checkbox and assigning its values
temp.setAttribute("type","checkbox");
temp.setAttribute("name","region");
temp.setAttribute("value",names[i]);
temp.setAttribute("id",id);
regions.appendChild(templ);
templ.innerText = names[i]+':'; //creating and placing the label, then placing its checkbox
regions.appendChild(temp);
}
document.getElementById("fieldsets").appendChild(regions); //adding the fieldset to the overall form
var nextButton = document.getElementById("next");
try{
if(tvalue == "trend"){
nextButton.onclick = "generateLocations()";
}
else if (tvalue == "stats"){
nextButton.onclick = "generateCategories()";
}
}
catch(err) {
document.getElementById("demo").innerHTML = err.message;
}
//document.getElementById("demo").innerHTML = tvalue; //checking that the type variable is properly found
}

Try adding an event listener to your code so the JavaScript is separated from the HTML markup. Like so:
var nextButton = document.getElementById("next");
try{
if(tvalue == "trend"){
nextButton.addEventListener("click",generateLocations()) ;
}
else if (tvalue == "stats"){
nextButton.addEventListener("click",generaCategories()) ;
}
}
catch(err) {
document.getElementById("demo").innerHTML = err.message;
}
You can test if the event listener is working by adding a console log on the functions you are executing.
Source: https://www.w3schools.com/js/js_htmldom_eventlistener.asp

Related

Making array with input of textarea

I'm trying to capture the input of a textarea and converting it to an array but it is reading the whole input as one element and making array of length 1.
<html>
<textarea id="area"></textarea>
<input type="submit" onclick="won()">
<p id="one" style="display: none;"></p>
</html>
The js part displays a message of the length of the array.
var area = document.getElementById("area");
var lines = area.value.split("\n");
var pa = document.getElementById("one");
function won() {
pa.style.display = "block";
pa.innerHTML = lines.length;
}
What I'm trying to achieve with the whole thing is that. The multi line input is to be converted into an array with each new line being a new element. Then I loop through the array and if even one element doesn't pass a validation function, an exception message is displayed under the texarea.
Can someone kindly help me with this?
With your snippet, you're grabbing the value onload so it would be empty, it should be in the event where you grab the value. Also avoid inline event triggering, add the event via js.
var area = document.getElementById("area");
var button = document.getElementById("btn-submit");
var one = document.getElementById("one");
button.addEventListener('click', () => {
// get value
var lines = area.value.split("\n");
one.style.display = "block";
one.innerHTML = lines.length;
})
<textarea id="area"></textarea>
<button type="button" id="btn-submit">Submit</button>
<p id="one" style="display: none;"></p>
What I'm trying to achieve with the whole thing is that. The multi
line input is to be converted into an array with each new line being a
new element. Then I loop through the array and if even one element
doesn't pass a validation function, an exception message is displayed
under the texarea.
const area = document.getElementById("area");
const button = document.getElementById("btn-submit");
const error = document.getElementById("error");
const items = document.getElementById("items");
button.addEventListener('click', () => {
// get textarea value, remove emptys
const lines = area.value.split("\n").filter(Boolean);
// reset error and items dom
error.innerHTML = items.innerHTML = ''
// do your validation, could loop or use .some(), .includes()
if (!lines.length) {
error.innerHTML = 'Enter at least one item'
} else if (!lines.includes('cat')) {
error.innerHTML = 'Entered lines should include at least one cat'
} else {
// no errors
items.innerHTML = `${lines.length} items<br><ul><li>${lines.join('</li><li>')}</li></ul>`
}
})
<textarea id="area"></textarea>
<button type="button" id="btn-submit">Submit</button>
<div id="error"></div>
<div id="items"></div>
Simply put your line var lines = area.value.split("\n"); under the won function like below and you will get your total lines.
Example
var area = document.getElementById("area");
var pa = document.getElementById("one");
function won() {
var lines = area.value.split("\n");
pa.style.display = "block";
pa.innerHTML = lines.length;
}
You can check it here too, https://codepen.io/vadera-abhijeet/pen/yLPxLRY

Element edit button should only edit "that" element, instead is updating all

So I am trying to make an edit function for a favorites bar. Editing one box is okay, but when I try to edit a different box, all the boxes that I clicked on previously gets edited as well. Here is a jsfiddle with the complete code: https://jsfiddle.net/1exrf9h8/1/
I am trying to understand why my editFavorite function is updating multiple boxes and not just one.
function clickEdit(input, title, url, plus, editIcon, anchorEdit, editBtn)
{
let i = editIcon.length - 1;
editIcon[i].addEventListener("click", function(event){
input.style.display = "block";
title.value = plus[i + 1].textContent;
url.value = anchorEdit[i].href;
console.log(i);
console.log(anchorEdit[i]);
editFavorite(anchorEdit[i], url, title, input, editBtn);
});
}
function editFavorite(changed, url, title, input, editBtn)
{
editBtn.addEventListener("click", function(){
changed.href = url.value;
changed.textContent = title.value;
input.style.display = "none";
});
}
There is a few problems in your logic, architecture and use of the event handler, Let's give it a shot in a more OOP way so you can actually make it to work and understand what is going on.
Every single favorite is an object by itself, that can spawn and update itself.
function favorite(newTitle, newUrl) {
this.element = container.appendChild(document.createElement("div"));
this.title = this.element.appendChild(document.createElement("h2"));
this.url = this.element.appendChild(document.createElement("h2"));
this.update = (newTitle, newUrl) => {
this.title.textContent = newTitle;
this.url.textContent = newUrl;
}
this.createButton = () => {
button = this.element.appendChild(document.createElement("button"));
button.append("Edit");
button.addEventListener("click", () => {
let titleInput = document.getElementById("title").value;
let urlInput = document.getElementById("url").value;
this.update(titleInput, urlInput);
})
}
this.update(newTitle, newUrl);
this.createButton();
}
Then let's have a simple form where we can take inputs, using the same for editing, and creating a new favorites.
<input id="title" type="text" name="title" placeholder="Title">
<input id="url" type="text" name="url" placeholder="Url">
<button id="submit">Create New</button>
Now the actual submit logic.
document.getElementById("submit").addEventListener("click", () => {
let titleInput = document.getElementById("title").value;
let urlInput = document.getElementById("url").value;
if (!titleInput.length || !urlInput.length) return;
let newFavorite = new favorite(titleInput, urlInput);
container.appendChild(newFavorite.element);
});
https://jsfiddle.net/p50L27us/48/
The problem is caused by editFavorite function. when you call editFavorite function automatically starts new listener. Evey click start new one.
The solution is " ,{once : true} "
function editFavorite(changed, url, title, input, editBtn)
{
editBtn.addEventListener("click", function(){
changed.href = url.value;
changed.textContent = title.value;
input.style.display = "none";
},{once : true});
}

Text Box Search / Javascript Function Arrays **not corresponding**

I want the user to "Search" some "Authors" and if they select the one in the database they are sent to a corresponding HTML. Otherwise "No Author Found" displays...
For some reason I cannot wrangle it properly - pls help!
//Search by Author
function searchAuth() {
var search_string = document.getElementById('search_string').value;
var arrayelement = ["John","Stan","Henry","Paul","Samuel"];
for (i=0;i<arrayelement.length;i++) {
if (input == arrayelement.John) {
var itemLink = document.getElementById('demo').innerHTML =
"<a href='https://www.google.ca/?gws_rd=ssl'>Your link</a>";
} else if (input == arrayelement.Stan) {
var itemLink = document.getElementById('demo').innerHTML =
"<a href='https://www.google.ca/?gws_rd=ssl'>Your link</a>";
}else {
var itemLink = document.getElementById('demo').innerHTML =
"Author not found."
}
}
<!--Author-->
<h3>Search By Author</h3>
<form name="searchTest" onsubmit="return(searchAuth());" action="#">
<input type="text" id="search_string" />
<input type="submit"/>
<p id="demo"></p>
Perhaps you are trying to do things like these..
P.S this is just a demo, for you to start :)
EDIT: added few explanation on some stuffs you might get confuse with. :)
//events once textbox gets out focus
//the events varies on which or where do you want to add the event. it can be on click of a search button or submit button just like in your example.
document.getElementById('search-text-box-id').addEventListener("focusout", function() {
//searchString gets the textbox value.
var searchString = document.getElementById('search-text-box-id').value;
var searchList = ["John","Stan","Henry","Paul","Samuel"];
//Loop searchList
for (i=0; i < searchList.length; i++) {
//i which usually means the index or the key of the array's object(s).
var searchItem = "";
//searchList[i] loops its object by getting the index resulting to John, Stan and so on and so forth.
if (searchString == searchList[i]) {
searchItem = searchList[i];
document.getElementById('search-result-container').innerHTML = searchItem + " link";
//stop looping as the loop found a match.
return;
}
else {
searchItem = "Author not found.";
document.getElementById('search-result-container').innerHTML = searchItem;
}
}
});
<label for="search-text-box"></label>
<input type="text" id="search-text-box-id" name="search-text-box" />
<p id="search-result-container"></p>

function only works one time

This is my first question on here. I use this site all of the time, but have never posted on here.
When I call the function writeMessage(), when the checkbox is checked, the textarea is created. When I uncheck the checkbox, the textarea is removed. When I check the checkbox the second time, the function is not called. Any suggestions? I need for it to show the textarea any time the checkbox is checked, not just the first time around. Below is my code.
HTML:
<table>
<th>
<input type = "checkbox" name = "os0" id = "spaceForMsg" onClick = "writeMessage()">
<label for "gift"> Gift for someone</label>
</th>
</table>
<table >
<tr id = 'parent'>
<div id = 'printMsg'></div>
</tr>
</table>
javascript function:
function writeMessage() {
var x = document.getElementById('spaceForMsg');
var docBody = document.getElementById('parent');
var element = document.createElement('textarea');
element.cols='60';
element.rows='8';
element.id = 'msgArea';
if (x.checked) {
give = 'Type your gift message here: ';
docBody.appendChild(element);
} else {
give = '';
y = document.getElementById('parent').parentNode;
y.removeChild(y.childNodes[0]);
}
document.getElementById('printMsg').innerHTML = give;
}
writeMessage is removing "the first child of the parent of document.getElementById('parent') (which happens to be equal to docBody). This means that you are removing docBody itself.
The next time you call writeMessage after removing docBody, the document will fail to find a proper parent, thus docBody.appendChild(element); will fail.
Try this instead:
function writeMessage() {
var give;
var x = document.getElementById('spaceForMsg');
var docBody = document.getElementById('parent');
if (x.checked) {
var element = document.createElement('textarea');
element.cols='60';
element.rows='8';
element.id = 'msgArea';
give = 'Type your gift message here: ';
docBody.appendChild(element);
} else {
give = '';
y = docBody.removeChild(docBody.getElementsByTagName('textarea')[0]);
}
document.getElementById('printMsg').innerHTML = give;
}
You are removing <div id='parent'></div>, with this line y.removeChild(y.childNodes[0]);, so you can't put anything in there since it doesn't exist.

List of buttons and JavaScript

I have a list of buttons in HTML. Depending on the button which is clicked, an AJAX call is supposed to be made and the data displayed. However JavaScript is not able to read the button. Here is the code in HTML
<ul>
<li><input type = "button" name = "lab" id = "map" value = "Computer Lab" onClick = "openPage(this)"></li>
<li><input type = "button" name = "lib" id = "map" value = "Library" onClick = "openPage(this)"></li>
<li><input type = "button" name = "mlib" id = "map" value = "Manuscript Library" onClick = "openPage(this)"></li>
<li><input type = "button" name = "radio" id = "map" value = "Agra ki Aawaz" onClick = "openPage(this)"></li>
</ul>
And here is the javascript code
function openPage(page){
try {
xmlHttp = new XMLHttpRequest ();
}
catch (e) {
try {
xmlHttp = new ActiveXObject ("Microsoft.XMLHTTP");
}
catch (el) {
try {
xmlHttp = new ActiveXObject ("Msxml2.XMLHTTP");
}
catch (el1) {
alert ("Your browser does not support AJAX! Please use a compatible browser!!");
}
}
}
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.state == 200) {
var sp = documet.getElementByID ("mainText");
sp.innerHTML = xmlHttp.responseText;
}
};
var target = "";
var parent = "";
var page = "";
switch(page.name){
case 'lab':
target = "get_content.jsp";
parent = "kmi";
page = "lab";
break;
case 'lib':
targt = "get_content.jsp";
parent = "kmi";
page= "gen_lib";
break;
case 'mlib':
targt = "get_content.jsp";
parent = "kmi";
page= "man_lib";
break;
case 'radio':
targt = "get_content.jsp";
parent = "kmi";
page= "radio";
break;
}
xmlHttp.open("POST", target, false);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
xmlHttp.send("parent=" + parent + "&page=" + page);
Now the problem is that page.name is coming as undefined.
I don't understand what is wrong with it and is it possible to create such a list of buttons and navigate using these?
Just above your switch statement, you have this:
var page = "";
since your function definition looks like this:
function openPage(page){
JavaScript drops the var (variable is declared already), and merely assigns "" (an empty string) to what used to be a reference to a DOM element. Fix the name conflict and you should be on your way

Categories