How to append select options after detaching them using jQuery - html

I'm having trouble trying to figure out how to append select options after detaching them based on the value of the initial select option of a form.
Here's the HTML for my form:
<form id="booking-form" action="#" method="post">
<legend class="bold">Bookings</legend>
<div class="input clearfix required">
<label for="cinema">Cinema</label>
<select name="cinema" id="cinema">
<option value></option>
<option value="maxima">Cinema Maxima</option>
<option value="rivola">Cinema Rivola</option>
</select>
<div class="error">
<p>Please select a cinema</p>
</div>
</div>
<div class="input clearfix required">
<label for="day">Day</label>
<select name="day" id="day">
<option value></option>
<option value="monday">Monday</option>
<option value="tuesday">Tuesday</option>
<option value="wednesday">Wednesday</option>
<option value="thursday">Thursday</option>
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
<div class="error">
<p>Please select a time</p>
</div>
</div>
<div class="input clearfix required">
<label for="time">Time</label>
<select name="time" id="time">
<option value></option>
<option value="12">12pm</option>
<option value="3">3pm</option>
<option value="4">4pm</option>
<option value="6">6pm</option>
<option value="7">7pm</option>
<option value="9">9pm</option>
</select>
<div class="error">
<p>Please select a time</p>
</div>
</div>
<div class="input">
<input type="submit" value="Submit">
</div>
</form>
And here's the jQuery code I've written:
$(document).ready(function(){
// ***** Begin Booking Form Manipulation ***** //
// If Cinema Maxima is selected, remove Cinema Rivola time options
$('#cinema').change(function() {
if( $('#cinema').val() == 'maxima') {
$('#time option[value="12"]').detach();
$('#time option[value="4"]').detach();
$('#time option[value="7"]').detach();
}
// Else, remove Cinema Maxima time options
else {
$('#time option[value="3"]').detach();
$('#time option[value="6"]').detach();
$('#time option[value="9"]').detach();
}
});
// If Cinema Maxima is selected but weekend session is not selected, remove 3pm time option
$('#day').change(function() {
if( $('#cinema').val() == 'maxima' && $('#day').val() != 'saturday' || 'sunday') {
$('#time option[value="3"]').detach();
}
});
});
// ***** End Booking Form Manipulation ***** //
I'm not sure I've I'm approaching this the best way after having spent the last few hours trawling through stackoverflow, but I can't seem to find a solution! Any advice for a beginner would be greatly appreciated!
I've upload my code to jsfiddle here: http://jsfiddle.net/nness/L9v6ejvt/
Wouldn't you know it - .show() and .hide() seem to work perfectly on my PC when using Chrome! Is anyone else using Chrome on Mac?.. If so, any thoughts as to why it's playing up? The saddest part is had I been using the PC from the get-go this would have saved me the best part of a day! Thanks for all your suggestions guys, all very much appreciated!

If you can add the corresponding classes for the select as follows:
<select name="time" id="time">
<option value></option>
<option value="12" class="rivola">12pm</option>
<option value="3" class="maxima">3pm</option>
<option value="4" class="rivola">4pm</option>
<option value="6" class="maxima">6pm</option>
<option value="7" class="rivola">7pm</option>
<option value="9" class="maxima">9pm</option>
</select>
You can simply hide and show them like
$(document).ready(function () {
$('#cinema').on('change', function (ev) {
$('#time option').hide();
$("."+this.value).show();
});
});
Updated Fiddle
Side note: unnecessary DOM manipulation is really bad...

You can set custom HTML attributes and then use jQuery
<option value="maxima" exceptitems="12,9">Cinema Maxima</option>
JQuery
$(document).ready(function(){
$('#cinema').on('change', function(ev) {
$('#time option').show();
var opt=$("option:selected", this);
var exceptItems=opt.attr('exceptitems');
if(exceptItems)
{
var items=exceptItems.split(",");
for (i = 0; i < items.length; i++) {
$('#time option[value="'+items[i]+'"]').hide();
}
}
});
});
DEMO1
Update 1:
I have nice solution
<option value="maxima" data-command="$('#time option[value=12]').hide()">Cinema Maxima</option>
JQuery
$(document).ready(function(){
$('#cinema').on('change', function(ev) {
var opt=$("option:selected", this);
var strCommand=opt.data("command");
eval(strCommand);
});
});
DEMO2
Update 2: For easy management
$.fn.extend({
executeCommand: function() {
return this.on('change', function(ev) {
var opt=$("option:selected", this);
var strCommand=opt.data("command");
eval(strCommand);
});
}
});
$('#cinema').executeCommand();
DEMO3

Related

JQUERY - Custom HTML Option Data for IF Statement for Chained Selection

