How to dynamically create a form element - javascript

I have the following code
I am trying to dynamically create radio button with and without labels in them. I am unable to put the text in radio button when I create radio button, here is the code without labels
This is what expect
<input type="radio" name="Alex" value="Alex"/>Alex
$('<input>').attr({
type:'radio',
name:'name',
value: "Alex",
text:"Alex"
}).insertAfter("#divid"));
Now for having labels,
<label><input type="radio" name="Alex" value="Alex"/>Alex<label>
//create a label tag
var label = $('<label>', { text:"Alex"});
//append input tag to label
$(label).append($('<input>').attr({
type:'radio',
name:"Alex",
value:"Alex"
}).insertAfter("#divid"));
Both of the above does not produce any error on console but it does not produce the right HTML tag I am interested in. Also is there a way to directly add label to radio as I create them dynamically. I mean I dont want to create a label tag separetely and append to it the radio button. Many Thanks for your help

Dynamically create label and radio
jsBin example
var $input = $('<input />', {
type : "radio",
name : "name",
value : "alex"
});
$("<label />", {
insertAfter: "#somediv", // (or use appendTo: to insert into it)
append: [$input, "Alex"] // include our $input and also some text description
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="somediv">DIV</div>

You should replace var label = $('<label>').attr({ text:"Alex"}); with var label = $('<label>').text("Alex");
Also - you have few syntax errors in your code, I don't see what's so hard to copy+paste properly.

I like Roko's answer, except that it's vulnerable to HTML injection if you're building the radio button labels from user content.
Here, I use the .text() method to make sure that the text is properly escaped.
var $target = $('#target'),
records = [{ id: 1, name: "Alex" },
{ id: 2, name: "Test that HTML <em>is not</em> injected" }];
$target.append('<h3>With Labels</h3>');
for (var i=0; i < records.length; i++) {
$target.append($('<label>').text(records[i].name)
.prepend($('<input type="radio" name="mychoice">',
{ value: records[i].id })));
}
$target.append('<h3>Without Labels</h3>');
for (var i=0; i < records.length; i++) {
$target.append($('<span>').text(records[i].name)
.prepend($('<input type="radio" name="mychoice">',
{ value: records[i].id })));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="target"></div>

Related

How to loop through items in a json file with Javascript and display in HTML

I have a json file that is created based on user input and the number of items in the json file can vary. I want to loop through all items in the json file in a Javascript function and display each item line by line in the HTML script.
The sample JSON file looks like this:
data={"What is your name": "Jason",
"What is your favorite color": "Blue",
When is your birtyday?", "Jan 15"}
In the HTML file, once a certain button is clicked, each item in the json file should appear as a Question/Answer pair. For example, "What is your name: should appear in the first "question" input box, and "Jason" should appear in the first "answer" input box. For the exmple above, since there are three items, there should be 6 lines of input html tags, 3 of which for the questions and the other three for the answers. If the JSON file has, for example, 5 items, there should be 5 sets of question/answer inputs. Here's my HTML code:
<input id="open-btn" class="right-button"></input>
<form class="form-container" action="mailto:?subject=Answers" method="post" enctype="text/plain" >
<!-- Question & Answer Input Sets: I want to loop this --!>
<div class="form-group">
<label for="question1">Question </label>
<input type="text" id="question1" class="form-input" name="Question1">
</div>
<div class="form-group">
<label for="answer1">Answer </label>
<input type="text" id="answer1" class="form-input" name="Answer1">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
In Javascript, I read the json file and tried to loop through all keys(questions) and values (answers) and pass them to the question and answer inputs in the HTML. But I'm not sure how to introduce the loop in the html component. For now, I have only one input for questions (id = question1) and answers(id=answer1) in HTML and it just displays the first item in the json file.
const open = document.getElementById("open-btn");
open.addEventListener('click', () => {
$.getJSON("../static/data.json", function(data) {
$.each(data, function (key, value) {
document.getElementById("question1").value = key
document.getElementById("answer1").value = value
}
)
console.log("Log Data:",data)
});
How can I loop through all items in the json file and display them in html line by line? For example, if there are three items in the json file like the example above, I want the 6 lines of inputs, 3 of which are for questions and the other 3 for answers. Since the length of the json file can vary, I can't create the pre-determined number of input sets in my HTML file.
Or is it possible to read the json file, and store the dictionary as a variable in the Javascript function and use that variable in a for loop in html?
You need to create new elements within the each method.
Since you appear to be using Jquery, we can insert new elements into our HTML using Jquery's appendTo method. To avoid duplicate IDs in our HTML and to bind each <label> to each corresponding <input>, we use a simple counter defined as i.
data = {
"What is your name": "Jason",
"What is your favorite color": "Blue",
"When is your birtyday?": "Jan 15"
};
const open = document.getElementById("open-btn");
var i = 1;
open.addEventListener('click', () => {
$("#open-btn").prop('disabled', true); // to avoid spamming.
// $.getJSON("../static/data.json", function(data) {
$.each(data, function(key, value) {
$("<div />", { "class":"form-group" })
.append($("<label />", { for:"question" +i, text:"Question " +i}))
.append($("<input />", { type: "text", id:"question"+i, value: key }))
.appendTo(".example-output");
$("<div />", { "class":"form-group" })
.append($("<label />", { for:"answer" +i, text:"Answer " +i}))
.append($("<input />", { type: "text", id:"answer"+i, value: value }))
.appendTo(".example-output");
i++;
})
// });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="" id="open-btn">open btn</button>
<form class="form-container" action="mailto:?subject=Answers" method="post" enctype="text/plain">
<div class="example-output"></div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
You can create a function to add an element to HTML such as
function addPair(parent,type,text,pairId){
var formGroup = document.createElement("div");
formGroup.className = "form-group";
var typeLabel = document.createElement("label");
typeLabel.htmlFor = type+pairId;
typeLabel.innerText = text;
var inputText = document.createElement("input");
inputText.type = "text";
inputText.id = type+pairId;
inputText.className = "form-input";
inputText.name = type+pairId;
inputText.value = text;
formGroup.appendChild(typeLabel);
formGroup.appendChild(inputText);
parent.appendChild(formGroup);
}
and then use it like this
const open = document.getElementById("open-btn");
var pairs = 0;
var formContainer = document.getElementById("form-container");
open.addEventListener('click', () => {
$.getJSON("../static/data.json", function(data) {
$.each(data, function (key, value) {
addPair(formContainer,"Question",key,pairs);
addPair(formContainer,"Answer",value,pairs);
pairs++;
}
)
console.log("Log Data:",data)
});
you can see an example here
Hope this helps!

Get the text from label of Radiobutton

I have a couple of radio button below. I want to get the text from the radio button I have chosen. For example: House Espresso or Guest Espresso. I have tried to use getElementsByName and for loop to get the checked value but it seems to return nothing.
Here is my HTML code:
<div class="type">
<p>Type<p>
<input type="radio" id="houseEspresso" name="singleEspresso" checked="checked"onclick="addProduct(this)">
<label for="houseEspresso">House Espresso</label><br>
<input type="radio" id="guestEspresso" name="singleEspresso" onclick="addProduct(this)">
<label for="guestEspresso">Guest Espresso</label><br>
</div>
And here is my Javascript code:
var type = document.getElementsByName("singleEspresso")
for (var i=0; i<type.length; i++){
if(type[i].checked){
var title_type=type[i].innerText
console.log(title_type)
}
}
Can anyone give me an idea to fix it? Thank you!
The problem is that you're trying to get innerText from the <input>, which has none. You need to get the <label>'s text:
for (var i=0; i<type.length; i++){
if(type[i].checked){
var title_type=type[i].nextElementSibling.innerText
console.log(title_type)
}
}
You need to find a checked input, for that you can use :checked css selector. Then you can pick any value from input DOM element which ties it to label (in your case it's id). And basing on the id you can find corresponding label.
const selectedRadioInput = document.querySelector('[name=singleEspresso]:checked');
const inputId = selectedRadioInput.id;
const label = document.querySelector(`[for=${inputId}]`);
console.log(label.innerText);
Working demo: https://jsfiddle.net/yo18mx9k/2/
You can set a value to input radio: <input type="radio" value="1">
Then just get the buttons and see which one is checked, like this:
let house = document.getElementById('houseEspresso');
let guest = document.getElementById('guestEspresso');
if (house.checked) {
console.log(house.value);
} else if (guest.checked) {
console.log(guest.value);
}
However, I would recommend that you take a look at jQuery so you can make it easier:
$("input[name='singleEspresso']:checked").val();

How to add multiple input field inside a div dynamically using JavaScript/jQuery?

I need to create some multiple input field dynamically on onkeypress event using JavaScript/jQuery.
I have one text-box,when user is entering any key on that text area two input field and second text-box is opening. When user will enter any key on second text box again another two input field and third text-box will open and so on. There is also a cross button is creating to close each individual set of text-box. In my current code I doing this putting all field static as user may create many numbers of input field so that I want to create those in dynamically with different name and id.
My code is in this Plunkr.
EDIT: Misunderstood question, answer below
This can easily be done if you have a specific field in which to create the input fields. For example, I will load input fields into document.body
Everytime you call newinput() an input field is created in parent who's id starts at input0 and increments each time
var id = 0;
var newinput = function() {
var parent = document.body
var field = document.createElement("input")
field.className = "myclassname"
field.style = "display:block;"
field.id = "input" + id;
parent.appendChild(field);
id += 1;
}
<body>
<div>Click plus to add input</div>
<button type="button" name="button" onclick="newinput()">+</button>
</body>
In your case, it looks like you want to add a group, you can do this:
var fieldgroup = document.querySelector(".questionshowp .form-group").cloneNode(true); // (1)
var addinput = function(){
var parent = this.parentNode.parentNode.parentNode; // (2)
var n = parent.querySelectorAll(".form-control").length
var f = fieldgroup.cloneNode(true);
f.children[0].id = "question"+n // (3)
f.querySelector(".secondsec").querySelector("button.btn-success").onclick = addinput // (4)
parent.insertBefore(f,parent.querySelector(".clear")); // (5)
}
Create a copy of a field-group to be used as a template
Get the container of input fields
Set the input field id with regard to total number of form-groups in parent
Make sure template applies addinput() to button
Insert input form before end of parent form
The easiest way apply this function to all + buttons is with JQuery
$("button.btn-sm.btn-success").on("click", addinput)
This would need to be located at the bottom of your html file, and below addinput() definition
EDIT: Real Answer
Turns out I wrote all that and just realized I misunderstood your question.
Still we can use the same principle to do what I believe you are asking
master = document.querySelector(".aquestionpart"); // (1)
form = document.querySelector(".questionparts"); // (2)
function show(){
var f = form.cloneNode(true);
var n = master.querySelectorAll(".questionparts").length;
f.id = "questionparts"+(n+1); // (3)
f.querySelector("#questions").onkeypress = show; // (4)
this.parentElement.parentElement.querySelector("#questionparts"+ n + " > .questionshowp").style ="display:block;"; // (5)
this.onkeypress = undefined; // (6)
master.insertBefore(f,master.children[master.children.length-1]) // (7)
}
form.querySelector("#questions").onkeypress = show; // (8)
form = form.cloneNode(true); // (9)
Get poll container
Get poll question form to use as template
Set new poll question form id with respect to number of others
Set show function to new poll question
Show multiple choice
Make sure subsequent keypresses dont create more questions
Insert question before .clear
sets up first question to show
creates copy of fresh question to use as template
With this your current scripts.js is unnecessary, and .aquestionpart must look like this for proper formatting
<div class="aquestionpart">
<div class="questionparts" id="questionparts1">...</div>
<div class="clear"></div>
</div>
From within .questionparts be sure to remove onkeypress="show();" from input. It should look like this.
<input name="questions" id="questions" class="form-control" placeholder="Questions" value="" type="text">
And finally an interesting note is that both of the scripts I've provided can be used together! (With some slight modifications)
//Author: Shane Mendez
var fieldgroup = document.querySelector(".questionshowp .form-group").cloneNode(true);
var addinput = function(){
var parent = this.parentNode.parentNode.parentNode;
var n = parent.querySelectorAll(".form-control").length
var f = fieldgroup.cloneNode(true);
f.children[0].id = "question"+n
f.querySelector(".secondsec").querySelector("button.btn-success").onclick = addinput
console.log(parent)
parent.insertBefore(f,parent.children[parent.children.length-1]);
}
master = document.querySelector(".aquestionpart");
form = document.querySelector(".questionparts");
function show(){
var f = form.cloneNode(true);
var n = master.querySelectorAll(".questionparts").length;
f.id = "questionparts"+(n+1);
f.querySelector("#questions").onkeypress = show;
console.log(this)
this.parentElement.parentElement.querySelector("#questionparts"+ n + " > .questionshowp").style ="display:block;";
this.onkeypress = undefined;
master.insertBefore(f,master.children[master.children.length-1])
$(f.querySelectorAll("button.btn-sm.btn-success")).on("click", addinput)
}
form.querySelector("#questions").onkeypress = show;
form = form.cloneNode(true);
$("button.btn-sm.btn-success").on("click", addinput)
If you put this in your scripts.js file and put that at the bottom of your body tag, then the only thing left is the - buttons.
You can use this Press to add multiple input field inside a div dynamically using jQuery. Here you only need to call the function that takes two parameter HTMLElement and config like:
$(".addInput").click(function() {
build_inputs($(this), config);
});
In the config you can add numbers of inputs form config like:
let config = {
title: "Slides",
forms: [
{
type: "text",
name: "name",
class: "form-control mb-2",
placeholder: "Enter Data..."
},
{
type: "file",
name: "image",
class: "btn btn-light btn-sm mb-2 btn-block"
},
{
type: "number",
name: "mobile",
class: "form-control mb-2",
placeholder: "Enter Data..."
}
],
exportTo:$('#getData')
};

jQuery specify between multiple textbox

I'm making a shopping cart for multiple items in a database but after adding a textbox and adding var quantity the code only understands the first textbox and adds that quantity for all the other add to cart links.
How do I tell the program to find a specific textbox based on the item it is associated with, just like the line below it that finds the item based on the 'data-id'.
I've tried using $(".qty-txt").children().value() but I still don't know how to specify which Anchor tag to find.
<script type="text/javascript">
$(function () {
$(".AddLink").click(function () {
var quantity = $("#qty").val();
var recordToAdd = $(this).attr("data-id");
if (recordToAdd != '') {
$.post("/ShoppingCart/AddToCart", { "id": recordToAdd, "qty": quantity },
function (data) {
$('#cart-status').text(data.CartCount);
});
}
});
});
</script>
The first 3 lines are my Texbox in the anchor tag (would prefer not to use anchor tag if possible)
The second anchor tag is my Link to Add to cart.
<a class="qty-txt" data-id="#item.ID">
#Html.TextBox("Quantity", 1, new { #class = "qty-input", #id = "qty", size = 1 })
</a>
<a href="#" class="AddLink" data-id="#item.ID" data-toggle="modal" data-target="#myModal">
Add to cart
</a>
You generating invalid html by including duplicate id attributes using
#Html.TextBox("Quantity", 1, new { #class = "qty-input", #id = "qty", size = 1 })
And var quantity = $("#qty").val(); will only ever return the value of the first element with id="qty"
You need to use new { id = "", ...} to remove the id attribute or just create the textbox manually using
<input type="text" class="qty-input" size = "1" value="1" />
Then wrap the textbox and the "Add to cart" link in a container so you can use relative selectors (not sure why you wrap the textbox in another <a> tag?)
<div class="product">
<input type="text" class="qty-input" size = "1" value="1" />
Add to cart
</div>
The modify the script to
$('.AddLink').click(function () {
var quantity = $(this).closest('.product').find('.qty-input').val();
var recordToAdd = $(this).data('id'); // correct usage to access data- attributes
if (recordToAdd != '') { // not sure why you need this (why would it ever be null?)
$.post("/ShoppingCart/AddToCart", { "id": recordToAdd, "qty": quantity }, function (data) {
$('#cart-status').text(data.CartCount);
});
}
});
Just select $(".qty-input") to get all the matching inputs. Otherwise, you're selecting the list of wrapper elements...if you went that way, then you need to navigate using loops on each instance of the wrapper object(s).

Radio Button List with Knockout.js

I'm trying to build a list of radio buttons with labels so that you can click the label to check the radio item. What I have works fine in Chrome, but not IE7. The HTML that get's spit out seems like it is correct, but when I click on the label, the corresponding radio button doesn't get selected.
JavaScript
function ReuqestType(id, name, billable) {
this.id = id;
this.name = name;
this.billable = billable;
}
function RequestViewModel() {
var self = this;
self.availableRequestTypes = [
new ReuqestType(1, "Travel", true),
new ReuqestType(2, "Bill Only", false),
new ReuqestType(3, "Both", true)
];
self.selectedRequestType = ko.observable();
}
HTML
Request Type
<br />
<!-- ko foreach: availableRequestTypes -->
<input type="radio" name="requestType" data-bind="value:id, attr: {'id': 'rt'+ id}" />
<label data-bind="text: name, attr:{'for':'rt'+id}">
</label>
<!-- /ko -->
What is the preferred way to do this?
This seems to be working correctly now as of the newest version of Knockout (2.1.0).
I'm unfamiliar with knockout.js, but you can normally bind label's to inputs just by making the label wrap around the input box too.
http://jsfiddle.net/QD2qC/
It looks like your HTML is fine. It could be a quirk of IE7 not being able to acknowledge clicks of labels that have been generated dynamically.
If you can't find a proper answer, you could always use this workaround:
$('label').on('click', function() {
var labelId = $(this).attr('for');
$('#' + labelId ).trigger('click');
});
I have changed it slightly by using on() instead of click() to account for these labels being generated dynamically.

Categories

Resources