Data and HTML Dropdown - javascript

So I'm trying to populate a HTML dropdown using Javascript/Jquery. I'd like each <option> tag to have some data associated with it, stuff like searchPurpose, searchTime, startDate, endDate. I then have two questions-
How should I associate that data - through data tags, or through something else?
How do I access that data once my user has clicked on a certain option?
Thanks

With HTML5, data-* attributes are definitely the way to go. Suppose you have the following:
<select id="ddl">
<option data-start-date="25-08-2012" value="1">A</option>
<option data-start-date="25-08-2013" value="1">B</option>
</select>
To access their value with plain JavaScript use:
selectedOption.getAttribute("data-start-date");
With jQuery use data():
$("#ddl").on('change', function () {
var selectedOption = this.options[this.selectedIndex];
alert($(selectedOption).data("start-date"));
});
DEMO.
DEMO (jQuery).

Are you using jQuery? If so, you may want to use the built-in data module.
If not, use data tags. I suggest putting all the data in one data tag.
i.e.
data="searchPurpose: thing, searchTime: sometime"
and separating it like this:
function data(elem) {
var data = {};
var a = elem.getAttribute('data').split(',');
var i = 0;
while(i < a.length){
data[a[i].split(':')[0]] = a[i].split(':')[1];
i++;
}
return data;
}
So:
data() returns an object literal like this: { searchPurpose: 'thing', searchTime: 'sometime' }

There's a lot of ways to associate data with the option tags. Some ideas off of the top of my head:
Use hidden inputs: <option id="option1">Option 1</option><input type="hidden" id="option1data" value="option1 data here" />
Use data- attributes (not supported by all browsers): <option id="option1" data-searchPurpose="searchPurpose">Option 1</option>
If you're using jQuery, you can use its .data() method: $('#option1').data('searchPurpose', 'data...');
As far as accessing the data, it depends on what you're doing with your dropdowns. If they're being submitted in a form, you could use some onSubmit JavaScript to a) return false and then b) submit the form using post or get with the extra data appended.
(In the case of the hidden input solution, this JavaScript intervention would not be necessary.)
Otherwise it should be very simple using Javascript to access/modify the data.

Related

How to escape the spaces and hyphens in append function of jQuery?

I'm using jQuery append function to dynamically create dropdowns. But when I do this:
var external = "External - Customer view";
In append function: '<option value='+internal+'>'
It is rendering it as
<option value="External" -="" customer="" view="">
I want it to render as:
<option value="External - Customer view">
Rather than setting the value that way (which you can), as you're using jQuery anyway, let it do the work for you.
let myOption = $("<option>");
myOption.val(internal);
foo.append(myOption);

Update some fields on change and on load

We have the following script which runs on a change to a drop-down - updates the price based on the currency code chosen. This basically gets the value of the drop-down and updates the priceamm and preicecurr fields within the text on the page.
<script>
function run() {
var f = document.getElementById("dropPrice");
priceamm.innerHTML = f.options[f.selectedIndex].value;
var e = document.getElementById("dropPrice");
pricecurr.innerHTML = e.options[e.selectedIndex].text;
}
HTML
<select id="dropPrice" onchange="run()" class="fa-select">
<option value = "a">aaa</option>
<option value = "b">bbb</option>
Question
Now, we would also like to load the drop-down to one of the options (selected) when loading the page (onload). We are able to populate the variables in the text but not the drop-down to show option bbb. In php this is quite easy but we are a bit lost with javascript. We tried something on these lines onload but does not work:
document.getElementById("dropPrice").value = "<?php echo $geo_price ;?>";
With jQuery this is probably easier but once again no luck:
window.onload = function() {
jQuery(document).ready(function($){
document.getElementById('dropPrice').find('option[value=<?php echo $geo_price ;?>]').attr('selected','selected');
});
}
Any help is appreciated. Thanks
The jQuery selector part is incorrect. You are mixing plain JS with jQuery. When you call document.getElementById('dropPrice') a regular DOM element is returned, but then you call find which is a jQuery method to be used on a jQuery element. So, you either need to wrap the first part to return a jQuery element like so:
$(document.getElementById('dropPrice'))
.find('option[value="b"]').attr('selected', true);
Or, select it via jQuery in the first place like:
$('#dropPrice [value="b"]');
However, your first example:
document.getElementById("dropPrice").value = "b";
should work. That makes me wonder if the value that is being echoed by PHP is correct and/or if there are other JS errors being thrown that would cause that code not to run.