edit: see "Edit" Section for updated question
I am trying to make the second dropdown selection dependent of the first, using jquery.
get "data-type" of first selection
if "data-type" == "String" trigger filter change of second selections "data-foo" containing value N
HTML Selections
<select id="first" name="first-selection" class="form-control">
<option value="a" class="b" data-type="c">a</option>
</select>
<select id="second" name="second" class="form-control">
<option value="n" data-foo="m">n</option>
</select>
I used to following code to check if I am able to get the "data-type" value and display it. But any attempt to get the data for an if statement failed so far.
$('#first').change(function () {
var selected = $(this).find('option:selected');
$('#type').html(selected.data('type'));
}).change();
edit - code with if statement
how do I use "data-type" for an if statement?
EDIT
New code and jsfiddle to make myself clear
<select id="first" name="first-selection" class="form-control">
<option value="1" class="type1" data-type="snowboot">bli</option>
<option value="2" class="type2" data-type="nose">bla</option>
<option value="3" class="type3" data-type="head">blu</option>
</select>
<p>Test output: <span id="type"></span>.</p>
<select id="second" name="second-selection" class="form-control">
<option value="11" data-foo="green">one of three</option>
<option value="22" data-foo="red">two of three</option>
<option value="33" data-foo="red">three of three</option>
</select>
$(function(){
$('#first').change(function(){
var selected = $(this).find('option:selected');
$('#type').html(selected.data('type'));
}).change();
});
Question
How do I use "data-type" and put it as an if statement before the function? The following won't do anything
if ($('select[id=first] option').filter(':selected').type() == "nose")
if(selected.data('type') == "nose")
var myvar = $('#first option:selected').data();
if(myvar == 'nose')
This is the code I want to run after the if statement:
var $firstvar= $("#first");
$secondvar= $("#second");
$options = $secondvar.find('option')
$firstvar.on('change', function () {
$secondvar.html($options.filter('[data-foo="' + 'red' + '"]'));
}).trigger('change');
This will do what you want. It will check, whether the selected option of the first select was of any of the types mentioned in the object conditions and will then go through all options of the second select and either show or hide them (using the jQuery .toggle(.toggle(!isNose||this.dataset.foo==="red")) method). The expression show=!found||this.dataset.foo===found will evaluate to true for all cases where found is undefined and to false only if found is "trueish" AND this.dataset.foo===found is false.
$(function() {
const conditions={nose:"red",head:"green"}; // add as many as you like ...
$('#first').change(function() {
let show,first=true; // first makes sure only ONE option can be set
const found=conditions[ $(this).find(":selected").data("type") ];
$('#second option').each(function(){
$(this).toggle(show=!found||this.dataset.foo===found);
if(first&&show) first=!(this.selected=true); // select first visible option
})
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="first" name="first-selection" class="form-control">
<option value="1" class="type1" data-type="snowboot">bli</option>
<option value="2" class="type2" data-type="nose">bla</option>
<option value="3" class="type3" data-type="head">blu</option>
</select>
<p>Test output: <span id="type"></span>.</p>
<select id="second" name="second-selection" class="form-control">
<option value="11" data-foo="green">one of three</option>
<option value="22" data-foo="red">two of three</option>
<option value="33" data-foo="red">three of three</option>
</select>

Dropdown list with others option which allows us to add value manually

I need a Dropdown list with others option which allows us to add value manually if the user's field is not in a dropdown list. is it possible?
Thanks in advance,
Balaji
Even though it is a duplicated question, let me give you a direct method using plain JavaScript and HTML. Check and let me know
function myFunction() {
var x = document.getElementById("mySelect").value;
var input = document.getElementById("others-text");
if (x === "others") {
input.style.display = "block";
} else {
input.style.display = "none";
}
}
<div>
<select name="select" id="mySelect" onchange="myFunction()">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="others">Others</option>
</select>
<input
style="display: none"
type="text"
name=""
id="others-text"
placeholder="User Input"
/>
</div>

Using HTML5 form validation, can I make an input field required only if a specific <option> from a <select> menu is selected?

Here's a simple form I have:
<form name="form_1">
<fieldset>
<select required name="choice">
<option value="1">Choice 1</option>
<option value="2">Choice 2</option>
<option value="Other">Other</option>
</select>
<label for="other_text">If other, please specify: </label>
<input id="other_text" name="other_text" size="30">
</fieldset>
</form>
How do I make the "other_text" input field required if, and only if, the "choice" selection is set to value "Other"? By default, the input field should not be required. Could this be done with only HTML5, or is Javascript required?
Since this use case is dependent upon user interaction and selection of an appropriate menu item, it requires Javascript, and can't be achieved independently with HTML5. You may use following snippet for the requested scenario
<form name="form_1">
<fieldset>
<select required name="choice">
<option value="1">Choice 1</option>
<option value="2">Choice 2</option>
<option value="Other">Other</option>
</select>
<label for="other_text">If other, please specify: </label>
<input id="other_text" name="other_text" size="30">
</fieldset>
</form>
<script type="text/javascript">
var form = document.getElementsByTagName('form')[0];
form.onsubmit = function(e) {
if (document.getElementsByTagName('select')[0].value == "Other") {
e.preventDefault();
// Block submitting form if option = Other selected
document.getElementById('other_text').setAttribute('required', true);
return false;
}
// Allow form submit otherwise
document.getElementById('other_text').removeAttribute('required');
console.log("Submitting form", e);
return true;
}
</script>
I believe that you must use a scripting language like javascript for this. Give your select field an ID and call your javascript funciton
<form name="form_1">
<fieldset>
<select required name="choice" id="choice" onchange="changeAttribute()">
<option value="1">Choice 1</option>
<option value="2">Choice 2</option>
<option value="Other">Other</option>
</select>
<label for="other_text">If other, please specify: </label>
<input id="other_text" name="other_text" size="30">
</fieldset>
</form>
Then use javascript to manipulate the other field
function changeAttribute(){
if(document.getElementById('choice').value == "Other") {
document.getElementById('other_text').setAttribute("required","");
}else{
document.getElementById('other_text').removeAttribute("required","");
}
}

Submit form with 2 select fields to go to different pages

I run a joomla site and would like to create an html form within an article that does the following:
<form action="compare.html" method="post">
<select id="select1" name="select1" required="">
<option value="A">OptionA</option>
<option value="B">OptionB</option>
<option value="C">OptionC</option>
</select>
<select id="select2" name="select2" required="">
<option value="1">Option1</option>
<option value="2">Option2</option>
<option value="3">Option3</option>
</select>
<input id="submit" type="submit" />
</form>
After selecting from the 2 dropdowns and submitting the form, the user should go to a page based on the selected options. E.g.
OptionA + Option1 --> goes to page_97.html
OptionA + Option2 --> goes to page_451.html
OptionA + Option3 --> goes to page_13.html
OptionB + Option1 --> goes to page_77.html
and so on.
I was hoping this could be done in pure html or with some simple JS (I'm a newbie to js,php)?
I came up with the following solution which works, but I am sure this could be optimized.
<select id="select1" name="select1" required="" oninput="join_names();">
<option value="">=== SELECT ===</option>
<option value="A">OptionA</option>
<option value="B">OptionB</option>
<option value="C">OptionC</option>
</select>
<br>
<select id="select2" name="select2" required="" oninput="join_names();">
<option value="">=== SELECT ===</option>
<option value="1">Option1</option>
<option value="2">Option2</option>
<option value="3">Option3</option>
</select>
<br>
<button id="compareButton" class="float-left submit-button">COMPARE</button>
<script type="text/javascript">
var urlMap = {
"default" : "/default.html",
"A1" : "/page_97.html",
"A2" : "/page_451.html",
"A3" : "/page_13.html"
"A3" : "/page_77.html"
}
function join_names() {
var input_select1 = document.getElementsByName('select1')[0].value;
var input_select2 = document.getElementsByName('select2')[0].value;
var var_select12 = concatenate(input_select1, input_select2);
var var_select12_url = getMapValue(urlMap,var_select12);
document.getElementById("compareButton").onclick = function () {
window.location.href = var_select12_url;
};
}
function concatenate(string_one, string_two) {
return string_one+string_two;
}
function getMapValue(obj, key) {
if (obj.hasOwnProperty(key)) {
return obj[key];
} else {
return obj['default'];
}
}
</script>

Chrome Select List Style Behavior Filtering Select List Options

In Chrome these do not behave as expected, the style options doesn't work if a size attribute is used. How can I make this work?
<select size=2>
<option>1</option>
<option selected>2</option>
<option style="display: none;">3</option>
<option>4</option>
</select>
<br/>
<select>
<option>1</option>
<option selected>2</option>
<option style="display: none;">3</option>
<option>4</option>
</select>
http://jsfiddle.net/D9X9U/1/
My end game here is to have a search box that filters a select list of some kind.
I ended up using a hidden select list and moving elements between the two. If someone finds this and can improve this please do so, I will mark yours as the answer. I'm more or less fumbling my way through javascript and jquery so I'm sure a lot can be done to make this better.
http://jsfiddle.net/x6cfF/1/
Edit: anyone who finds this looking for a solution, there is a better one here https://codereview.stackexchange.com/questions/23706/better-way-to-filter-select-list/23710?noredirect=1#23710
<input type="search" id="SearchBox" />
<br />
<div class="scrollable" id="CustomerSelectDiv">
<select size=2 class="scrollableinside" id="CustomerSelect">
<option value=100>test</option>
<option value=101>test1</option>
<option value=102>test2</option>
<option value=103>test3</option>
</select>
</div>
<div style="display: none;">
<select id="CustomerSelectHidden"></select>
</div>
<script type="text/javascript">
window.onload=function() {
var $options = $('#CustomerSelect option');
document.getElementById("SearchBox").onkeyup = function () {
var $HiddenOptions = $('#CustomerSelectHidden option');
$HiddenOptions.each(function (index, value) {
document.getElementById('CustomerSelect').appendChild(this);
});
var search = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
var element = $options.filter(function () {
var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
return !~text.indexOf(search);
}).appendTo(document.getElementById('CustomerSelectHidden'));
}
}
</script>