Some problems getting a button value in javascript - javascript

I'm not sure I'm using this properly, but I need some help. I want to make a calculator, and I don't want to repeat code in html like onclick="insert(value)" so I wrote that code that would add an eventlistener on every button but I'm not sure how should I get the value of the button. At the moment text.value is [object MouseEvent]. I think I need something like btn.value but this doesn't work. Any ideas?
const btns = document.querySelectorAll(".button");
for(const btn of btns){
btn.addEventListener("click", function insert(value) {
text.value = text.value + value;
})
};

First of all. When you take a value from a html component you are taking a string.
You should use parseInt or parseFloat to convert these values in numbers.
the other thing is the html elements they are object in js with properties. You can use the function console.log and make you its best friend :) because although it is not a good practice all the time will help you a lot. When you log the element you can see how you can extract the value inside an Html Element. Normally all the HTMl Elements have a property called innerText and innerHtml with them you can extract the value inside. For the inputs type elements you have the property value to extract the value inside the element.
I couldn't understand what exactly are you trying to achieve but i supose is something like make the sum of entered values. One last and not more important thing is that if you are expecting some value in js and is undefined or null or isNaN you will not get the result you are expecting for. For that reason you should always ask first if what you are expecting for is what you are receiving.
<div class='container'>
<input type='text' id='display' />
<button>1</button>
<button>2</button>
<button>3</button>
</div>
const buttons = Array.from(document.getElementsByTagName('button'));
const display = document.getElementById('display');
for (const btn of buttons) {
btn.addEventListener("click", function(event) {
const buttonValue = parseInt(event.target.innerText);
const displayValue = display.value;
if (displayValue.length === 0) {
display.value = buttonValue;
return;
}
display.value = parseInt(displayValue) + buttonValue;
console.log(displayValue);
console.log(buttonValue);
})
};
Here the codepen if you want to see it :)

Everything I had to do was to add .target.value.
text.value = text.value + value.target.value;

Related

How to remove inner HTML content onchange

I created a form where a user selects options from a checkbox list. So when a user selects an option in the checkbox, I use a function to show the value of the input field using onchange within inner HTML. My question is, how do we remove that same inner HTML content if the user un-selects those options? So when the user toggles back and forth, it either appears or when un-selected, the value gets removed. Thanks
function functionOne() {
var x = document.getElementById("wheels").value;
document.getElementById("demo").innerHTML = x;
}
<input type="checkbox" id="wheels" onchange="functionOne()" value="feature 1">
<div id="demo"></div>
Check the state of the checkbox before you read the value.
function functionOne(cb) {
var x = cb.checked ? cb.value : '';
document.getElementById("demo").innerHTML = x;
}
<input type="checkbox" id="wheels" onchange="functionOne(this)" value="feature 1">
<div id="demo"></div>
Inside the change function on deselect do this:
document.getElementById("demo").innerHTML = '';
The element that is changed has a checked property which can be inspected - it will be either true or false. So write an if/else condition to update the content of the demo element depending on its value.
I've adjusted your code slightly to cache the elements outside of the function, and to add an event listener to the checkbox instead of using inline JS which is a bit old-school these days. Also, since the value is just a string textContent is more suitable in this case than innerHTML.
// Cache the elements
const wheels = document.getElementById('wheels');
const demo = document.getElementById('demo');
// Add a listener to the wheels element which calls the
// handler when it changes
wheels.addEventListener('change', handleChange);
// Here `this` refers to the clicked element. If its
// checked property is `true` set the text content of
// `demo` to its value, otherwise use an empty string instead
function handleChange() {
if (this.checked) {
demo.textContent = this.value;
} else {
demo.textContent = '';
}
}
<input type="checkbox" id="wheels" value="feature 1">
<div id="demo"></div>

inputting grades (javascript function)

