I'm trying to make a list where users can insert their favourite beer. there have to be a check if the "userinput" is already in the array..
My thoughts were as follows: loop through the beersArray and check if there is a value in the array that is the same as what user puts in. If there is, alert and do not add. If not, then add the user input to a list item.
var submitBier = document.getElementById("submitbeer");
submitBier.addEventListener("click", function(){
event.preventDefault();
var beersArray = [];
var beer = document.getElementById("favobeer");
var beerList = document.getElementById("listwithbeer");
var beerLi = document.createElement("LI");
var BeerName = document.createTextNode(beer.value);
var i;
var j;
for (j = 0; j < beersArray.length; j++) {
if (beersArray[j] === beer.value) {
alert("This beer is already in the list");
} else {
for (i = 0; i < beersArray.length; i++) {
beersArray[i].className = 'beer';
beerLi.appendChild(BeerName);
beerList.appendChild(beerLi);
beersArray.push(beerList.appendChild(beerLi));
}
}
}
});
<div class="beers">
<h1 id="vraagnaam">add your favourite beers</h1>
<input type="text" id="favobeer" value = "" />
<button id="submitbeer" type="submit" value="Submit" >add</button>
<ul id="listwithbeer"></ul>
</div>
There are multiple problems in the code
The array should be declared outside of the handler else every click will create a new handler
The array should be populated with the input value, not with the value returned by appendChild()
You can use indexOf to check whether the current value is present in the array
So
var beersArray = [];
var submitBier = document.getElementById("submitbeer");
var beer = document.getElementById("favobeer");
var beerList = document.getElementById("listwithbeer");
submitBier.addEventListener("click", function() {
event.preventDefault();
var value = beer.value.trim();
if (beersArray.indexOf(value) == -1) {
var beerLi = document.createElement("LI");
var BeerName = document.createTextNode(value);
beerLi.appendChild(BeerName);
beerList.appendChild(beerLi);
beersArray.push(value);
} else {
alert("This beer is already in the list");
}
});
<div class="beers">
<h1 id="vraagnaam">add your favourite beers</h1>
<input type="text" id="favobeer" value="" />
<button id="submitbeer" type="submit" value="Submit">add</button>
<ul id="listwithbeer"></ul>
</div>
A 2nd for loop won't be necessary if you are looping through the same array.
The correct way to putting in a 'if-else' statement within a for loop can be done as follows:
for (var j = 0; j < beersArray.length; j++) {
// A If-conditional statement to short-circuit existing beer list
if (beersArray[j] === beer.value) alert ('This beer is already in the list')
// Core Logic
beersArray[j].className = 'beer';
beerLi.appendChild(BeerName);
beerList.appendChild(beerLi);
beersArray.push(beerList.appendChild(beerLi));
}
Related
Why when I try to search for substrings within values of cardDescs and console log the results it just console logs an empty array
const cardDescs = [];
$.getJSON("https://db.ygoprodeck.com/api/v7/cardinfo.php", null, function(result){
var i = 0;
for (var i = 0; i <= 10767; i++){
(cardDescs).push(result["data"][i]["desc"])
}
})
function summonCardToFieldByName() {
var cardName = document.getElementById('cN').value;
const useableCards = [];
for (description in cardDescs){
if (description.includes("Special Summon 1 \""+cardName+"\" from your Deck")){
useableCards.push({description});
}
}
console.log(cardDescs[132]);
console.log(useableCards);
}
The relevant relevant HTML
<form id="cardSearch">
<input type="text" size="12" id="cN" />
<input type="button" onclick="showChosenCard(); summonCardToFieldByName();" value="Submit Card" />
</form>
I don't see you calling the function at all before you do the console logging, so that might be the issue, you never fill the array with usable cards before logging it out.
I got it to work by using a for loop rather than a for/in loop and push the specific index from the array
const cardDescs = [];
$.getJSON("https://db.ygoprodeck.com/api/v7/cardinfo.php", null, function(result){
var i = 0;
for (var i = 0; i <= 10767; i++){
(cardDescs).push(result["data"][i]["desc"])
}
})
function summonCardToFieldByName() {
var cardName = document.getElementById('cN').value;
const useableCards = [];
for (var i = 0; i <= 10767; i++){
if (cardDescs[i].includes("Special Summon 1 \""+cardName+"\" from your Deck")){
useableCards.push(cardDescs[i]);
}
}
What I am trying to accomplish is have the user click button one and a text field is created, this button is pushed 3 times and 3 text fields appear. When each text field appears it should the user should then enter text in each text field. Once all text fields are filled by the user, there is a second button that when clicked; should display and sort the manually entered input fields text in a bonafide node list by alphabetical order.
(NOT AN ARRAY) it must be a true nodelist. Keep in mind, each input field is being created upon the push of button #1. Then the user entered information is being displayed and sorted when pushing button #2. A for-loop should be used to retrieve value of each element of the nodelistand store each value into an element of the new listItemValues array.
Appreciate any help.
javascript:
var $ = function (id) {
return document.getElementById(id)
}
var adding = function() {
var newInput = document.createElement("input");
var newBreak = document.createElement("br");
var myparent = $("todolist");
newInput.setAttribute("title", "text");
newInput.setAttribute("class", "listitem");
myparent.appendChild(newInput);
myparent.appendChild(newBreak);
};
var sorting = function() {
var display = "";
var listItemValues = document.getElementsByTagName("input");
for (i = 1; i <= listItemValues.length; i++)
var myItem = $("additem") + i;
var myItemName = (myItem).value;
display += myItemName;
}
window.onload = function() {
$("additem").onclick = adding;
$("sortitems").onclick = sorting;
}
I have made some changes to your code to make it a completely a javascriptsolution.
To reduce the use of the repetitive syntax of document.getElementById and document.createElement. I have 2 Function Declarations:
function id(id) {
return document.getElementById(id);
}
function ce(el) {
return document.createElement(el);
}
Other change is in the Function Expression adding() where I've added: newInput.type = "text"; to setting the input type when you click in the Add Item button.
In the Function Expression sorting() I've declared:
nodeList = document.querySelectorAll("input[type=text]");
The document.querySelectorAll() method returns a list of the
elements within the document (using depth-first pre-order traversal of
the document's nodes) that match the specified group of selectors. The
object returned is a NodeList.
Finally I've made a Function Expression printSortedValues() to print the sorted values in <p id="displayitems"></p>. In this function use the Array.prototype.sort() to sort its values ascending.
var printSortedValues = function(listItemValues) {
listItemValues.sort(); // Sorting the values.
var html = "", i, len = listItemValues.length;
for (i = 0; i < len; i++) {
html += "<span>";
html += listItemValues[i];
html += "</span>";
}
return html; // Return the html content with the sorted values.
};
Something like this:
function id(id) {
return document.getElementById(id);
}
function ce(el) {
return document.createElement(el);
}
var adding = function() {
var newInput = ce("input"), newBreak = ce("br"), myparent = id("todolist");
newInput.setAttribute("title", "Some title...");
newInput.setAttribute("class", "listitem");
newInput.type = "text";
myparent.appendChild(newInput);
myparent.appendChild(newBreak);
};
var sorting = function() {
var listItemValues = [], nodeList = document.querySelectorAll("input[type=text]"), i, len = nodeList.length, node;
for (i = 0; i < len; i++) {
node = nodeList[i];
listItemValues.push(node.value); // Store its values.
}
id("displayitems").innerHTML = printSortedValues(listItemValues);
};
var printSortedValues = function(listItemValues) {
listItemValues.sort(); // Sorting the values.
var html = "", i, len = listItemValues.length;
for (i = 0; i < len; i++) {
html += "<span>";
html += listItemValues[i];
html += "</span>";
}
return html; // Return the html content with the sorted values.
};
window.onload = function() {
var additem = id("additem"), sortitems = id("sortitems");
additem.onclick = adding;
sortitems.onclick = sorting;
};
#displayitems span {
border: solid 1px #ccc;
border-radius: 5px;
display: block;
margin: 2px 0;
padding: 4px;
}
<body>
<h1>ToDo List - Date: <span id="today"> </span></h1>
<div id="todolist">
<p>
<input type="button" id="additem" value="Add Item">
</p>
</div>
<hr>
<div>
<p>
<input type="button" id="sortitems" value="Sort and Display Items">
</p>
<p id="displayitems"></p>
</div>
</body>
Hope this helps.
I have an un-ordered list with items that are generated programatically in web2py...
I'm displaying them in HTML as displayed below... I want to have a textbox that allows a user to type in a string. this string should "toggle" the visibility of the <li> values if they match or not.
<input type="text" id="userTextSearch" onkeyup="listSearch(this.value)"></input>
<ul id="fileResultsID">
{{for item in mylist:}}
<li>
<input type="checkbox" name="FileListItem" id="value"> {{=item}}</label>
</li>
{{pass}}
</ul>
function listSearch(textValue)
{
var fileGroup = document.getElementById('fileResultsID');
var items = fileGroup.getElementsByTagName('li');
var chkBx;
for(var i = 0, n = items.length; i < n; i++)
{
chkBx = items[i].getElementsByTagName('input');
alert(chkBx.InnerHtml);
//if(!items[i].value.startswith(textValue))
//{
// items[i].toggle();
//}
}
}
So far when I type, nothing visible occurs...
Q: How can get certain <li> row items to disappear as the user types?
I will need them all to comeback if the text box is empty too btw
This is what worked for me... I also have a quick loop to renable all of the list items if the textbox is cleared out.
function listSearch(textValue){
var fileGroup = document.getElementById('fileResultsID');
var items = fileGroup.getElementsByTagName('li');
var chkBx;
//check to see if user deleted everything first
if(!textValue)
{
for(var i = 0, n = items.length; i < n; i++)
{
items[i].style.display = "block";
}
}
for(var i = 0, n = items.length; i < n; i++)
{
chkBx = items[i].getElementsByTagName('input');
var str = chkBx[0].id
if(!str.toLowerCase().startsWith(textValue.toLowerCase()))
{
items[i].style.display = "none";
}
}}
I want the user to enter a number then when it is submitted, it is inserted into the array totalBags.
The user can then submit another number, when submitted the array elements are added together.
E.g. Input = 2
Press submit
Output = 2
New input = 3
Press submit
Output = 5
Here is my code:
<html>
<head>
<script type = "text/javascript">
function submitOrder()
{
var allBags = [];
var bags_text = document.getElementById("bags").value;
allBags.push(bags_text);
var totalBags = 0;
for (var i = 0; i < allBags.length; i++)
{
totalBags += allBags[i]; // here is the problem... i think
}
document.getElementById("container").innerHTML = "<p>"+totalBags+"</p><input type=\"reset\" value=\"New Order\" onClick=\"resetOrder()\" />";
}
function resetOrder()
{
document.getElementById("container").innerHTML = "<p><label for=\"bags\">No. bags: </label><input type=\"text\" id=\"bags\" /></p><p><input type=\"button\" value=\"Subit order\" onClick=\"submitOrder()\"> <input type=\"reset\" value=\"Reset Form\" /></p>";
}
</script>
</head>
<body>
<form name="order_form" id="order_form">
<div id="container">
<label>Total bags: </label><input id="bags" type="text" ><br>
<input type="button" id="submitButton" value="Subit order" onClick="submitOrder()">
<input type="reset" value="Reset" class="reset" />
</div>
</form>
</html>
I should rewrite the program a bit. First, you can define global variables which won't be instantiated in the function. You are doing that, which resets the variables. Fe
function submitOrder()
{
var allBags = [];
// ...
}
It means that each time you're clicking on the button allBags is created as a new array. Then you add an value from the input element. The result is that you have always an array with one element. It's best to declare it outside the function. By this, you ensure that the variables are kept.
// general variables
var allBags = [];
var totalBags = 0;
function submitOrder()
{
// the result is a string. You have to cast it to an int to ensure that it's numeric
var bags_text = parseInt(document.getElementById("bags").value, 10);
// add result to allBags
allBags.push(bags_text);
// total bags
totalBags += bags_text;
// display the result
document.getElementById("container").innerHTML = "<p>"+totalBags+"</p><input type=\"reset\" value=\"New Order\" onClick=\"resetOrder()\" />";
}
by leaving out the loop, you have an more performant program. But don't forget to clear the array and the totalBags variable to 0 if you're using the reset button.
function resetOrder()
{
document.getElementById("container").innerHTML = "...";
// reset variables
totalBags = 0;
allBags = [];
}
Try to use:
for (var i = 0; i < allBags.length; i++)
{
totalBags += parseInt(allBags[i],10);
}
Or use Number(allBags[i]) if you prefer that.
Your element allBags[i] is a string and + between strings and concatenting them.
Further study: What is the difference between parseInt(string) and Number(string) in JavaScript?
function submitOrder()
{
var allBags = parseInt(document.getElementById("bags").value.split(""),10);//Number can also used
var totalBags = 0;
for (var i = 0; i < allBags.length; i++)
{
totalBags += allBags[i];
}
document.getElementById("container").innerHTML = "<p>"+totalBags+"</p><input type=\"reset\" value=\"New Order\" onClick=\"resetOrder()\" />";
}
I have a javascript which appends a string like 222222222222222 to another field (which will either be blank or already have numbers like 222222222222222 33333333333333) with a click of a button. Actually it's 15 digit IMEI of the phone. User has the option of submitting a single IMEI or bulk IMEI. When more then one IMEI is added to the bulk field by pressing the button from myVar1, the new IMEI gets inserted below the previous IMEI in the bulk field(myVar2).
Currently, I am using the below script to do this and it's working perfectly fine. The problem is that it doesn't check for duplicates before appending.
function append_myVar1_to_myVar2(){
var myVar1 = document.getElementById('myVar1_value').value;
var myVar2 = document.getElementById('myVar2_value').value;
if(document.getElementById('myVar2_value').value == ''){
document.getElementById('myVar2_value').value = myVar1;
}else{
document.getElementById('myVar2_value').value = document.getElementById('myVar2_value').value + "\r\n" + myVar1;
}
}
I have modified the script now as below (updated to include the first response, thanks to Brian) to check for duplicates, but it's not working. Request experts to have a look into it.
function append_myVar1_to_myVar2(){
var myVar1 = document.getElementById('myVar1_value').value;
var myVar2 = document.getElementById('myVar2_value').value;
if(document.getElementById('myVar2_value').value == ''){
document.getElementById('myVar2_value').value = myVar1;
}else{
var flag = 0;
var wordsarr = myVar2.split("\r\n");
for(var i = 0; i < wordsarr.length; i++)
{
if(wordsarr[i].value == myVar1)
{
flag = 1;
}
}
if(flag == 1)
{
alert('Value is duplicate.');
}
else{
document.getElementById('myVar2_value').value = document.getElementById('myVar2_value').value + "\r\n" + myVar1;
}
}}
Here is the html of the page:
<html>
<body>
<input id="myVar1_value" type="text" maxlength="15" name="myVar1_value">
<input id="IMEI_ADD" class="button_gray" type="button" onclick="append_myVar1_to_myVar2()" value="Add this IMEI to bulk entry" name="IMEI_ADD">
<p id="imei_bulk_field" class="form-row notes">
<textarea id="myVar2_value" class="input-text" rows="2" cols="5" placeholder="If you have more than one IMEI, insert them here by pressing the button above." name="myVar2_value"></textarea>
</p>
</body>
</html>
for(var i = 0; i < (myVar2.split("\r\n")).length; i++)
{
//here is wrong
if(myVar2[i].value == myVar1)
{
flag = 1;
}
You should change to
var wordsarr = myVar2.split("\n");
for(var i = 0; i < worsarr.length; i++)
{
if(wordsarr[i] == myVar1)
{
flag = 1;
}
}
if(flag == 1)
{
alert('Value is duplicate.');
}
Store splitted chunks ,and iterate over them:
var chunkArray = myVar2.split("\r\n");
for(var i = 0; i !== chunkArray.length; i++){
if(chunkArray[i] == myVar1){
flag = 1;
break;
}
}
var myVar2 = document.getElementById('myVar2_value').value;
Later...
if(myVar2[i].value == myVar1)
It looks like you are adding .value when you don't need to. Try:
if(myVar2[i] == myVar1)
This could be of assistance
function inArray(needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] == needle) return true;
}
return false;
}
you could change the if with:
haystack[i].value == needle