I am trying to populate a form option value if it's attribute quantity equals zero.
My goal is to add the a message to the current option value
My html is:
<select class="valid">
<option disabled="disabled" selected="selected" value="">Select Bar</option>
<option value="1" quantity="99">value 1 </option>
<option value="2" quantity="0">value 2 </option>
</select>
So far I've tried the following in jQuery but it's not working:
if($(this).attr('quantity') == '0') {
$(this).append('<span>message</span>');
}
If you don't care about preserving the original message, than you can simply say $(this).text("message"). Leave out the <span> since it cannot be rendered inside of an <option> element anyway.
if($(this).attr('quantity') == '0') {
$(this).text('message');
}
If you want to preserve the original message, you have a couple options. One would simply be to append the new message to the original, however, it may get tricky to remove it later, so I would suggest having some sort of delimiter so you can easily identify the original vs the appended message, like so:
var $option = $(this);
if($option.attr('quantity') == '0') {
$option.text($option.text().trim() + ' (message)');
}
Then, to remove the message, you can do something like this:
$option.text($option.text().slice(0, $option.text().indexOf('(')).trim());
You can populate the option with like this,
$(document).ready(function () {
$('.valid').on('change', function () {
if ($(this.options[this.selectedIndex]).attr('quantity') == 0) {
$(this.options[this.selectedIndex]).find('span').remove();
$(this.options[this.selectedIndex]).append('<span>Message</span>')
}
});
});
JSFIDDLE
I'm not entirely sure of what you're trying to achieve from your question, but you cannot add html elements to an option element. You can however change the text as follows:
$(document).on('change', '.valid', function(){
var selected = $('.valid > option:selected');
if(selected.attr('quantity') == '0'){
selected.text('something else');
}
});
if you wanted to append an error you could do so by using jQuery append() or concatenating with the original value. Alternatively if you wanted it as validation outside of the select box, you could simply assign to the value of a div by replacing the line inside of the if statement.
<select class="valid" onchange="quality(this.options[this.selectedIndex].getAttribute('quantity'));">
<option disabled="disabled" selected="selected" value="">Select Bar</option>
<option value="1" quantity="99">value 1 </option>
<option value="2" quantity="0">value 2 </option>
</select>
<span id="msg"></span>
<script type="text/javascript">
function quality(val) {
if(parseInt(val) == 0){
document.getElementById("msg").innerHTML = "Message";
}
}
Related
I have an HTML pulldown menu along with a text element that allows users to add new options to the menu. I'd like to make sure that every option that is added is unique. The following two lines were the first option I thought of that worked (option value = innHTML for all of the options). I'm wondering if there's a more elegant solution to this -- the second line just seems clunky. It also doesn't handle spaces in the new_name string.
var new_name = document.getElementById("preset_name").value
var unique_name = $("option[value="+new_name+"]").length === 0 ? true : false
Do you need something like this?
HTML:
<select id="myselect">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<input id="newoption" type="text" />
<button id="check">Check</button>
jQuery:
$(document).ready(function() {
$("button#check").click(function() {
var newOpt = $("input#newoption").val();
$("#myselect option").each(function(){
var text = $(this).val();
if(newOpt.length>0 && text.indexOf(newOpt)!=-1){
console.log("already present!");
}
});
});
});
jsfiddle
Combining the two comments on the question, you could streamline down to 1 line:
var unique_name = $("option[value="+$("#preset_name").val()+"]").length === 0;
You don't need the ternary, as the === results in a true or false value. Unless you need the test value again, you don't even need to store it in a variable - you can just retrieve it with jQuery.
I have a dropdown <select> element to select states from the list of 50 states, I select the 1st value, save it, and show the value in DOM. I changed and select to the 5th value, saving it shows the value updates in DOM. Now back i am selecting the 2nd Value, and saving it. It's not saving the value in DOM and it's showing the previous selected 5th value. I Checked with different values, and found that, after selecting any higher index value, selecting back, lower values are not affecting in DOM, and hence i am not getting the correct values in POST.
This is the function i am calling on change.
function updateDOM(inputField) {
var elementId = inputField;
if (inputField.type == "select-one") {
var prev_select = inputField.selectedIndex;
$('#'+inputField.id+' option').each(
function() {
$(this).removeAttr('selected');
}
);
document.getElementById(elementId.id).selectedIndex = prev_select;
if (browserVersion == 9) {
document.getElementById(elementId.id)
.options[prev_select].setAttribute("selected","selected");
}
else {
document.getElementById(elementId.id)
.options[prev_select].setAttribute("selected","selected");
}
document.getElementById(elementId.id).value
= document.getElementById(elementId.id).options[prev_select].value;
}
The HTML
<select id="abc" name="abc" onchange="javascript:updateDOM(this);" class="required" >
<option name="" value="" title="null" selected ></option>
<option name="AK" value="Alaska" title="null" >Alaska</option>
<option name="AL" value="Alabama" title="null" >Alabama</option>
<option name="AR" value="Arkansas" title="null" >Arkansas</option>
<option name="AZ" value="Arizona" title="null" >Arizona</option>
</select>
First of all, why don't you use ":selected" selector of jQuery, which you are using anyway? Also, why are you using jQuery only once?
I would recommend doing it in jQuery-style (sorry, I'm not quite sure what you are trying to do exactly in your code):
http://jsfiddle.net/msLXt/1/
P.S. What is the difference between these conditions?
if (browserVersion == 9) {
document.getElementById(elementId.id)
.options[prev_select].setAttribute("selected","selected");
}
else {
document.getElementById(elementId.id)
.options[prev_select].setAttribute("selected","selected");
}
I have two select boxes like so:
<select id="one">
<option value="default">Select File</option>
<option value="path/to/file1">File One</option>
<option value="path/to/file2">File Two</option>
<option value="path/to/file3">File Three</option>
</select>
<select id="two">
<option value="default">Select File</option>
<option value="path/to/file4">File Four</option>
<option value="path/to/file5">File Five</option>
<option value="path/to/file6">File Six</option>
</select>
<p class="button_image">
<a onclick="download(document.getElementById("one").value)"></a>
</p>
Here is my download function:
function download(file) {
if (file == 'default') return;
window.location = 'http://www.mysite.com/download/' + file;
}
This works fine for one select box, but I can't seem to figure out how to use the same button image. Oh yah, the p.class=button_image has background image that is a button with hover effects.
The reason I want these select boxes to be separate is because they each represent a group of files, eg, 32-bit versus 64-bit. So they cannot be combined, because it won't flow with the page design.
I've tried some if/else blocks in PHP using the getElementById but I'm getting stuck. This is what I tried and it seems to only partially work:
<?php
if ('document.getElementById(\"one\")' == 'one') {
echo "<a onclick='download(document.getElementById(\"one\").value)'></a>";
}
else if ('document.getElementById(\"two\")' == 'two') {
echo "<a onclick='download(document.getElementById(\"one\").value)'></a>";
}
?>
I should note that I don't necessarily need to use PHP in this case to solve this problem. It was just an option I tried because I'm using PHP for the server-side programming. I could be happy with any number of options, so long as they work.
Thanks.
** EDIT **
This design might be flawed. But the intention is that either a file from box one is downloaded OR a file from box two is downloaded. If one selection is made, then the other should be rest to default and vice versa. This is what I'm working on now.
** EDIT **
I ended up goign with Dawson Loudon's answer for one part and I created another function based on Barmar's comment that looks like this:
// resets other select box when selected
function reset_index(id) {
document.getElementById(id).selectedIndex = 'default';
}
An A element as a button doesn't seem appropriate, just use an img.
Anyhow, a function to use the first select with a selected option other than the first can be something like:
function getPath() {
var select;
var args = arguments;
for (var i=0, iLen=args.length; i<iLen; i++) {
select = document.getElementById(arg[i]);
if (select && select.selectedIndex > 0) {
window.location = 'http://www.mysite.com/download/' + select.value;
}
}
}
The above expects the first option to be the default selected, so if it's selected, or no option at all is selected, the select's selectedIndex will be 0 or -1 respsectively. I would ensure one option is selected by adding the selected attribute to the first one:
<option value="default" selected>Select File</option>
and the call is:
<img src="buttonImage.jpg" onclick="download('one', 'two');">
though you might want to add a class to the select elements and get them using getElementsByClassName or similar and loop over that collection, rather than hard code the ids.
Try replacing this:
<p class="button_image">
<a onclick="download(document.getElementById('one').value)"></a>
</p>
with:
<p class="button_image">
<a onclick="download(document.getElementById('one').value, document.getElementById('two').value)"></a>
</p>
and then replace your download function with this:
function download(file1,file2) {
if (file1 == 'default' && file2 == 'default'){
return;
}
else if(file1 != 'default'){
window.location = 'http://www.mysite.com/download/' + file1;
}
else{
window.location = 'http://www.mysite.com/download/' + file2;
}
}
I have universal code to remove spaces at the beginning and at the end of field value:
var fieldValue = $('#'+fieldName).val().replace(/\s+$/g, '');
But in case <select multiple="multiple" field is passed, it fails.
Can I have universal code to bypass such fields?
Given a select multiple, the val() method will return an array (unless no items are selected, in which case it will return null), not a string.
If you want to strip the whitespace from the values, you will have to loop over the array (possibly using each, or jQuery's map) and apply your regular expression to each value in turn.
val
In the case of elements, the .val() method returns an array containing each selected option; if no option is selected, it returns null.
$('#'+fieldName).val() on <select multiple> returns array
You could use
var value = $.map( $('#'+fieldName).val(), function (opt) {
return $.trim(opt);
} );
If you want to change both the value and the inner text of all options, regardless of whether they are selected or not:
<select id="mySelect" multiple="multiple">
<option name="1" value="Test 1 ">Test 1 </option>
<option name="2" value=" Test 2"> Test 2</option>
<option name="3" value=" Test 3 "> Test 3 </option>
</select>
<script type="text/javascript">
// Iterate through the individual option elements
$("#mySelect option").each(function () {
// "this" points to the option element encountered during the current iteration of .each()
// Trim each text node (in between the <option> and </option> tags)
// Using native JS String Object .trim()
$(this).text( $(this).text().trim() );
// Trim each value attribute
$(this).val( $(this).val().trim()) });
});
</script>
After the script is run you will get the following HTML, ensuring that all data whether selected or not will be trimmed as desired before form submission/Ajax request:
<select id="mySelect" multiple="multiple">
<option name="1" value="Test 1">Test 1</option>
<option name="2" value="Test 2">Test 2</option>
<option name="3" value="Test 3">Test 3</option>
</select>
To make this universal, you could add a check to see if the element is a select element (and then do the .each() method above) or default to the more simple method of trimming a single element's text or value fields.
function trimInputs(fieldId) {
var el = $('#' + fieldId);
if (el.prop('tagName') === 'SELECT') {
$('#' + fieldId + ' option').each(function () {
$(this).val( $(this).val().trim()) });
$(this).text( $(this).text().trim() );
});
} else {
el.val( el.val().trim() );
el.text( el.text().trim() );
}
}
I'm trying to change the innerHTML of a element based on the value of the previous element.
I have the javascript correctly grabbing the current value and everything works correctly in Firefox, Safari, Chrome and Opera. IE is a pain.
sample code:
<form action="soap.php" method="post">
<select name="circuitproduct" id="circuitproduct" onchange="bandwidthfunction();">
<option>Dedicated Voice</option>
<option>Frame Relay</option>
<option>ATM</option>
<option>Dedicated Internet</option>
<option>IP Solutions Private Port</option>
<option>IP Solutions Enhanced Port</option>
<option>Private Line – Domestic</option>
<option>Int’l Private Line</option>
<option>Qwest Metro Private Line (QMPL)</option>
<option>Qwest Metro Ethernet Private Line (QMEPL)</option>
</select><br />
<select name="term" id="term">
<option value="1-Year">1-Year</option>
<option value="2-Year">2-Year</option>
<option value="3-Year">3-Year</option>
</select>
<select id="bandwidth">
</select>
<select id="sublooptype">
</select>
</form>
sample javascript:
function bandwidthfunction() {
var product = document.getElementById('circuitproduct').value;
if (product == 'Dedicated Voice') {
document.getElementById('bandwidth').innerHTML = ('<option value="DS-1">DS-1</option><option value="DS-3">DS-3</option><option value="OC-3">OC-3</option><option value="OC-12">OC-12</option>');
document.getElementById('sublooptype').innerHTML = ('<option value="Special Access">Special Access</option><option>CO MtPt - Special Access</option><option>CPA Special Access</option>');
}
else if (product == 'Frame Relay') {
document.getElementById('bandwidth').innerHTML = ('<option value="DS-1">DS-1</option><option value="DS-3">DS-3</option><option value="OC-3">OC-3</option><option value="OC-12">OC-12</option>');
document.getElementById('sublooptype').innerHTML = ('<option value="Special Access">Special Access</option><option>CO MtPt - Special Access</option><option>CPA Special Access</option>');
}
Well, first of all you have a closing tag for the select that you try to put inside the select element, which makes the code invalid.
Then there might be a problem with how the select element treats it's content. When the HTML code is parsed, the select element doesn't have any child elements, like a regular element does. Instead the options are items in it's options collection.
If you want to change the items in the select element, change the content of it's option collection. I.e. to add items, create option objects using the document.createElement method and add to the collection. Example:
var opt = document.createElement('OPTION');
opt.text = 'Choose me';
opt.value = 42;
document.getElementById('bandwidth').options.add(opt);
You have to remove the "select"-Element and the end of setting the innerHTML-Property. This is not a part of innerHTML. Its the end-tag of the element 'bandwith' itself.
document.getElementById('bandwidth').innerHTML = ('<option value="DS-1">DS-1</option><option value="DS-3">DS-3</option><option value="OC-3">OC-3</option><option value="OC-12">OC-12</option>');
Here's a handy hack I came across that works in both FF and IE as a workaround to the inability to change innerHTML on select elements.
document.getElementById('bandwidth').outerHTML = document.getElementById('bandwidth').outerHTML.replace( document.getElementById('bandwidth').innerHTML + '</select>' , '<option value="DS-1">DS-1</option><option value="DS-3">DS-3</option><option value="OC-3">OC-3</option><option value="OC-12">OC-12</option>' + '</select>' );
or as a function for readability:
function swapInnerHTML(objID,newHTML) {
var el=document.getElementById(objID);
el.outerHTML=el.outerHTML.replace(el.innerHTML+'</select>',newHTML+'</select>');
}
I recently came across this problem with IE. I came up with a turnkey solution that works with the following things in mind:
You don't want to use jQuery
Need it to work in IE < 9
You want to append ( not replace the existing options ) string options into an existing select element
The select must be a type of "select-one"
Must wrap selects in their own parent element
We have many landing pages requesting the same information (age, products, country, state etc... ) but with different select options. The implementation I use appends new select options. This was done to allow a custom default option per lading page. One page may have the first option as "select item" another may have "choose one" and so forth.
Select format:
<div> <!-- you MUST wrap the select in a tag without any siblings -->
<select name="age" id="form-age">
<option value="">Choose Age</option>
</select>
</div> <!-- you MUST wrap the select in a tag without any siblings -->
Here is the function to APPEND/ADD values:
function addOptions(el, options){
// checks to make sure element exists and is a select
if(el && el.type === "select-one"){
el.innerHTML = el.innerHTML + options;
el.parentNode.innerHTML = el.outerHTML; // needed for IE
}
}
Now to execute the function pass in the select object and string values:
addOptions(
document.getElementById("form-age"),
'<option value="1">18-25</option><option value="2">26-35</option><option value="3">36-45</option><option value="4">46-55</option><option value="5">56-65</option><option value="6">66-75</option><option value="7">76-85</option><option value="8">86+</option>'
);
This will generate a select with the options passed, even in IE!
<div> <!-- you MUST wrap the select in a tag without any siblings -->
<select name="age" id="form-age">
<option value="">Choose Age</option>
<option value="1">18-25</option><option value="2">26-35</option><option value="3">36-45</option><option value="4">46-55</option><option value="5">56-65</option><option value="6">66-75</option><option value="7">76-85</option><option value="8">86+</option>
</select>
</div> <!-- you MUST wrap the select in a tag without any siblings -->
If you needed the script to REPLACE the values use the following:
function replaceOptions(el, options){
if(el && el.type === "select-one"){
el.innerHTML = options;
el.parentNode.innerHTML = el.outerHTML; // needed for IE
}
}
I hope this helps someone else!
A quick search shows this has been a known bug in IE since at least IE5. You could try to use createElement and make options and append to the select object, or use a library like jQuery and append the html to the node (which must take care of the magic necessary to work in IE).
The real cause of the problem is that due to a DOM parsing/updating problem, IE will not insert child option elements into a select element. Even IE9 still has this problem (later versions not checked).
You have to put the select in a div or span and replace the whole select. Below you will find an example that shows that then IE will play ball as well. Because this innerHTML problem generally occurs when dynamically generating selects, I made an AJAX & PHP example.
The html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chain(ed) select with AJAX and PHP</title>
<style>
select {
min-width: 170px;
}
option.toSelect {
background: yellow;
}
</style>
</head>
<body>
<form action="whatever.php">
<span>
<select id="cities" onchange="getOptions(this.value,'airlinesContainer')">
<option value="">Select a city:</option>
<option value="boston_airlines">Boston</option>
<option value="chicago_airlines" class="toSelect">Chicago</option>
<option value="newyork_airlines">New York</option>
</select>
</span>
<span id="airlinesContainer">
<select>
</select>
</span>
<span id="classesContainer">
<select>
</select>
</span>
</form>
<script>
function getOptions(qValue,containerId) {
var ajaxRequest = new XMLHttpRequest();
if ((qValue == "") || (containerId == "")) {
alert('Invalid selection.');
return;
}
ajaxRequest.onreadystatechange = function() {
if ((ajaxRequest.readyState == 4) && (ajaxRequest.status == 200)) {
document.getElementById(containerId).innerHTML = ajaxRequest.responseText;
}
}
ajaxRequest.open("GET","getoptions.php?q="+qValue,true);
ajaxRequest.send();
}
</script>
</body>
</html>
.
And the php file, which should be named 'getoptions.php' and should be put in the same folder:
<?php
$q = $_GET['q'];
$chicago_airlines ='
<select id="airlines" onchange="getOptions(this.value,\'classesContainer\')">
<option value="">Select an airline:</option>
<option value="delta_classes">Delta</option>
<option value="klm_classes" class="toSelect">KLM</option>
<option value="united_classes">United Airlines</option>
</select>';
$klm_classes ='
<select id="classes">
<option value="business">World Business Class</option>
<option value="comfort">Economy Comfort</option>
<option value="economy">Economy</option>
</select>';
if ($q == 'chicago_airlines') {
echo $chicago_airlines;
}
elseif ($q == 'klm_classes') {
echo $klm_classes;
}
else {
echo '<select>
<option>Invalid selection</option>
</select>';
}
?>
.
Be sure to select only the options with a yellow background, in this demo.
use Jquery
$('#bandwidth').html('<option value="DS-1">DS-1</option><option value="DS-3">DS-3</option><option value="OC-3">OC-3</option><option value="OC-12">OC-12</option>');