How to iterate through jQuery UI selectmenu by using 2 buttons? - javascript

Please try the jsFiddle with jQuery UI selectmenu and 2 buttons.
With the help of 2 buttons prevGame and nextGame I am able to change the selectedIndex variable tracking the currently selected game number.
The jQuery UI selectmenu doc unfortunately does not explain how to set and get (so that I can update the span currGame) the currently selected item:
Please explain: how to set and get the selected item in jQuery UI selectmenu?
HTML-code:
<form>
<select name="games" id="games"></select>
<button id="prevGame"><</button>
<span id="currGame">Loading...</span>
<button id="nextGame">></button>
</form>
JavaScript-code:
var yourGames = [1, 3, 5];
var hisGames = [8, 10, 12, 14];
var selectedIndex = 0;
$("#games").selectmenu();
// emulate repeating server responses
setInterval(function() {
updateMenu();
}, 5000);
$('#prevGame').button().click(function(e) {
e.preventDefault();
selectedIndex = Math.max(selectedIndex - 1, 0);
updateButtons();
});
$('#nextGame').button().click(function(e) {
e.preventDefault();
selectedIndex = Math.min(selectedIndex + 1, lastIndex());
updateButtons();
});
function lastIndex() {
return yourGames.length + hisGames.length - 1;
}
function updateButtons() {
$('#currGame').html('selectedIndex=' + selectedIndex); // TODO: change to "Game #"
$('#prevGame').button(selectedIndex == 0 ? "disable" : "enable");
$('#nextGame').button(selectedIndex == lastIndex() ? "disable" : "enable");
}
function updateMenu() {
var yourGroup = ['<optgroup label="YOUR TURN">'];
for (var i = 0; i < yourGames.length; i++) {
var gameNumber = yourGames[i];
var selectedTag = (i == selectedIndex ? 'selected="selected"' : '');
yourGroup.push(
'<option ' +
selectedTag +
' value="' +
gameNumber +
'">Game #' +
gameNumber +
'</option>');
}
yourGroup.push('</optgroup>');
var hisGroup = ['<optgroup label="HIS TURN">'];
for (var i = 0; i < hisGames.length; i++) {
var gameNumber = hisGames[i];
var selectedTag = (i - yourGames.length == selectedIndex ? 'selected="selected"' : '');
hisGroup.push(
'<option ' +
selectedTag +
' value="' +
gameNumber +
'">Game #' +
gameNumber +
'</option>');
}
hisGroup.push('</optgroup>');
$("#games").selectmenu('destroy')
.empty()
.append(yourGroup.length > 2 ? yourGroup.join('') : '')
.append(hisGroup.length > 2 ? hisGroup.join('') : '')
.selectmenu(); // TODO: select the game at selectIndex
}
UPDATE:
I have prepared a newer jsFiddle using selectmenu("refresh") instead of selectmenu("destroy"), but it still has some issues.

