Reputation: 7599
here's my markup:
<button>next</button
<div class="seats">
<div class="seat taken">1</div>
<div class="seat taken">2</div>
<div class="seat">3</div>
<div class="seat">4</div>
<div class="seat taken">5</div>
<div class="seat">6</div>
<div class="seat">7</div>
<div class="seat taken">8</div>
<div class="seat taken">9</div>
</div>
i'm looking for a way to select the first 2 free seats (which don't have class "taken"), given example should return seat 3+4. would there be an easy way to have a variable amount of seats, eg. selecting 4 seats next to each other? is it possible defining a offset where to start searching free seats? i mean i want to hit the next button and it should pick the next 2 free seats (6+7). thanks in advance.
Upvotes: 3
Views: 1230
Reputation: 241198
You could utilize the :not()
pseudo-class and the methods .eq()
, .nextUntil()
, and .addBack()
in order to achieve this in a single line:
$('.seat.taken + .seat:not(.taken)').eq(index).nextUntil('.taken').addBack()
It's also worth pointing out that this will work for groups of elements of varying lengths (not just groups of two elements).
Explanation:
The initial query, $('.seat.taken + .seat:not(.taken)')
will select .seat
elements without a class of .taken
that follow an element with the classes .seat
and .taken
.
The .eq(index)
method will reduce the set based on the index
variable (where index
denotes which group of available seats that you want to select).
The .nextUntil('.taken')
method will select all the following elements until another .taken
element.
Then the initial element is added back to the query with .addBack()
.
Basic example:
var index = 0;
$('.next').on('click', function () {
$('.seat.taken + .seat:not(.taken)').eq(index).nextUntil('.taken').addBack().toggleClass('selected');
index++;
});
.selected { background-color: #f00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="next">next</button>
<div class="seats">
<div class="seat taken">1</div>
<div class="seat taken">2</div>
<div class="seat">3 - Not taken</div>
<div class="seat">4 - Not taken</div>
<div class="seat taken">5</div>
<div class="seat">6 - Not taken</div>
<div class="seat">7 - Not taken</div>
<div class="seat">8 - Not taken</div>
</div>
And if you want to cycle through the elements, you could create a basic function that returns a group of available seats based on the index:
function getNextGroup (index) {
return $('.seat.taken + .seat:not(.taken)').eq(index).nextUntil('.taken').addBack();
}
Then you can call the function to determine if index + 1
yields any elements. If it doesn't, then you would reset index
back to 0
like in the example below:
Updated example:
var index = 0;
$('.next').on('click', function () {
$('.seat.selected').removeClass('selected');
getNextGroup(index).toggleClass('selected');
index = getNextGroup(index + 1).length ? index + 1 : 0;
});
function getNextGroup (index) {
return $('.seat.taken + .seat:not(.taken)').eq(index).nextUntil('.taken').addBack();
}
.selected { background-color: #f00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="next">next</button>
<div class="seats">
<div class="seat taken">1</div>
<div class="seat taken">2</div>
<div class="seat">3 - Not taken</div>
<div class="seat">4 - Not taken</div>
<div class="seat taken">5</div>
<div class="seat">6 - Not taken</div>
<div class="seat">7 - Not taken</div>
<div class="seat">8 - Not taken</div>
<div class="seat taken">9</div>
<div class="seat taken">10</div>
<div class="seat">11 - Not taken</div>
<div class="seat">12 - Not taken</div>
<div class="seat">13 - Not taken</div>
<div class="seat">14 - Not taken</div>
<div class="seat taken">15</div>
<div class="seat">16 - Not taken</div>
</div>
Upvotes: 1
Reputation: 2855
Assuming you're allowed and able to add some more information to each chair: I'd extend your current html so that it'd look like this:
<button>next</button>
<div class="seats">
<div class="seat taken" data-chairNumber="0">1</div>
<div class="seat taken" data-chairNumber="1">2</div>
<div class="seat" data-chairNumber="2">3</div>
<div class="seat" data-chairNumber="3">4</div>
<div class="seat taken" data-chairNumber="5">5</div>
<div class="seat" data-chairNumber="6">6</div>
<div class="seat" data-chairNumber="7">7</div>
<div class="seat taken" data-chairNumber="8">8</div>
<div class="seat taken" data-chairNumber="9">9</div>
</div>
Then use jQuery to only select the non taken chairs:
var chairs = $(".seat:not(.taken)");
Then walk over these chairs and check whether or not there exists a pair (probably extend this for bigger combinations):
var chairs = $(".seat:not(.taken)");
var currentChair = -2; //idunnkno
$.each(chairs, function(chair) {
var chairnumber = $(chair).data("chairNumber");
if(chairnumber - 1 === currentChair)
{
return { chairA : currentChair, chairB : chairNumber };
}
else {
currentChair = chairnumber;
}
});
Return an object with the chairs if you find a pair.
Upvotes: 1