createElement - select boxes interspersed in the midst of text - javascript

This is the HTML I'm trying to create:
<td>
Tiana is
<select name="U4">...</select>
keen to go to the
<select name="J4">...</select>
market.
</td>
As you can see, there is a <td> element which contains a prose sentence with select boxes in the midst of it.
It's easy to do with $('#id').html(...);. What I want to do is build it using createElement. How do you create the select boxes in the middle of the other text? The following code is a start :)
var doc = document,
fr = doc.createDocumentFragment(),
td = doc.createElement("td"),
sel1 = doc.createElement("select"),
sel2 = doc.createElement("select");
td.innerHTML = "Tiana is keen to go to the market";
sel1.name = "U4";
sel2.name = "J4";
fr.appendChild(td);
td.appendChild(sel1); // But these are not in the middle of the sentence
td.appendChild(sel2);
BTW: I recognise, too, that I'll have to create the select options.
Thanks.

There is also a function called createTextNode() (MDN docu) for creating simple text as content. So one solution would be to split your text accordingly, transform it to textnodes and then append it as well:
var doc = document,
fr = doc.createDocumentFragment(),
td = doc.createElement("td"),
sel1 = doc.createElement("select"),
sel2 = doc.createElement("select"),
text1 = doc.createTextNode( 'Tiana is ' ),
text2 = doc.createTextNode( ' keen to go to the ' ),
text3 = doc.createTextNode( 'market' );
sel1.name = "U4";
sel2.name = "J4";
fr.appendChild(td);
td.appendChild( text1 );
td.appendChild(sel1);
td.appendChild( text2 );
td.appendChild(sel2);
td.appendChild( text3 );
Here you can find an example fiddle: link.

I think you'll need to have this:
<td>
<span>Tiana is</span>
<select name="U4">...</select>
<span>keen to go to the</span>
<select name="J4">...</select>
<span>market.</span>
</td>
or do this:
td.innerHTML = 'Tiana is <select id="U4" name="U4" /> keen to go to the <select id="J4" name="J4" /> market';
var uOpt1 = document.createElement('option');
//Set option properties
td.getElementById('U4').appendChild(uOpt1); //etc

How about this? I adapted the example from mdn createElement. Fiddle.
<div id='org_div1'> The text above has been created dynamically.</div>​
var my_div = null;
var newDiv = null;
var newSelect = null;
var newDiv2 = null;
function addElement()
{
// create a new div element
// and give it some content
newDiv = document.createElement("div");
newContent = document.createTextNode("Hi there and greetings!");
newSelect = document.createElement("select");
newSelect.innerHTML='<option value="value1">Value 1</option><option value="value2" selected>Value 2</option><option value="value3">Value 3</option>';
newDiv.appendChild(newContent); //add the text node to the newly created div.
newDiv.appendChild(newSelect)
newDiv2 = document.createElement("span");
newDiv2.appendChild(document.createTextNode("Foo"));
newDiv.appendChild(newDiv2)
// add the newly created element and it's content into the DOM
my_div = document.getElementById("org_div1");
document.body.insertBefore(newDiv, my_div);
}
addElement()​

Related

Append List of <select> Elements

