I have a webpage and I need to allow the user to select or de-select from predefined keywords from a list.
Something like the tags below in stackoverflow where the user can only select or de-select predefined keywords.
Also when the user returns to the site, he must be able to see his old selections and edit them at anytime.
For example maybe can have two columns like this
UNSELECT SELECTED
-------------------
A
B
C
D
E
F
G
[ --> ] select button
[ <-- ] unselect button
So there are two columns FROM and TO, then buttons allowing the user to move items back and forth between the two columns.
Doesnt have to be two columns, but any method that allows the user to only select predefined words, se-select any keyword, and can edit them later when they return to the site.
Anybody knows how to do this?
I guess you can use a library like multiSelect, and save user selection to a cookie or browser's local storage.
$('#callbacks').multiSelect({
afterSelect: function(values) {
alert("Select value: " + values);
},
afterDeselect: function(values) {
alert("Deselect value: " + values);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/multi-select/0.9.12/css/multi-select.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/multi-select/0.9.12/js/jquery.multi-select.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/multi-select/0.9.12/css/multi-select.css" rel="stylesheet" />
<select id='callbacks' multiple='multiple'>
<option value='elem_1'>elem 1</option>
<option value='elem_2'>elem 2</option>
<option value='elem_3'>elem 3</option>
<option value='elem_4'>elem 4</option>
<option value='elem_100'>elem 100</option>
</select>
jsfiddle
At a high-level, you'll basically want to maintain two lists (in JavaScript), one for everything in the first column, one for everything in the second column.
Probably a <select> with multiple will give you the UI you want. You can build this dynamically using the JavaScript you have in the lists (How to populate the options of a select element in javascript).
When they click one of the buttons to move them, with a <select> you can loop through the <option> elements it contains, see which are checked, move them to the other JavaScript list, then re-render your select elements. (How to get all selected values from <select multiple=multiple>?)
As for making them reload when users come back, there are lots of ways to do that. The most common would be to store it in a database, which would require back-end development (Node.JS, PHP, Java, etc.).
Another way would be to use either LocalStorage or cookies.
Related
I have a datalist that is created on the fly based on the user's selection from a group select menu. After the group is selected, the datalist is created. The datalist allows users to choose from a "dropdown" list or just start typing in the input box and have the list filtered accordingly. It is structured like this:
<div id="projectSelect">
<input type="text" name="ProjTitle" id="ProjTitle" placeholder="~ select project ~" list="projectList" autocomplete="off" value="">
<datalist id="projectList">
<select id="projectOptions">
<option data-projid="390" value="Project 1">Project 1</option>
<option data-projid="391" value="Project 2">Project 2</option>
<option data-projid="392" value="Project 3">Project 3</option>
</select>
</datalist>
</div>
In the default use case, the user double-clicks on the input box, a drop down appears, a project is selected (clicked) and the rest of the page (a report) is populated. This all works great.
In the alternate use case for the page, the groupid and a particular projid are passed to the page via a stored browser value.
In this case, the presence of the 'groupid' triggers the group selector just fine and the datalist element is populated just as if the user had made the group choice. All good so far.
What I'm having difficulty doing is interacting with the datalist via jquery to select the item matching the projid that is passed AND displaying the resulting title of the project in the input control. The title of each project is the "value" of each option.
From lots of other references I've found, the way to select an item in a datalist is to actually set the value of the associated input like this:
$('#ProjTitle').val("Project 1");
This doesn't work in my case, because the value being passed to the page is the projid that is in the data-projid value for each option and not the project title that is the "value" of each option.
One approach I thought of using for this was to select (using jQuery) all of the datalist options and then use $.each() to loop over the items and find the matching projid. If I could do this, I would then get the valueof that option and pass it to ('#ProjTitle').val().
However, when I use jQuery to select the options like this:
let $options = $(document).find('option');
$options is empty.
Are the options for a datalist not accessible with jQuery for some reason? in the Firefox developer tools the options are greyed out as if they are hidden. If they can not be accessed directly, how can I get the "value" of the option that matches the projid?
What other approach could I use to set the selected value of the datalist (based on the projid)?
Edit
I am suspicious that the dynamic loading of the content is in play here. The code to set the datalist is inside the $(function() { }) block of javascript so execution occurs after page load. Nonetheless, if I add console.log($('#ProjectList')); (or '#ProjectSelect') to the javascript I get the following in Firefox Developer Tools:
Normally, I'd be able to access all the nodes for the element.
I think the comments in the demo are sufficient to explain things, but feel free to ask any questions if you need a more details.
/* Assume this is the id passed to your page: */
const projid = 392
/*
Select the option element with a matching data-projid attr
and store the actual value for the selected option.
*/
const val = $(`[data-projid="${projid}"]`).val()
/*
Select the input that is a direct descendant of the
#projectSelect element and set the value for it
to the project name
*/
$('#projectSelect > input').val(val)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<div id="projectSelect">
<input type="text" name="ProjTitle" id="ProjTitle" placeholder="~ select project ~" list="projectList" autocomplete="off" value="">
<datalist id="projectList">
<select id="projectOptions">
<option data-projid="390" value="Project 1">Project 1</option>
<option data-projid="391" value="Project 2">Project 2</option>
<option data-projid="392" value="Project 3">Project 3</option>
</select>
</datalist>
</div>
Is there a way to create multiple selectbox's with same values populated using Chosen plugin or Select2.
Conditions:
All the selectbox's should have same values
Single Select for each selectbox
Options cannot be selected twice in all of the selectbox's (eg:
A,B,C.. are options, where A can be selected only once)
Option to add custom values in the selectbox, which is updated to
all selectbox's
Selected values are disabled in rest of the selectbox's
So, there are a few questions within here, I'll give a separate answer for all of them. Note that I am the maintainer of Select2, so all of my answers are for Select2. Some will apply to Chosen, but I can't guarantee it.
The full code is available at the bottom of this answer, as a complete runnable Stack Snippet. Individual snippets will be included beneath the questions when available.
All the selectbox's should have same values
This is something that you should be able to do without Select2 or Chosen, as it is all a matter of cloning the contents of one <select> to the rest of them. This can be as a simple as
$("select").html($(".main-select").html());
Which will make sure that all <select> boxes have the same options as the one with the class of main-select.
Single Select for each selectbox
Both Select2 and Chosen determine if multiple selections are allowed based on whether or not you specify the multiple attribute on your <select>. So the easy solution here is to never include it, and all of the select boxes will only allow a single selection.
Options cannot be selected twice in all of the selectbox's (eg: A,B,C.. are options, where A can be selected only once)
This one is more difficult, and the implementation will all depend on how each plugin can handle disabling options on the fly. Both plugins will trigger the change event when the value of the <select> changes, so you can detect when a new option is selected and disable it in the other <select> boxes. Both plugins determine if an option can be selected by checking the disabled property on the <option>, just like a browser would, so you will want to use that.
The trick here is to detect the value of the newly selected option and disable all other <option> elements in other <select> boxes that have that same value.
$select2.find("option:not(:selected)").filter(function () {
return this.value == val;
}).prop("disabled", true);
Note that due to a current bug in Select2, you will need to call removeData("data") on those <option> elements to clear the cached data for the element.
Option to add custom values in the selectbox, which is updated to all selectbox's
Select2 allows you to enable custom values by setting tags: true when initializing Select2. Chosen does not have the ability to add custom values, so that may be a deal breaker.
Selected values are disabled in rest of the selectbox's
This is solved when solving 3.
var $select2 = $(".select2");
// Copy the options to all selects based on the first one
$("select").html($select2.first().html());
// Initialize Select2
$select2.select2({
allowClear: true,
placeholder: "Select an option",
tags: true
});
// Handle disabling already-selected options
$select2.on("change", function () {
$select2.find("option:disabled").prop("disabled", false).removeData("data");
$select2.each(function () {
var val = $(this).val();
$select2.find("option:not(:selected)").filter(function () {
return this.value == val;
}).prop("disabled", true).removeData("data");
});
});
body { margin: 0; }
.select2 { width: 200px; }
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.js"></script>
<select class="select2">
<option></option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
</select>
<select class="select2"></select>
<select class="select2"></select>
<select class="select2"></select>
I have a set of drop down lists (8 in all). All drop downs have the same set of drop down options available to them. However the business requirement is to make sure that the user cannot select the same option more than once.
Looking at the problem, at first it appears simple but it's rapidly becoming lots of code. However it seems like a relatively common problem. Does anyone know of a solution, have any tips on how to do this without writing reams of Javascript. Some sort of reusable jquery plugin might be handy for this too. Does one exist?
One issue is that when a select item is chosen, it then becomes unavailable to the other select lists. The item is removed from the other select drop downs. When it becomes available again (a drop down changes) it needs to be inserted at the correct point in the list (the drop down options have an order). This is the bit where my solution has started to get quite complex.
Personally, the way I'd implement it is to have a "master" drop down containing all possible options, simply for the purpose of caching. These options are then replicated in each of the "slave" drop downs. Whenever any slave drop down is changed, they're all re-populated again to ensure that no two drop downs can share the same selected value.
For the purpose of demonstration, I've only worked with 3 drop down lists in the code below, but it should scale up pretty easily. Just add mode drop downs and make sure they contain the attribute class="slave".
Also, if you want any of the options to be immune from being removed, so that it's possible to exist in all of your slave drop downs (such as the default option in the code below), just add the attribute class="immune" to the option tag in the master drop down.
<script type="text/javascript">
// document - on load
$(document).ready(function() {
// initially populate all the drop downs
PopulateAllDropDowns();
// populate all drop downs on each subsequent change
$('select.slave').change(function(){
PopulateAllDropDowns();
});
});
function PopulateAllDropDowns()
{
// populate all the slave drop downs
$('select.slave').each(function(index){
PopulateDropDown($(this).attr('id'));
});
}
function PopulateDropDown(id)
{
// preserve the selected value
var selectedValue = $('#'+id).val();
// clear current contents
$('#'+id).html('');
// attempt to add each option from the master drop down
$('select#ddlTemplate').children('option').each(function(index){
// scope-safe var
var masterOptionValue = $(this).val();
// check if option is in use in another slave drop down, unless it's immune
var optionInUse = false;
if (!$(this).hasClass("immune"))
{
$('select.slave option:selected').each(function(index){
if (masterOptionValue == $(this).val() )
optionInUse = true;
});
}
// if it's not in use, add it to this slave drop down
if (!optionInUse)
{
// create new option
var newOption = $('<option></option>').val($(this).val()).html($(this).text());
// ensure selected value is preserved, if applicable
if (selectedValue == $(this).val())
newOption.attr('selected', 'selected')
// add the option
$('#'+id).append(newOption);
}
});
}
</script>
<form>
<!-- master drop down -->
<select id="ddlTemplate" class="master" style="display:none">
<option value="" class="immune">Select ...</option>
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="c">Option C</option>
<option value="d">Option D</option>
<option value="e">Option E</option>
</select>
<!-- slave drop downs -->
<select id="ddlOne" class="slave"></select>
<select id="ddlTwo" class="slave"></select>
<select id="ddlThree" class="slave"></select>
</form>
Hope that helps.
The simplest way to do what you want is binding a function in the select event from dropdown list that filter content from all other dropdowns and remove or disable the options with value already selected.
To keep the order from your list, cache the options list in array, then you can remove and add in the right position, or remove all options and re-add the current possible options.
If you want re-select the cached already chosen options, and you don't lose anything.
I'm building a recipe-finder for a new food blog. The design I have basically involves the user selecting ingredients, one at a time, from a drop down <select>, the option disappearing from the list (so they can't select it again) and appearing on another HTML list with a link to remove it from the list. Once they're done, they click a button and that takes them through to a results page.
Here's the select markup as generated by the PHP:
<select>
<option value="">Please select</option>
<option value="beef-mince">Beef mince</option>
<option value="carrots">Carrots</option>
...
</select>
It's not drastically complex but it does raise a few questions on how I'm going to do some of these things. I'm using jquery.
I need to store the selected items in memory so I know what to send to the search page when they've done selecting items. What's the best way of doing that in your opinion as each item has two values (its "real" value and its database-value)?
How do I make "Please select" the selected option after they've selected something (preferable without triggering the onchange event)?
Once I've stored it in memory and added it to the displayed list of things they're searching for, how do I delete that item from the available items? Can I just "hide" or disable it (safely)?
If in #3 I have to delete it from the DOM, when I add it again, can I sort the list (based on either value) and keep the please-select option at the top?
1.) You can append hidden form elements to the page whose value is the value of the selected option.
2.)
jQuery("#select-list")[0].options[0].selected = true // assuming it's the first item
3.) I would remove the element from the DOM using jQuery("#select-list option:selected").remove()
4.) You can use before(). jQuery(your_default_option).before("#select-list option:first");
You can store the 'two values' in a hidden form field as an object in JSON notation. This will make it easy to modify in jQuery as the user interacts with the page.
You will need to use a combination of the onchange, keyup and keydown event to capture possible changes to the form so that you can re-select the 'Please Select' option.
You will need to remove the option from the dom and re-add it later. You can easily do this through jquery through something like this:
$("select option:selected").remove();
You can write a sorting function for the options starting with index 1, and keep the 'Please Select' as the first option.
1)
Basic idea, you need to check to make sure the first is not picked
var selections = [];
var mySel = document.getElementById("mySelectId");
var ind = mySel.selectedIndex;
selections.push( mySel.options[ind].value ); //add to a list for you to remember
mySel.options[ind] = null; //remove
2)
mySel.selectedIndex = 0;
3)
See #1
4) Yes you can add it anywhere you want by using insertBefore
Example here: http://www.pascarello.com/lessons/forms/moveSelectOptions.html
Will leave this answer here but I think I failed to read your whole post, so it might not help much.
You need to give your select a id like this:
<select id="MySelect">
<option value="">Please select</option>
<option value="beef-mince">Beef mince</option>
<option value="carrots">Carrots</option>
...
</select>
And to get it is just something like this:
<?php
$value = $_REQUEST["MySelect"];
echo $value;
?>
Code is not tested and $_REQUEST can be replaced by $_GET or $_POST regarding what you have specified as action on your form. $_REQUEST will eat it all though.
I have a select dropdown that could possibly contain over 1000 items for a large customer.
<select name="location" id="location">
<option value="1">Store# 1257</option>
<option value="2">Store# 1258</option>
...
<option value="973">Store# 8200</option>
<option value="974">Store# 8250</option>
<option value="975">Store# 8254</option>
<option value="976">Store# 8290 Fuel Center</option>
</select>
I also have a text box and when the user types in text I want to move the selected item in the dropdown.
For example, if the user types 82 then I want to move to the first item in the box where an 82 exists which would be value 973. If the user types 825 then move to 974, etc. If the user types Fuel, find the first option containing that string.
I am currently using jquery as my javascript library.
What do you suggest for solving this? Should I switch to an autocomplete? If so I need something that has a arrow to dropdown the entire list as some customers may only have 3 or 4 to select from.
Thanks.
Given a variable searchFor that contains the search string, you can select the first option that contains that text with this jquery snippet:
$("#location option[text*=" + searchFor + "]:first").attr("selected", true);
So if you have a text input with the id selectSearchBox, you could write it like this:
$("#selectSearchBox").keyup(function () {
var searchFor = $(this).val();
$("#location option[text*=" + searchFor + "]:first").attr("selected", true);
});
Using jQuery autocomplete plugin might be the best option for you. You can have a look at a previous answer here on SO (please, don't do that select => array translation, use an array or a server side script).