Create Select Tag from Split String - javascript

How do I split this string:
waterfowl||tvs||guitar||pillow||mouse
...by ||?
Then, I'd like to create a select list like this:
<select name="options" id="options">
<option value="waterfowl">waterfowl</option>
<option value="tvs">tvs</option>
<option value="guitar">guitar</option>
<option value="pillow">pillow</option>
<option value="mouse">mouse</option>
</select>

var options = 'waterfowl||tvs||guitar||pillow||mouse';
$( '#someDiv' ).html( '<select name="options" id="options">'
+ options.replace(/(\w+)\|*/g, '<option value="$1">$1</option>')
+ '</select>' );

// Turns a string in to a combo box based on:
// #d Delimiter to split the string up by
// #so Select box attributes (adding name="foo" means passing {name:'foo'})
// Result: jQuery object of the new select element, populated with the items
// from the string
String.prototype.toSelect = function(d,so){
so = so || {};
var s = $('<select/>',so),
items = this.split(d);
for (var i = 0; i < items.length; i++){
$('<option/>').val(items[i]).text(items[i]).appendTo(s);
}
return s;
}
// an example
// Append the following string to the body of the document
// after it's been converted in to a <Select> element
$('body').append("waterfowl||tvs||guitar||pillow||mouse".toSelect('||',{
name: 'select',
id: 'select'
}));
Version with a bit more flexibility (and jQuery abilities): http://jsfiddle.net/j6DjR/

Preamble:
I used a <select> element with id and name attributes of
"assorted". "options" is a terrible id/name for a form element.
Read here for more: http://www.fortybelow.ca/hosted/comp-lang-javascript/faq/names/
Code:
No mess, no fuss.
(commonElements.testing is the form containing the <select> element)
var commonElements =
{
"testing": document.getElementById("testing"),
"assorted": document.getElementById("assorted")
},
options = "waterfowl||tvs||guitar||pillow||mouse";
function addOptions (optionList)
{
var i = 0,
limit = optionList.length,
parent = commonElements.assorted,
option;
for (i;i<limit;i++)
{
option = document.createElement(
"option"
);
option.text = optionList[i];
option.value = optionList[i];
parent.add(option, null);
}
}
function createOptions (toSplit)
{
var optionList = toSplit.split("||");
addOptions(optionList);
}
createOptions(options);
Working Link (with full code):
http://jsbin.com/ucajep

Try the following:
var input = 'waterfowl||tvs||guitar||pillow||mouse';
var split = input.split('||');
var select = $('<select name="options" id="options"></select>');
$.each(split, function(index, value) {
var option = $('<option></option>');
option.attr('value', value);
option.text(value);
select.append(option);
});
$('#idOfContainer').empty().append(select);

Your problem is simple:
Split string, using || as separator.
Loop over the splitted string.
Create a new option element
Set its value and text to the current item
Add the element to containing select element
Here's a simple implementation of it (without using jQuery). I use Array.prototype.forEach and element.textContent (the former being ES5 and latter being non-IE), but it should bring the point across (and they're not hard to shim).
function makeSelect( options, separator ) {
var select = document.createElement( 'select' ),
optionElem;
options.split( separator || '||' ).forEach(function( item ) {
optionElem = document.createElement( 'option' );
optionElem.value =
optionElem.textContent =
item;
select.appendChild( optionElem );
});
return select;
}
var selectElem = makeSelect( 'waterfowl||tvs||guitar||pillow||mouse' );
You can then manipulate selectElem just like you'd manipulate any other DOM element.

You can split the string into an array, then iterate through the array building an HTML string that you can then append to the DOM:
var str = 'waterfowl||tvs||guitar||pillow||mouse',//the string to be split
arr = str.split('||'),//the split string, each split stored in an index of an array
out = '';//our output buffer variable
//iterate through each array index
for (var index; index < arr.length; i++) {
//add this index to the output buffer
out += '<option value="' + arr[index] + '">' + arr[index] + '</option>';
}
//add the HTML we've built to the DOM, you can also use `.append(<code>)` instead of `.html(<code>)` but if you are using an ID for your select element then you ant to make sure and replace the HTML
$('#container-element').html('<select name="options" id="options">' + out + '</select>');
Here's a jsfiddle to demonstrate: http://jsfiddle.net/jasper/eb5Dj/

Related

Building HTML Selection field and selecting option with JavaScript Array