I am trying to create a button that calls a function which creates new list items with selection boxes. The code below create a select element however, the button disappears and it doesn't create one list item after another. Any idea how I can persist the button and add one select element after another?
<button type="button" onclick="createTable()">Add Item</button>
function createTable()
{
var itemName = "Selections: ";
document.write(itemName);
for (var i=0;i<7;i++)
{
var myTable = " ";
myTable+="<select name='test' id='mySelect"+i+"' style='font-size:10px' onchange='Calculate()'>";
myTable+="<option value='zeroPoint'>0</option>";
myTable+="<option value='halfPoint'>1/2</option>";
myTable+="<option value='onePoint'>1</option>";
myTable+="</select>";
document.write(myTable);
}
}
I made some changes to the documnet.write way you have. However, I would strongly recommend dynamically creating html dom nodes. I added another method, createTable2, which does the required. It will also be easier for you to preserve the html content you have, which can be easily written over with document.write way.
Edit:
I added one more method, createTable2, to allow adding multiple selects. There is a model you can pass in with the select and option information you have. There is a flag, empty, which is set to true if you would like to empty the div before adding new selects; i.e. createTable3(true).
function createTable()
{
var itemName = "Selections: ";
var selectElement = document.getElementById("render");
for (var i=0;i<7;i++)
{
var myTable = " ";
myTable+="<select name='test' id='mySelect"+i+"' style='font-size:10px' onchange='Calculate()'>";
myTable+="<option value='zeroPoint'>0</option>";
myTable+="<option value='halfPoint'>1/2</option>";
myTable+="<option value='onePoint'>1</option>";
myTable+="</select>";
selectElement.innerHTML = myTable;
}
}
function createTable2(){
var myDiv = document.getElementById("render");
//Create array of options to be added
var array = ["zeroPoint","halfPoint","onePoint"];
var texts = ["1","1/2","1"];
var selectList = document.createElement("select");
selectList.id = "mySelect";
selectList.style.fontSize = "10px";
selectList.onChange = 'Calculate()';
myDiv.appendChild(selectList);
//Create and append the options
for (var i = 0; i < array.length; i++) {
var option = document.createElement("option");
option.value = array[i];
option.text = texts[i];
selectList.appendChild(option);
}
}
function createTable3(empty){
var myDiv = document.getElementById("render");
if(empty){
myDiv.innerHTML = "";
}
let model = {
"select1": [{value: "zeroPoint", label: "1"},
{value: "halfPoint", label: "1/2"},
{value: "onePoint", label: "1"}],
"select2": [{value: "zeroPoint1", label: "11"},
{value: "halfPoint1", label: "11/22"},
{value: "onePoint1", label: "11"}]
};
Object.keys(model).forEach(function(key){
let entry = model[key];
var selectList = document.createElement("select");
selectList.id = key;
selectList.style.fontSize = "10px";
myDiv.appendChild(selectList);
//Create and append the options
for (var i = 0, item; item = entry[i]; i++) {
var option = document.createElement("option");
option.value = item.value;
option.text = item.label;
selectList.appendChild(option);
}
});
}
<button type="button" onclick="createTable3()">Add Item</button>
<div id= "render"/>
If you use document.write("") the entire web page content will be replace by the content you pass inside the document.write function. Instead create a div element under button element like
<div id="list"></div>
then in the javascript file change as
function createTable()
{
var itemName = "Selections: ";
var selectElement = document.getElementById(list);
for (var i=0;i<7;i++)
{
var myTable = " ";
myTable+="<select name='test' id='mySelect"+i+"' style='font-size:10px' onchange='Calculate()'>";
myTable+="<option value='zeroPoint'>0</option>";
myTable+="<option value='halfPoint'>1/2</option>";
myTable+="<option value='onePoint'>1</option>";
myTable+="</select>";
selectElement.innerHTML = myTable;
}
}
I am unsure what you are exactly trying to achieve, but having DOM elements in strings and then modifying an elements innerHTML or using document.write is just a hack. You need to leverage the DOM apis.
While that means my code is maybe double or triple the the size of your code. Its the more maintainable version long term.
function createTable() {
var selectMenu = document.querySelector('#selectionsContainer');
// Array of options elements
var myTable = [];
// Pushing some elements to our my table array
//
myTable.push(
createOption('zeroPoint', 0),
createOption('halfPoint', 0.5),
createOption('onePoint', 1)
)
// Looping through all elements and adding them to the //selections container
//
myTable.forEach( element => {
selectionsContainer.appendChild(element);
});
}
/** Creates an option element and returns it for usage */
function createOption(value, label) {
var option = document.createElement('option');
option.value = value;
option.innerText = label;
return option;
}
function Calculate(value) {
console.log('do whatever you want to with the value: ', value);
}
select {
font-size:10px
}
<button type="button" onclick="createTable()">Add Item</button>
<label for="selectionsContainer">
Selections
<label>
<select id="selectionsContainer" onchange='Calculate(this.value)'>
<option value=5> 5 </option>
<select>
All the answers so far are pointing that OP might be doing something wrong by not creating select dynamically. But we don't know his requirements.
Also everybody already explained document.write will write on you entire document thus deleting everything, you don't want that.
document.write --> https://developer.mozilla.org/en-US/docs/Web/API/Document/write
appendChild should be used but you wanted a string and appendChild expect Node not string.
appendChild --> https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
node --> https://developer.mozilla.org/en-US/docs/Web/API/Node
So the only way to solve this is by using innerHTML and summing up inner Html by adding new ones.
Or by creating node from sting, which requires some more logic, see here --> Creating a new DOM element from an HTML string using built-in DOM methods or prototype
innerHTML --> https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
const selectTamplate = (selectId, onChangeCallbackName) => {
return `
<select name='test' id='mySelect${selectId}' style='font-size:10px' onchange='${onChangeCallbackName}()'>
<option value='zeroPoint'>0</option>
<option value='halfPoint'>1/2</option>
<option value='onePoint'>1</option>
</select>
`
};
const appendStringHtml = (elementTargetHtml, elemenAppend) => {
elemenAppend.innerHTML += elementTargetHtml;
}
const doSomethingOnChange = () => {
console.log('I am the KING!');
};
const placeToAppend = document.querySelector('.append-selects-here');
const buttonAppender = document.querySelector('.btn-append');
let selectID = 1;
buttonAppender.addEventListener('click', ()=>{
const selectHTML = selectTamplate(selectID, 'doSomethingOnChange');
appendStringHtml(selectHTML, placeToAppend);
selectID ++;
});
<button class="btn-append">Add Selects</button>
<div class="append-selects-here"></div>
see the working code here --> https://codepen.io/nikolamitic/pen/PEpEbj
I used template string so that interpolation is possible, little bit more clear. And separate the logic while still keeping yours.

