So I'm working on my very first 'real' JavaScript project -> the famed Quiz app :)
I'm passing questions and answers via an array, and I want make sure to allow for a variable number of answer options. To do this, I'm using a For loop and the createElement method to add and populate the appropriate HTML for each answer in the array. To my eyes, what I've built actually works great. And after running the function I can see the resultant HTML elements in the right place and with all the appropriate tagging in my console. However, the inner DIV text won't render on screen! Very confused. What am I missing? Please help!
My JS code:
<body>
<form id="form1">
</form>
<script>
var answers = ["answer1", "answer2", "answer3", "answer4", "answer5"];
function createRadioButtonFromArray(array) {
var len = array.length;
var form = document.getElementById("form1");
for (var i = 0; i < len; i++){
var radio = document.createElement("input");
radio.type = "radio";
radio.name = "choices";
radio.class = "radioButtons";
radio.value = i;
radio.id = "choice" + i;
var radioText = document.createElement("div");
radioText.id = "c" + i;
radioText.class = "choiceText";
form.appendChild(radio);
radio.appendChild(radioText);
document.getElementById("c" + i).innerHTML=array[i];
}
}
</script>
</body>
And here's a screenshot of my console AFTER I run the function, for reference:
You're plan is nearly working but Input elements have no content! So the div's will not be rendered at all!
Create a div that contains your radio button and the input text on the same level:
var radio = document.createElement("input");
radio.type = "radio";
radio.name = "choices";
radio.class = "radioButtons";
radio.value = i;
radio.id = "choice" + i;
var radioText = document.createElement("div");
radioText.id = "c" + i;
radioText.class = "choiceText";
radioText.innerHTML = array[i];
radioText.appendChild(radio);
form.appendChild(radioText);
Add label after or before radio button. Label will let you check radio button by clicking on it's text
var radio = document.createElement("input");
radio.type = "radio";
radio.name = "choices";
radio.class = "radioButtons";
radio.value = i;
radio.id = "choice" + i;
var radioText = document.createElement("label");
radioText.id = "c" + i;
radioText.setAttribute("for", "choice" + i);
radioText.class = "choiceText";
form.appendChild(radio);
form.appendChild(radioText);
document.getElementById("c" + i).innerHTML=array[i];
<input> cannot contain any DOM elements or DOM nodes. But if you want to have checkboxes associated with some text, I suggest you to use <input> with <label for=""> where label.for is name of input element. For combining them you can put them into some container(i.e. <div>):
By default on label with set property for raises click event on element with the same name property value as for property value. This means that you do not need to add additional click event handlers for <label> elements.
var checkId = 1;
var container = document.createElement("div");
var radio = document.createElement("input");
radio.type = "radio";
radio.name = "choices"+checkId;
radio.class = "radioButtons";
radio.value = i;
radio.id = "choice" + i;
var label = document.createElement("label");
label.innerHTML = array[i];
// Set attribute for
label.setAttribute("for","choices"+checkId);
//Increase counter for check element name.
checkId++;
container.appendChild(radio);
container.appendChild(label);
form.appendChild(container);
Related
I'm a beginner in vanilla js and I create a few HTML elements using js. I use a function to create div elements with labels and input inside.
function createElements( passengers ){ //passengers is input number
var form = document.getElementById("c-form"); //gets an html form
for(let i=0;i<passengers;i++){
var passenger = document.createElement("div");
passenger.setAttribute("class" , "p-container");
var num = document.createElement("h3");
num.innerHTML = "Passenger : " + (i+1); //display passenger number
passenger.appendChild(num);
passenger.appendChild(document.createElement("br"));
var nameLabel = document.createElement("label"); //create a label
var nameSpan = document.createElement("span");
var t = document.createTextNode("Please enter name : ");
Namespan.appendChild(t); //append span to plain text
var NameInpt = document.createElement("input");
NameInpt.setAttribute("type" , "text"); //input for name
nameLabel.appendChild(nameSpan);
nameLabel.appendChild(NameInpt);
passenger.appendChild(nameLabel); //append label to div
form.appendChild(passenger); //append div element to html form
}
}
With the above code, I can create an element like below
I would like to do the same for a surname without creating more variables and doing the same thing. I am thinking if there is a way I can reassign different values to the variables I already have and I would appreciate your help. I cannot use jquery, this is a uni project
You could move the relevant part of your code (that deals with creating a particular label/input) in a for loop, and let that loop over some different label-strings you want to use:
function createElements( passengers ) {
var form = document.getElementById("c-form");
for(let i=0;i<passengers;i++){
var passenger = document.createElement("div");
passenger.setAttribute("class" , "p-container");
var num = document.createElement("h3");
num.innerHTML = "Passenger : " + (i+1);
passenger.appendChild(num);
for (let label of ["first name", "surname"]) {
passenger.appendChild(document.createElement("br"));
var nameLabel = document.createElement("label");
var nameSpan = document.createElement("span");
var t = document.createTextNode("Please enter " + label + " : ");
nameSpan.appendChild(t);
var NameInpt = document.createElement("input");
NameInpt.setAttribute("type" , "text");
nameLabel.appendChild(nameSpan);
nameLabel.appendChild(NameInpt);
passenger.appendChild(nameLabel);
}
form.appendChild(passenger);
}
}
I'm trying to add and remove text boxes dynamically using javascript and HTML.
I can get it to add and remove but sometimes the remove button doesn't work. when I inspect the element it says that there is no onclick value for the remove button. I don't understand why when I set the onclick in the add function.
Heres my code:
<div id="reqs">
<h3 align = "center"> Requirements </h3>
<script>
var reqs_id = 0;
function removeElement(elementId,elementId2) {
// Removes an element from the document
var element2 = document.getElementById(elementId2);
var element = document.getElementById(elementId);
element2.parentNode.removeChild(element2);
element.parentNode.removeChild(element);
}
function add() {
reqs_id++;// increment reqs_id to get a unique ID for the new element
//create textbox
var input = document.createElement('input');
input.type = "text";
input.setAttribute("class","w3-input w3-border");
input.setAttribute('id','reqs'+reqs_id);
var reqs = document.getElementById("reqs");
//create remove button
var remove = document.createElement('button');
remove.setAttribute('id','reqsr'+reqs_id);
remove.onclick = function() {removeElement('reqs'+reqs_id,'reqsr'+reqs_id);return false;};
remove.setAttribute("type","button");
remove.innerHTML = "Remove";
//append elements
reqs.appendChild(input);
reqs.appendChild(remove);
}
</script>
<button type="button" value="Add" onclick="javascript:add();"> Add</button>
This will work:
<div id="reqs">
<h3 align="center"> Requirements </h3>
</div>
<script>
var reqs_id = 0;
function removeElement(ev) {
var button = ev.target;
var field = button.previousSibling;
var div = button.parentElement;
div.removeChild(button);
div.removeChild(field);
}
function add() {
reqs_id++; // increment reqs_id to get a unique ID for the new element
//create textbox
var input = document.createElement('input');
input.type = "text";
input.setAttribute("class", "w3-input w3-border");
input.setAttribute('id', 'reqs' + reqs_id);
input.setAttribute('value', reqs_id);
var reqs = document.getElementById("reqs");
//create remove button
var remove = document.createElement('button');
remove.setAttribute('id', 'reqsr' + reqs_id);
remove.onclick = function(e) {
removeElement(e)
};
remove.setAttribute("type", "button");
remove.innerHTML = "Remove" + reqs_id;
//append elements
reqs.appendChild(input);
reqs.appendChild(remove);
}
</script>
<button type="button" value="Add" onclick="javascript:add();"> Add</button>
Fixed from my previous answer. Another option that may be necessary is to have each element know its exact place and be able to adjust itself based on what was added or removed. This enhancement will account for that by re-adjusting and ensuring your elements are always in order. (if desired)
See JSFiddle example.
Html
<div id="reqs">
<h3>Requirements</h3>
<button type="button" value="Add" onclick="javascript:add();">Add</button>
<br>
</div>
Javascript
function removeElement(e) {
let button = e.target;
let field = button.previousSibling;
let div = button.parentElement;
let br = button.nextSibling;
div.removeChild(button);
div.removeChild(field);
div.removeChild(br);
let allElements = document.getElementById("reqs");
let inputs = allElements.getElementsByTagName("input");
for(i=0;i<inputs.length;i++){
inputs[i].setAttribute('id', 'reqs' + (i+1));
inputs[i].setAttribute('value', (i+1));
inputs[i].nextSibling.setAttribute('id', 'reqsr' + (i+1));
}
}
function add() {
let allElements = document.getElementById("reqs");
let reqs_id = allElements.getElementsByTagName("input").length;
reqs_id++;
//create textbox
let input = document.createElement('input');
input.type = "text";
input.setAttribute("class", "w3-input w3-border");
input.setAttribute('id', 'reqs' + reqs_id);
input.setAttribute('value', reqs_id);
let reqs = document.getElementById("reqs");
//create remove button
let remove = document.createElement('button');
remove.setAttribute('id', 'reqsr' + reqs_id);
remove.onclick = function(e) {
removeElement(e);
};
remove.setAttribute("type", "button");
remove.innerHTML = "Remove";
//append elements
reqs.appendChild(input);
reqs.appendChild(remove);
let br = document.createElement("br");
reqs.appendChild(br);
}
Here's the code for the dynamically created checkboxes. How do I add line breaks to the code so that I have one checkbox per line? I tried to do document.createElement("br") and appending it after get.appendChild(label) but it didn't work.
function setCheckboxes(browser) {
var get = document.getElementById("get");
if (browser == "courses") {
for (var i = 1; i < coursesGetKeys.length; i++) {
var checkBox = document.createElement("input");
var label = document.createElement("label");
checkBox.type = "checkbox";
checkBox.value = coursesGetKeys[i];
checkBox.name = "r";
label.textContent = setOpt(coursesGetKeys[i], browser);
get.appendChild(checkBox);
get.appendChild(label);
//label.appendChild(document.createTextNode(setOpt(validCoursesKeys[i], dataset)));
}
}
if (browser == "rooms") {
for (var i = 1; i < validRoomsKeys.length; i++) {
var checkBox = document.createElement("input");
var label = document.createElement("label");
checkBox.type = "checkbox";
checkBox.value = validRoomsKeys[i];
checkBox.name = "r";
label.textContent = setOpt(validRoomsKeys[i], browser);
get.appendChild(checkBox);
get.appendChild(label);
//label.appendChild(document.createTextNode(setOpt(validCoursesKeys[i], dataset)));
}
}
};
You already know how to create an input:
var checkBox = document.createElement("input");
and how to append it:
get.appendChild(checkBox); // get is the parent element you selected at the top of your code
So your first hunch was correct, you can also do this:
var br = document.createElement("br");
get.appendChild(br);
which creates a br element, and then also appends it to the "get" parent.
function printPerson(nop) {
if (nop == null || nop == 0) {
document.getElementById("div1").innerHTML = "";
}
else {
for (var i = 0; i < nop; i++) {
var element = document.createElement("input");
var label = document.createElement("Label");
var button1 = document.createElement("input");
var button2 = document.createElement("input");
var br = document.createElement("br");
label.innerHTML = "User Name :";
// addition text box
element.setAttribute("type", "text");
element.setAttribute("name", "addition");
element.setAttribute("id", "cal");
// button 1
button1.setAttribute("type", "button");
button1.setAttribute("value", "+");
button1.setAttribute("onclick", "document.getElementById('cal').value += '+' ");
// button 2
button2.setAttribute("type", "button");
button2.setAttribute("value", "=");
button2.setAttribute("onclick", "document.getElementById('cal').value = eval(document.getElementById('cal').value)");
var para = document.getElementById("div1");
para.appendChild(label);
para.appendChild(element);
para.appendChild(br);
para.appendChild(button1);
para.appendChild(button2);
para.appendChild(br);
count++;
}
}
}
Here I am trying to create text boxes and buttons based on the user input but I was not able to give unique IDs for each and every dynamically generated fields so the actions are being performed only one first created text box
Try with -
element.setAttribute("id", "cal" + i);
The ids will be cal1, cal2 and so on.. And hope you will do the same for the name attribute.
I'm trying to create a tool where the user clicks on a button and it adds a label,input and remove button. I have it all working for the most part but there is only couple things missing. If the user had let's say adds "4" items and he/she deleted item "2"; I want the label value to subtract
"-1" of its value and the id of that item to subtract "-1" of its value. Any help would be appreciated!
I have created a jsFiddle below:
http://jsfiddle.net/ryanverdel/fUhL8/
HTML
<input type="input" value="0" id="theValue" />
<div id="myDiv">
</div>
Javascript
function addItem() {
if ($('#theValue').val() < 10){
var ni = document.getElementById('myDiv');
var numi = document.getElementById('theValue');
var num = (document.getElementById('theValue').value -1)+ 2;
numi.value = num;
var newdiv = document.createElement('form');
var newlabel = document.createElement('input');
var newinput = document.createElement('input');
var newbutton = document.createElement('input');
var divIdName = 'Address'+num;
newdiv.setAttribute('id',divIdName);
newbutton.setAttribute('type','button');
newbutton.setAttribute('onclick','onclick=confirmDelete("'+divIdName+'"); return false;');
newbutton.setAttribute('value','Delete');
//newlabel.innerHTML ='Address('+num+')';
newlabel.setAttribute('value','Address '+num+':')
newlabel.setAttribute('size','8');
newlabel.setAttribute('class','label');
newlabel.setAttribute('readonly','true');
newinput.setAttribute('type','text');
newinput.setAttribute('id',divIdName+'_input');
ni.appendChild(newdiv);
newdiv.appendChild(newlabel);
newdiv.appendChild(newinput);
newdiv.appendChild(newbutton);
}
else{
return false;
};
}
function confirmDelete(divNum){
if (confirm("Are you sure you want to delete " +divNum+"?"))
{
var d = document.getElementById('myDiv');
var olddiv = document.getElementById(divNum);
var getLabel = olddiv.getElementsByClassName("label");
var counter= $('#theValue').val();
$('#theValue').val( (counter-1<0)?counter:--counter );
//$(getLabel).nextAll().css( "color", "red" );
$(olddiv).nextAll().css('background-color', 'red').css('color','red');
d.removeChild(olddiv);
}
else{};
}