I have some JavaScript Arrays that are used to generate HTML selection fileds and then to also make the option a user has selected as the selected opton in the generated Selection list.
I have a working example for a basic JavaScript array. I need help with a more complex JS array though.
function buildFormSelection(optionArray, selectedOption){
var optionsHtml = '';
for(var i = 0; i < optionArray.length; i++){
optionsHtml += "<option value='" + optionArray[i] + "' "
+ (selectedOption == optionArray[i] ? "selected='selected'" : "")
+ ">" + optionArray[i] + "</option>";
}
return optionsHtml;
};
var typesArray = ['Other', 'SugarCRM', 'Magento', 'Design'];
console.log(buildFormSelection(typesArray, 'SugarCRM'));
This generates this HTML output...
<option value='Other'>Other</option>
<option value='SugarCRM' selected='selected'>SugarCRM</option>
<option value='Magento'>Magento</option>
<option value='Design'>Design</option>
Here is a JSFiddle to show it working. http://jsfiddle.net/jasondavis/4twd8oz1/
My issue is I now need to have the same functionality on a more complex array like this one below. It has an ID and a Name Value...
var milestonesArray = [
['1','Milestone 1'],
['2','milestone 2'],
]
Using similar code as my function above, I need to pull in a user's selected value from a database for example if they have saved the value of 2 then it should select selection option of 2 and show the text milestone 2 from a selection that looks like this...
<option value='1'>milestone 1</option>
<option value='2' selected='selected'>milestone 2</option>
I am not sure how to properly build a JavaScript array that can handle a key and value like this and make my function work with the milestone array.
Any help please?
What you need to do just add another array index to your function like so:
function buildFormSelection(optionArray, selectedOption){
var optionsHtml = '';
for(var i = 0; i < optionArray.length; i++){
optionsHtml += "<option value='" + optionArray[i][0] + "' "
+ (selectedOption == optionArray[i][0] ? "selected='selected'" : "")
+ ">" + optionArray[i][1] + "</option>";
}
return optionsHtml;
};
Where optionArray[i][0] is the value and optionArray[i][1] is the text.
JSFiddle
Answers with lots of code is usually frowned on but this is a trivial solution as #imtheman pointed out in his answer. But not everything needs to be so concise.
function makeOptionElement(value, title, selected) {
var option = document.createElement('option');
option.value = value;
if (selected) {
option.setAttribute('selected', 'selected');
}
option.innerHTML = title;
return option;
}
function dataToOptions(data, selectedIndex) {
var selectList = document.createElement('select');
data.forEach(function(item, index) {
var isSelected = (index === selectedIndex);
var option = makeOptionElement(item[0], item[1], isSelected);
selectList.appendChild(option);
});
return selectList;
}
Essentially, each time you call the array with your variables to be printed, you are calling the contents of the array in the position specified between the [ ]. It may be another array. That you can access as you would any other array. So, it would be:external_array[extrenal_array_index][internal_array_index]

Trouble parsing a select element

I have a dropdown in a Grid. This is how it looks like. Now I am
trying to get the name of the select tag.
var x = document.getElementsByTagName('select');
I need to get the name and
parse it in such a way to get this value 13442111. What's the best way to go about getting this information?
<td class="cl">
<select name="ctrlvcol%3DId%3Bctrl%3DTabListView%3Brow%3D13442111%3Btype%3Dtxt" onchange="getTypeValue(this.value,13442111)">
<option value="1025">TEST-AAAA</option>
<option selected="" value="1026">TEST-BBBB</option>
<option value="1027">TEST-CCCC</option>
</select>
</td>
var selectElements = document.getElementsByTagName('select');
var selectElementsLen = selectElements.length;
for (var i = 0; i < selectElementsLen; i++) {
// split row parts
var rowID = unescape(selectElements[i].name).split(';');
if (rowID.length >= 3) {
// trim meta
rowID = rowID[2].replace(/^row=/, '');
// validate row ID
if (/^[0-9]+$/.test(rowID)) {
console.log('Valid Row ID: ' + rowID);
// do whatever needs to be done
}
}
}
http://jsfiddle.net/N4sJv/
Here's the approach with regular expression only:
var selectElements = document.getElementsByTagName('select');
var selectElementsLen = selectElements.length;
for (var i = 0; i < selectElementsLen; i++) {
// extract Row ID
var rowID = unescape(selectElements[i].name).match(/(?:row=)([0-9]+)/);
if (rowID && (rowID.length >= 2)) {
rowID = rowID[1];
console.log('Valid Row ID: ' + rowID);
// do whatever needs to be done
}
}
http://jsfiddle.net/N4sJv/1/
Keep in mind that document.getElementsByTagName() may not be the best choice as it selects all specified elements in the DOM tree. You might want to use a framework such as jQuery to consider browser compatibilities and performance.
Here is a bit of code that may help you. This little snippet will work if and only if this is the only select element on the page. As the comments above state, it would be better to identify this element with an id. However, for your use case the following should work:
// Get all select elements (in this case the one) on the page.
var elems = document.getElementsByTagName("select");
// Select the first "select" element and retrieve the "name" attribute from it
var nameAttr = decodeURIComponent(elems[0].getAttribute("name"));
// Split the decoded name attribute on the ";" and pull the second index (3rd part)
var nameProp = nameAttr .split(';')[2];
// Substr the name prop from the equal sign to the the end
nameProp = nameProp.substr(nameProp .indexOf('=') + 1);