jQuery and jQuery UI provides no way to directly set selected index of a select menu. You can use pure javascript way to set the selected index. Also I assume you want to change the text between buttons every time select menu changes. You can do it like so:
var yourGames = [1, 3, 5];
var hisGames = [8, 10, 12, 14];
var selectedIndex = 0;
setInterval(function() {
updateMenu();
updateCurrentGame();
updateButtons();
}, 5000);
$("#games").selectmenu();
$('#prevGame').button().click(function(e) {
e.preventDefault();
selectedIndex = Math.max(selectedIndex - 1, 0);
updateButtons();
updateCurrentGame();
});
$('#nextGame').button().click(function(e) {
e.preventDefault();
selectedIndex = Math.min(selectedIndex + 1, lastIndex());
updateButtons();
updateCurrentGame();
});
function lastIndex() {
return yourGames.length + hisGames.length - 1;
}
function updateButtons() {
$('#prevGame').button(selectedIndex == 0 ? "disable" : "enable");
$('#nextGame').button(selectedIndex == lastIndex() ? "disable" : "enable");
}
// Update the select menu when prev & next buttons are pressed
function updateCurrentGame() {
var selectedText = $($("select#games option")[selectedIndex]).text();
$('#currGame').html(selectedText);
// pure js vay to set selected index
$("#games")[0].selectedIndex = selectedIndex;
$("#games").selectmenu("refresh");
}
// Update the selected index every time the select menu is changed manually
$("#games").on("selectmenuchange", function(e, ui) {
console.log(ui);
selectedIndex = ui.item.index;
var selectedText = ui.item.element.text();
$('#currGame').html(selectedText);
updateButtons();
})
function updateMenu() {
var yourGroup = ['<optgroup label="YOUR TURN">'];
for (var i = 0; i < yourGames.length; i++) {
var gameNumber = yourGames[i];
var selectedTag = (i == selectedIndex ? 'selected="selected"' : '');
yourGroup.push(
'<option ' +
selectedTag +
' value="' +
gameNumber +
'">Game #' +
gameNumber +
'</option>');
}
yourGroup.push('</optgroup>');
var hisGroup = ['<optgroup label="HIS TURN">'];
for (var i = 0; i < hisGames.length; i++) {
var gameNumber = hisGames[i];
var selectedTag = (yourGames.length + i == selectedIndex ? 'selected="selected"' : '');
hisGroup.push(
'<option ' +
selectedTag +
' value="' +
gameNumber +
'">Game #' +
gameNumber +
'</option>');
}
hisGroup.push('</optgroup>');
$("#games").selectmenu('destroy')
.empty()
.append(yourGroup.length > 2 ? yourGroup.join('') : '')
.append(hisGroup.length > 2 ? hisGroup.join('') : '')
.selectmenu();
}
button#prevGame,
span#currGame,
button#nextGame,
button#newGame {
vertical-align: top;
}
select#games {
width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.min.css" rel="stylesheet" />
<form>
<select name="games" id="games"></select>
<button id="prevGame"><</button>
<span id="currGame">Loading...</span>
<button id="nextGame">></button>
</form>

This can be done in much better way but the following code provides what you asked for:
var yourGames = [1, 3, 5];
var hisGames = [8, 10, 12, 14];
var selectedIndex = 0;
$("#games").selectmenu();
$('#prevGame').button().click(function(e) {
e.preventDefault();
selectedIndex = Math.max(selectedIndex - 1, 0);
updateMenu();
updateButtons();
});
$('#nextGame').button().click(function(e) {
e.preventDefault();
selectedIndex = Math.min(selectedIndex + 1, lastIndex());
updateMenu();
updateButtons();
});
function lastIndex() {
return yourGames.length + hisGames.length - 1;
}
function updateButtons() {
var selectedText = $("#games option:selected").text();
$('#currGame').html(selectedText);
$('#prevGame').button(selectedIndex == 0 ? "disable" : "enable");
$('#nextGame').button(selectedIndex == lastIndex() ? "disable" : "enable");
}
function updateMenu() {
var yourGroup = ['<optgroup label="YOUR TURN">'];
for (var i = 0; i < yourGames.length; i++) {
var gameNumber = yourGames[i];
var selectedTag = (i == selectedIndex ? 'selected="selected"' : '');
yourGroup.push(
'<option ' +
selectedTag +
' value="' +
gameNumber +
'">Game #' +
gameNumber +
'</option>');
}
yourGroup.push('</optgroup>');
var hisGroup = ['<optgroup label="HIS TURN">'];
for (var i = 0; i < hisGames.length; i++) {
var gameNumber = hisGames[i];
var selectedTag = (yourGames.length + i == selectedIndex ? 'selected="selected"' : '');
hisGroup.push(
'<option ' +
selectedTag +
' value="' +
gameNumber +
'">Game #' +
gameNumber +
'</option>');
}
hisGroup.push('</optgroup>');
console.log(yourGroup);
console.log(hisGroup);
$("#games").selectmenu('destroy')
.empty()
.append(yourGroup.length > 2 ? yourGroup.join('') : '')
.append(hisGroup.length > 2 ? hisGroup.join('') : '')
.selectmenu();
}
I also updated your Fiddle so you can play with it.
https://jsfiddle.net/q07uarwr/35/

