So what i am trying to do is to have
1.add function to add an input box
2.remove function to remove the last input box in the list
3.sort function to sort the list of input texts by alphabetic order
I think my add function is working, but i am running into problem when i am trying to remove the last input box or trying to sort it.
Any idea or suggestion would be very much appreciated. thanks
<form id="mainform" >
<button onclick="add()">add</button>
<button onclick="remove()">remove</button>
<button onclick="sort()">sort</button>
</form>
<script>
var i = 0;
var count =0;
function add() {
var x= document.createElement("INPUT");
x.setAttribute("type", "text");
x.setAttribute("placeholder", "Name");
i += 1;
count=count+1;
document.body.appendChild(x);
}
function remove(){
i -= 1;
count=count-1;
}
function sort(){
var x;
x=count;
var strings=[]
var t;
var i=0;
t=x;
while(t!=0){
strings.push(document.forms["mainform"].elements[i].value);
t=t-1;
i=i+1}
strings=strings.sort()
var j=0;
var msg='';
while(x!=0){
var msg=msg+strings[j]+'\n';
document.forms["mainform"].elements[j].value=strings[j];
j=j+1;
x=x-1;}
}
</script>
Looks like your add function adds the inputs directly to the body, while your sort function is looking for elements in the form['mainform'] element.
Your remove function is just decrementing your iterator without actually affecting the form at all.
That would do the job:
<form id="mainform" >
<input type="button" value="add" onclick="add()"></input>
<input type="button" value="remove" onclick="remove()"></input>
<input type="button" value="sort" onclick="sort()"></input>
</form>
<script>
function add() {
var x= document.createElement("INPUT");
x.setAttribute("type", "text");
x.setAttribute("placeholder", "Name");
x.setAttribute("class", "someInput");
document.body.appendChild(x);
}
function remove() {
var childs = document.body.getElementsByClassName("someInput");
if(childs.length > 0) {
document.body.removeChild(childs[childs.length - 1]);
}
}
function sort(){
var hash = {};
var childs = document.body.getElementsByClassName("someInput");
// Map each element to its value
for(var i = 0; i < childs.length; i++) {
var currentElement = childs[i];
hash[currentElement.value] = currentElement;
}
// Remove all added elements
for(var i = 0; i < childs.length; i++) {
var currentElement = childs[i];
document.body.removeChild(currentElement);
}
// Sort by map keys, and add all elements back sorted
Object.keys(hash).sort().forEach(function(v, i) {
document.body.appendChild(hash[v]);
});
}
</script>
Please note that I replaced the button elements with input elements in order to prevent the form from being submitted.
Also pay attention that I marked each inserted textbox with class named "someInput". That will make our life easier when we want to query and get all the inserted textboxes.
Related
I am trying to understand the insertion sort algorithm. I want to use an input button and diagram. When the user writes a number then click the button, my page will create random values. I found some snippets on the internet but they use i = 0. I want to use my input value instead of i = 0. How can I do it?
A part of my index.html:
<div id="buttons">
<a class="button" id="butonInsert" href="javascript://">insertion sort</a>
<a class="button" id="butonReset" href="javascript://">Reset</a>
<input type="number" id="myNumber" value="blabla">
<button onclick="reset()"></button>
A part of my script.js:
function reset() {
for (i=0; i<50; ++i) {
data[i] = ~~(i*160/50);
}
for (i=data.length-1; i>=0; --i) {
var ridx = ~~( Math.random() * ( data.length ) );
data.swap(i, ridx);
}
var tb = $("#sortPanel");
tb.empty();
var tr = $("<tr></tr>");
for (i=0; i<data.length; ++i) {
tr.append("<td id='b"+i+"'>" +
"<div class='cc' style='height: "+data[i]+"px;'>" +
"</div></td>");
}
tb.append(tr);
resetted = true;
}
I didn't quite understand what you are trying to do but if you just want to use an input's value you can easily get it with javascript and use it instead of i=0.
var inputValue = document.getElementById("myNumber").value ;
Then in your for statements :
for (var i = inputValue ; i < data.length; ++i) {
// code
}
Use document.getElementbyId('myNumber').value. This might work.
I don't understand why this code is not working, could you help me please ?
I want that when you click on the button, the "theloop" div get filled with yo 0 , yo 1 etc... till the number you inputed
<p>
enter how many time you want the loop to repeat
<input id="nloop">
</p>
</br>
<button onclick="displayLoop()">
Try it
</button>
<p id="theloop"></p>
<script>
var nloop = document.getElementById("nloop").value;
var theloop = document.getElementById("theloop")
function displayLoop () {
for (var i=0; i<nloop; i++) {
theloop.innerHTML = "yo" + i;
}
}
</script>
You have many Syntax error + code error
<p>enter how many time you want the loop to repeat <input id="nloop"></p> </br>
<button onclick="displayLoop()">Try it</button>
<p id="theloop"></p>
<script>
var theloop = document.getElementById("theloop")
function displayLoop(){
var nloop = document.getElementById("nloop").value;
theloop.innerHTML = '';
for (var i=0; i<nloop; i++){
theloop.innerHTML = theloop.innerHTML + "yo" + i+ "<br/>";
}
}
</script>
You need to get the value of nloop when you call the function or the value will be the value when the script is loading, so an empty value.
If you affect something to innerHtml it will erase the content of the innerHtml.
I added BR only for the style you can ignore that.
You missed few syntax checks that I have corrected:
<p>enter how many time you want the loop to repeat <input id="nloop" /></p>
</br>
<button onclick="displayLoop();">Try it</button>
<p id="theloop"></p>
<script>
var theloop = document.getElementById("theloop");
function displayLoop () {
var nloop = document.getElementById("nloop").value;
for (var i=0; i<nloop; i++)
{
theloop.innerHTML = "yo" + i;
}
}
</script>
<script>
function displayLoop()
{
var nloop = document.getElementById("nloop").value;
for (var i=0; i<nloop; i++)
{
document.getElementById("theloop").innerHTML += "yo" + i;
}
}
</script>
This is working fine now :)
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.
so I have this HTML code:
<form method="get" action="#" id="startForm">
<input type="text" name="period" id="period" placeholder="The number of days"/>
<input type="submit" name="submit" value="submit" id="startSubmit"/>
</form>
and this is the JavaScript code:
var btnSubmit = document.getElementById('startSubmit');
btnSubmit.addEventListener('click', function (e) {
e.preventDefault();
var myForm = document.createElement('form');
var period = document.getElementById('period').value;
for(var i = 0; i < period ; i++){
var input0 = document.createElement('input');
input0.setAttribute('type', 'text');
input0.setAttribute('placeholder', 'The count of tasks');
input0.setAttribute('style', 'margin: 10px');
input0.setAttribute('id', 'taskDone'+i);
input0.setAttribute('onchange', 'myFunction()');
document.body.appendChild(input0);
myForm.appendChild(input0);
document.body.appendChild(myForm);
function myFunction(){
var taskDone = document.getElementById('taskDone').value;
var newForm = document.createElement('form');
for(var j = 0; j < taskDone ; j++){
var input1 = document.createElement('input');
input1.setAttribute('type', 'text');
input1.setAttribute('id', 'time'+i);
document.body.appendChild(input1);
newForm.appendChild(input1);
document.body.appendChild(newForm);
};
};
};
console.log(myForm);
});
so my problem is that in the function when I try to take the value from the generated DOM element it will reset the page what I want to do is to take the number that is going to be placed into the input and make as many new inputs textboxes as it's the number is typed (it takes the number from the generated dom element and creates new dom element)
You are just doing the wastage of memory you must not place the definition of function inside a loop. You must place it outside the block or a separate definition. You should only call the function inside loop. However, inside your
myFunction()
you are trying to get the id of an element that doesn't exist as you have created the element with id = 'taskdone'+i. So you must also append 'i' inside the myFunction() to get element ids.
But I will suggest you there is a clean way to this task is just pass the element inside myFunction on changing the element value.
Use something like that :
`input0.setAttribute('onchange', 'myFunction(this)');`
Then you would no longer require the element id to get its value.
And create your myFunction like this:
function myFunction(element) {
var id = element.id;
var taskDone = element.value;
var i = id.split('taskDone')[1];
var newForm = document.createElement('form');
for (var j = 0; j < taskDone; j++) {
var input1 = document.createElement('input');
input1.setAttribute('type', 'text');
input1.setAttribute('id', 'time' + i);
document.body.appendChild(input1);
newForm.appendChild(input1);
document.body.appendChild(newForm);
};
};
See the snippet for more details and help:
var btnSubmit = document.getElementById('startSubmit');
console.log(btnSubmit);
btnSubmit.addEventListener('click', function (e) {
e.preventDefault();
var myForm = document.createElement('form');
var period = document.getElementById('period').value;
for(var i = 0; i < period ; i++){
var input0 = document.createElement('input');
input0.setAttribute('type', 'text');
input0.setAttribute('placeholder', 'The count of tasks');
input0.setAttribute('style', 'margin: 10px');
input0.setAttribute('id', 'taskDone'+i);
input0.setAttribute('onchange', 'myFunction(this)');
document.body.appendChild(input0);
myForm.appendChild(input0);
document.body.appendChild(myForm);
};
console.log(myForm);
});
function myFunction(element){
var id = element.id;
var taskDone = element.value;
var i = id.split('taskDone')[1];
var newForm = document.createElement('form');
for(var j = 0; j < taskDone ; j++){
var input1 = document.createElement('input');
input1.setAttribute('type', 'text');
input1.setAttribute('id', 'time'+i);
document.body.appendChild(input1);
newForm.appendChild(input1);
document.body.appendChild(newForm);
};
};
<form method="get" action="#" id="startForm">
<input type="text" name="period" id="period" placeholder="The number of days"/>
<input type="submit" name="submit" value="submit" id="startSubmit"/>
</form>
You need to define the function myFunction() as myFunction = function(){..}
Secondly the id attribute needs to be unique. Hence use
input0.setAttribute('id', 'taskDone'+i); to set the id and
input0.setAttribute('onchange', 'myFunction("'+i+'")');
to call the function.
Similarly access the id as
var taskDone = document.getElementById('taskDone'+i).value;
Try the fiddle - https://jsfiddle.net/djbb79d8/
I am trying to write a web app that takes user input as numbers in 15 text or number inputs on a html form, it should then add these values together and display the total in a label elsewhere on the page.
I have 15 inputs with the class name "takings" and a label with the ID "TotalLabel" on the page.
function getsum () {
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i = 0; i < rows.length; i++) {
var val = parseFloat(rows[i].value);
total += val;
}
var label = document.getElementById("TotalLabel");
label.value = total;
alert(parseFloat(total));
}
window.onload = getsum;
The alert is only in place for debugging purposes and it appears that the variable total is still set to zero at the end of the script. I also need to make the getsum() function fire every time a user enters data in any of the fields with class "takings".
Can anyone help?
So you need to add change events to all of the elements and call getsum
function getsum () {
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i = 0; i < rows.length; i++) {
var val = parseFloat(rows[i].value);
total += val;
}
var label = document.getElementById("TotalLabel");
label.value = total;
}
window.onload = getsum;
//Example showing how to add one event listener to the page and listen for change events
//The following works in modern browsers, not all browsers support addEventListener, target, and classList.
document.body.addEventListener("change", function(evt) {
var targ = evt.target;
if(targ.classList.contains("takings")) {
getsum();
}
});
label { display: block; }
<label>1</label><input type="text" class="takings" value="0"/>
<label>2</label><input type="text" class="takings" value="0"/>
<label>3</label><input type="text" class="takings" value="0"/>
<label>4</label><input type="text" class="takings" value="0"/>
<label>5</label><input type="text" class="takings" value="0"/>
<label>Total:</label><input type="text" id="TotalLabel" value="0" readonly/>
To have your getSum() function fire for all of those elements, you can use Javascript to add an onchange event to all elements with the required class name
var input = document.getElementsByClassName("takings");
for (var i = 0; i < cells.length; i++) {
input[i].onchange = getSum;
}
Other than that, I don't see any visible errors in your getSum() function.
You need to add an EventListener to your input fields and call getsum, for example
var a = document.getElementsByClassName("takings");
for (var i = 0;i<a.length;i++){
addEventListener('keyup',getsum);
}
Please note that a label has innerHTML, not a value:
label.innerHTML = total;
With your actual function, you will get NaN as a result as long as not all the inputs have a value, so you will need to add
if (val) {
total += val;
}
to your for loop.
Full working code:
function getsum(){
var rows = document.getElementsByClassName("takings");
var total = 0;
for (var i =0; i < rows.length; i++){
var val = parseFloat(rows[i].value);
if (val) {
console.log(val);
total += val;
}}
var label = document.getElementById("TotalLabel");
label.innerHTML = total;
}
var a = document.getElementsByClassName("takings");
for (var i = 0;i<a.length;i++){
this.addEventListener('keyup',getsum);
}
DEMO