Is it possible to make these functions into one function? - javascript

I'm trying to get this program to add a special character when the assigned button for the character is pressed. The problem is, I'm going to have a lot of functions. Can I somehow just make one function that I can use for all of the buttons?
//These are buttons
var aa = document.querySelector('#aa')
var oo = document.querySelector('#oo')
var uu = document.querySelector('#uu')
var khii = document.querySelector('#khii')
//This is the text box
var textBox = document.querySelector('#typeIn')
//Functions to add a character into the text box
function addAa() {
textBox.innerHTML += "ā";
}
function addOo() {
textBox.innerHTML += "ō";
}
function addUu() {
textBox.innerHTML += "ū";
}
function addKhii() {
textBox.innerHTML += "χ";
}
//Telling the buttons to call on the functions when clicked
aa.onclick = addAa
oo.onclick = addOo
uu.onclick = addUu
khii.onclick = addKhii
Additionally: why does this not work?
var aa = document.querySelector('#aa')
var textBox = document.querySelector('#text')
function addLetter(a) {
textBox.innerHTML += a
}
aa.onclick = addLetter("ā")
This just adds the character once into the text box. Clicking on the button then does nothing. Why does it do that?

Yes you can do it with only one function. Pass the character as parameter to the function. Like that:
version with addEventListener (prefered)
const btns = document.querySelectorAll('button');
const textBox = document.querySelector('#typeIn');
btns.forEach(b => {
b.addEventListener('click', e => {
textBox.innerHTML += e.target.getAttribute('data-char')
})
});
#typeIn {
margin:10px;
padding: 10px;
color: white;
min-height:40px;
background: gray;
}
<button data-char="aa">aa</button>
<button data-char="X">X</button>
<button data-char="ō">ō</button>
<button data-char="ū">ū</button>
<div id="typeIn"></div>
Generally try to avoid onclick events and use eventListener instead.
Version onclick Event
const textBox = document.querySelector('#typeIn');
function add(what) {
textBox.innerHTML += what;
}
#typeIn {
margin:10px;
padding: 10px;
color: white;
min-height:40px;
background: gray;
}
<button onclick="add('aa')">aa</button>
<button onclick="add('X')">X</button>
<button onclick="add('ō')">ō</button>
<button onclick="add('ū')">ū</button>
<div id="typeIn"></div>

You could do something like this:
Add (for example) data-value attributes to each of your buttons
<button data-value="A">A</button>
<button data-value="B">B</button>
<button data-value="C">C</button>
Grab all these buttons, and add "click" event listeners to each, like so:
document
.querySelectorAll('button') // Use appropriate class name here
.forEach(button =>
button
.addEventListener("click", (e) =>
console.log(e.target.dataset.value) // Do whatever you want here
)
)
Modify the listener function's body as per your needs
Here's a link to a JsFiddle that I've created for demo.

Related

How can I create iterative scalable arguments in a HTML element?