Appending new DOM elements to existing elements

I am trying dynamically increase the number of selects my form has on a website. I use javascript to do so.
JS code:
var div = document.getElementById("graph-form");
var para = document.createElement('span');
para.innerHTML = "Test Type";
var form = document.getElementById("form-id");
var selectList = document.createElement("select");
selectList.setAttribute("name","Test");
for(var i = 0; i < test_form_values.length; i++){
var option = document.createElement("option");
option.value = test_form_values[i];
option.text = test_form_text[i];
selectList.appendChild(option);
}
form.appendChild(para);
form.appendChild(selectList);
var para = document.createElement('span');
para.innerHTML = "Parameter";
var selectList = document.createElement("select");
selectList.setAttribute("name","Parameter");
for(var i = 0; i < param_form_values.length; i++){
var option = document.createElement("option");
option.value = param_form_values[i];
option.text = param_form_text[i];
selectList.appendChild(option);
}
form.appendChild(para);
form.appendChild(selectList);
Html code:
<form action="/analytics" method = "post"></form>
<div id = "form-id">
<span>Test Type </span>
<select name="Test">
<option value="Aop2DContact">AOP 2D Contact</option>
<option value="Aop2DMag">AOP 2D Magnification</option>
</select>
<span>Parameter </span>
<select name="Parameter">
<option value="MTF1">MTF at 2 lp/mm parallel</option>
<option value="MTF2">MTF at 4 lp/mm parallel</option>
</select>
</div>
<div class="buttons">
<input type="submit">
</div>
</form>
After appending:
After I append the newly created elements, it not only doesn't append inside the element but takes the div I had placed inside the element and moved it outside. I feel like there is probably an obvious answer as to why my HTML is getting restructured but I am not sure what that is.
Like Turnip commented, you are ending your form right after you open it.
Also, your JS is looking to append to the element with the id "form-id" and your form does not have that id, your inner div does.

Dynamic checkbox list in javascript - not working

