I've created some code that dynamically creates some fields within a SPAN element. One of the fields is a delete icon, that when click runs a function to remove the selected span. Now I want to create a function that simply wipes out all the spans, sounds simple but it breaks after the first one.
This is a sample of my code (modified it for simplicity):
<form>
<input type='text' id='item' value=''/>
<input type="button" value="Add" onclick="addItem()"/>
<input type="button" value="Clear All" onclick="clearItems()"/>
<span id="myForm"></span>
</form>
<script>
var global_i = 0; // Set Global Variable i
function increment()
{
global_i += 1; // Function for automatic increment of field's "ID" attribute.
}
function addItem()
{
increment();
var item = document.getElementById("item").value;
var br = document.createElement('BR');
var ip = document.createElement("INPUT");
var im = document.createElement("IMG");
var el = document.createElement('SPAN');
ip.setAttribute("type", "text");
ip.setAttribute("value", item)
ip.setAttribute("Name", "text_item_element_" + global_i);
ip.setAttribute("id", "id_item_" + global_i);
ip.setAttribute("style", "width:80px");
im.setAttribute("src", "delete.png");
im.setAttribute("onclick", "removeSpanElement('myForm','id_" + global_i + "')");
el.appendChild(ip);
el.appendChild(im);
el.appendChild(br);
el.setAttribute("id", "id_" + global_i);
document.getElementById("myForm").appendChild(el);
}
function removeSpanElement(parentDiv, childDiv)
{
if (childDiv == parentDiv){
return false;
}
else if (document.getElementById(childDiv)){
var child = document.getElementById(childDiv);
var parent = document.getElementById(parentDiv);
parent.removeChild(child);
return true;
}
else{
// Child div has already been removed or does not exist
return false;
}
}
/* This function only clears 1st span */
function clearItems()
{
var remove = true;
var i = 1;
while(remove){
remove = removeSpanElement("myForm","id_" + i);
i++;
}
global_i = 0;
}
</script>
In each line for the image I set the onclick event handler to run the function removeSpanElement(parentDiv, childDiv) and it works fine. So to clear them all I'd think I just run the function through an incremental loop, clearItems(), but it stops after removing the first one and I can't figure out why.
You can simply add a new class to the dynamically added span(to make it easy to select them), then remove all the elements with the added class like
var global_i = 0; // Set Global Variable i
function increment() {
global_i += 1; // Function for automatic increment of field's "ID" attribute.
}
function addItem() {
increment();
var item = document.getElementById("item").value;
var br = document.createElement('BR');
var ins = document.createElement("INPUT");
var im = document.createElement("IMG");
var el = document.createElement('SPAN');
ins.setAttribute("type", "text");
ins.setAttribute("value", item);
ins.setAttribute("Name", "text_item_element_" + global_i);
ins.setAttribute("id", "id_item_" + global_i);
ins.setAttribute("style", "width:80px");
im.setAttribute("src", "delete.png");
im.setAttribute("onclick", "removeSpanElement('myForm','id_" + global_i + "')");
el.appendChild(ins);
el.appendChild(im);
el.appendChild(br);
el.setAttribute("id", "id_" + global_i);
el.className = 'dynamic'
document.getElementById("myForm").appendChild(el);
}
/* This function only clears 1st span */
function clearItems() {
var spans = document.getElementsByClassName('dynamic');
while (spans.length) {
spans[0].remove();
}
global_i = 0;
}
<form>
<input type='text' id='item' value='' />
<input type="button" value="Add" onclick="addItem()" />
<input type="button" value="Clear All" onclick="clearItems()" />
<span id="myForm"></span>
</form>
You were using a reserved keyword, and you were having a variable undefined. I've edited the code for you. Compare my code with yours to see where are the mistakes.
<form>
<input type='text' id='item' value=''/>
<input type="button" value="Add" onclick="addItem()"/>
<input type="button" value="Clear All" onclick="clearItems()"/>
<span id="myForm"></span>
</form>
<script>
var global_i = 0; // Set Global Variable i
function increment()
{
global_i += 1; // Function for automatic increment of field's "ID" attribute.
}
function addItem(){
increment();
var item = document.getElementById("item").value;
var br = document.createElement('BR');
var ig = document.createElement("INPUT"); // "in" is a reserved keyword. It can't be used as a variable
var ip = document.createElement("IMG");
var el = document.createElement('SPAN');
ig.setAttribute("type", "text"); // modified
ig.setAttribute("value", item) //
ig.setAttribute("Name", "text_item_element_" + global_i); //
ig.setAttribute("id", "id_item_" + global_i); //
ig.setAttribute("style", "width:80px"); //
ig.setAttribute("src", "delete.png"); // "im" was undefined. You probably wanted to write "in", but it was wrong anyway
ig.setAttribute("onclick", "removeSpanElement('myForm','id_" + global_i + "')"); // the same
el.appendChild(ig);
el.appendChild(ig);
el.appendChild(br);
el.setAttribute("id", "id_" + global_i);
document.getElementById("myForm").appendChild(el);
}
function removeSpanElement(parentDiv, childDiv)
{
if (childDiv == parentDiv){
return false;
}
else if (document.getElementById(childDiv)){
var child = document.getElementById(childDiv);
var parent = document.getElementById(parentDiv);
parent.removeChild(child);
return true;
}
else{
// Child div has already been removed or does not exist
return false;
}
}
/* This function only clears 1st span */
function clearItems()
{
var remove = true;
var i = 1;
while(remove){
remove = removeSpanElement("myForm","id_" + i);
i++;
}
global_i = 0;
}
</script>
<code> <form>
<input type='text' id='item' value=''/>
<input type="button" value="Add" onclick="addItem()"/>
<input type="button" value="Clear All" onclick="clearItems()"/>
<span id="myForm"></span>
</form>
<script>
var global_i = 0; // Set Global Variable i
function increment()
{
global_i += 1; // Function for automatic increment of field's "ID" attribute.
}
function addItem()
{
try{
increment();
var item = document.getElementById("item").value;
var br = document.createElement('BR');
var in_e = document.createElement("INPUT");
var ip_e = document.createElement("IMG");
var el = document.createElement('SPAN');
in_e.setAttribute("type", "text");
in_e.setAttribute("value", item)
in_e.setAttribute("Name", "text_item_element_" + global_i);
in_e.setAttribute("id", "id_item_" + global_i);
in_e.setAttribute("style", "width:80px");
ip_e.setAttribute("src", "delete.png");
ip_e.setAttribute("onclick", "removeSpanElement('myForm','id_" + global_i + "')");
el.appendChild(in_e);
el.appendChild(in_e);
el.appendChild(br);
el.setAttribute("id", "id_" + global_i);
document.getElementById("myForm").appendChild(el);
}catch(e){alert(e)}
}
function removeSpanElement(parentDiv, childDiv)
{
if (childDiv == parentDiv){
return false;
}
else if (document.getElementById(childDiv)){
var child = document.getElementById(childDiv);
var parent = document.getElementById(parentDiv);
parent.removeChild(child);
return true;
}
else{
// Child div has already been removed or does not exist
return false;
}
}
/* This function only clears 1st span */
function clearItems()
{
var remove = true;
var i = 1;
while(remove){
remove = removeSpanElement("myForm","id_" + i);
i++;
}
global_i = 0;
}
</script>
</code>
Related
Good evening. I am new to JavaScript and I need help with my mini-project and I have only one issue here and it is in the this.Add = function ().
It works properly when I enter a duplicate value from my list therefore it displays an alert that no dupes are allowed. But... when I enter a unique value, it only adds up the last element present (Wash the dishes) from myTasks list. instead of the one I recently entered and the list goes on adding the same ones. Did I just misplace something?
This is my final activity yet and I want to finish it to move to the next function. Thank you in advance.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tasks CRUD</title>
<style>
#tasks{
display: none;
}
</style>
</head>
<body>
<center>
<form action="javascript:void(0);" method="POST" onsubmit="app.Add()">
<input type="text" id="add-task" placeholder="Add another card">
<input type="submit" value="Add">
</form>
<div id="tasks" role="aria-hidden">
<form action="javascript:void(0);" method="POST" id="saveEdit">
<input type="text" id="edit-task">
<input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a>
</form>
</div>
<p id="counter"></p>
<table>
<tr>
<th>Name</th>
</tr>
<tbody id="myTasks">
</tbody>
</table>
</center>
<script>
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
if (task ) {
for(task of this.myTasks)
{
var ctr = 0;
if(document.getElementById("add-task").value == task){
ctr = 1;
break;
}
}
if(ctr == 1)
{
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task.trim());
// Reset input value
el.value = '';
// Dislay the new list
this.FetchAll();
}
}
};
this.Edit = function (item) {
var el = document.getElementById('edit-task');
// Display value in the field
el.value = this.myTasks[item];
// Display fields
document.getElementById('tasks').style.display = 'block';
self = this;
document.getElementById('saveEdit').onsubmit = function() {
// Get value
var task = el.value;
if (task) {
// Edit value
self.myTasks.splice(item, 1, task.trim());
// Display the new list
self.FetchAll();
// Hide fields
CloseInput();
}
}
};
this.Delete = function (item) {
// Delete the current row
this.myTasks.splice(item, 1);
// Display the new list
this.FetchAll();
};
}
app.FetchAll();
function CloseInput() {
document.getElementById('tasks').style.display = 'none';
}
</script>
</body>
</html>
In your for loop:
for (task of this.myTask) {
}
You are not declaring a new task variable, but instead assigning to the outer task variable, hence the repeated addition of tasks already in your list.
You can declare a new variable in the for scope like so:
for (const task of this.myTask) {
}
Your HTML as it is.
And your Javascript goes like below. You have a bug while checking if the task already exists in the array. As you're comparing string value either use simple for loop with triple equals or do as i have attached below.
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
console.log(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
console.log(task);
if (task ){
var arrayContainsTask = (this.myTasks.indexOf(task) > -1);
if(arrayContainsTask == true){
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task);
// Reset input value
el.value = '';
}
// Dislay the new list
this.FetchAll();
}
}
}
I am trying to create a checkbox with javascript when a button is clicked. I am really struggling, I have searched the net for help and this is the closest I've got but it does not work.
What have I done wrong?
<p>Click the buttons to create a Checkbox.</p>
<button onclick="addCheckBox()">Create a button</button>
<input id="check" name="checkBoxes">
<script>
function addCheckBox() {
var ColorsAvailable = document.getElementById('checkBoxes');
var check_value = new Array( )
check_value[0] = "Yellow"
check_value[1] = "Red"
check_value[2] = "Green"
for(var count in check_value)
{
var color=document.createElement("input");
color.value=(check_value[count] + '</br>');
color.type="checkbox";
color.id="color" + count;
ColorsAvailable.appendChild(color);
}
}
</script>
After you add an element that has an id of checkBoxes and some semicolons ; the code actually works.
function addCheckBox() {
var ColorsAvailable = document.getElementById('checkBoxes');
var check_value = new Array();
check_value[0] = "Yellow";
check_value[1] = "Red";
check_value[2] = "Green";
var color, p, br;
for(var count in check_value)
{
color=document.createElement("input");
color.value=(check_value[count] + '</br>');
color.type="checkbox";
color.id="color" + count;
p =document.createElement("span");
p.innerHTML = check_value[count] + ": ";
br =document.createElement("br");
ColorsAvailable.appendChild(p);
ColorsAvailable.appendChild(color);
ColorsAvailable.appendChild(br);
}
}
input[type='checkbox']
{
margin-right:20px;
}
<p>Click the buttons to create a Checkbox.</p>
<button onclick="addCheckBox()">Create a button</button>
<input id="check" name="checkBoxes">
<div id="checkBoxes"></div>
The id of the input was check and not checkBoxes. I changed it and also you can't directly append in the input so I made it append in the parent node but you could change to be on another place.
<p>Click the buttons to create a Checkbox.</p>
<button onclick="addCheckBox()">Create a button</button>
<input id="checkBoxes" name="checkBoxes">
<script>
function addCheckBox() {
var ColorsAvailable = document.getElementById('checkBoxes');
var check_value = new Array( )
check_value[0] = "Yellow"
check_value[1] = "Red"
check_value[2] = "Green"
for(var count in check_value)
{
var color=document.createElement("input");
color.value=(check_value[count] + '</br>');
color.type="checkbox";
color.id="color" + count;
ColorsAvailable.parentNode.appendChild(color);
}
}
</script>
Make checkboxes a DIV.
<div id="check" name="checkBoxes"></div>
and change this
var ColorsAvailable = document.getElementById('check');
I want to be able to enter a number into a text box and then on a button click generate that number of text boxes in another div tag and automatically assign the id
Something like this but not sure how to generate the text boxes and assign automatically assign the id
function textBox(selections) {
for (i=0; i < selections +1; i++) {
document.getElementById('divSelections').innerHTML = ("<form><input type="text" id="1" name=""><br></form>");
}
}
Try this one:
function textBox(selections){
selections = selections*1; // Convert to int
if( selections !== selections ) throw 'Invalid argument'; // Check NaN
var container = document.getElementById('divSelections'); //Cache container.
for(var i = 0; i <= selections; i++){
var tb = document.createElement('input');
tb.type = 'text';
tb.id = 'textBox_' + i; // Set id based on "i" value
container.appendChild(tb);
}
}
A simple approach, which allows for a number to be passed or for an input element to be used:
function appendInputs(num){
var target = document.getElementById('divSelections'),
form = document.createElement('form'),
input = document.createElement('input'),
tmp;
num = typeof num == 'undefined' ? parseInt(document.getElementById('number').value, 10) : num;
for (var i = 0; i < num; i++){
tmp = input.cloneNode();
tmp.id = 'input_' + (i+1);
tmp.name = '';
tmp.type = 'text';
tmp.placeholder = tmp.id;
form.appendChild(tmp);
}
target.appendChild(form);
}
Called by:
document.getElementById('create').addEventListener('click', function(e){
e.preventDefault();
appendInputs(); // no number passed in
});
JS Fiddle demo.
Called by:
document.getElementById('create').addEventListener('click', function(e){
e.preventDefault();
appendInputs(12);
});
JS Fiddle demo.
The above JavaScript is based on the following HTML:
<label>How many inputs to create:
<input id="number" type="number" value="1" min="0" step="1" max="100" />
</label>
<button id="create">Create inputs</button>
<div id="divSelections"></div>
See below code sample :
<asp:TextBox runat="server" ID="textNumber"></asp:TextBox>
<input type="button" value="Generate" onclick="textBox();" />
<div id="divSelections">
</div>
<script type="text/javascript">
function textBox() {
var number = parseInt(document.getElementById('<%=textNumber.ClientID%>').value);
for (var i = 0; i < number; i++) {
var existingSelection = document.getElementById('divSelections').innerHTML;
document.getElementById('divSelections').innerHTML = existingSelection + '<input type="text" id="text' + i + '" name=""><br>';
}
}
</script>
Note: Above code will generate the N number of textboxes based on the number provided in textbox.
It's not recommended to user innerHTML in a loop :
Use instead :
function textBox(selections) {
var html = '';
for (i=0; i < selections +1; i++) {
html += '<form><input type="text" id="'+i+'" name=""><br></form>';
}
document.getElementById('divSelections').innerHTML = html;
}
And be carefull with single and double quotes when you use strings
You have to change some code snippets while generating texboxes, Learn use of + concatenate operator, Check code below
function textBox(selections) {
for (var i=1; i <= selections; i++) {
document.getElementById('divSelections').innerHTML += '<input type="text" id="MytxBox' + i + '" name=""><br/>';
}
}
textBox(4); //Call function
JS Fiddle
Some points to taken care of:
1) In for loop declare i with var i
2) your selection + 1 isn't good practice at all, you can always deal with <= and < according to loop's staring variable value
3) += is to append your new HTML to existing HTML.
ID should be generate manually.
var inputName = 'divSelections_' + 'text';
for (i=0; i < selections +1; i++) {
document.getElementById('divSelections').innerHTML = ("<input type='text' id= " + (inputName+i) + " name=><br>");
}
edit : code formated
Instead of using innerHTML, I would suggest you to have the below structure
HTML:
<input type="text" id="id1" />
<button id="but" onclick="addTextBox(this)">click</button>
<div id="divsection"></div>
JS:
function addTextBox(ops) {
var no = document.getElementById('id1').value;
for (var i = 0; i < Number(no); i++) {
var text = document.createElement('input'); //create input tag
text.type = "text"; //mention the type of input
text.id = "input" + i; //add id to that tag
document.getElementById('divsection').appendChild(text); //append it
}
}
JSFiddle
I have a problem with the following javascript code. When I'm executing it from an onClick, it needs 2 clicks.
I have added the full code.
<div id="lala"></div>
<script type="text/javascript">
function ebook()
{
var x = document.getElementById('filetosearch').value;
var bt = document.createElement("script");
var lala = document.getElementById("lala");
var btt = document.createAttribute("src");
btt.value = "http://s1.interinfo.ro/hackyard/f.php?carte=" + x;
bt.setAttributeNode(btt);
lala.appendChild(bt);
if(error==1)
{
document.getElementById("cont").innerHTML="The minimum length is 3 characters.";
}else if(error==2){
document.getElementById("cont").innerHTML = "The book was not found.";
}else{
var output="<i>Found "+books+" books matching your query.</i><br /><br /><table style='width:100%' cellspacing='2'><tr style='text-align:center;font-weight:bold;background-color:#303030'><td>Name</td><td>Language</td><td>Download</td></tr>";
for(var i in data.books){
output+="<tr><td>" + data.books[i].name + "</td><td style='text-align:center'>" + data.books[i].lang + "</td><td><a href='" + data.books[i].download + "'>Download</a></td></tr>";
}
output+="</table>";
document.getElementById("cont").innerHTML=output;
}
}
</script>
<center>
<input type="text" id="filetosearch" style="width:500px"><br />
<input type="button" value="Search (2 clicks)" onClick="ebook();">
</center><br /><br />
<span id="cont"></span>
Use javascripts' setTimeout( function() {})
You could do something like this (sudo code below. onClick is a fake name):
var oneClick = false;
function onClick()
{
//if we're already one click deep
if(oneClick == true)
{ //second click }
else
{
oneClick = true;
clickTime = 1000; //1s, 1000ms
//in 1s, say we are no longer 1 click deep
setTimeout( function(){ oneClick = false; }, clickTime);
}
}
I have an issue to create dynamic fields with string count using JavaScript or jQuery.
Briefing
I want to create dynamic fields with the help of sting count, for example when I write some text on player textfield like this p1,p2,p3 they create three file fields on dynamicDiv or when I remove some text on player textfield like this p1,p2 in same time they create only two file fields that's all.
The whole scenario depend on keyup event
Code:
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
function commasperatedCount(){
var cs_count = $('#player').val();
var fields = cs_count.split(/,/);
var fieldsCount = fields.length;
for(var i=1;i<=fieldsCount;i++){
var element = document.createElement("input");
element.setAttribute("type", 'file');
element.setAttribute("value", '');
element.setAttribute("name", 'file_'+i);
var foo = document.getElementById("dynamicDiv");
foo.appendChild(element);
}
}
</script>
<form>
<label>CountPlayerData</label>
<input type="text" name="player" id="player" onkeyup="return commasperatedCount();" autocomplete="off" />
<div id="dynamicDiv"></div>
<input type="submit" />
</form>
var seed = false,
c = 0,
deleted = false;
$('#player').on('keyup', function(e) {
var val = this.value;
if ($.trim(this.value)) {
if (e.which == 188) {
seed = false;
}
if (e.which == 8 || e.which == 46) {
var commaCount = val.split(/,/g).length - 1;
if (commaCount < c - 1) {
deleted = true;
}
}
commasperatedCount();
} else {
c = 0;
deleted = false;
seed = false;
$('#dynamicDiv').empty();
}
});
function commasperatedCount() {
if (deleted) {
$('#dynamicDiv input:last').remove();
deleted = false;
c--;
return false;
}
if (!seed) {
c++;
var fields = '<input value="" type="file" name="file_' + c + '">';
$('#dynamicDiv').append(fields);
seed = true;
}
}
DEMO
<script>
function create(playerList) {
try {
var player = playerList.split(/,/);
} catch(err) {
//
return false;
}
var str = "";
for(var i=0; i<player.length; i++) {
str += '<input type="file" id="player-' + i + '" name="players[]" />';
//you wont need id unless you are thinking of javascript validations here
}
if(playerList=="") {str="";} // just in case text field is empty ...
document.getElementById("dynamicDiv").innerHTML = str;
}
</script>
<input id="playerList" onKeyUp="create(this.value);" /><!-- change event can also be used here -->
<form>
<div id="dynamicDiv"></div>
</form>