I gave it a try and got both updating and displaying text. But only thing you need to find next is how to set value once selected index changes to the next <option> group in the drop down.
This is the main change:
function updateButtons() {
var gamesOptions = $('#games option');
$('#currGame').html("<span>" + $(gamesOptions[selectedIndex]).text() + "</span>");
$("#games").val(selectedIndex).change();
$('#prevGame').button(selectedIndex == 0 ? "disable" : "enable");
$('#nextGame').button(selectedIndex == lastIndex() ? "disable" : "enable");
updateMenu();
}
https://jsfiddle.net/q07uarwr/34/

Related

FacetWP: Show labels only if facet has options

I want to show labels only if the facet has any options. Therefore I tried the following code:
<script>
(function($) {
$(document).on('facetwp-loaded', function() {
$('.facetwp-facet').each(function() {
var facet_name = $(this).attr('data-name');
var facet_label = FWP.settings.labels[facet_name];
if ($('.facet-label[data-for="' + facet_name + '"]').length < 1 && $(this).children()
.length > 0) {
$(this).before('<p class="h5 facet-label" data-for="' + facet_name + '">' + facet_label + '</p>');
}
});
});
})(jQuery);
</script>
It works but only if I reload the page with active filters.
If I change the filter, the labels stay.
Is there any option to ask if the are a new filters after a click?
The plugin author gave me an hint for a solution:
<script>
(function($) {
$(document).on('facetwp-loaded', function() {
$('.facetwp-facet').each(function() {
var facet_name = $(this).attr('data-name');
var facet_label = FWP.settings.labels[facet_name];
if ( 'undefined' !== typeof FWP.settings.num_choices[facet_name] && FWP.settings.num_choices[facet_name] > 0 && $('.facet-label[data-for="' + facet_name + '"]').length < 1 ) {
$(this).before('<h3 class="facet-label" data-for="' + facet_name + '">' + facet_label + '</h3>');
} else if ( 'undefined' !== typeof FWP.settings.num_choices[facet_name] && !FWP.settings.num_choices[facet_name] > 0 ) {
$('.facet-label[data-for="' + facet_name + '"]').remove();
}
});
});
})(jQuery);
</script>

css has to apply only one seat <li> ( restrict multiple select)