How do I make it so that the numbers I input are all on top of one another and another together in one spacing.
It supposed to show all the 3 grades I have input and when the button is clicked it should show the average and either pass or fail (I know it's supposed to be an if else statement but I really can't comprehend the codes and where will I put it)
If someone helps me solve this one can someone give me more user input / function related exercises that I can work on? thanks.
var p = prompt ("enter first grade");
var c = prompt ("enter second");
var o = prompt ("enter third grade");
document.write (p);
document.write (c);
document.write (o);
function xxx (p,c,o)
{
document.getElementById("demo4").innerHTML = ((parseInt(p)+parseInt(c)+parseInt(o)) / 3)
}
<p id="demo"></p>
<p id="demo2"></p>
<p id="demo3"></p>
<button onclick="xxx()">calculate</button>
<p id="demo4"></p>
<p id="demo5"></p>
Let me start first with the main non-logic problems with your code:
You shouldn't use prompt, it's just bad user experience. Dynamically create HTML elements instead.
You shouldn't use document.write. You aren't able to specify where the text should go and it makes your code vulnerable towards XSS vulnerabilities.
You shouldn't use onclick. You should never mix the JS with your HTML like that. (React's HTML-like syntax is not HTML, it's JSX. It's okay to do that there.)
Now, back to the main logic which your code should follow.
Provide the user with one <input type='number'> field and an "Add" button.
Recalculate the result on every change, don't rely on a "Calculate" button to update your state.
You can use an if statement to detect a failing grade.
Here is an example of a more proper implementation of what you're trying to accomplish. I know I'm basically doing the homework task for you so I would like you to learn from this.
// Storing references to elements.
const grades = document.getElementById('grades');
const template = document.getElementById('template');
const addButton = document.getElementById('add');
const averageOut = document.getElementById('average');
const failedOut = document.getElementById('failed');
function recalculate() {
// Let's create a sum variable.
let sum = 0;
// Let's query the document for grade input fields.
const numberFields = document.querySelectorAll('#grades input');
// Iterate over number fields with for ... of.
for (let field of numberFields) {
// Unary + converts the value into a number.
// parseInt can be used instead as well.
sum += +field.value;
}
// .length gives you the total amount of input fields.
// .length works on any array and some lists. (querySelectorAll returns a NodeList instead of an array)
const average = sum/numberFields.length;
// Use innerText to prevent XSS.
averageOut.innerText = average;
// If statement to check if the person has failed.
if (average < 3.0) {
failedOut.innerText = 'FAIL';
} else {
failedOut.innerText = 'NOT FAIL';
}
}
// Let's recalculate the average on any change made in ANY field in the document.
// This is basically what jQuery does in its '.on(eventType, selector, listener)' method.
// This technique relies on event bubbling.
// Make sure to replace this once you start adding more functions into the document.
// Also, () => is a closure in JavaScript, which is a function but with a different context.
document.addEventListener('change', () => recalculate());
// Adding new fields.
addButton.addEventListener('click', () => {
// Clone the template...
const templateClone = template.cloneNode(true);
// ...and append it to our grades.
grades.appendChild(templateClone);
// Also recalculate.
recalculate();
});
// Recalculate on load.
recalculate();
<ul id="grades">
<li id="template">
<input type="number" value="1" min="1" max="5" />
</li>
</ul>
<button id="add">Add</button>
<div>
<span>Average:</span> <span id="average"></span>
</div>
<div>
<span>Failed?:</span> <span id="failed"></span>
</div>
What you could improve upon is adding a "Remove" button.

Find elements by text

I have input tags on the page that are generated dynamically using JS.
They are initialized using $("#input1").val(value). How can I find specific input elements base on text?
The values are initialized as follows:
$("input[name='DeviceIP']").each(function(index,elem){$(elem).val(value)});
The solution I am using now is to select all the inputs I want to inspect and then using find.
$("[name='DeviceIP']").filter(function(index, elem) {
var res = false;
var _this = this;
$("[name='DeviceIP']").each(function(index2, elem2) {
if(elem2 !== _this) {
if(_this.value === elem2.value) {
errMessage = "error text";
res = true;
}
}
});
return res;
}
I looked at the question here but the ":contains" didn't find them for some reason(maybe because there is no value attribute?)
"$("input[name='DeviceIP'][value='your_value_here']")
element.value is also an attribute, so You can define it in Your query ;)
Still, you shouldn't perform such query very often if You have a lot of elements.
I would also suggest You to create map, with values as keys, and nodes as values.
Suppose you have an input field like
<input type="text" value="5" name="DeviceIP">
<input type="text" value="8" name="DeviceIP">
you want the element with specific value. so you can do this,
alert($("input[name='DeviceIP'][value='5']").val());
Here is the fiddle.
If your value is dynamic, say for example your searching value is 8.so you can do this in a way,
var val = 8;
alert($("input[name='DeviceIP'][value='"+val+"']").val());