I'm trying to create a list of checkboxes when a certain element is selected from the dropdown list. However, in the following code I am getting only the last element in the checkbox list. That is, at the output, there aren't 3 checkboxes (length of my array) but there is only one - only with the last element in the array.
What am I doing wrong?
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script>
function chooseTable(db) {
if(db=="hr.employee"){
var div = document.getElementById("table");
var ids = ["id","name", "write_uid"];
var main = document.getElementById('main1');
var parentElement = document.getElementById('ids');
for(var count in ids)
{
var newCheckBox = document.createElement('input');
newCheckBox.type = 'checkbox';
newCheckBox.id = 'id' + count; // need unique Ids!
parentElement.innerHTML = ids[count];
newCheckBox.value = ids[count];
parentElement.appendChild(newCheckBox);
}
}
}
</script>
<center>
<bold>
<h2>
Make Query
</h2>
</bold>
<div id="main1">
<div>
Choose database:<br/>
<select id="table" name="table" onchange="chooseTable(this.value)">
<option name="choice" value=""></option>
<option name="choice1" value="hr.employee">Employees</option>
<option name="choice2" value="account.account">Accounts</option>
</select>
</div>
<div id="ids">
</div>
</div>
</center>
</body>
</html>
the problem is the parentElement.innerHTML = ids[count]; code. It clean all the previous html content. And to add label to the checkbox it's better use label tag. Try this:
for(var count in ids)
{
var newCheckBox = document.createElement('input');
newCheckBox.type = 'checkbox';
newCheckBox.id = 'id' + count; // need unique Ids!
newCheckBox.value = ids[count];
parentElement.appendChild(newCheckBox);
var newLabel = document.createElement('label');
newLabel.innerHTML = ids[count];
parentElement.appendChild(newLabel);
}
because innerHTML method will clean its own inside and rewrite new element.
how about try this?
for(var count in ids)
{
var newCheckBox = document.createElement('input');
var newSpan = document.createElement('span');
newCheckBox.type = 'checkbox';
newCheckBox.id = 'id' + count; // need unique Ids!
newSpan.innerHTML = ids[count];
newCheckBox.value = ids[count];
parentElement.appendChild(newSpan);
parentElement.appendChild(newCheckBox);
}

Taking tab example from fiddle ans use in my project

http://jsfiddle.net/738wtmhs/1/
using above example in fiddle in my own project: for the purpose of this exercise I am using DOM methods to create and append the elements.
function GetFeatureProperties(feature) {
//add header to 1st FirstTabContent
var featureHeader = "<center><b> <FONT COLOR='FF6600'> Feature Properties </FONT> </b> </center> </br>";
var FirstTabContent = document.createElement('div');
FirstTabContent.id = "tabs-1";
FirstTabContent.innerHTML = featureHeader;
//Second Tab
var SecondTabContent = document.createElement('div');
SecondTabContent.id = "tabs-2";
var newImage = document.createElement("img");
newImage.src = "http://mintywhite.com/wp-content/uploads/2012/10/fond-ecran-wallpaper-image-arriere-plan-hd-29-HD.jpg";
newImage.width = "100";
newImage.height = "100";
SecondTabContent.appendChild(newImage);
//add li and ul
var DivHolding2Tabs = document.createElement('div');
DivHolding2Tabs.class = "shoptab";
var header2 = document.createElement('h2');
header2.innerHTML = "Feature";
DivHolding2Tabs.appendChild(header2);
var _ul = document.createElement('ul');
var _anchor1 = document.createElement("a");
_anchor1.href = "#tabs-1";
_anchor1.innerHTML = "Info";
var _li1 = document.createElement('li');
_li1.appendChild(_anchor1);
var _anchor2 = document.createElement("a");
_anchor2.href = "#tabs-2";
_anchor2.innerHTML = "Images";
var _li2 = document.createElement('li');
_li2.appendChild(_anchor2);
_ul.appendChild(_li1);
_ul.appendChild(_li2);
DivHolding2Tabs.appendChild(_ul);
DivHolding2Tabs.appendChild(FirstTabContent);
DivHolding2Tabs.appendChild(SecondTabContent);
var jelm = $(DivHolding2Tabs); //convert to jQuery Element
var htmlElm = jelm[0]; //convert to HTML Element
var OuterDiv = document.createElement('div');
OuterDiv.id = "loc-list";
OuterDiv.appendChild(htmlElm);
return OuterDiv.innerHTML;
}
and this looks like the image seen below....if I click on the link 'image' the page jumps a bit but nothing happens and nothing happens when I press 'info' also I have included the CSS in my project so why arnt the tabs showing and yes I am using jquery ui 1.10.3.custom.js
---------------------------------------------------------------------------------------------
UPDATE
<ul id="list"><li><div><h2>Feature</h2><ul><li>Info</li><li>Images</li></ul><div id="tabs-1"><center><b> <font color="FF6600"> Feature Properties </font> </b> </center> <br></div><div id="tabs-2"><img src="http://mintywhite.com/wp-content/uploads/2012/10/fond-ecran-wallpaper-image-arriere-plan-hd-29-HD.jpg" width="100" height="100"></div></div></li></ul>
Also changed from jquery 1.10.3 custom to jquery 1.11.2.custom with all the downloaded tabs selected
If you look at this fiddle, I managed to make it work.
Here's the possible problems
1) I changed return OuterDiv.innerHTML because I needed the <div id="loc-list"> to be part of the code to initialize it. You gave it an id so my guess is you wanted it to be included but by doing innerHTML, you didn't get it.
2) Once your function returns, you need to initialize the tabs with $('#loc-list').tabs();