hide the text inside select control

How can I hide the part of the text written inside of the option?
I've tried the following:
<select name='what'>
<option value='some value'>Value to be shown <span class='hide'>value to be hidden</span></option>
....
</select>
And here is the CSS.
.hide{ visibility : hidden; }
But it doesn't seem to work. I've also tried display:none instead of visibility:hidden but that doesn't work either.
P.S: Why I want to do this? I want to do this because I want the hidden text to be included in the search.
UPDATE I am well aware that it may be achieved using the html5 meta tags, but unfortunately that I can't use here as I am using Jquery plugin called Chosen and it doesn't support the search over meta tags.
In order to add extra data to your option, e.g. for search, you may use the value or extra attributes of the option element.
For example,
<option value="value to be hidden" data-meta="value to be hidden">Value to be shown</option>
HTML
<select>
<option value="value to be hidden1" data-meta="value to be hidden11">Value to be shown1</option>
<option value="value to be hidden2" data-meta="value to be hidden22">Value to be shown2</option>
<option value="value to be hidden3" data-meta="value to be hidden33">Value to be shown3</option>
</select>
<div class='output'></div>
JS
$(document).ready(function(){
$('select').change(function(){
$('.output').html($('select option:selected').val()+'<br/>'+
$('select option:selected').data('meta'));
});
});
http://jsfiddle.net/uHY5P/
You may introduce as many attributes as you want with the prefix "data-" and retrieve them by calling jQuery.data('yourCustomAttr')
You can't do this. <option> tag cannot contain any other tags. Use Select2
It's been a while since you posted your question but it may help someone in the future. I went through exactly the same process in the past few days.
I needed to search for select options with or without special characters using jquery Chosen plugin (ver. 1.1.0).
I have a drop down with wine producers which includes names with foreign characters like Château Bénitey. In this case free text search should find the producer with "château bénitey" and "chateau benitey" keywords.
This is how I achieved it:
I used PHP to dynamically convert special characters to their equivalents eg. "â" => "a".
I created an extra attribute in <option> tags in html called data-search-text="Château Bénitey Chateau Benitey".
Then I patched Chosen plugin to read the data-search-text value instead of option text.
In SelectParser.prototype.add_option method I added a new property to store attribute values.
this.parsed.push({
array_index: this.parsed.length,
options_index: this.options_index,
value: option.value,
text: option.text,
html: option.innerHTML,
selected: option.selected,
disabled: group_disabled === true ? group_disabled : option.disabled,
group_array_index: group_position,
classes: option.className,
style: option.style.cssText, // extra comma ;)
searchTextAttribute: option.getAttribute('data-search-text') // this is the line I added
});
Then I modified AbstractChosen.prototype.winnow_results method:
Replace:
option.search_match = this.search_string_match(option.search_text,
regex);
With:
var textToSearch = option.search_text;
if (option.searchTextAttribute) {
textToSearch = option.searchTextAttribute;
}
option.search_match = this.search_string_match(textToSearch, regex);
I have multiple dropdowns in my advanced search so only the selects that have data-search-text attribute populated will behave that way.
I also had to remove the feature that highlights matched parts of option text as it was breaking it.
if (searchText.length) {
startpos = option.search_text.search(zregex);
text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
}
Make sure you initialise the Chosen plugin with the following setting, otherwise it will search from the beginning of search only and the converted text won't be matched.
$('.your-select').chosen({search_contains: true});

javascript and <option>

