Couldn't find anything quite what I was looking for but if I've missed something obvious I'm sorry. I'm basically trying to have a JavaScript function check that each of a number of select boxes have unique values before the form is submitted to then be entered into a database.
There could be any number of select boxes but all follow a similar naming format in the form of:
operator_address_type_0
operator_address_type_1
operator_address_type_2
etc.
I was just wondering how a JavaScript function could be set up to loop through all of the select boxes and alert the user and stop the submitting if any are found to have the same value.
Thanks for any help.
EDIT:
Here is some simplified HTML of my current select boxes. I've had to simplify it a lot as the table that they are in is all loaded via AJAX from querying a database.
<select name="operator_address_type_0">
<option value="Main">Main</option>
<option value="Payment">Payment</option>
<option value="Poster">Poster</option>
</select>
<select name="operator_address_type_1">
<option value="Main">Main</option>
<option value="Payment">Payment</option>
<option value="Poster">Poster</option>
</select>
It is like that but there could be more options in the future, I just want to check that there is only one main address, one payment address, one poster address etc.
Something like the following?
function checkDuplicates() {
var selects = document.getElementsByTagName("select"),
i,
current,
selected = {};
for(i = 0; i < selects.length; i++){
current = selects[i].selectedIndex;
if (selected[current]) {
alert("Each address type may not be selected more than once.");
return false;
} else
selected[current] = true;
}
return true;
}
Demo: http://jsfiddle.net/GKTYE/
This loops through the selects and records the selected index of each, stopping if a duplicate is found. This assumes all the selects have the same options in the same order. To test the actual selected values:
current = selects[i].options[selects[i].selectedIndex].value;
Related
I'm trying to provide a multi-select HTML element in which the user can select one or more payment methods. I also want to prevent data loss in case the user accidentally presses back button or equivalent and then comes back. I want to offer the users the freedom to change the URL (whether it's intended or not) and after return continuing from where they left.
The below code stores the latest multi-select option value into the local storage and fills it back on page load. That was easy. But how to store multiple values like for example "credit cards" and "cash" into the local storage?
I've studied JSON stringify function but so far I couldn't make it right, so I didn't leave my failed attempts into the code. I've also studied more or less related questions on this page but couldn't make use of the short replies the experts were pointing out.
(To make it shorter I didn't include styles. For the same reason, I didn't include the form that this is a part of. If it's not totally obvious, you can select multiple values by pressing CTRL [command should work on Mac] and clicking on the options.)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
Select one or more payment methods:
<br>
<select multiple id="payment_methods" onchange="saveMultipleValues(this);">
<option value="credit"> Credit cards</option>
<option value="iban"> IBAN </option>
<option value="cash"> Cash </option>
</select>
<script>
// Passing multiselect id "payment_methods" to below function "getSavedValue" to
// check if local storage has a value for it. If value exists, selecting it on the
// payment methods list above.
document.getElementById("payment_methods").value = getSavedValue("payment_methods");
function saveMultipleValues(currentObject){
var id = currentObject.id; // get the requester's id to save it
var val = currentObject.value; // get the value
localStorage.setItem(id, val); // On user input, the local storage's value will
// override which should be fixed
}
function getSavedValue(v){
if (localStorage.getItem(v)) // if there is a value for the current HTML id...
{
return localStorage.getItem(v); // value found, returning it
}
}
</script>
</body>
</html>
this way:
<select id="payment_methods" multiple >
<option value="credit"> Credit cards</option>
<option value="iban"> IBAN </option>
<option value="cash"> Cash </option>
</select>
const payMethSelect = document.querySelector('#payment_methods');
// init
let opts = (JSON.parse( localStorage.getItem('payment_methods') || '[]' ))
Array.from( payMethSelect.options).forEach(opt =>
{
opt.selected = opts.includes(opt.value)
});
payMethSelect.onchange =_=>
{
let opts = Array.from(payMethSelect.selectedOptions).map(opt=>opt.value)
localStorage.setItem('payment_methods', JSON.stringify(opts))
}
Hi I've been modifying a script that got the data from <span id=> to instead use a <option value=> from a dropdown list and it seems to work except for always choosing the first <option value=> in the list. If i arrange the order of the html list the first currency will be what it converts to onChange.
Here is the script and html
function ChangeCurrency() { $('select').click(function () {
var cc = $(this).children('option').attr('value').substring(1);
document.cookie = 'CurrencyId=' + cc + ';path=/';
var s = location.pathname;
if (s.length > 3 && s.substring(3, 4) == '/')
s = s.substring(3);
location.pathname = s;
})};
<select onchange="ChangeCurrency()">
<option value="c1">USD</option>
<option value="c2">EUR</option>
<option value="c3">AUD</option>
etc...
</select>
I don't know what I'm doing wrong? How can I get it to actually process a user selected option from the list (and hopefully keep that option displayed so the list doesn't show USD when the currency on the store is changed to AUD for example)
EDIT:
I need to keep how this code gathers data to "build" the cookie, I don't understand enough to know what string it is putting together from the option list to name the cookie but it is important for the store currency to work. This is the code that worked but the list was a div with span id for the option value. It took me a while to get it sort of working using option values rather than span id's except for being stuck on the first option in the list.
Your code just fetches the first option, not the selected one.
Change the:
var cc = $(this).children('option').attr('value').substring(1);
to:
var cc = $(this).val();
My client has a huge list of contacts.
I created a form with a scrolling list, in order to select a contact. The issue is that the scrolling list is too long.
Is there a way (and if so, how?) for my client to start typing the first letters of a contact name, so the 'field area' (or other) fills in automatically the correspondant contact name?
Thank you in advance for your help.
Kind regards,
You can load the select with this javascript:
function updateSelect(vA)
{
var select = document.getElementById("sel1");//or whatever you select id is
select.options.length = 0;
for(var i=0;i<vA.length;i++)
{
select.options[i] = new Option(vA[i],vA[i]);
}
}
The html select element:
<select id="sel1">
<option value="" selected></option>
</select>
I often load selects when the page loads with something like this:
$(function(){
google.script.run
.withSuccessHandler(updateSelect)
.getSelectOptions();//a gs function which passes an array to updateSelect via the success handler
});
That way I can use a spreadsheet to store the values that I want. In your case you may want to filter them alphabetically perhaps. And you might want to pass the getSelectOptioptions() function or whatever you call it a parameter to determine how to filter the list.
I am automating testing of a web page in which there exists two multi select fields on a form. The one on the left contains a list of country names, the one on the right contains the ones you have selected. Countries can exist on one list but not the other. When you click a country it moves to the other list (you get the idea). When the form is submitted the values in the POST look like this (from chrome inspection):
data[Campaign][unselected_country_codes]:
data[Campaign][unselected_country_codes][]:AF
data[Campaign][unselected_country_codes][]:AX
data[Campaign][unselected_country_codes][]:AL
data[Campaign][unselected_country_codes][]:DZ
data[Campaign][unselected_country_codes][]:AS
data[Campaign][unselected_country_codes][]:AD
data[Campaign][unselected_country_codes][]:AO
data[Campaign][unselected_country_codes][]:AI
data[Campaign][unselected_country_codes][]:AG
data[Campaign][unselected_country_codes][]:AR
... (ALL countries not selected are in this list)
data[Campaign][country_codes]:
data[Campaign][country_codes][]:US
data[Campaign][country_codes][]:AQ
data[Campaign][country_codes][]:BD
... (this part contains the ones we have selected)
and here is what the HTML looks like for the select list of the countries you want included:
<select name="data[Campaign][country_codes][]" multiple="multiple" id="CampaignCountryCodes" data-quicklist-ref="CampaignCountryCodes_quick" data-alter-ref="CampaignCountryCodes_alter">
<option value="US" selected="selected">United States</option>
<option value="AQ" selected="selected">Antarctica</option>
<option value="BD" selected="selected">Bangladesh</option>
</select>
What I don't understand is, how would I set those form values at the time of testing? I don't really understand the <select> attribute of a form comes through as an array of values or what? I would like to be able to submit the form and have a list of countries that are on, and a list that are off.
Here is an example of what I do to set other values on the form that works correctly. I really have no idea how to do this for a multiple and that is the question being asked.
This example is a text area that works just great.
casper.waitForSelector(x('//*[#id="some text area"]'),
function success() {
test.assertExists(x('//*[#id="some text area"]'));
this.fill('form#campaign_form', {
'data[Campaign][some_field]': 'include',
'data[Campaign][the_field]': myvar + "\n"
}, true);
},
function fail() { ... }
);
You can move the options from one select to the other:
casper.evaluate(function(){
var values = ["US", "CA"];
var src = document.querySelector('[name="data[Campaign][unselected_country_codes][]"]');
var dest = document.querySelector('[name="data[Campaign][country_codes][]"]');
values.forEach(function(val){
dest.appendChild(src.querySelector('[value="'+ val +'"]'));
});
});
After that you probably still have to select them. Just because the options are present in the select box doesn't mean that they are sent to the server when you submit the form they are in. You need to select the values:
casper.evaluate(function(){
var values = ["US", "CA"];
var src = document.querySelector('[name="data[Campaign][unselected_country_codes][]"]');
var dest = document.querySelector('[name="data[Campaign][country_codes][]"]');
values.forEach(function(val){
dest.appendChild(src.querySelector('[value="'+ val +'"]'));
});
// select intended values
[].forEach.call(dest.options, function(opt){
if (values.indexOf(opt.value) !== -1) {
opt.selected = true;
}
});
// trigger change event to run some page JavaScript
var evt = document.createEvent("UIEvents");
evt.initUIEvent("change", true, true);
dest.dispatchEvent(evt);
});
I suspect all of this is not necessary, because you should be able to select the necessary options as seen in CasperJS/ Javascript Selecting Multiple Options and they should appear in the target select box.
I'm trying to find the best way to make my teachers' lives a little easier.
I've got a select field and list of options generated by a tlist sql query. The select field itself already has a javascript attached to it, which fleshes out other field values (credit values and credit types) elsewhere based on the id of the select option chosen. This is the javascript that works for that purpose:
<script type="text/javascript">
function changeValue(){
var option=document.getElementById('courseno').value;
if(option=="E100"){
document.getElementById('credval').value="10";
document.getElementById('credtype').value="EngFresh";
}
else if(option=="E200"){
document.getElementById('credval').value="10";
document.getElementById('credtype').value="EngSoph";
}
}
</script>
I also need to populate a hidden field that is (and must remain) outside the tlist sql tag that generates the select list.
Here is my sql code:
<select id="courseno" name="course_number" onchange="changeValue();">
<option value="">Select a Course</option>
~[tlist_sql;
SELECT cc.course_number, cc.section_number, c.COURSE_NAME
FROM cc cc
RIGHT JOIN COURSES c ON c.COURSE_NUMBER = cc.course_number
RIGHT JOIN STUDENTS s ON cc.studentid = s.id
WHERE cc.studentid = ~(curstudid)
AND TERMID = ~(curtermid)
AND c.CreditType LIKE 'English%'
AND NOT EXISTS (
SELECT * FROM storedgrades sg
WHERE sg.studentid = ~(curstudid)
AND sg.course_number = c.course_number
)
ORDER BY c.course_name;]
<option name="~(course_no)" value="~(course_no)" id="~(secno)">~(course_no).~(secno) (~(cname))</option>
[/tlist_sql]
</select></td>
</tr>
And just below that is the hidden field I would like to populate:
<td width="25%" class="bold"> </td>
<td><input type="text" id="secnum" name="section_number" value=""> </td>
I gave each of the options the section number as its ID, thinking I could use the ID element of each of those options and some clever jquery to populate the hidden field, but I'm having no luck. I just read on another question that was ably answered by the community that you shouldn't use an option ID tag that begins with a number... so now what can I do?
Could somebody please help me?
Thanks forever,
Schelly
I don't think your problem comes from the ID being a number. We haven't seen what jQuery you've tried, but you most likely don't need jQuery at all. Assuming what you have is working correctly, and the PowerSchool code is putting out elements the way you expect them to be (View Source in your browser to be sure, if this doesn't work), you should be able to grab the ID from the selected option inside your changeValue function, store it in a variable, and push that value into the "secnum" field as follows:
function changeValue(){
var courseDropdown = document.getElementById('courseno');
var selectedElement=courseDropdown.options[courseDropdown.selectedIndex];
var option=selectedElement.value;
var courseNo = selectedElement.getAttribute("id");
if(option=="E100"){
document.getElementById('credval').value="10";
document.getElementById('credtype').value="EngFresh";
}
else if(option=="E200"){
document.getElementById('credval').value="10";
document.getElementById('credtype').value="EngSoph";
}
document.getElementById('secnum').value=courseNo;
}
I changed the way that your "option" variable is being set, but it will work the same way. You might end up wanting to move the last line, where the "secnum" field is being set, or wrap it in an "if", etc.; I don't know your full requirements.
All that said, there would be nothing wrong with using jQuery in this situation, but it's not necessary in this case unless you need extreme backwards-browser compatibility.
Working Example Here
You can use multiple on change events to do whatever you want. On change add a new event and populate the hidden input. You can define custom attributes to any html element with any data that is required to populate the hidden input
<select id="myselect">
<option>Select</option>
<option data-number="1">One</option>
<option data-number="2">Two</option>
<option data-number="3">Three</option>
<option data-number="4">Four</option>
<option data-number="5">Five</option>
</select>
<input type="hidden" id="hiddenInput"/>
$(document).ready(function(){
$('#myselect').on('change', mySelectChange);
function mySelectChange(){
console.log('your standard change value here');
}
$('#myselect').on('change', mySelectChange2);
function mySelectChange2(){
var option = $("#myselect option:selected");
console.log(option.text());
console.log(option.attr('data-number'));
}});