Hiding Text inside of an input element

I have a text input, and I want to hide the text inside, on a given event(I disable the input, when it is not needed). I would like to display the hidden text, when the given event is reversed.
I know I can store the value and retrieve as needed. I'd like to avoid moving data, since this is a purely cosmetic operation.
Can the input text be hidden, or is manipulating the data in the input the only way? I would like the simplest solution.y?
I can use pure JS and jQuery.
I would use "value" attribute of the same input object, since the attribute is the default value. In this case you don't even need any additional variables. The idea of this approach comes from the difference between properties and attributes. It means that if you change value property of the object, the attribute value remains the same as it was before.
var input = document.querySelector('input');
function hide() {
input.value = "";
}
function show() {
input.value = input.getAttribute('value');
}
<input type="text" value="Some text">
<button onclick="hide()">Hide</button>
<button onclick="show()">Show</button>
An example on how to store the value of an input element inside the dataset of the element.
and show/hide it on hover.
var hello = document.getElementById('hello');
hello.dataset.value = hello.value;
hello.value = '';
hello.addEventListener('mouseover', function() {
hello.value = hello.dataset.value;
});
hello.addEventListener('mouseout', function() {
hello.value = '';
});
<input id="hello" value="Hello World" />

How to select textarea and check if it is readonly?

I am struggling with jQuery. I want to write a script which checks if the text area sharing the same parent (list item) with the button is read-only when that button is clicked. Here is the HTML:
...
<li>
<h1>Title</h1>
<button type="button" onclick="javascript:confirmDelete();">Delete</button>
<button type="button" onclick="javascript:toggle();">Toggle</button>
<textarea class="readOnly" readonly="true">Some text</textarea>
</li>
...
And the script:
<script language="JavaScript">
<!--
...
function toggle()
{
var textArea = $(this).parent("li").children("textarea");
var isReadOnly = textArea.attr("readonly");
if (isReadOnly == "true") {
alert('It\'s read-only.');
} else {
alert('It\'s not read-only.');
}
}
//-->
</script>
It appears that I cannot get passed the var textArea = ...
Update 1:
OK, I broke apart the selection in order to help myself analyze the problem:
...
var btn = $(this);
console.log(btn); //returns value, but not sure what exactly
var li = btn.parent();
console.log(li); //returns value, but not sure what exactly
var textArea = li.children('textarea');
console.log(textArea.prop('tagName')); //returns unidentified
So, there's the error. I can't seem to understand what is actually wrong, as I cannot really learn much if all the output I get from the debug is an object (and I don't even know what it represents; is it an element, or array ...) or unidentified. jQuery is not exactly intuitive.
The property is case sensitive. Try instead
var isReadOnly = textArea.attr("readOnly");
if it is the only you likely need:
...find("textarea")[0];
not
...children("textarea");
or simply $(this).siblings("textarea")[0];
OR select directly
var mylist = $(this).siblings("textarea.readOnly");
if (mylist.length > 0)//true if it is
There are some errors in here.
Firs of all, turns out that when the attribute "readonly" is active, it doesn't have a "true" value, but a "readonly" value.
On the other hand, if you invoque a function by onclick (and I'm not 100% sure), you cannot use $(this). I'd recommend you to do (after giving some ID to the trigger button, or anything to identify it):
$(function() {
$("button#my-button").bind("click", function() {
if ($(this).siblings("textarea").attr("readonly") == "readonly") {
alert("It's readonly");
} else {
alert ("It's not");
}
});
});

Categories