Get value of multi-select - No jQuery

Every relevant "question that may already have [my] answer" uses jQuery, which I am not using.
So, is there any simple way to get the values of selected options in a <select multiple> tag, or do I have to loop through all the options to see which ones are selected and manually build an array?
Side-question: Which browsers don't support selectElement.value and instead require selectElement.options[selectElement.selectedIndex].value?
You can use select.selectedOptions. However, this returns an HTMLCollection, so you still have to clean it to get a string array. http://jsfiddle.net/9gd9v/
<select multiple>
<option value="foo" selected>foo</option>
<option value="bar">bar</option>
<option value="baz" selected>baz</option>
</select>
and:
var select = document.querySelector("select");
var values = [].map.call(select.selectedOptions, function(option) {
return option.value;
});
If you end up wanting to loop through and grab the selected values you could use something like this:
function loopSelected()
{
var txtSelectedValuesObj = "";
var selectedArray = new Array();
var selObj = document.getElementById('selectID');
var i;
var count = 0;
for (i=0; i<selObj.options.length; i++) {
if (selObj.options[i].selected) {
selectedArray[count] = selObj.options[i].value;
count++;
}
}
txtSelectedValuesObj = selectedArray;
alert(txtSelectedValuesObj);
}
You can view an example HERE, adapted from this example.
.
You could also simply track the selected options via the onchange event in real-time and collect them whenever you want them. I admit it's still looping, but at least you're not doing it every time you need to retrieve the selected options, and it has the added bonus of being simple (come retrieval time, anyway...). Working fiddle: http://jsfiddle.net/cyg9Z/
var Test;
if (!Test) {
Test = {
};
}
(function () {
Test.trackSelected = function (e) {
var selector = document.getElementById('selector'),
selected = [],
i = 0;
for (i = 0; i < selector.children.length; i += 1) {
if (selector.children[i].selected) {
selected.push(selector.children[i].value)
}
}
selector.selMap = selected;
};
Test.addListeners = function () {
var selector = document.getElementById('selector'),
tester = document.getElementById('tester');
selector.onchange = Test.trackSelected;
tester.onclick = Test.testSelected;
};
Test.testSelected = function () {
var div = document.createElement('div');
div.innerText = document.getElementById('selector').selMap.join(', ');
document.body.appendChild(div);
};
Test.addListeners();
}());​

appending the items into the combo box