<!DOCTYPE html>
<html>
<body>
<h2>What Can JavaScript Do?</h2>
<p>JavaScript can change HTML attribute values.</p>
<p>In this case JavaScript changes the value of the src (source) attribute of an image.</p>
<button onclick="document.getElementById('bulb0').src='pic_bulbon.gif'">Turn on the light</button>
<img id="bulb0" src="pic_bulboff.gif" style="width:50px">
<button onclick="document.getElementById('bulb0').src='pic_bulboff.gif'">Turn off the light</button>
<p></p>
<button onclick="document.getElementById('bulb1').src='pic_bulbon.gif'">Turn on the light</button>
<img id="bulb1" src="pic_bulboff.gif" style="width:50px">
<button onclick="document.getElementById('bulb1').src='pic_bulboff.gif'">Turn off the light</button>
<p></p>
<button onclick="document.getElementById('bulb2').src='pic_bulbon.gif'">Turn on the light</button>
<img id="bulb2" src="pic_bulboff.gif" style="width:50px">
<button onclick="document.getElementById('bulb2').src='pic_bulboff.gif'">Turn off the light</button>
<p></p>
<button onclick = turnOn()>Turn All lights ON</button>
<button onclick = turnOff()>Turn All lights OFF</button>
<button onclick = turnRandomOn()>Turn Any light ON</button>
<script>
function turnOn() {
document.getElementById('bulb0').src='pic_bulbon.gif';
document.getElementById('bulb1').src='pic_bulbon.gif';
document.getElementById('bulb2').src='pic_bulbon.gif';
console.log('All lights were turned on');
}
function turnOff() {
document.getElementById('bulb0').src='pic_bulboff.gif';
document.getElementById('bulb1').src='pic_bulboff.gif';
document.getElementById('bulb2').src='pic_bulboff.gif';
console.log('All lights were turned off');
}
function turnRandomOn() {
let random = Math.floor(Math.random() * 3);
console.log(random);
turnOff();
if (random == 0) {
document.getElementById('bulb0').src='pic_bulbon.gif';
} else
if (random == 1) {
document.getElementById('bulb1').src='pic_bulbon.gif';
} else
if (random == 2) {
document.getElementById('bulb2').src='pic_bulbon.gif';
}
}
</script>
</body>
</html>
Hello there! I'm on my first steps learning JS. I practiced with an interesting self-invented exercise that I just finished, the task consist in creating N-lamps that you can switch On/Off with a button for each lamp, I also added the idea of turning all on/off with just one button and the same for setting on/off a random lamp.
The code I shared works fine but I know is not scalable at all since I had to put the lamps by hand. My question is the following:
How can I improve this code to select an HTML element defined by a recursive variable? What I'm trying to say is, for example, instead having a line with the object "document.getElementById('bulb0')", how could I change it for something like "document.getElementById('bulbN')"(where N is variable).
I know it is with an iterative loop but every time I try defining the argument it throws me an error. I tried these two ways:
getElementById('"' + bulb + N + '"').innerHTML
Defining the argument ('"' + bulb + N + '"') as a separated variable and later adding it with the same procedure
I will truly appreciate your help, even more if you can share the code
PS: The exercise can be found here https://www.w3schools.com/js/tryit.asp?filename=tryjs_intro_lightbulb
you can do it using template literal strings.
function turnOn() {
for(let i of [0,1,2]) {
document.getElementById(`bulb${i}`).src='pic_bulbon.gif';
}
console.log('All lights were turned on');
}
function turnOff() {
for(let i of [0,1,2]) {
document.getElementById(`bulb${i}`).src='pic_bulboff.gif';
}
console.log('All lights were turned off');
}
Now, what you are doing wrong?
getElementById('"' + bulb + N + '"').innerHTML
// '"' + bulb + N + '"' -> bulb is taken as variable, not like string.
// instead of this you can just use "bulb" + N
getElementById("bulb" + N).innerHTML
e.g.
let N = 0
console.log("bulb" + N)
// now here, bulb is taken as a variable
// this will give you an error. because bulb variable is not defined
// console.log('"' + bulb + N + '"') throw an error
// if you define bulb variable,
{
const bulb = 'bulb'
console.log('"' + bulb + N + '"')
console.log(bulb + N)
// you can see '"' + bulb + N + '"' !== bulb + N
}
if you need to know more details:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
There are several techniques you can use which I've commented on in the code but I'll mention here with some links to the documentation.
Use a loop as you suggested to build some HTML using template strings. Push each string into an array, and then join that array into one string and add it to the element that contains the lamps: lampsContainer.
Attach event listeners to the lampsContainer, and the buttons. When they're clicked they'll call a handler. With regards to lampsContainer we're using event delegation - attaching one listener to a container that catches events from its child elements as they "bubble up" the DOM.
If the lampsContainer is clicked we first check to see if the element that we clicked on is a button, and then we get that button's lamp element using previousElementSibling. We toggle the class on that lamp on/off.
The other buttons, as mentioned, have their own handlers. They either turn off (remove the on class) or turn on (add the on class) on all of the lamps. The random button simply toggles one random lamp from the lamp node list on/off.
// Initialise the lamp number,
// and an array to store the HTML string
const n = 4;
const html = [];
// Using a template string create a series of
// sections each containing a button, and a "lamp"
// element. Push each string into the array
for (let i = 0; i < n; i++) {
const str = `
<section class="lampContainer">
<div class="lamp"></div>
<button>lamp${i + 1}</button>
</section>
`;
html.push(str);
}
// Cache the elements for the lamps container,
// and the other buttons
const lampsContainer = document.querySelector('.lampsContainer');
const toggleAllOn = document.querySelector('.toggleAllOn');
const toggleAllOff = document.querySelector('.toggleAllOff');
const random = document.querySelector('.random');
// Add the HTML string to the lampsContainer element
lampsContainer.innerHTML = html.join('');
// Add some listeners to the lamps container, and the buttons
lampsContainer.addEventListener('click', handleLamps);
toggleAllOn.addEventListener('click', handleToggleAllOn);
toggleAllOff.addEventListener('click', handleToggleAllOff);
random.addEventListener('click', handleRandom);
// When an element in the lamps container is clicked
// check that it was a button, and then find its lamp
// element. Toggle the lamp `on` class.
function handleLamps(e) {
if (e.target.matches('button')) {
const lamp = e.target.previousElementSibling;
lamp.classList.toggle('on');
}
}
// Find all the lamps in the lamps container,
// and add an `on` class
function handleToggleAllOn() {
const lamps = lampsContainer.querySelectorAll('.lamp');
lamps.forEach(lamp => lamp.classList.add('on'));
}
// Find all the lamps in the lamps container,
// and add an `on` class
function handleToggleAllOff() {
const lamps = lampsContainer.querySelectorAll('.lamp');
lamps.forEach(lamp => lamp.classList.remove('on'));
}
// Find all the lamps in the lamps container,
// find a random lamp from that node list,
// and toggle its `on` class
function handleRandom() {
const lamps = lampsContainer.querySelectorAll('.lamp');
const rnd = Math.floor(Math.random() * lamps.length);
lamps[rnd].classList.toggle('on');
}
.lampContainer { display: flex; flex-direction: row; width:20%; align-items: center; }
.lamp { margin: 0.25em; border: 1px solid #dfdfdf; width: 20px; height: 20px; background-color: white; }
.on { background-color: yellow; }
button, .lamp { border-radius: 5px; }
button { text-transform: uppercase; }
button:hover { cursor: pointer; background-color: lightgreen; }
.buttonsContainer { margin-top: 1em; }
<section class="lampsContainer"></section>
<section class="buttonsContainer">
<button class="toggleAllOn">Toggle all on</button>
<button class="toggleAllOff">Toggle all off</button>
<button class="random">Toggle random on/off</button>
</section>
Use Document.createElement() to create element with any iterator
Then assign attributes. Then simply add that to DOM 👍
Extending it further you can even customize each element while creation base on your conditions

Displaying images through series of button clicks

I'm trying to build a website with a very basic functionality. Essentially the website is supposed to contain various buttons and display images based on which series of buttons are clicked. Unfortunately my experience in web development is limited (to non-existent), but I've found some code that works to some extent here on stackoverflow. Building on that, I wanted to alter the code in a way that allows me to achieve the functionality I desire.
Here's how the website is supposed to look like:
As you can notice, the website contains various buttons from A-D and 0-9. The button clicks are logged in the field beneath and once a combination has been put in that matches the name of a file, the image will be displayed.
Here's the code:
$(document).ready(function() {
/**
* Select the buttons.
* The $display and $clickedButtons are just to output
* the values that are stored.
*/
const $buttons = $('.button');
const $display = $('#display');
const $clickedButtons = $('#clicked-buttons');
const $reset = $('#reset');
$reset.on('click', function() {
values = [];
$clickedButtons.text(values);
});
/**
* Array which tracks your clicked buttons.
* If a button is clicked, the value of that button
* should be added to this array. The combination
* of the values will then later represent the key.
*/
var values = [];
/**
* Listen for the click event on all the buttons.
* When clicked, get the value of that clicked button
* and add that to the values array.
* After that the clicked button values will be combined
* to form a single key and check if that key matches
* a combination. If there is a match the content should
* be anything other than undefined.
*/
$buttons.on('click', function() {
// This is the currently clicked button.
const $button = $(this);
// Get the value of the button.
const value = $button.val();
// If there already are 15 previously clicked buttons,
// then empty the array, so we can start a new combination.
if (values.length === 15) {
values = [];
}
// Now add the newly clicked value.
values.push(value);
// This will output the current values in the array.
$clickedButtons.text(values);
// Transform the array into a single string.
// This will be the key to select content.
// ["1", "2", "3"] becomes "123".
const key = values.join('');
// Check if key has a match in the combinations object.
$display.attr('src', 'output/' + key + '.png');
});
});
Now to my problem: The code requires that they combination of buttons is clicked exactly in the order of the name of the image. So for example, inputting A-B-C-1-2-3 will display ABC123.png. For my purpose however, I would need the code to display ABC123.png even if the inputs are 31B2AC or any other combination of these 6 inputs. I've looked into the option of 'sorting' but this creates a problem on the other hand, namely that some of the pictures are named like this e.g. D9B6C4.png so there is no applicable logic like alphabetic or numerical that would be required for a sorting algorithm to function. Every image in the folder has an unique however so when ABC123.png exists, BCA321 cannot.
What I would need the script to do is to parse through the pictures and find the unique picture that contains all letters & numbers that are entered regardless of their order. Is that even possible? How would I go about achieving this?
///////// EDIT ////////
My attempt to add a display, a tracker of clicked buttons and as well as a remove button:
So not really sure why literally nothing is working. Neither the inputs are displayed in the appropriate field nor is a picture being displayed ...
const $buttons = $('.button');
const $display = $('#display');
const $clickedButtons = $('#clicked-buttons');
const $removeButton = $('#remove-button');
const values = [];
var imgs = ["ABC123.png", "1A2B4C.png", "ABC132.png", "123ABC.png"];
function case_insensitive_comp(strA, strB) {
return strA.toLowerCase().localeCompare(strB.toLowerCase());
}
function reSortFiles() {
var all = {};
imgs.forEach(function(a) {
d = a.split(".");
img = d[0].split("");
img = sortStr(img);
img = img.join("");
all[img] ? all[img].push(a) : all[img] = [a];
});
return all;
}
function sortStr(str) {
return str.sort(case_insensitive_comp)
}
function tryCombination() {
// This will output the current values from the array.
$clickedButtons.text(values);
const key = values.join('');
allImages = reSortFiles()
console.log(allImages)
buttons = document.querySelectorAll("button")
clicked = "";
buttons.forEach(function(btn) {
btn.addEventListener("click", function(e) {
clicked += e.target.dataset.value;
clicked_s = sortStr(clicked.split("")).join("")
console.log(clicked, clicked_s)
img = allImages[clicked_s]
if (img) {
console.log("Found: ", img.join(","))
clicked="";
}
});
});
.container {
display: grid;
grid-template-rows: auto auto;
grid-template-columns: 200px 1fr;
grid-gap: 1em;
border: 1px solid #d0d0d0;
background-color: #f7f7f7;
padding: 1em;
border-radius: 5px;
}
.buttons {
grid-area: 1 / 1 / 2 / 3;
}
#display {
grid-area: 2 / 1 / 3 / 2;
width: 200px;
height: 200px;
background-color: #d0d0d0;
border-radius: 5px;
}
#clicked-buttons {
grid-area: 2 / 2 / 3 / 3;
display: block;
background-color: #d0d0d0;
border-radius: 5px;
padding: 1em;
margin: 0;
}
#remove-button {
grid-area: 1 / 2 / 2 / 3;
}
.hidden {
opacity: 0;
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="buttons">
<button class="button" id="1" value="1" >1</button>
<button class="button" id="2" value="2" >2</button>
<button class="button" id="3" value="3" >3</button>
<button class="button" id="4" value="4" >4</button>
<button class="button" id="5" value="5" >5</button>
<button class="button" id="6" value="6" >6</button>
</div>
<img id="display" class="hidden">
<button id="remove-button">Remove last input</button>
<code id="clicked-buttons"></code>
</div>
Here is my working solution, albeit its kind of hacky.
Have all of your images loaded in an array, just the file names.
Then loop through ALL of those files and create an object with the sorted name as the key and the file name as the value. That way no matter how the images are named, they will have a key like 999XXX.
Then it's just a matter of getting the buttons clicked and sorting its string until that string exists as a key.
var imgs = ["ABC123.png", "1A2B4C.png"];
function case_insensitive_comp(strA, strB) {
return strA.toLowerCase().localeCompare(strB.toLowerCase());
}
function reSortFiles() {
var all = {};
imgs.forEach(function(a) {
d = a.split(".");
img = d[0].split("");
img = sortStr(img);
img = img.join("");
all[img] = a;
});
return all;
}
function sortStr(str) {
return str.sort(case_insensitive_comp)
}
allImages = reSortFiles()
buttons = document.querySelectorAll("button")
clicked = "";
buttons.forEach(function(btn) {
btn.addEventListener("click", function(e) {
clicked += e.target.dataset.value;
clicked = sortStr(clicked.split("")).join("")
img = allImages[clicked]
if (img) {
console.log(img)
}
});
});
<button type="button" data-value="A">A</button>
<button type="button" data-value="B">B</button>
<button type="button" data-value="C">C</button>
<button type="button" data-value="1">1</button>
<button type="button" data-value="2">2</button>
<button type="button" data-value="3">3</button>
Version that allows multiple
var imgs = ["ABC123.png", "1A2B4C.png", "ABC132.png", "123ABC.png"];
function case_insensitive_comp(strA, strB) {
return strA.toLowerCase().localeCompare(strB.toLowerCase());
}
function reSortFiles() {
var all = {};
imgs.forEach(function(a) {
d = a.split(".");
img = d[0].split("");
img = sortStr(img);
img = img.join("");
all[img] ? all[img].push(a) : all[img] = [a];
});
return all;
}
function sortStr(str) {
return str.sort(case_insensitive_comp)
}
allImages = reSortFiles()
console.log(allImages)
buttons = document.querySelectorAll("button")
clicked = "";
buttons.forEach(function(btn) {
btn.addEventListener("click", function(e) {
clicked += e.target.dataset.value;
clicked_s = sortStr(clicked.split("")).join("")
console.log(clicked, clicked_s)
img = allImages[clicked_s]
if (img) {
console.log("Found: ", img.join(","))
clicked="";
}
});
});
<button type="button" data-value="A">A</button>
<button type="button" data-value="B">B</button>
<button type="button" data-value="C">C</button>
<button type="button" data-value="1">1</button>
<button type="button" data-value="2">2</button>
<button type="button" data-value="3">3</button>
<button type="button" data-value="4">4</button>

both buttons trigger one script

I have a button that triggers a script on a webpage. One instance works. When I try to add a second button/script, both buttons trigger the second script only. I know (think?) it's because the var I'm defining for the buttons are not unique to their individual scripts, but every way I attempt I break the whole thing.
button {
display: block;
cursor: pointer;
margin-left: 10px;}
button:after {
content: " (off)";
}
button.on:before {
content: "✓ ";
}
button.on:after {
content:" ";
}
.frac span {
-webkit-font-feature-settings: "frac" 1;
font-feature-settings: "frac" 1;
}
.onum span {
-webkit-font-feature-settings: "onum" 1;
font-feature-settings: "onum" 1;
}
Html:
<button name="frac" id="frac">Fractions</button>
<button name="onum" id="onum">Oldstyle Numbers</button>
This text is supposed change OT features when the buttons are pressed.
JS:
<script> var btn = document.getElementById("frac"),
body = document.getElementById("textA"),
activeClass = "frac";
btn.addEventListener("click", function(e){
e.preventDefault();
body.classList.toggle(activeClass);
btn.classList.toggle('on');
}); </script>
<!-- onum -->
<script> var btn = document.getElementById("onum"),
body = document.getElementById("textA"),
activeClass = "onum";
btn.addEventListener("click", function(f){
f.preventDefault();
body.classList.toggle(activeClass);
btn.classList.toggle('on');
}); </script>
The variance between the scripts/buttons are some of the changes from different things I've done, but I've gone mostly back to the beginning so it's simpler.
In javascript, every variable that you declare is inherently available across the entire page. So, putting them in separate tags will have no effect.
So essentially, your second variable btn is actually overwriting the first one. Rename the second variable to say, btn2.
Or, as an alternative, change the line
btn.classList.toggle('on')
to
this.classList.toggle('on')
this within the click handler will always point to the current button being clicked.
You can do it in fewer lines of code
// you create the array of buttons
let butons = Array.from(document.querySelectorAll("button")),
// you define the _body
_body = document.getElementById("textA")
// for every button in the buttons array (map is an iterator)
butons.map((btn) =>{
//you define the activeClass to be the name attribute of the button
let activeClass = btn.getAttribute("name");
// everytime you click the button
btn.addEventListener("click", (e) =>{
/*this was in your code. I don't know why you need it
e.preventDefault();*/
//you toggle the activeClass & the on class
_body.classList.toggle(activeClass);
btn.classList.toggle("on");
})
})
button {
display: block;
cursor: pointer;
margin-left: 10px;
}
button:after {
content: " (off)";
}
button.on:before {
content: "✓ ";
}
button.on:after {
content: " ";
}
/* I'm using color to visualize the change */
.frac span {
color: red;
}
.onum span {
color: green;
}
<button name="frac" id="frac">Fractions</button>
<button name="onum" id="onum">Oldstyle Numbers</button>
<p id="textA">The variance between the <span>scripts/buttons</span> are some of the changes from different things I've done, but I've gone mostly back to the beginning so it's simpler.</p>

How to toggle a button to an active state using vanilla JS?

I have a list of 20 buttons on a page. When I click on a button I want it to switch to an "active" state. In this active state it will be a different color. I would like to do this using only vanilla javascript and css.
I have the following code to create the buttons:
var button;
createButtons();
function createButtons() {
for (i = 0; i < 20; i++) {
//creates a new button
button = document.createElement('Button');
//sets correct button number and button text
var index = i + 1;
var text = document.createTextNode('Button ' + index);
button.appendChild(text);
button.className += "button";
button.className += " default-button";
document.body.appendChild(button);
}
}
Modern browsers support the classList API now.
In order to use the classList API, try adding the following to your code:
var buttons = document.getElementsByClassName('button')
Array.prototype.forEach.call(buttons, function (button) {
button.addEventListener('click', function (event) {
button.classList.toggle('button-active')
})
})
If you want to only turn the active state on, switch the toggle method of classList to add. Read more on classList.
Breakdown of code example:
First I select all .button elements and store them in a NodeList data type.
Then I call array's forEach function (another way of doing the same would be [].forEach.call() but that creates new Array instance every time it runs). I add an event listener for click event upon which I toggle a new class name.
For a direct CSS manipulation, you can use button.style.color = 'red' - but I discourage you from this approach to keep your code maintainable.
Note from Phil (in the comments to this answer):
You can use NodeList.prototype.forEach() which shortens the line into buttons.forEach(function (button) {. Bear in mind that Internet Explorer does not support this.
CSS alternative without JavaScript:
input[type=checkbox] { display: none; }
input[type=checkbox] + label { background-color: cyan; }
input[type=checkbox]:checked + label { background-color: red; }
<input type=checkbox id=t1><label for=t1> Toggle 1 </label><br>
<input type=checkbox id=t2><label for=t2> Toggle 2 </label><br>
<input type=checkbox id=t3><label for=t3> Toggle 3 </label><br>
<input type=checkbox id=t4><label for=t4> Toggle 4 </label><br>
<input type=checkbox id=t5><label for=t5> Toggle 5 </label><br>
Assuming you only want one button "active" at a time, I would just use the CSS :focus / :active pseudo-class. For example
for (let i = 1; i <= 20; i++) {
let btn = document.createElement('button')
btn.textContent = `Button ${i}`
btn.classList.add('button', 'default-button')
document.body.appendChild(btn)
}
.button {
background-color: blue;
color: white;
font-weight: bold;
}
.button:active, .button:focus {
background-color: red;
}
You can use button.onclick = function(){ // do things here. };
I have included the code in a snippet below. Good luck.
var button;
createButtons();
function createButtons() {
for (i = 0; i < 20; i++) {
//creates a new button
button = document.createElement('Button');
//sets correct button number and button text
var index = i + 1;
var text = document.createTextNode('Button ' + index);
button.appendChild(text);
button.className += "button";
button.className += " default-button";
// --------------------------------------------------------
// on click check if it contains the class for the color
// and toggle it on or off.
button.onclick = function() {
if (this.classList.contains("enableColor")) {
this.classList.remove('enableColor');
} else {
this.classList.add("enableColor");
}
}
// --------------------------------------------------------
document.body.appendChild(button);
}
}
.enableColor {
background: red;
color: white;
}
.focus(), but most browsers actually block button click type behavior for security purposes. What you can do is set the button elements disabled = true attribute then when you get whatever action you are looking for toggle that attribute to disabled = false.
Here's a snippet you could adapt:
// enables submit button iif inputs meet validation contraints
function attachKeyupListenerToInputElements(){
var inputs = doc.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener("keyup", keyupHandler);
}
function keyupHandler() {
if(this.value === ''){
this.setCustomValidity('Required Field');
} else {
this.setCustomValidity('');
}
//for dialog inputs
if(doc.querySelector(".mdc-dialog").classList.contains("mdc-dialog--open")){
//dialog is open
var thisSection = this.parentElement.parentElement;
var theseInputs = thisSection.querySelectorAll("input");
var inputsFull = true;
for (var i = 0; i < theseInputs.length; i++) {
if(!theseInputs[i].checkValidity()){
inputsFull = false;
}
}
if(inputsFull){
doc.getElementById("dialog-accept-button").disabled = false;
}
}
}
}

Building button in jQuery through function-paramater usage

Good morning! I am trying to create a function to generate a set of buttons on a webpage using jQuery. My sample code is below. The buttons are created (yay) but the parameters for value, onclick etc. are not used (boo). Please can someone with better skills that me show me the error in my code? Thanks so much for your help! I am beating my head against a wall here...
var buttonBar = document.getElementById("ButtonBar");
function genButton (butName, butLabel, action) {
$('#buttonBar').append
('<input type="button"
name=butName
value = butLabel
onclick = action>');
}
genButton('butAsIs', 'Buy As Is', 'funAsIs()');
function funAsIs() {
window.alert("Buy Me Pressed"); //TestCode 001
}
With your code you append just strings as parameters, not your variables.
For correct work, you may write
$('#buttonBar').append
('<input type="button" name="' + butName + '" value ="' + butLabel + '" onclick="' + action + '">');
Or use es6 syntax with ${expressions}
The butName, butLabel and Action are taken as string and not as interpolated variables inside your code. Here is a working examaple of your code :
https://jsfiddle.net/qtjtbsz6/
To create new input you should use document.createElement("input");.
// Let's create an input
var element = document.createElement("input");
Assigning new attributes are really easy in this way
element.type = 'button';
element.value = butLabel;
element.name = butName;
Adding onclick event is a bit tricky. We need to wrap it inside function then we can invoke it.
element.onclick = function() {
action(actionParams);
};
To generate new button we will use:
function generateButton(butName, butLabel, action, actionParams) { ... }
we can call this function for example like this:
generateButton('yourName', 'yourLabel', popAlert, { alertText: 'hello!', randomStuff: 'random' })
action is a function name that we pass as an argument. Remember now to add () - important part here.
actionParams are our action arguments. In our case it is just javascript object { alertText: 'hello!', randomStuff: 'random' }, you can pass anything you want.
Finally we append new input to our #result selector.
Here is working example. Run code snippet to see how it works.
function generateButton(butName, butLabel, action, actionParams) {
// Let's create an input
var element = document.createElement("input");
// Now we assign
element.type = 'button';
element.value = butLabel;
element.name = butName;
element.onclick = function() {
action(actionParams);
};
// Now we append
var result = document.getElementById("result");
result.appendChild(element);
}
function popAlert(params) {
alert(params.alertText);
console.log(params.randomStuff);
}
#result {
padding: 20px;
border: 1px solid #eee;
}
input[type="button"] {
margin: 2px;
}
<input type="button" value="click me to generate new button!" onclick="generateButton('yourName', 'yourLabel', popAlert, { alertText: 'hello!', randomStuff: 'random' })" />
<div id="result"></div>

Categories

Resources