how to save sorting order in select2() field? - javascript

I'm using select2() field using select2 library and Drag and Drop Sorting is enabled in the field.
It works well, but once i save it, the ordering break and they are ordered alphabetically.
I was wondering if its possible to anyhow save ordering of elements after drag drop in select2() fields.
Please suggest.

Per Select2 documentation, the new ordered values are saved in a attached hidden field.
http://ivaynberg.github.io/select2/
(right click on the Input field and then inspect element to find the line below just after the div#select2-container)
There are two options that might work for you:
Option 1:Easy one
Check the ordering of how you are feeding the control, specific on:
$("#e15").select2({tags:["red", "green", "blue", "orange", "white", "black", "purple", "cyan", "teal"]});
The control just render the same order that the above line is specified.
If you are not saving those values as comma separated text and instead as row records, maybe your database query is ordering them alphabetically.
Option 2: A little bit further
This code will serve you to save the ordered values in a cookie, so you can have the same order within your whole session.
$(function(){
if ($.cookie('OrderedItemList') != null){
$("#e15").select2({tags: $.cookie('OrderedItemList').split(',')});
}
$("#e15").on("change", function() {
$("#e15_val").html($("#e15").val());
$.cookie('OrderedItemList', $("#e15").val(), { expires: 365 });
});
});
Please note, this code might not work for database bound fields, you might need to add some code if thats what you need.

Well I had your problem. I've overcome it with something like this...
A hidden input to save your order.
the listener on the select2.
$("#reports").on('change', function(){
var data = $(this).select2('data');
var array = [];
$.each(data, function(index, val) {
array[index]=val.id;
});
array.join(',');
$("input[name=reports]").val( array );
});
<form class="form-horizontal form-bordered" action="#something" method="post" accept-charset="utf-8" target="_blank" >
<input type="text" name="reports" >
<select id="reports" class="form-control select2me" multiple >
<? foreach ($Balance::getSeparators() as $key => $value ) { ?>
<option value="<?=( $key )?>"><?=( $value )?></option>
<? } ?>
</select>
</form>
This way the input[name=reports] sends to your page the correct order.

Select2 has progressed to version 4, which is based on <select/> and <option/>-tags, instead of <input/>-tags. I solved it for version 4 as follows:
$(".select2").select2().on('select2:select', function(e){
var $selectedElement = $(e.params.data.element);
var $selectedElementOptgroup = $selectedElement.parent("optgroup");
if ($selectedElementOptgroup.length > 0) {
$selectedElement.data("select2-originaloptgroup", $selectedElementOptgroup);
}
$selectedElement.detach().appendTo($(e.target));
$(e.target).trigger('change');
})
Basically I remove and re-add the selected items to the select-options-list, so that they appear in order of selection.

The hidden field solution was a good solution in my case, but Select2 plugin still keep a numerical/alphabetical(?) order, that is not the user selection's order
I found a solution, that solves all my needs.
In my symfony form declaration will be the hidden field called selectOrder in which to save the current order:
$("#form_people").on('change', function(){
var data = $(this).select2('data');
var array = [];
$.each(data, function(index, val) {
array[index]=val.id;
});
array.join(',');
$("#selectOrder").val( array );
});
and in the javascript part after form declaration there is my Multi Select2:
var sel = $("#form_people").select2({
maximumSelectionSize: 3,
minimumInputLength: 1,
escapeMarkup: function(m) { return m; },
});
then
//After reloading page you must reselect the element with the
//right previous saved order
var order = $("#selectOrder").val().split(",");
var choices = [];
for (i = 0; i < order.length; i++) {
var option = $('#form_people option[value="' +order[i]+ '"]');
choices[i] = {id:order[i], text:option[0].label, element: option};
}
sel.select2('data', choices);
It's what I need, and maybe can help other developers

Related

How to serialize just one value of input via jQuery?

I started to do dropdown list instead select bcz it is not possible to stylize but I did not think to future and now I found that if I want to save data from form to db I need to get ids via $_POST instead of names.
For ex. I have dropdown list with status of product:
New
Old
Handmade
If I want to save chosen sattus for chosen product it is better for me to get ID of status option. Bcz my table is like this:
item_id | option_value
1 | 1
If I send name as "old" via $_POST, I need to get its ID from another table before insert it.
I created dropdown list like this:
/* SELECT REPLACED BY DIV JS */
var select = $('.add-item__select').hide(); // Hide original select options
// Replace each select by div
select.each(function() {
var selectVal = $(this).find('.add-item__select-main').text(),
name = $(this).attr('name');
newDropdownDiv = $('<input class="add-item__input-select" name="' + name + '" placeholder="' + selectVal + '" readonly required><i class="arrow down"></i></input>')
.insertAfter($(this))
.css({paddingLeft: '0.3em', cursor: 'pointer'});
});
Each SELECT has addaed INPUT after it.
If I want to show shosen vale from dropdown list I need to show it in this way:
$('.add-item__input-select').val("text copied from list");
After this if I add ID of option to input in this way:
$('.add-item__input-select').attr("value", optionID);
Then If I want to serialize all fields values from form and this is point,
$('.add-item__form').serializeArray()
I get two results for status:
name: "status", value: "text copied from list"
and
name: "status", value: optionID
But I need just optionID.
I have everything optimized for this structure, so I would like to ask you if there is some easy way how to fix it or I need to modify structure.
I am thinking to remove INPUT and just change SELECT opacity to 0 instead of display none and use SELECT for form data serialize. But then I will need to replace all INPUTs by some DIV which will hold text of chosen option and also change everything else connected with it. For ex, if user clicked on INPUT the label was showed above it.
Thanks for advices
I found one solution but I have problem that it is working just if user will not refresh page. In DOM is everything the same after refresh but serializeArray() get just input text value and not value="ID" after page refresh.
I just remove these values which I do not want from FormData.
// Send formData to upload.php
$('.add-item__form').on('submit', function() {
event.preventDefault();
event.stopPropagation();
if ( checkFieldsIfNotEmpty() == true ) {
var formDataFields = $('.add-item__form').serializeArray(), // Get all data from form except of photos
count = Object.keys(data).length; // count fields of object
// Fill formData object by data from form
$.each(formDataFields, function(index, value) {
if ( value.name === 'category' && !$.isNumeric(value.value) || value.name === 'subcategory' && !$.isNumeric(value.value) ) {
// do nothing
} else if ( (value.name.indexOf('filter') >= 0) && !$.isNumeric(value.value) ) {
// do nothing
}
else {
formData.append(value.name, value.value); // add name and value to POST data
}
});
// foreach - fill formData with photos from form
$.each(data, function(index, value) {
formData.append('files[]', value);
});
uploadData(formData); // send data via ajax to upload.php
}
});
Can you advice me what can be problem?

Update a Chosen multiple select field with a localStorage variable

i have a Chosen multiple select field and i save the choices of the user in localstorage.language_request. When the user come back i need tu update the field with the previous choices.
My JS to save the choices selected by the user:
$('.calcul_checkout').on("change keyup", function(){
var language_request_brut = $('#language_request').val();
var language_request = [];
jQuery.each(language_request_brut, function(i, val){
language_request.push(val)
});
localStorage.language_request = language_request;
}
My JS when the user return on the page and i need to update the Chosen field with the choices selected previously
if (localStorage.language_request != null){
$("#language_request").val(localStorage.language_request).trigger("chosen:updated");
}
The Chosen field (in Rails):
<span>
<%= select_tag(:language_request, options_for_select([['Français', 'FR'],
['Anglais', 'EN'],
['Italien', 'IT'],
class:"answer language_request calcul_checkout chosen-select", multiple: true) %>
</span>
The problem, localStorage.language_request is equal to ["FR,EN"]. It's save all the choices into one string. And to update the Chosen field i need to format this array into ["FR","EN"] (one string by choice).
I had to update my code like this with the split methode:
if (localStorage.language_request != null){
$("#language_request").val(localStorage.language_request.split(",")).trigger("chosen:updated");
}
Here, you need to change code from
$('.calcul_checkout').on("change keyup", function(){
var language_request_brut = $('#language_request').val();
var SelectedLanguage = language_request_brut.split(",");
var language_request = [];
for(i=0;i<SelectedLanguage.length;i++)
{
language_request.push(SelectedLanguage[i])
}
localStorage.language_request = language_request;
}
This will help you because $('#language_request').val() function returns value as "FR,EN" and you push it directly.So spiting string will help you.

How can I capture checkboxes that I'm creating programmatically?

In my code below, I'm pulling in data from SharePoint (basically an excel spreadsheet) and displaying on my page. Checkboxes are pushed to my page using .innerHTML and are given an ID programmatically.
My question: How can I determine whether those checkboxes are checked (being that they could be different each time my app loads) ?
(Once I know what is checked, I'll display more metadata on the next page based on the checks - that part I have figured out)
$.ajax({
url: "myWebsite",
type: "GET",
headers: { "ACCEPT": "application/json;odata=verbose" },
success: function(data){
$.each(data.d.results, function(index) {
var $this = $(this);
var courseName = $this.attr('Title');
var courseNumber = $this.attr('Course_x0020_Number');
var courseUrl = $this.attr('URL');
var trainingGroup = $this.attr('Training_x0020_Group');
var recurrence = $this.attr('Recurrence');
if (trainingGroup == 'Group1') {
if (recurrence == "Don't Specify") {recurrence = '';
} else recurrence = " ("+recurrence+")";
document.getElementById('officeListSpan').innerHTML += '<ul class="courseLists"><li><input type="checkbox" id="'+courseName.replace(/\s+/g, '')+'"/>'+courseName+recurrence+'</li></ul>';
}
if (trainingGroup == 'Group2') {
if (recurrence == "Don't Specify") {recurrence = '';
} else recurrence = " ("+recurrence+")";
document.getElementById('labListSpan').innerHTML += '<ul class="courseLists"><li><input type="checkbox" id="'+courseName.replace(/\s+/g, '')+'"/>'+courseName+recurrence+'</li></ul>';
}
});
},
error: function(){
alert("Failed to query SharePoint list data. Please refresh (F5).");
}
});
You will need a way to know how many checkboxes has been created. When creating the checkboxes, them id must have a generic name and a number, for example id="checkbox0", id="checkbox1 and so on, then write the ammount of checkboxes in some part of the html code and put it some hidden tag. Then when reading the checkboxes data read the ammount of checkboxes and do a for
function getCheckboxes(){
var ammount = parseInt(document.getElementById("checkBoxesAmmount"));
var checkbox;
for(var i = 0; i<ammount; i++){
checkbox = document.getElementById("checkbox"+i);
//do staff
}
return;
I hope this works for you c:
This bit of jQuery returns all the checked input boxes that are in a ul with the class courseList:
jQuery('ul.courseList input:checked')
If your question is asked because the course name might change (your checkbox IDs are based on the course name), I suggest switching to the course number instead (or an appropriate mix of the two).
If you want to know if your dynamically created checkboxes were checked and want to do this via Javascript before the form is submitted, then add a class to your checkboxes (say dynamicCourse) and look for get the checked checkboxes via jQuery('input.dynamicCourse:checked').
Also, your checkboxes in your example don't have a value attribute set. If you're submitting it to a backend, you'll probably want it to have some value (course number would be my suggestion from the looks of it).

Getting multiple selected checkbox values in a string in javascript and PHP

I have location name and location Id in database table. Using foreach loop i'm printing the values in checkbox in PHP. I have a submit button which triggers a javascript. I want the user selected all checkbox values separated by comma, in a javascript variable. How can I do this?
<!-- Javascript -->
<script>
function getLoc(){
var all_location_id = document.getElementByName("location[]").value;
var str = <!-- Here I want the selected checkbox values, eg: 1, 4, 6 -->
}
<script>
foreach($cityrows as $cityrow){
echo '<input type="checkbox" name="location[]" value="'.$cityrow['location_id'].'" />'.$cityrow['location'];
echo '<br>';
}
echo '<input name="searchDonor" type="button" class="button" value="Search Donor" onclick="getLoc()" />';
var checkboxes = document.getElementsByName('location[]');
var vals = "";
for (var i=0, n=checkboxes.length;i<n;i++)
{
if (checkboxes[i].checked)
{
vals += ","+checkboxes[i].value;
}
}
if (vals) vals = vals.substring(1);
This is a variation to get all checked checkboxes in all_location_id without using an "if" statement
var all_location_id = document.querySelectorAll('input[name="location[]"]:checked');
var aIds = [];
for(var x = 0, l = all_location_id.length; x < l; x++)
{
aIds.push(all_location_id[x].value);
}
var str = aIds.join(', ');
console.log(str);
var fav = [];
$.each($("input[name='name']:checked"), function(){
fav.push($(this).val());
});
It will give you the value separeted by commas
I you are using jQuery you can put the checkboxes in a form and then use something like this:
var formData = jQuery("#" + formId).serialize();
$.ajax({
type: "POST",
url: url,
data: formData,
success: success
});
In some cases it might make more sense to process each selected item one at a time.
In other words, make a separate server call for each selected item passing the value of the selected item. In some cases the list will need to be processed as a whole, but in some not.
I needed to process a list of selected people and then have the results of the query show up on an existing page beneath the existing data for that person. I initially though of passing the whole list to the server, parsing the list, then passing back the data for all of the patients. I would have then needed to parse the returning data and insert it into the page in each of the appropriate places. Sending the request for the data one person at a time turned out to be much easier. Javascript for getting the selected items is described here: check if checkbox is checked javascript and jQuery for the same is described here: How to check whether a checkbox is checked in jQuery?.
This code work fine for me, Here i contvert array to string with ~ sign
<input type="checkbox" value="created" name="today_check"><strong> Created </strong>
<input type="checkbox" value="modified" name="today_check"><strong> Modified </strong>
<a class="get_tody_btn">Submit</a>
<script type="text/javascript">
$('.get_tody_btn').click(function(){
var ck_string = "";
$.each($("input[name='today_check']:checked"), function(){
ck_string += "~"+$(this).val();
});
if (ck_string ){
ck_string = ck_string .substring(1);
}else{
alert('Please choose atleast one value.');
}
});
</script>

jQuery - Store drop down values from multiple selects in an array

The following code populates the second select statement with HTML data. The problem I'm facing is that I clone the two select statements and on submission of the form, I'd like to save all of the selected option values from the two selects into an Array().
What would be the best way to iterate through all of the drop-down values (there's a maximum of 5 that can be added for both Subject Matter and Category)?
Thanks in advance.
$(".SubjectCategory").live("click", function () {
var $this = $(this);
var $elem = $this.closest('div').nextAll('div').first().find('select');
var a = $this.val();
$.get("/userControls/BookSubjectHandler.ashx?category=" + a, {}, function (data) {
$elem.html(data);
});
});
<div class="singleField subjectField">
<label id="Category" class="fieldSml">Subject Matter</label>
<div class="bookDetails ddl"><select id="ddlSubjectMatter" class="fieldSml SubjectCategory"></select></div>
<label id="Subjects" class="fieldSml">Category</label>
<div class="bookDetails ddl" id="subjectMatter"><select id="ddlSubjects" class="fieldSml Subjects"></select></div>
</div>
Using jQuery .map function you can retrieve all values at once:
var arrayOfValues = $(".bookDetails.ddl select").map(function (i, el) { return $(el).val(); }).get();
fiddle: http://jsfiddle.net/e9zxY/

Categories