I do have the following JavaScript.
<form>
<select id="sel">
<option value="1">item_1</option>
<option value="2">item_2</option>
<option value="3">item_3</option>
</select>
<div id="show"></div>
</form>
<script type="text/javascript">
var sel = document.getElementById('sel');
sel.onchange = function() {
var show = document.getElementById('show');
show.innerHTML = this.value;
};
</script>
If I click onchange a new value (here: 1,2, or 3) is shown in the div "show". This is working fine. But my problem is that I want a different value to be shown but the value (1,2, or 3) should be submitted. The item has a unit like kg, pound, m, m², ....
I want something like that:
<option value="1" value2="kg">item_1</option>
I changed value to value2 in <script> but it didn't help.
show.innerHTML = this.value2;
How can I get it to work?
if you apply what #Simon said, you can try the following:
sel.onchange = function() {
var show = document.getElementById('show');
show.innerHTML = this.options[this.selectedIndex].getAttribute('value2');
}
Revised HTML:
<form>
<select id="sel">
<option value="1" data-unit="kg">item_1</option>
<option value="2" data-unit="kph">item_2</option>
<option value="3" data-unit="m2">item_3</option>
</select>
</form>
<div id="show"></div>
The revised HTML uses the custom, and in HTML5 valid, data-* attribute to store the units. I've also moved the div out of the form, but that's an entirely personal inclination, and one that you don't have to maintain (obviously...).
Amended JavaScript:
var sel = document.getElementById('sel');
sel.onchange = function() {
var show = document.getElementById('show');
show.innerHTML = this.value + this.options[this.selectedIndex].getAttribute('data-unit');
};
JS Fiddle demo.
The JavaScript looks for the option within the this node with the selectedIndex, and then uses getAttribute() to find the string contained within the data-unit attribute and concatenates that to the this.value string.
That should probably be:
show.innerHTML = this.options[this.selectedIndex].value;
If the list is not a dynamically generated one, why don't you use an "if else" construct or a "switch" construct on the populated values and display whatever you like?
Use the value attribute for the value you want submitted to the server since value is meant to contain a string that is meant to be interpreted by a computer as part of a form.
Use a different attribute to associate human readable text with the <option>. title and longdesc would be good choices.
I would recommend using jQuery if you can. If you're expecting to be able to use html5 compliant browsers, you can use the data attributes on your <option> elements. This way you'd be able to store whatever attributes you found useful.
jQuery data attributes usage
You can use .innerHTML instead of .value if you want to display the text from the drop down. If you want something completely different to be displayed, you'll need a lookup table or something similar - might be easier to use jQuery.

How to relate data (id's) to links for JavaScript?

I'm trying to write a fairly complex dynamic web page, using JQuery AJAX, and I am struggling with how to relate my links (<a ...>) with the the data their tied to, such as action names, and data element ids. I have pondered several different schemes, but I'm not sure I like any of them.
Building it into onclick, which means I have to configure it in the link generation.
<a onlick="func('abc', 123)">...</a>
Inserting it into the id of the link, which means parsing it out in JavaScript.
<a id="link_abc_123">...</a>
Putting the link in a div with hidden input elements...
<div>
<a>...</a>
<input type="hidden" name="action" value="abc"/>
<input type="hidden" name="id" value="123"/>
</div>
Is there a best practice or a commonly accepted way of structuring this data?
Best practice should always be, to strictly separate Code.
That means, you shouldn't include any Javascript into your backend-source code. So personally I'm a big fan of either putting the necesarry data into the elements (your last example) when using a template-engine, or sending just the necesarry data on a separate request (JSON for instance) to the client.
Using jQuery, it's a very convinient way to create data- attributes, where you can store any information, while jQuery will translate the values from those attributes into the data expandos. For instance:
<div id="test" data-foo='bar' data-test='{"cool": "stuff"}'>Just a div</div>
When selecting that element with jQuery var $test = $('#test'), you can access:
$test.data('foo') // === 'bar'
$test.data('test').cool // === 'stuff'
Read more: http://api.jquery.com/data/
With HTML5, you have the luxury of using data-* attributes - for example:
...
Which jQuery actually has support for - calls to $('a').data() will include the data-* values in it.
For simple things, I use a function like:
function getIdStr(i, sDelim) {
if (typeof i != "string") {
var i = $(i).attr("id");
}
var arr = i.split(sDelim || /_|-/);
if (arr.length > 1) {
return arr[arr.length-1];
} else {
return "";
}
}
// usage
$(function(){
$(".data .action").click(function(){
doSomething(getIdStr(this)); // -> 123
});
});
For something heavier, you might try to attach a data to the topmost container.
i would go with the new Custom Data Attributes HTML5 brings along.
Just use this <a data-action="foo" data-id="bar">...</a>
Also, jQuery already has support to get these data-attributes
You can add a custom property to the input and access it in javascript.
eg
<input type="hidden" name="action" value="abc" yourproperty='<%= Eval("YourDataID") %>'/>

Categories

Resources