I need to add the item in a combo box for a particular number of times.This is my code.
for(i=0;i<3;i++)
{
othercompaniesli.innerHTML= '<select onchange="document.location.href = this.options[this.selectedIndex].value;"><option VALUE="http://www.google.com">'+fStr1[0]+'</option> </select>';
}
Here I want to add the fStr1 string 3 times.But it adds only one time.That is the for loop is working but only item value is not appending.Only last value is added in the combo box. Can anyone help me how to append the items into combo box.
var tmpStr = '<select onchange="document.location.href = this.options[this.selectedIndex].value;">';
for(i=0;i<3;i++)
{
tmpStr+= '<option VALUE="http://www.google.com">'+fStr1[0]+'</option> ';
}
tmpStr = '</select>';
othercompaniesli.innerHTML = tmpStr;
try othercompaniesli.innerHTML +=.
Since you are using equal to =, it is re-assigning to the same element
Use append()
$('#othercompaniesli').append('<select onchange="document.location.href = this.options[this.selectedIndex].value;"><option VALUE="http://www.google.com">'+fStr1[0]+'</option> </select>');
Note that your select and option elements are repeating, you need to change it accordingly.
Place select tag out of loop
var selectTag = '<select onchange="document.location.href = this.options[this.selectedIndex].value;">';
for(i=0;i<3;i++) {
selectTag += '<option VALUE="http://www.google.com">'+fStr1[0]+'</option>';
}
selectTag +="</select>"
othercompaniesli.innerHTML = selectTag;
What you are doing is the inside the loop you are ending your select tag , so every element will have it own select opening and closing tag. and you are just updating your innerHTML with the newer element thats why its getting the last element.
var openingTag= '<select onchange="document.location.href = this.options[this.selectedIndex].value;">';
for(i=0;i<3;i++)
{
openingTag+= '<option VALUE="http://www.google.com">'+fStr1[0]+'</option> ';
}
openingTag= '</select>';
othercompaniesli.innerHTML = openingTag;
var select= $('mySelect');
var opt = new Option("OptionTitle", "123");
select.selectedIndex = InsertNewOption(opt, select[0]);
function InsertNewOption(opt, element)
{
var len = element.options.length;
element.options[optsLen] = opt;
return len;
}

How would I dynamically create input boxes on the fly?

I want to use the value of a HTML dropdown box and create that number of input boxes underneath. I'm hoping I can achieve this on the fly. Also if the value changes it should add or remove appropriately.
What programming language would I need to do this in? I'm using PHP for the overall website.
Here is an example that uses jQuery to achieve your goals:
Assume you have following html:
<div>
<select id="input_count">
<option value="1">1 input</option>
<option value="2">2 inputs</option>
<option value="3">3 inputs</option>
</select>
<div>
<div id="inputs"> </div>
And this is the js code for your task:
$('#input_count').change(function() {
var selectObj = $(this);
var selectedOption = selectObj.find(":selected");
var selectedValue = selectedOption.val();
var targetDiv = $("#inputs");
targetDiv.html("");
for(var i = 0; i < selectedValue; i++) {
targetDiv.append($("<input />"));
}
});
You can simplify this code as follows:
$('#input_count').change(function() {
var selectedValue = $(this).val();
var targetDiv = $("#inputs").html("");
for(var i = 0; i < selectedValue; i++) {
targetDiv.append($("<input />"));
}
});
Here is a working fiddle example: http://jsfiddle.net/melih/VnRBm/
You can read more about jQuery: http://jquery.com/
I would go for jQuery.
To start with look at change(), empty() and append()
http://api.jquery.com/change/
http://api.jquery.com/empty/
http://api.jquery.com/append/
Doing it in javascript is quite easy. Assuming you've got a number and an html element where to insert. You can obtain the parent html element by using document.getElementById or other similar methods. The method assumes the only children of the parentElement is going to be these input boxes. Here's some sample code:
function addInput = function( number, parentElement ) {
// clear all previous children
parentElement.innerHtml = "";
for (var i = 0; i < number; i++) {
var inputEl = document.createElement('input');
inputEl['type'] = 'text';
// set other styles here
parentElement.appendChild(inputEl);
}
}
for the select change event, look here: javascript select input event
you would most likely use javascript(which is what jquery is), here is an example to show you how it can be done to get you on your way
<select name="s" onchange="addTxtInputs(this)" onkeyup="addTxtInputs(this)">
<option value="0">Add</option>
<option value="1">1</option>
<option value="3">3</option>
<option value="7">7</option>
</select>
<div id="inputPlaceHolder"></div>
javascript to dynamically create a selected number of inputs on the fly, based on Mutahhir answer
<script>
function addTxtInputs(o){
var n = o.value; // holds the value from the selected option (dropdown)
var p = document.getElementById("inputPlaceHolder"); // this is to get the placeholder element
p.innerHTML = ""; // clears the contents of the place holder each time the select option is chosen.
// loop to create the number of inputs based apon `n`(selected value)
for (var i=0; i < n; i++) {
var odiv = document.createElement("div"); //create a div so each input can have there own line
var inpt = document.createElement("input");
inpt['type'] = "text"; // the input type is text
inpt['id'] = "someInputId_" + i; // set a id for optional reference
inpt['name'] = "someInputName_" + i; // an unique name for each of the inputs
odiv.appendChild(inpt); // append the each input to a div
p.appendChild(odiv); // append the div and inputs to the placeholder (inputPlaceHolder)
}
}
</script>

Categories