Creating buttons from Multiple Select Value in Javascript - javascript

I am working on a website where teachers can create questions and question pages and student can log in and answer them. Now in the teacher interface, when creating the question the teacher can see how the question will appear in the student interface. For that I use javascript to get my form data and display it in real time. The problem I had was with a multiple select, it is supposed to be question labels that appear in the form of buttons in the student interface, but whenever I select more than an option, is is not only the button for the last selected option that is created, but buttons for all the selected options every new select.
$("#etiquettes").on('change', function() {
var affiche= [];
const myDiv = $("#etiquette-display");
for (var option of document.getElementById("etiquettes")) {
if (option.selected && (!affiche.includes(option.value))) {
let html = '<button class="button is-info" type="button">'+option.value+'</button>';
myDiv.append(html);
affiche.push(option.value);
}
}
});
I tried creating the affiche array and add in it every option that was selected and it's button created so that when I loop over all the selected options, the ones whose buttons were created don't get created again. But it doesn't seem to work!

You have to empty myDiv every time multiselect changes.
$("#etiquettes").on('change', function() {
var affiche= [];
const myDiv = $("#etiquette-display");
myDiv.empty();
for (var option of document.getElementById("etiquettes")) {
if (option.selected && (!affiche.includes(option.value))) {
let html = '<button class="button is-info" type="button">'+option.value+'</button>';
myDiv.append(html);
affiche.push(option.value);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="etiquettes" multiple>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<div id="etiquette-display"></div>

Related

When registering both onchange and onclick on a select, the click event is triggered twice

Goal: Have a select whose option have nested structure when user clicks on the select, but when user selects an option the option should be displayed "normally" (ie with no leading spaces).
Attempted solution using JS and Jquery: My JS is far from sophisticated so I apologize in advance :)
I attempted to use .on("change") and .on("click") to change the selected option value (by calling .trim() since I achieve the "nested" structure with ). I'm also storing the original value of the selected option because I want to revert the select menu to its original structure in case the user selects another option.
The problem: The function registered for .on("click") is called twice, thus the select value immediately resets itself to its original value.
I suspect there is a much, much easier solution using CSS. I will be happy to accept an answer that will suggest such solution.
JSFiddle: https://jsfiddle.net/dv6kky43/9/
<form>
<select id="select">
<option value=""></option>
<option value="a"> a</option>
<option value="b"> b</option>
</select>
</form>
<textarea id="output"/>
var orig;
var output = $("#output");
output.val("");
function onDeviceSelection(event){
output.val(output.val() + "\nonDeviceSelection");
var select = event.target;
orig = select.selectedOptions[0].text;
select.selectedOptions[0].text = select.selectedOptions[0].text.trim()
}
function resetDeviceSelectionText(event) {
output.val(output.val() + "\nresetDeviceSelectionText");
var select = event.target;
if (orig !== undefined){
select.selectedOptions[0].text = orig;
}
}
$("#select").on("change", onDeviceSelection);
$("#select").on("click", resetDeviceSelectionText);
If you are already using jQuery, why not utilize data function to store the original value. This way you will also be able to specify different nest levels.
(function($){
$(document).on('change', 'select', function(event) {
$(this).find('option').each(function(index, element){
var $option = $(element);
// Storing original value in html5 friendly custom attribute.
if(!$option.data('originalValue')) {
$option.data('originalValue', $option.text());
}
if($option.is(':selected')) {
$option.html($option.data('originalValue').trim());
} else {
$option.html($option.data('originalValue'));
}
})
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<select id="select">
<option value=""></option>
<option value="a"> a</option>
<option value="b"> b</option>
</select>
</form>
Once caveat I see is, the selected option will appear trimmed on the list as well, if dropdown is opened after a previous selection has been made:
Will it still work for you?
Instead of keeping the state of the selected element i would simply go over all options and add the space if that option is not selected:
function onDeviceSelection(event){
// Update textarea
output.val(output.val() + "\nonDeviceSelection");
// Higlight the selected
const {options, selectedIndex} = event.target;
for(let i = 0; i < options.length; i++)
options[i].innerHTML = (i === selectedIndex ? "":" ") + options[i].text.trim();
}
$("#select").on("change", onDeviceSelection);
Note that you need to use innerHTML to set the whitespace...

jQuery - Each loop to select all items by data attribute, but also dependent on select (option) values

I am in the process of building an e-Commerce shop and have hit a small bump in the road for my actual product page. Based on any product options set that would add to the price if selected, I would like to be able to update the price on the page live when these options have been added. I have managed to iterate through every element with a "data-price-effect" attribute attached to them, HOWEVER, when it comes to a select element, I would need to check if the item is selected as an option, each option has their respective price change attribute of course, but the value would only update to the actual select element.
Here is my code upto now:
function updatePrice(){
$('[data-price-effect]').each(function( index ) {
// do something
});
}
Basic HTML set-up to explain further:
<form>
<input type="text" name="foo" onchange="updatePrice();" data-price-effect="10.00" />
<select name="bar" onchange="updatePrice();">
<option selected value="Item1" data-price-effect="5.00">Item 1</option>
<option selected value="Item2" data-price-effect="8.00">Item 2</option>
<option selected value="Item3" data-price-effect="10.00">Item 3</option>
</select>
</form>
I have NO idea how to even logically do this, not even with some huge messy code. Any pointers here from someone more experienced with Javascript?
Instead of having "updatePrice()" on each element, you could have a listener for all form elements for the function:
var EffectElements = $('form input[data-price-effect], form select');
EffectElements.on('change', function() {
var PriceEffect = 0;
EffectElements.each(function() { // Loop through elements
if ($(this).is('select')) { //if this element is a select
$(this).children().each(function() { //Loop through the child elements (options)
if ($(this).is(':selected')) { //if this option is selected
PriceEffect += parseFloat($(this).attr('data-price-effect'));
}
});
} else {
PriceEffect += parseFloat($(this).attr('data-price-effect'));
}
});
});
You could then use the PriceEffect variable to update your price on the website.
Ultimately it's the IS function doing the dirty work you needed ~_o
Working Example

customize java script function from particular page when that method is used by many pages

I have a drop down like
<select>
<option value="">Select</option>
<option value="1">ABC</option>
<option value="2">DEF</option>
</select>
I have the same select box in more than 10 places in different pages.This is populating through ajax.But when i am calling this from a particular page i need to select ABC by default.But i don't want in remaining places.
I don't want to write the code again in my page.Is there any possibility for this.
Thanks in advance...
It's going to be a very generic answer that you'll have to modify for your needs, but if the select and all other markup is the same on all pages, which is very unlikely, you have to check the URL to see if you're on a certain page.
At the bottom of the page, before </body>, you can do something like :
if ( window.location.href.indexOf('/mysite.html') != -1 ) {
document.getElementsByTagName('select')[0].value = '1';
}
This will set the default value of the first select on the page to 1, and show ABC, if the URL contains mysite.html.
FIDDLE
Here you have another example (with JQuery) taking into account the comment you did about loading your combos with options obtained with ajax: Try if yourself
JQUERY:
var options = "<option value=\"\">Select</option><option value=\"1\">ABC</option><option value=\"2\">DEF</option>";
function test() {
// Populate select with ID destiny 1 without selecting a value
populate("#destiny1", null, options);
// Populate select with ID destiny 2, selecting the value of the first index
populate("#destiny2", 1, options);
}
function populate(destiny, indexOption, options) {
$(destiny).html(options);
if (indexOption != null) {
$(destiny + " option")[indexOption].selected = true;
$(destiny).trigger("change");
}
}
HTML:
<select id="destiny1"></select>
<select id="destiny2"></select>
<input type="button" onclick="test()" value="TEST"></input>

Removing and adding options from a group of select menus with jQuery

This is a little more complicated than the title makes it out to be, but here are the essential business rules:
There are three select menus on the
page, each filled with the same
options and values.
There will always be three select
menus.
There will always be the same number
of options/values in each select
menu.
Selecting a question in any of the
menus will remove that question as an option from
the other two menus.
Re-selecting a different question
from any of the menus will bring
back the question that was
previously removed from the other
two menus at the index it was at previously.
I've tried this a few different ways, and the thing that is killing me is number 5. I know that it wouldn't be inserted at the exact index because some questions may have already been removed, which would reorder the index. It basically needs an insertBefore or insertAfter that puts it in the same "slot".
Even if you don't post any code, some thoughts on how you might approach this would be extremely helpful. The select menus and jQuery look something like this, but I've had numerous tries at it in different variations:
jQuery:
$(function() {
$(".questions").change(function() {
var t = this;
var s = $(t).find(":selected");
// Remove, but no "insert previously selected" yet...
$(".questions").each(function(i) {
if (t != this) {
$(this).find("option[value=" + s.val() + "]").remove();
}
});
});
});
HTML:
<select name="select1" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
<select name="select2" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
<select name="select3" class="questions">
<option value="1">Please select an option...</option>
<option value="2">What is your favorite color?</option>
<option value="3">What is your pet's name?</option>
<option value="4">How old are you?</option>
</select>
Don't remove the elements, hide them. With removing, you are causing you a lot more problems than necessary. This works for me:
$(function() {
$('select.questions').change(function() {
var hidden = [];
// Get the values that should be hidden
$('select.questions').each(function() {
var val = $(this).find('option:selected').val();
if(val > 0) {
hidden.push($(this).find('option:selected').val());
}
});
// Show all options...
$('select.questions option').show().removeAttr('disabled');
// ...and hide those that should be invisible
for(var i in hidden) {
// Note the not(':selected'); we don't want to hide the option from where
// it's active. The hidden option should also be disabled to prevent it
// from submitting accidentally (just in case).
$('select.questions option[value='+hidden[i]+']')
.not(':selected')
.hide()
.attr('disabled', 'disabled');
}
});
});
I made a small change to your HTML also, I denoted an option that should always be visible with a value of 0. So the valid options go from 1 to 3.
Here's a working example, tell me if I misunderstood you:
http://www.ulmanen.fi/stuff/selecthide.php
I was working on a solution of this recently and modified this code to remove rather than disable/hide. For my solution it was required (I'm also using UI to style the select elements). Here's how I did it:
// Copy an existing select element
var cloned = $('select[name="select1"]').clone();
// Each time someone changes a select
$('select.questions').live('change',function() {
// Get the current values, then reset the selects to their original state
var hidden[];
$('select.questions').each(function() {
hidden.push($(this).val());
$(this).html(cloned.html());
});
// Look through the selects
for (var i in hidden) {
$('select.questions').each(function() {
// If this is not the current select
if ((parseInt(i)) != $(this).parent().index()) {
// Remove the ones that were selected elsewhere
$(this).find('option[value="'+hidden[i]+'"]').not('option[value="0"]').remove();
} else {
// Otherwise, just select the right one
$(this).find('option[value="'+hidden[i]+'"]').not('option[value="0"]').attr('selected','selected');
}
});
}
});

Enabling and disabling fields

I have a form that has two drop down fields lets say A is one and B is another. I want the drop down box B to be disabled until one of the value in the drop down A is selected .
How should I write a Java script?
Use the onchange event of dropdown A to check it's value and change the disabled property of dropdown B:
document.getElementById("dropdown_A").onchange = function ()
{
if (this.selectedIndex == 2) // if the 3rd option is selected
document.getElementById("dropdown_B").disabled = true;
}
Note this code needs to run after the dropdown A element (or the entire document) has been parsed.
For your dropdown_b, make the disabled property = "disabled"
for your dropdown_a, make the onchange to a function that will change dropdown_b's disabled property.
<html>
<head>
window.onload = function()
{
dda = document.getElementById("dropdown_A");
ddb = document.getElementById("dropdown_b");
dda.onchange = function()
{
if(dda.options[dda.selectedIndex] != "")
ddb.disabled = "";
};
}
</head>
<body>
<select id="dropdown_A">
<option value="" selected="selected"></option>
<option value="asdf">asdf</option>
<option value="12345">12345</option>
</select>
<select id="dropdown_B">
..
</select>
</body>
</html>
Basically, until the user selects an actual option nothing will happen... so the blank option [""] won't deselect the other select.

Categories

Resources