populate form select dropdown based on url - javascript

I have a drop down that looks like this :
<select>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
How can I pre populate the value to saab, based on the url. I have links on a different page, one for each of these options. I want people to be able to selct the link "saab", some how pass that though the url and make "saab" selected when the page with this form loads.
Preferably a java script solution if possible?

Getting the window's location and parsing out the pathname should do the trick. Then all you have to do is set the selected attribute on the appropriate option in your select drop-down.
Note: This code does not require any dependencies.
function main() {
var url = new URLParser(window.location);
var path = url.pathname;
//Say our pathname is "/saab"
path = '/saab';
var selectEl = document.getElementById('make');
for (var i = 0; i < selectEl.length; i++) {
var optionEl = selectEl.options[i];
if (optionEl.value === path.substr(1)) {
optionEl.setAttribute('selected', 'selected');
}
}
}
// I wrote this URL parser a while back. It should be cross-browser safe.
// http://stackoverflow.com/a/27964708/1762224
var URLParser = (function(document) {
var PROPS = 'protocol hostname host pathname port search hash href'.split(' ');
var self = function(url) {
this.aEl = document.createElement('a');
this.parse(url);
};
self.prototype.parse = function(url) {
this.aEl.href = url;
if (this.aEl.host == "") {
this.aEl.href = this.aEl.href;
}
PROPS.forEach(function(prop) {
switch (prop) {
case 'hash':
this[prop] = this.aEl[prop].substr(1);
break;
default:
this[prop] = this.aEl[prop];
}
}, this);
if (this.pathname.indexOf('/') !== 0) {
this.pathname = '/' + this.pathname;
}
this.requestUri = this.pathname + this.search;
};
self.prototype.toObj = function() {
var obj = {};
PROPS.forEach(function(prop) {
obj[prop] = this[prop];
}, this);
obj.requestUri = this.requestUri;
return obj;
};
self.prototype.toString = function() {
return this.href;
};
return self;
})(document);
main();
<select id="make">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>

Related

Issue changing value of dropdown with js [duplicate]