bus reservation
The following code generate multilpe <li> and when the user click seats, the selected seats css will change. but i want to restrict the multiple selection. the user has to be allow to select only one seat, if he select second <li> (seat) , then the first one has to go unselect
DEMO : http://demo.techbrij.com/780/seat-reservation-jquery-demo.php
CODE : http://techbrij.com/seat-reservation-with-jquery
$(function () {
var settings = {
rows: 6,
cols: 6,
rowCssPrefix: 'row-',
colCssPrefix: 'col-',
seatWidth: 30,
seatHeight: 30,
seatCss: 'seat',
selectedSeatCss: 'selectedSeat',
selectingSeatCss: 'selectingSeat'
};
var init = function (reservedSeat) {
var str = [], seatNo, className;
for (i = 0; i < settings.rows; i++) {
for (j = 0; j < settings.cols; j++) {
seatNo = (i + j * settings.rows + 1); // Seat No eg : seatNo = 0+0*0+1 (1)
className = settings.seatCss + ' ' + settings.rowCssPrefix + i.toString() + ' ' + settings.colCssPrefix + j.toString(); // Class each seat class Name=seat row-0 col-0
if ($.isArray(reservedSeat) && $.inArray(seatNo, reservedSeat) != -1) {
className += ' ' + settings.selectedSeatCss;
}
str.push('<li onclick="gettable('+ seatNo+')" class="' + className +" table"+seatNo+ '">'
+'<a title="' + seatNo + '">' + seatNo + '</a>' +
'</li>');
}
}
$('#place').html(str.join(''));
};
var bookedSeats = [5, 10, 25];
init(bookedSeats);
$('.' + settings.seatCss).click(function () {
if ($(this).hasClass(settings.selectedSeatCss)){
alert('This seat is already reserved');
}
else{
$(this).toggleClass(settings.selectingSeatCss);
}
});
First remove the class from all elements, then add it to the selected one.
$('.' + settings.seatCss).click(function () {
if ($(this).hasClass(settings.selectedSeatCss)){
alert('This seat is already reserved');
}
else{
$('.' + settings.seatCss).removeClass(settings.selectingSeatCss);
$(this).addClass(settings.selectingSeatCss);
}
});
Change the else part to:
else{
$(this).toggleClass(settings.selectingSeatCss);
$(".settings.selectingSeatCss").not(this).removeClass('settings.selectingSeatCss');
}
try changing the code in click() event with this one.
$('.' + settings.seatCss).click(function () {
$(this).addClass(settings.selectedSeatCss).siblings(this).removeClass(settings.selectedSeatCss);
});
working Demo. Hope it helps you.

get text from attribute and format it

I have a div elements with data-seat and data-row property:
<div class='selected' data-seat='1' data-row='1'></div>
<div class='selected' data-seat='2' data-row='1'></div>
<div class='selected' data-seat='3' data-row='1'></div>
<div class='selected' data-seat='1' data-row='2'></div>
<div class='selected' data-seat='2' data-row='2'></div>
I want print friendly message for selected seats:
var selectedPlaceTextFormated ='';
$(".selected").each(function () {
var selectedPlace = $(this);
selectedPlaceTextFormated += "Row " + selectedPlace.attr("data-row") + " (seat " + selectedPlace.attr("data-seat") + ")\n";
});
alert(selectedPlaceTextFormated);
This code works well and shows the following:
Row 1 (seat 1)
Row 1 (seat 2)
Row 1 (seat 3)
Row 2 (seat 1)
Row 2 (seat 2)
But, I want group seats by row, i.e I want the following:
Row 1(seats: 1,2,3)
Row 2(seats: 1,2)
also, order by row number. How can I do this?
Thanks. DEMO
Here is the code
var selectedPlaceTextFormated ='';
var row_array = [];
$(".selected").each(function () {
var selectedPlace = $(this);
if (!row_array[selectedPlace.attr("data-row")]){
row_array[selectedPlace.attr("data-row")] = selectedPlace.attr("data-seat");
}
else row_array[selectedPlace.attr("data-row")] += ','+selectedPlace.attr("data-seat");
});
for (row in row_array){
alert("Row "+ row +"(seat " + row_array[row] + ")\n" );
}
And here the link to the working fiddle: http://jsfiddle.net/3gVHg/
First of all, jQuery is kind enough to automatically grab data- attributes into its data expando object, that means, you can access those data via:
jQueryObject.data('seat');
for instance.
Your actual question could get solved like
var $selected = $('.selected'),
availableRows = [ ],
selectedPlaceTextFormated = '',
currentRow,
currentSeats;
$selected.each(function(_, node) {
if( availableRows.indexOf( currentRow = $(node).data('row') ) === -1 ) {
availableRows.push( currentRow );
}
});
availableRows.forEach(function( row ) {
selectedPlaceTextFormated += 'Row ' + row + '(';
currentSeats = $selected.filter('[data-row=' + row + ']').map(function(_, node) {
return $(this).data('seat');
}).get();
selectedPlaceTextFormated += currentSeats.join(',') + ')\n';
});
jsFiddle: http://jsfiddle.net/gJFJW/3/
You need to use another variable to store the row, and format accordingly.
var selectedPlaceTextFormated ='';
var prevRow = 0;
$(".selected").each(function () {
var selectedPlace = $(this);
var row = selectedPlace.attr("data-row");
var seat = selectedPlace.attr("data-seat");
if(prevRow == row){
selectedPlaceTextFormated += "," + seat;
}
else{
if(selectedPlaceTextFormated != ''){
selectedPlaceTextFormated += ')\n';
}
selectedPlaceTextFormated += "Row " + row + " (seat " + seat;
prevRow = row;
}
});
selectedPlaceTextFormated += ')\n';
alert(selectedPlaceTextFormated);
Check http://jsfiddle.net/nsjithin/R8HHC/
This can be achieved with a few slight modifications to your existing code to use arrays; these arrays are then used to build a string:
var selectedPlaceTextFormated = [];
var textFormatted = '';
$(".selected").each(function(i) {
var selectedPlace = $(this);
var arr = [];
selectedPlaceTextFormated[selectedPlace.attr("data-row")] += "," + selectedPlace.attr("data-seat");
});
selectedPlaceTextFormated.shift();
for (var i = 0; i < selectedPlaceTextFormated.length; i++) {
var arr2 = selectedPlaceTextFormated[i].split(",");
arr2.shift();
textFormatted += "Row " + (i + 1) + " seats: (" + arr2.join(",") + ")\n";
}
alert(textFormatted);
​
Demo
I'd just do this:
var text = [];
$(".selected").each(function () {
var a = parseInt($(this).data('row'), 10),
b = $(this).data('seat');
text[a] = ((text[a])?text[a]+', ':'')+b;
});
var selectedPlaceTextFormated ='';
$.each(text, function(index, elem) {
if (!this.Window) selectedPlaceTextFormated += "Row " + index + " (seat " + elem + ")\n";
});
alert(selectedPlaceTextFormated);
FIDDLE

Replacing part of innerHTML text of a html select option field within multiple select does not work

THE FUNCTION
The SelectMultiple function comes up with a pop-up div with checkboxes in it.
The checkboxes are built equally to select options and added click event to build up
an array.
Beacuse there are many select menus on the page there is built a filterstack object to make the distinction per select menu name.
THE AIM AND THE PROBLEM
When a checkbox clicked the innerHTML (not the option value) text of option will be shown in the very first option field of referred select menu with comma separation, so far works.
On checkbox un-check should the text removed by javascripts replace function, but it not works.
NOTE 1:
Checkbox events building at this moment a string. Before this I've tried an array and did not worked too.
NOTE 2:
Tested on Firefox.
var filterstack = {};
var objSelected = {};
function SelectMultiple(field, isAction, paneId) {
//the first paramater might be "this" or the field id.
if (typeof field == "string")
field = $(field);
field.onchange = function () {};
objSelected["" + field.name + ""] = new Array();
var popdiv = document.createElement('DIV');
$(popdiv).setStyle({
backgroundColor: '#fff',
'z-index': '999999999991',
'margin': '-24px -2px',
'width': field.parentNode.offsetWidth + 'px',
'height': field.options.length * 20 + 31 + 'px',
'position': 'absolute',
'display': 'block'
});
popdiv.id = "" + field.name + "";
var selArr = new Array();
var selinnerHTML = "";
for (var i = 0; i < field.options.length; i++) {
var innerdiv = document.createElement('DIV');
$(innerdiv).setStyle({
'width': 'auto',
'position': 'relative'
});
var optionlabel = document.createElement('LABEL');
optionlabel.innerHTML = field.options[i].innerHTML;
$(optionlabel).setStyle({
'width': field.offsetWidth - 25 + 'px'
});
innerdiv.appendChild(optionlabel);
var optionfield = document.createElement('INPUT');
var fieldName = field.name + '[' + field.options[i].value + ']';
optionfield.type = 'checkbox';
optionfield.id = fieldName; //p.vendors_id[0]
optionfield.name = fieldName;
optionfield.toreplace = field.options[i].innerHTML.toString();
if (filterstack["" + fieldName + ""] &&
objSelected["" + field.name + ""]) {
optionfield.checked = true;
selArr.push(field.options[i].value);
if (!(selinnerHTML.match('/' + optionfield.toreplace + '/gi')))
selinnerHTML += optionfield.toreplace + ', ';
} else {
optionfield.checked = false;
selinnerHTML.replace('/' + optionfield.toreplace + '/gi', '');
}
optionfield.value = field.options[i].value;
$(optionfield).setStyle({
'width': '10px',
'display': 'inline'
});
optionfield.onclick = function (e) {
var el = (e) ? e.target : ((window.event.srcElement) ? window.event.srcElement : null);
var selArr = objSelected["" + field.name + ""];
if (el.checked) {
selArr.push(el.value);
filterstack["" + field.name + ""] = selArr;
if (!(selinnerHTML.match('/' + el.toreplace + '/gi')))
selinnerHTML += el.toreplace + ', ';
} else {
// .replace DOES NOT WORK
if ((selinnerHTML.match('/' + el.toreplace + '/gi')))
selinnerHTML.replace('/' + el.toreplace + '/gi', '');
field.options[field.selectedIndex].innerHTML = selinnerHTML;
for (var i = 0; i < selArr.length; i++) {
if (!selArr[i].checked && selArr[i] == el.value) {
selArr.splice(i, 1);
break;
}
}
filterstack["" + field.name + ""] = selArr;
}
}; //optionfield.onclick
//ignore empty values
if (optionfield.value != "")
innerdiv.appendChild(optionfield);
popdiv.appendChild(innerdiv);
} //for
field.options[0].innerHTML = selinnerHTML;
objSelected["" + field.name + ""] = selArr;
filterstack["" + field.name + ""] = selArr;
var ok = document.createElement('INPUT');
ok.type = 'button';
ok.value = 'OK';
$(ok).setStyle({
'width': '55px',
'margin': '5px 0px 0px 7px',
'text-align': 'center'
});
ok.onclick = function (el) {
postFilter(null, null, isAction + '/', field.name + '/', filterstack["" + field.name + ""] + '/', paneId);
field.parentNode.removeChild(popdiv);
};
var cancel = document.createElement('INPUT');
cancel.type = 'button';
cancel.value = 'Cancel';
$(cancel).setStyle({
'width': '55px',
'margin': '0',
'text-align': 'center',
'display': 'inline'
});
cancel.onclick = function (el) {
field.parentNode.removeChild(popdiv);
};
popdiv.appendChild(ok);
popdiv.appendChild(cancel);
field.parentNode.appendChild(popdiv);
}​
Using innerHTML is not the way to go for <option> elements. Use the option's text property instead.

How to rewrite this Javascript code using Jquery?

function SelectDistrict(argument)
{
var sel=document.getElementById("city");
sel.style.display = '';
sel.options.length = 0;
sel.options.add(new Option('Please select a location',''));
var i=1;
var tempInt=parseInt(argument);
if (tempInt%10000==0)
{
var place1=document.getElementById('place1');
place1.innerHTML =county[tempInt];
}
sel.options.add(new Option('all',tempInt));
$('#inputcity').hide();
while (i<=52)
{
tempInt+=100;
if (county[tempInt]==undefined)
{
break;
}
else {
op_cir = new Option(county[tempInt], tempInt);
sel.options.add(op_cir);
}
i++;
}
}
You could do something like this:
function SelectDistrict(argument)
{
var sel = $('#city'); // Store the jQuery object to save time
sel.hide().empty().append('<option>Please select a location.</option');
var i = 1;
var tempInt = argument;
if (tempInt % 10000 == 0)
{
$('#place1').html(county[tempInt]);
}
sel.append('<option value="'+tempInt+'">all</option>');
$('#inputcity').hide();
var optionsValue = ''; // Appending strings to each other is faster than modifying the DOM
tempInt += 100;
while ((i <= 52) && (county[tempInt] != undefined)) // Just put the condition here instead of breaking the loop
{
optionsValue += "<option value='" + tempInt + "'>" + county[tempInt] + "</option>";
tempInt += 100;
i++;
}
sel.append(optionsValue);
}
I hope that works for you!
you have to replace every document.getElementById() by $("#elementid") like $("#city");
and place1.innerHTML =county[tempInt]; by $("#place1").text(county[tempInt]);
You can change the while loop to:
$.each(county, function(i, itm) {
optionsValue += "<option value='" + i + "'>" + itm + "</option>";
})

Categories