How to get the name or id of a select dropdown in a dynamic form

I have a dynamic form with a select dropdown, and I want to know what select was changed, however any time that I add a new form and try to change any select the alert is the same: "origen1"
Here is my js code:
<SCRIPT language="javascript">
function addRow(divId) {
count = 0;
count++;
var etiquetas = new Array();
var origenes = new Array();
var parentDiv = document.getElementById(divId);
// create a div dynamically
var eleDiv = document.createElement("div");
eleDiv.setAttribute("name", "olddiv");
eleDiv.setAttribute("id", "olddiv");
// create a label dynamically
var etiqueta = document.createElement("input");
etiqueta.setAttribute("name", 'etiqueta' + count);
etiqueta.setAttribute("value", "etiqueta");
etiqueta.setAttribute('disabled', true);
etiquetas.push(etiqueta);
//create a select dynamically
var myarray=new Array(3)
myarray[0] = "Opt1"
myarray[1] = "Opt2"
myarray[2] = "Opt3"
var origen = document.createElement("select");
origen.setAttribute("name", 'origen' + count);
for (i=0; i<3; i++)
{
opt = document.createElement('option');
opt.value = i;
opt.innerHTML = myarray[i];
origen.appendChild(opt);
}
origen.onchange = function(){testselect(this);};
origenes.push(origen);
// create a delete button dynamically
var eleBtn = document.createElement("input");
eleBtn.setAttribute("type", "button");
eleBtn.setAttribute("value", "delete");
eleBtn.setAttribute("name", "button");
eleBtn.setAttribute("id", "button");
eleBtn.setAttribute("onclick", "deleteRow('button')");
// append new div to parent div
parentDiv.appendChild(eleDiv);
// append textbox & button to new div
eleDiv.appendChild(etiqueta);
eleDiv.appendChild(origen);
eleDiv.appendChild(eleBtn);
}
function testselect(seleccion)
{
alert(seleccion.name);
}
function deleteRow(tableID) {
var div = document.getElementById('olddiv');
if (div) {
div.parentNode.removeChild(div);
}
}
</SCRIPT>
And the html:
<form name="objForm" action="test1.php">
<INPUT type="button" value="Add Row" onclick="addRow('dataTable')" />
<div id="dataTable" width="350px">
</div>
<input type="submit" value="Submit"/>
</form>
Try inspecting the drop down using firebug. With that you might be able to get the name and ID of the selected drop down but remember the selected drop down has to be selected using firebug in order to see the ID or name used with it.
Since this is JS and the drop down is not selected properly you might not see the name or id used.
So make sure to it is properly selected

Categories

Resources