Reputation: 1684
I have an issue that I cant seem to figure out how to fix.. Im still green on javascript.
I am having this markup:
<div class="area-listing">
<div id="list-filter">
<input type="radio" id="all" name="rr" data-filter="all" checked />
<label for="all"><span></span>Samtliga</label>
<input type="radio" id="student" name="rr" data-filter="student" />
<label for="student"><span></span>Studentboende</label>
<input type="radio" id="construction" name="rr" data-filter="construction" />
<label for="construction"><span></span>Nybyggnation</label>
<input type="checkbox" id="available" name="cc" data-filter="available" />
<label for="available"><span></span>Visa endast lediga lägenheter</label>
</div>
<div class="area col-sm-4"></div>
<div class="area col-sm-4 construction"></div>
<div class="area col-sm-4 available student"></div>
<div class="area col-sm-4 available"></div>
<div class="area col-sm-4 available"></div>
<div class="area col-sm-4 available"></div>
</div>
function areaListing() {
if ($(".area-listing").length) {
var filters = $(".area-listing #list-filter");
var areas = $(".area-listing .area");
areas.show();
var $areas = $('input').on("change", function () {
if (this.id == 'all') {
areas.fadeIn(450);
} else {
var $el = $('.' + this.id).fadeIn(450);
areas.not($el).hide();
}
$areas.removeClass('filtered');
$(this).addClass('filtered');
})
}
}
And with the javascript I am now filtering fine based on the radio buttons.. However I want to add the possibility to trigger another filter on the "checkbox"
to filter out "available" elements. However I can't get it to work.. can anyone assist me? Right now it works on the first checkbox click, but doesnt register when untoggling it.
To clarify: When clicking the checkbox the filtering should remain but only show the areas with available. And when untoggled it should show all.
Upvotes: 0
Views: 1618
Reputation: 87203
Here's code for the filtering based on both Checkbox AND Radio button. When any of the radio button or checkbox is checked(or checkbox is unchecked), you need to first get the checked status of checkbox. If this checkbox is checked, only areas with .available
should be shown and others should be hidden. If this checkbox is unchecked, there is no need to bother about .available
elements.
Here are some suggestions:
ready
$('.area-listing').length
is not needed as it'll always be true
provided that code is executed after page loadfilters
is never used, thus can be removed.areas.show()
is not needed if .area
elements are not hidden.data-filter
to get the class on which the filter is to be applied.// When DOM is completely loaded
$(document).ready(function() {
'use strict';
// Cache element references
var $areas = $('.area');
var $checkbox = $('#available');
var $radios = $('#list-filter :radio');
var checkboxFilter = $checkbox.data('filter');
// Bind change event on radio buttons and checkbox
$('#list-filter').on('change', ':radio, :checkbox', function(e) {
// Get the checked status of checkbox
var isCheckboxChecked = $checkbox.is(':checked');
// Get the checked radio button filter
var radio = $radios.filter(':checked').data('filter');
// Create filter based on checked radio button and checkbox state
var filter = isCheckboxChecked ? '.' + radio + '.' + checkboxFilter : '.' + radio;
if (radio === 'all') {
if (isCheckboxChecked) {
// Show only .available
$areas.filter('.' + checkboxFilter).fadeIn(450);
} else {
// Show all
$areas.fadeIn(450);
}
} else {
// Hide those except filtered
$areas.not(filter).hide();
// Show filtered
$areas.filter(filter).fadeIn(450);
}
}).trigger('change'); // To call the handler on page load
});
label {
margin-right: 2px;
}
div.area {
margin: 5px;
color: green;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="area-listing">
<div id="list-filter">
<input type="radio" id="all" name="rr" data-filter="all" checked />
<label for="all"><span></span>Samtliga</label>
<input type="radio" id="student" name="rr" data-filter="student" />
<label for="student"><span></span>Studentboende</label>
<input type="radio" id="construction" name="rr" data-filter="construction" />
<label for="construction"><span></span>Nybyggnation</label>
<input type="checkbox" id="available" name="cc" data-filter="available" />
<label for="available"><span></span>Visa endast lediga lägenheter</label>
</div>
<div class="area col-sm-4">First</div>
<div class="area col-sm-4 construction">Second</div>
<div class="area col-sm-4 available student">Third</div>
<div class="area col-sm-4 available">Fourth</div>
<div class="area col-sm-4 available">Fifth</div>
<div class="area col-sm-4 available">Sixth</div>
</div>
Upvotes: 3
Reputation: 415
I think i know what you want to do, first of all, doing the checks from radios or checkboxes is a little bit weird for normal usage, i think you need to use a "filter" button, so i added one to filter every option selected.
This is the JS code:
//Launch the filter with a button
$("#list-filter input[type='button']").click(function(){
//Get the element
var input = $("#list-filter input[type='radio']:checked").attr("data-filter");
var check = $("#list-filter input[type='checkbox']");
//Check for available only
if(check.is(":checked")){
if(input=="all"){ //Show all available
$(".area-listing .area").css("display","none");
$(".area-listing .area.available").css("display","block");
}
else{ //Show only available in the desired area
$(".area-listing .area").css("display","none");
$(".area-listing .area.available."+input).css("display","block");
}
}
else //If not available is checked
{
if(input=="all"){ //Show all
$(".area-listing .area").css("display","block");
}
else{ //Show only the desired area
$(".area-listing .area").css("display","none");
$(".area-listing .area."+input).css("display","block");
}
}
});
This is the full test (i added a CSS to hide all areas by default, and the button to filter all options)
https://jsfiddle.net/psyzc79w/
Tell me if this way is useful for you.
Upvotes: 1
Reputation: 1485
You can store current filters in variables and change them after clicking on radio or checkbox input.
function areaListing() {
if ($('.area-listing').length) {
var filters = $('.area-listing #list-filter');
var areas = $('.area-listing .area');
areas.show();
var currentFilter = 'all';
var showOnlyAvailable = false;
function filterAreas() {
var currentSelector = '.area';
if (currentFilter !== 'all') {
currentSelector += '.' + currentFilter;
}
if (showOnlyAvailable) {
currentSelector += '.available';
}
var $el = $(currentSelector).fadeIn(450);
areas.not($el).hide();
}
$('input[type="radio"]').on('change', function() {
currentFilter = this.id;
filterAreas();
});
$('input[type="checkbox"]').on('change', function() {
showOnlyAvailable = $(this).is(':checked');
filterAreas();
});
}
}
areaListing();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="area-listing">
<div id="list-filter">
<input type="radio" id="all" name="rr" data-filter="all" checked />
<label for="all"><span></span>Samtliga</label>
<input type="radio" id="student" name="rr" data-filter="student" />
<label for="student"><span></span>Studentboende</label>
<input type="radio" id="construction" name="rr" data-filter="construction" />
<label for="construction"><span></span>Nybyggnation</label>
<input type="checkbox" id="available" name="cc" data-filter="available" />
<label for="available"><span></span>Visa endast lediga lägenheter</label>
</div>
<div class="area col-sm-4">a</div>
<div class="area col-sm-4 construction">b</div>
<div class="area col-sm-4 available student">c</div>
<div class="area col-sm-4 available">d</div>
<div class="area col-sm-4 available">e</div>
<div class="area col-sm-4 available">f</div>
</div>
Upvotes: 3