I want to create a function in order to programmatically add some elements on a page.
Lets say I want to add a drop-down list with four options:
<select name="drop1" id="Select1">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
How can I do that?
This will work (pure JS, appending to a div of id myDiv):
Demo: http://jsfiddle.net/4pwvg/
var myParent = document.body;
//Create array of options to be added
var array = ["Volvo","Saab","Mercades","Audi"];
//Create and append select list
var selectList = document.createElement("select");
selectList.id = "mySelect";
myParent.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 = array[i];
selectList.appendChild(option);
}
var sel = document.createElement('select');
sel.name = 'drop1';
sel.id = 'Select1';
var cars = [
"volvo",
"saab",
"mercedes",
"audi"
];
var options_str = "";
cars.forEach( function(car) {
options_str += '<option value="' + car + '">' + car + '</option>';
});
sel.innerHTML = options_str;
window.onload = function() {
document.body.appendChild(sel);
};
I have quickly made a function that can achieve this, it may not be the best way to do this but it simply works and should be cross browser, please also know that i am NOT a expert in JavaScript so any tips are great :)
Pure Javascript Create Element Solution
function createElement(){
var element = document.createElement(arguments[0]),
text = arguments[1],
attr = arguments[2],
append = arguments[3],
appendTo = arguments[4];
for(var key = 0; key < Object.keys(attr).length ; key++){
var name = Object.keys(attr)[key],
value = attr[name],
tempAttr = document.createAttribute(name);
tempAttr.value = value;
element.setAttributeNode(tempAttr)
}
if(append){
for(var _key = 0; _key < append.length; _key++) {
element.appendChild(append[_key]);
}
}
if(text) element.appendChild(document.createTextNode(text));
if(appendTo){
var target = appendTo === 'body' ? document.body : document.getElementById(appendTo);
target.appendChild(element)
}
return element;
}
lets see how we make this
<select name="drop1" id="Select1">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
here's how it works
var options = [
createElement('option', 'Volvo', {value: 'volvo'}),
createElement('option', 'Saab', {value: 'saab'}),
createElement('option', 'Mercedes', {value: 'mercedes'}),
createElement('option', 'Audi', {value: 'audi'})
];
createElement('select', null, // 'select' = name of element to create, null = no text to insert
{id: 'Select1', name: 'drop1'}, // Attributes to attach
[options[0], options[1], options[2], options[3]], // append all 4 elements
'body' // append final element to body - this also takes a element by id without the #
);
this is the params
createElement('tagName', 'Text to Insert', {any: 'attribute', here: 'like', id: 'mainContainer'}, [elements, to, append, to, this, element], 'body || container = where to append this element');
This function would suit if you have to append many element, if there is any way to improve this answer please let me know.
edit:
Here is a working demo
JSFiddle Demo
This can be highly customized to suit your project!
This code would create a select list dynamically. First I create an array with the car names. Second, I create a select element dynamically and assign it to a variable "sEle" and append it to the body of the html document. Then I use a for loop to loop through the array. Third, I dynamically create the option element and assign it to a variable "oEle". Using an if statement, I assign the attributes 'disabled' and 'selected' to the first option element [0] so that it would be selected always and is disabled. I then create a text node array "oTxt" to append the array names and then append the text node to the option element which is later appended to the select element.
var array = ['Select Car', 'Volvo', 'Saab', 'Mervedes', 'Audi'];
var sEle = document.createElement('select');
document.getElementsByTagName('body')[0].appendChild(sEle);
for (var i = 0; i < array.length; ++i) {
var oEle = document.createElement('option');
if (i == 0) {
oEle.setAttribute('disabled', 'disabled');
oEle.setAttribute('selected', 'selected');
} // end of if loop
var oTxt = document.createTextNode(array[i]);
oEle.appendChild(oTxt);
document.getElementsByTagName('select')[0].appendChild(oEle);
} // end of for loop
Here's an ES6 version of the answer provided by 7stud.
const sel = document.createElement('select');
sel.name = 'drop1';
sel.id = 'Select1';
const cars = [
"Volvo",
"Saab",
"Mercedes",
"Audi",
];
const options = cars.map(car => {
const value = car.toLowerCase();
return `<option value="${value}">${car}</option>`;
});
sel.innerHTML = options;
window.onload = () => document.body.appendChild(sel);
const countryResolver = (data = [{}]) => {
const countrySelecter = document.createElement('select');
countrySelecter.className = `custom-select`;
countrySelecter.id = `countrySelect`;
countrySelecter.setAttribute("aria-label", "Example select with button addon");
let opt = document.createElement("option");
opt.text = "Select language";
opt.disabled = true;
countrySelecter.add(opt, null);
let i = 0;
for (let item of data) {
let opt = document.createElement("option");
opt.value = item.Id;
opt.text = `${i++}. ${item.Id} - ${item.Value}(${item.Comment})`;
countrySelecter.add(opt, null);
}
return countrySelecter;
};
Here's an ES6 version, conversion to vanilla JS shouldn't be too hard but I already have jQuery anyways:
function select(options, selected) {
return Object.entries(options).reduce((r, [k, v]) => r.append($('<option>').val(k).text(v)), $('<select>')).val(selected);
}
$('body').append(select({'option1': 'label 1', 'option2': 'label 2'}, 'option2'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
const cars = ['Volvo', 'Saab', 'Mervedes', 'Audi'];
let domSelect = document.createElement('select');
domSelect.multiple = true;
document.getElementsByTagName('body')[0].appendChild(domSelect);
for (const i in cars) {
let optionSelect = document.createElement('option');
let optText = document.createTextNode(cars[i]);
optionSelect.appendChild(optText);
document.getElementsByTagName('select')[0].appendChild(optionSelect);
}
it's very simple yet tricky but here is what you wanted, hope it's helpful :
this function generates a select list from 1990 to 2018
i think this example can help ya, if you want to add any other value just
change value of x and y ;)
function dropDown(){
var start = 1990;
var today = 2019;
document.write("<select>");
for (var i = start ; i <= today; i++)
document.write("<option>" + i + "</option>");
}
document.write("</select>");
dropDown();

How to build a JSON like this using js?

I'm trying to build a JSON like this and send it server via form post. All these json values are from select options in the UI.
{
"pages":[
{
"id":"messages",
"name":"yourinbox",
"value":"ACTIVE"
},
{
"id":"emails",
"name":"newmail",
"value":"INACTIVE"
}
]
}
I've tried with below code, but i'm not able to get the correct format.
Any help? Thanks!
var self = this;
var request = new HttpRequest();
this.form$ = $(selector);
self.form$.find('.loader').hide();
this.onSubmit = function(e){
hideSubmit();
e.preventDefault();
e.stopPropagation();
var parsedata = {};
var data = {};
var selectedOptions = self.form$.find('select');
for (var i = 0, ii = selectedOptions.length; i < ii; ++i) {
var input = selectedOptions[i];
data["name"] = input.id;
data["value"] = input.value;
parsedata.push(data); } };
This is the rough approach; Feel free to improvise.
let object = {"pages" : []};
let options = document.getElementsByTagName("option");
for(i=0;i<options.length; i++) {
object["pages"][i] = {}
object["pages"][i]["id"] = options[i].getAttribute('id');
object["pages"][i]["value"] = options[i].getAttribute('value');
let activeStatus = options[i].getAttribute('selected');
if(activeStatus == "true") object["pages"][i]["activeStatus"] = activeStatus;
else object["pages"][i]["activeStatus"] = false;
}
console.log(object)
<select>
<option id="1" value="One" selected=true>One</option>
<option id="2" value="Two">Two</option>
<option id="3" value="Three">Three</option>
<option id="4" value="Four">Four</option>
</select>

Can this javascript be shortened? Jquery is an option

The idea is when each select field is changed, it will pass part of the directory needed for the form action (the value of each option). ie:
<select onChange="chgFrmAtn" id="1-1">
<option value="">Any</option>
<option value="exDir1Option1">option 1</option>
<option value="exDir1Option2">option 2</option>
</select>
So here is the javascript, basically I want to build 2 directories, several different options. The number of options is much longer than the list in this example script. The options can be in any order. if any is selected, it doesn't add to the directory.
function chgFrmAtn( itemVal )
{
var directory1Part1 = '';
var directory1Part2 = '';
var directory1Part3 = '';
var directory2Part1 = '';
var directory2Part2 = '';
if(itemVal == '1-1'){
directory1Part1 = document.getElementById(itemVal);
}
if(itemVal == '1-2'){
directory1Part2 = document.getElementById(itemVal);
}
if(itemVal == '1-3'){
directory1Part3 = document.getElementById(itemVal);
}
if(itemVal == '2-1'){
directory1Part1 = document.getElementById(itemVal);
}
if(itemVal == '2-2'){
directory1Part2 = document.getElementById(itemVal);
}
document.advancedSearchForm.action = directory1Part1 + directory1Part2 + directory1Part3 + '/' + directory2Part1 + directory2Part2 + '/';
}
Thank you in advance.
You can use two array and map the comparison.
function chgFrmAtn(itemVal) {
var vals = ['1-1', '1-2', '1-3', '2-1', '2-2'],
directory = vals.map(function (a) {
return itemVal === a ? document.getElementById(a) : '';
});
document.advancedSearchForm.action = directory[0] + directory[1] + directory[2] + '/' + directory[3] + directory[4] + '/';
}
try
function chgFrmAtn(itemVal)
{
document.advancedSearchForm.action = document.getElementById(itemVal).value;
}
basically you will only get one value in your directoryxParty since itemVal will remain same and only one if statement will true.
Edit:
If it has to append values from each select, then
var selectIds = ["1-1", "1-2", "1-3", "2-1", "2-2"];
function chgFrmAtn()
{
var vals = selectIds.map(function(id){
var obj = document.getElementById(id);
return obj && obj.value ? obj.value : "";
});
document.advancedSearchForm.action = vals[0] + vals[1] + vals[2] + '/' + vals[3] + vals[4] + '/';
}

How to set a value for a dropdown list with a value from URL by clicking on a link

I'm trying to set a value for a dropdown list by clicking on a link(links to the same page), and the value that i want to set for the select is in the link.
I tried to do it this way, but because it is messed up it didn't work.
Here's the code i used:
<html>
<body>
<select id="select">
<option value="one">Pen</option>
<option value="two">Paper</option>
<option value="three">Book</option>
</select>
<a class="link1" href="page.php?cc=three">Set select value</a>
<script>
function $_GET(param) {
var vars = {};
window.location.href.replace( location.hash, '' ).replace(
/[?&]+([^=&]+)=?([^&]*)?/gi, // regexp
function( m, key, value ) { // callback
vars[key] = value !== undefined ? value : '';
}
);
if ( param ) {
return vars[param] ? vars[param] : null;
}
return vars;
}
var cc = $_GET('cc');
var elmnt = document.getElementsByClassName('link1'),
selectClasse = document.getElementById('select');
function setSelect () {
for (var i = 0; i < elmnt.length; i++) {
elmnt[i].onclick = function () {
selectClasse.value = cc;
}
window.history.pushState('Form', 'My form', this.getAttribute("href"));
return false;
};
}
}
setSelect ();
</script>
</body>
</html>
Any help would be much appreciated.
If you want to do this with a link and its url parameters;
Based on the answer: https://stackoverflow.com/a/979996/2956448
So you can do it like;
var params = {};
if (location.search) {
var parts = location.search.substring(1).split('&');
for (var i = 0; i < parts.length; i++) {
var nv = parts[i].split('=');
if (!nv[0]) continue;
params[nv[0]] = nv[1] || true;
}
}
var cc = params.cc;
var element = document.getElementById('select');
element.value = cc;

