My ToDo List dont wanna work the way i want. I've just been working with JavaScript for 2 weeks sthis is very new to me, therefor the code maybe doesnt look that nice.
The result comes out wrong. If I type in "buy food" the first line gonna show just that, but the next time I wanna add "walk the dog", then it displays
buy food
buy food
walk the dog
I hope you understand my problem. It also ends the unordered list tag after the first click and adds the rest of the things in another.
Here's the JavaScript:
var taskList = [];
var text = "<ul>"
function addToList() {
var task = document.getElementById("toDoTask").value;
taskList.push(task);
for(i = 0; i < taskList.length; i++){
text += "<li>" + taskList[i] + "</li>" ;
}
text += "</ul>";
document.getElementById("todoList").innerHTML = text;
}
The issue is you're closing the ul tag after adding each item. Instead of concatenating raw HTML, consider using element objects and appending, and using a text node object to handle the user input - this removes the possibility of a DOM Based XSS vulnerability.
window.onload = function() {
var taskList = [];
var container = document.getElementById("todoList");
document.getElementById("add").onclick = addToList;
function addToList() {
var task = document.getElementById("toDoTask").value;
taskList.push(task);
var ul = document.createElement('ul');
var li;
for (i = 0; i < taskList.length; i++) {
li = document.createElement('li');
li.appendChild(document.createTextNode(taskList[i]))
ul.appendChild(li);
}
container.innerHTML = '';
container.appendChild(ul);
}
};
Task:
<input id="toDoTask" /> <input type="button" id="add" value="Add" />
<div id="todoList">
</div>
You should not use the innerHtml. This replace all the text of your content. You should just add the li to your ul.
You can do that by using the append function by jquery Append
your <ul> must contain an id like this <ul id="toDoList">
then you make $("#toDoList").append("yourTask");
yourTask must contains the li.
With this, you don't need to iterate on all your element list
Not sure, but you seem to keep adding to text the second time, so text will be something like <ul><li>buy food</li></ul><li>buy food</li><li>walk the dog</li></ul>, which is invalid HTML by the way, but gets outputted anyway...
On each call of function addToList() you should reset the variable text.
For example:
function addToList() {
var task = document.getElementById("toDoTask").value;
taskList.push(task);
text="";
for(i = 0; i < taskList.length; i++){
text += "<li>" + taskList[i] + "</li>" ;
}
text += "</ul>";
document.getElementById("todoList").innerHTML = text;
}
The whole list of items in array will appends to variable text on each call.
Related
I have a form that has multiple fields all with the same class. These are populated with URL's that follow the same structure. I am trying to extract the same section from each URL. So far var res = x.split('/')[5]; will achieve this but only for the first URL. I can also use var x = document.querySelectorAll(".example") to change all the url's but I cannot find the correct way to combine both of these function. so far my code looks like this:
script>
function myFunction() {
var x = document.querySelectorAll(".example").innerHTML;
var res = x.split('/')[5];
var i;
for (i = 0; i < x.length; i++) {
x[i].innerHTML = res;
}
}
</script>
I have looked around but can't find a solution that fits. Thanks in advance for your help.
So loop over the HTML Collection, this is making assumptions based on code.
// Find all the elements
var elems = document.querySelectorAll(".example")
// loop over the collection
elems.forEach(function (elem) {
// reference the text of the element and split it
var txt = elem.innerHTML.split("/")[5]
// replace the text
elem.innerHTML = txt
})
<div class="example">1/2/3/4/5/a</div>
<div class="example">1/2/3/4/5/b</div>
<div class="example">1/2/3/4/5/c</div>
<div class="example">1/2/3/4/5/d</div>
<div class="example">1/2/3/4/5/e</div>
<div class="example">1/2/3/4/5/f</div>
I'm working on a personal project and I've run into an issue that I haven't been able to solve.
Here is a function that generates new table rows into a table (with id of "tableData") when a button is clicked:
function addNewRow(){
var tableEl = document.getElementById("tableData");
var newLine = '<tr class="newEntry">';
var classArray = ["classA", "classB", "classC", "classD"];
for (var i = 0; i < classArray.length; i++){
newLine += '<td><input class="' + classArray[i] + '"></td>';
}
newLine += '</tr>';
tableEl.insertAdjacentHTML("beforeend", newLine);
}
document.getElementById("addRow").addEventListener("click", addNewRow, false);
//the element with id="addRow" is a button
I've simplified the code for the above function for the sake of readability as it's not the focus of the problem. When the button is clicked, a new row is added successfully.
The problematic part involves another function that takes the sum of the respective classes of each row and displays them in a div.
The goal is to get the sum of the values of all input fields with matching class names. For example, let's say I use the addNewRow function to get six rows. Then I want to have the div showing the sum of the values of all input fields with the class name of "classA"; the number in that div should be the sum of those six values, which gets updated as I type in the values or change the existing values in any of the input fields with class name of "ClassA".
function sumValues(divId, inputClass){
var sumVal = document.getElementsByClassName(inputClass);
var addedUp = 0;
for (var j = 0; j < sumVal.length; j++){
addedUp += Number(sumVal[j].value);
}
document.getElementById(divId).innerHTML = addedUp;
}
Here are a couple (out of several) failed attempts:
document.input.addEventListener("keyup", sumValues("genericDivId", "classA"), false);
document.getElementsByClassName("classA").onkeyup = function(){sumValues("genericDivId", "classA");}
Unfortunately, after scouring the web for a solution and failing to find one, I just added an event listener to a button that, when clicked, would update the div to show the sum of values. Also had to modify the sumValues function to take values from an array rather than accepting arguments.
My question is: How can I modify the code so that the sum value updates as I type in new values or change existing values using pure Javascript (vanilla JS)?
You are very close, document.getElementsByClassName() returns an array of DOM objects, you need to set the onkeyup function for each and every element by looping through that array.
var classA = document.getElementsByClassName('classA'); // this is an array
classA.forEach(function(elem){ // loop through the array
elem.onkeyup = function(){ // elem is a single element
sumValues("genericDivId", "classA");
}
}
Hopefully this fixes your issue
Maybe the example below is not same with your situation, but you'll get the logic, easily. Anyway, do not hesitate to ask for more guide.
document.getElementById("row_adder").addEventListener("click", function() {
var t = document.getElementById("my_table");
var r = t.insertRow(-1); // adds rows to bottom - change it to 0 for top
var c = r.insertCell(0);
c.innerHTML = "<input class='not_important_with_that_way' type='number' value='0' onchange='calculate_sum()'></input>";
});
function calculate_sum() {
var sum = ([].slice.call(document.querySelectorAll("[type=number]"))).map(e=>parseFloat(e.value)).reduce((a, b) => a+b);
document.getElementById("sum").innerHTML = sum;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div>
<p>
<strong>Sum</strong>:<span id="sum">0</span>
</p>
</div>
<button id="row_adder">
Click me
</button>
<table id="my_table">
</table>
</body>
</html>
I have a confusing problem where a line of code in my function is running before a loop which is stated above it. In my HTML I have:
<textarea id="textBox"></textarea>
<button id="submitButton" onclick="parseData()">submit</button>
<div id="put"></div>
And my JS function is:
function parseData() {
var data = $("#textBox").val();
var tab = /\t/;
data = data.split(tab);
$("#put").html($("#put").html() + "<table>");
for (var i = 0; i < data.length; i++) {
$("#put").html($("#put").html() + "<tr>"+data[i]+"</tr>");
};
$("#put").html($("#put").html() + "</table>");
return;
};
The resulting html in $("#put") is this:
<table></table>
"SiO2 (%)Al2O3 (%)TiO2 (%)CaO2 (%)MgO2 (%) 8.21.25.31.51.8 45.32.52.60.210.5 65.23.48.70.0662.3 20.11.85.42.540.2 18.91.12.34.810.7"
I'm not sure why the final </table> is being placed before the for loop runs, and I'm not sure why the <tr> tags aren't being added within the for loop. Any pointers?
jQuery automatically closes up tags upon insertion. Try this.
function parseData() {
var data = $("#textBox").val();
var tab = /\t/;
var put_html = $("#put").html() + "<table>";
data = data.split(tab);
for (var i = 0; i < data.length; i++) {
put_html += "<tr>"+data[i]+"</tr>";
};
put_html += '</table>';
$("#put").html(put_html);
return;
};
However, I notice that you aren't using <td> elements. You might want to look into fixing that too.
Every time you are adding content into the html() property rather than building the entire content and adding it.
Since you are using jQuery you can bind the event using jQuery rather than adding that directly in the HTML
<textarea id="textBox"></textarea>
<button id="submitButton">submit</button>
<div id="put"></div>
$(function(){
$("#submitButton").click(function(){
parseData();
});
function parseData() {
var data = $("#textBox").val();
var tab = /\t/;
data = data.split(tab);
// Build your html
$("#put").html('htmlstructure');
return;
}
});
Also you can look for something similar like concatenating the string in an array so that you don't create string isntances each time when you append, since strings are immutable.
Good example
enter code hereI have an html UL control that gets dynamicaly populated with LI (list items).
I want a javascript function to process the items of the list and need a csv of all the list items.
I am trying this and getting errors:
javascript:
var ulTags = document.getElementById("basic_tag_handler");
var listItem = ulTags.getElementsByTagName("li");
var stringOfTags = '';
for (var i = 0; i < listItem.length-1; i++) {
stringOfTags += listItem[i].innerHTML & "," );
}
alert (stringOfTags);
html:
<ul id="basic_tag_handler" runat ="server" ></ul>
You've a syntax error when you have &, I suppose, you meant +. Also, you need to remove the trailing comma, but however better way would be to use Array.map and Array.join
var stringOfTags = [].map.call(listItem, function(elm){
return elm.innerHTML;
}).join(",");
I am going to have to repost my previous question because I need to reformulate what I need.
So, here it goes.
I have a webpage containing some list items,
HTML
<div class="container">
<p>Items are ordered Alphabetically and I want the text to be untouched</p>
</div>
All of these list items are contained in a folder on my computer. What I want to do is not have to manually input the ../Html/1.html , ../Html/2.html, ... instead, I was hoping to find a script to do the job for me.
All the items are numbered in numerical order, starting at 1 all the way to 100.
So I know iterating using i++ might come in handy in a loop. But I really dont know more than that!
Use this:
<div id="theContainer" class="container">
<p>Items are ordered Alphabetically and I want the text to be untouched</p>
</div>
<script>
window.addEventListener('DOMContentLoaded', function() {
var container = document.getElementById('theContainer'), i, p, s;
var numStart = 1, numEnd = 100;
var path = '../Html/*.html'; //use "*" to substitute the number
for (i = numStart; i <= numEnd; i++) {
p = path.replace(/\*/,i);
s += '<li>' + p + '</li>';
}
container.innerHTML = container.innerHTML + '<ol>' + s + '</ol>';
}, false);
</script>