Javascript url modification

I have a couple of menu's that add a variable to the current link uppon click. Here is an example:
<select onChange="window.location.href+=this.value">
<option value="&numb=1">1</option>
<option value="&numb=2">2</option>
<option value="&numb=3">3</option>
</select>
<select onChange="window.location.href+=this.value">
<option value="&cord=x">x</option>
<option value="&cord=y">y</option>
<option value="&cord=z">z</option>
</select>
My problem is then, if I choose "y" 2 times, it adds "&cord=y" 2 times. Instead I want it to replace the current value from that menu. So if "&cord=x" is allready present, it would then just change it to "&cord=y" instead of adding a new variable to the link. Ofcourse, if I choose one from the &numb menu, it shouldn't replace one from the &cord menu.
Can this be done? If yes, then how?
EDIT: Here is another example. If I have the url
"www.google.com?cat=p&comp=x&type=1" and I choose "&comp=3" in my select box, It will then replace the current &comp with the new. If &comp is not set, it will just add &comp=3 (or whatever I chose) to the url.
These functions should let you parse and edit the URL parameters:
function splitObj(str, rowSplit, columnSplit) {
var obj = {};
var rows = str.split(rowSplit);
for (var i = 0; i < rows.length; i++) {
var kv = rows[i].split(columnSplit);
if (kv.length === 1) {
obj[kv[0]] = null;
} else {
obj[kv[0]] = kv[1];
}
}
return obj;
}
function joinObj(obj, rowSplit, columnSplit) {
var rows = [];
for (var name in obj) {
if (name[obj] === null) {
rows.push(name);
} else {
rows.push(name + columnSplit + obj[name]);
}
}
return rows.join(rowSplit);
}
function setUrlParam(name, value) {
var parts = window.location.href.split('?');
var urlbase = parts[0];
var params = {};
if (parts.length > 1) {
params = splitObj(parts[1], '&', '=');
}
params[encodeURIComponent(name)] = encodeURIComponent(value);
window.location.href = urlbase + '?' + joinObj(params, '&', '=');
}
function changeURL(elem) {
var kv = elem.value.slice(1).split('=');
setUrlParam(kv[0], kv[1]);
}
Then you can do:
<select id="select" onChange="changeURL(this);">
<option value="&cord=x">x</option>
<option value="&cord=y">y</option>
<option value="&cord=z">z</option>
</select>
UPDATE:
You can make it cut out the splitObj and joinObj at the cost of readability.
function setUrlParam(name, value) {
var parts = window.location.href.split('?'), params = {};
if (parts.length > 1)
parts[1].split('&').forEach(function(x){
var p = x.split('=');
params[p[0]] = (p.length > 1) ? p[1] : null;
});
params[encodeURIComponent(name)] = encodeURIComponent(value);
window.location.href = parts[0] + '?' + Object.keys(params).map(function(x){
return (params[x] === null) ? x : (x + '=' + params[x]);
}).join('&');
}
function changeURL(elem) {
var kv = elem.value.slice(1).split('=');
setUrlParam(kv[0], kv[1]);
}
You would add an if statement so that it checks if there is already a value in the window. By doing this, you would replace the value with the current one.
Change window.location.href to window.location.origin
<select onChange="window.location.href=window.location.origin+this.value">
fiddle
EDIT Go for something like this: http://jsfiddle.net/63s8eb70/5/
<select onChange="makeUrl()">
<option value="?numb=1">1</option>
<option value="?numb=2">2</option>
<option value="?numb=3">3</option>
</select>
<select id="select" onChange="makeUrl();">
<option value="&cord=x">x</option>
<option value="&cord=y">y</option>
<option value="&cord=z">z</option>
</select>
<br><br>
<div id="cu"></div>
JS
var current_Url = "";
function makeUrl() {
var base = window.location.origin;
var e = document.getElementById("select");
var val = e.options[e.selectedIndex].value;
if (current_Url === "") {
current_Url = base + val;
document.getElementById('cu').innerHTML = current_Url;
//Comment out the next line on you actual site
//document.location.href = current_Url;
}
else {
current_Url += val;
document.getElementById('cu').innerHTML = current_Url;
//Comment out the next line on you actual site
//document.location.href = current_Url;
}
}
This function takes the a parameter and a value and either adds it to the URL or updates the parameter if it already exists.
function urlQueryString(parameter, value) {
var url = window.location.href;
var regex = new RegExp("([?&])" + parameter + "=.*?(&|#|$)(.*)", "gi"),
hash;
if (regex.test(url)) {
if (typeof value !== 'undefined' && value !== null)
window.location = url.replace(regex, '$1' + parameter + "=" + value + '$2$3');
else {
hash = url.split('#');
url = hash[0].replace(regex, '$1$3').replace(/(&|\?)$/, '');
if (typeof hash[1] !== 'undefined' && hash[1] !== null)
url += '#' + hash[1];
window.location = url;
}
}
else {
if (typeof value !== 'undefined' && value !== null) {
var separator = url.indexOf('?') !== -1 ? '&' : '?';
hash = url.split('#');
url = hash[0] + separator + parameter + '=' + value;
if (typeof hash[1] !== 'undefined' && hash[1] !== null)
url += '#' + hash[1];
window.location = url;
}
else
window.location = url;
}
}
It would be wise to give your input element a name attribute indicating the name of the parameter you're trying to change so you don't repeat the numb= part and coord= part over and over. Consider something like this, which lets you parameterize the name of the query key you're trying to change:
<select name="numb" onChange="updateSearch(event)">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select name="coord" onChange="updateSearch(event)">
<option value="x">x</option>
<option value="y">y</option>
<option value="z">z</option>
</select>
That way you can make as many of these input element you'd like and use the same event handler for the onchange.
The corresponding javascript could look like this:
function updateSearch(event) {
var param = event.target.name;
var value = event.target.value;
var params = parseQuery(window.location.search);
params[param] = value;
window.location.search = buildQuery(params);
}
function parseQuery(querystring) {
if (!querystring) { return {}; }
var pairs = querystring.replace(/^\?/, '').split('&');
var params = {};
var pair;
var i;
for (i = 0; i < pairs.length; i++) {
pair = pairs[i].split('=');
params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return params;
}
function buildQuery(params) {
var pairs = [];
var key;
for (key in params) {
if (!params.hasOwnProperty(key)) { continue; }
pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
}
return pairs.join('&');
}
Some of the verbosity here is dealing with a string of serialized parameters in your URL safely and without using a lot of string manipulation. Consider those functions reusable for any instances you want to fetch or set some query parameters from the client-side.
Here's a jsFiddle: https://jsfiddle.net/8fftmwzn/20/
This implementation does not (of course) handle settings the inputs to what's already in your URL querystring. That's a separate challenge.

Categories