That code basically hides articles that won't match the category I choose from my select menu.
But then this happens.. Basically if I have only 3 images with matching category I will be left with a huge "blank" space on the bottom of the page.
$(".filter").change(function() {
var filterValue = $(this).val();
var row = $('.portfolio-item');
row.hide()
row.each(function(i, el) {
if($(el).data('type').split(' ').indexOf(filterValue) !== -1) {
$(el).show();
}
})
// In Addition to Wlin's Answer (For "All" value)
if ("all" == filterValue) {
row.show();
}
});
Is there anyway I can automatically resize the height of the section or div?
I already tried ( overflow:hidden, resize:both ) and some other CSS stuff but its not working...
Related
In a container I have four rows. Each with a different number of columns. Whenever I click on each row it should move to its next row. However on clicking the final row (any row which comes to the final position) it should move to the first row.I am able to move the rows using the following code but i need to move the rows with animation gliding effect(that is how to move the rows with animation).
$(".row").each(function() {
$(this).click(function(){
if (($(this).next()).length === 1 )
{
$(this).insertAfter($(this).next());
}
else
{
$(this).insertBefore($(this).siblings().first());
}
}
}
Do you want like this?
$(".row").each(function() {
$(this).click(function(){
if (($(this).next()).length === 1 )
{
$(this).insertAfter($(this).next()).hide().show('slow');;
}
else
{
$(this).insertBefore($(this).siblings().first()).hide().show('slow');;
}
});
});
fiddle link
I have html page containing 70 or so divs, all with the same name, but each has different content within it. I am trying to make them searchable by filtering the content using jquery. I have it working already somewhat, you can see the page here:
http://smokefreehousingak.org/find-housing.html
The trouble I'm having is combining both the input from text, and the selects you see underneath the search bar. Right now the divs are filtered, but only per item, that is you cannot put a string in the text input, then change the value of the selects, and have it filter the divs based on all 3 or 4 pieces of data. It will only filter based on whichever input or select was last acted upon.
The jquery/javascript for the input filtering is thus:
function searchPage(searchQuery) {
$('.secondary-container').hide();
var searchQuery = $('#search-criteria').val();
console.log("search query is");
console.log(searchQuery);
$('.secondary-container').each(function(){
if($(this).text().toUpperCase().indexOf(searchQuery.toUpperCase()) != -1){
$(this).fadeIn(450);
}
});
console.log("page searched");
}
$('#search').click(function(){
searchPage();
});
$("#searchbox").submit(function() {
searchPage();
return false;
});
The HTML for each item being filtered is like so (just with different info in each one):
<div class="main-container secondary-container">
<aside id="filler-aside">
</aside>
<div class="main-content full listing">
<div class="main-content listing-picture" style="background: url('img/maps/image70.jpg') no-repeat center center;-webkit-background-size: cover;-moz-background-size: cover;-o-background-size: cover;background-size: cover;"></div>
<div class="main-content listing-data">
<h3>"Retirement Community of Fairbanks Inc."</h3>
<h3>Raven Landing</h3>
<p><span>Address:</span> 1222 Cowles St.<br>
<span>City:</span> Fairbanks<br>
<span>Zip:</span> 99701<br>
<span>Type of Housing:</span> Senior <br>
<span>Classification:</span> * Smoking is not allowed anywhere inside a building or complex</p>
</div>
</div>
</div>
The jquery/javascript for filtering divs based on one a select is like so (this is the code for the city select):
function citySelect() {
$('.secondary-container').hide();
$("#city-select").bind("change", function() {
console.log("city changed to");
city = $("#city-select option:selected").text();
console.log(city);
// searchPage(city);
$('.secondary-container').each(function(){
if($(this).text().toUpperCase().indexOf(city.toUpperCase()) != -1){
$(this).fadeIn(450);
console.log("text");
}
});
});
Right now I have each select with its own function thats called after its acted on, that then filters the divs based on the data selected. I think what I need is just one function that gets called anytime a select or input is acted upon, that will filter the divs based on all inputs or selects instead of statically choosing just one piece of data to work with.
Currently, the input search filter works by seeing if any div contains the text inputed into the field:
$('.secondary-container').each(function(){
if($(this).text().toUpperCase().indexOf(searchQuery.toUpperCase()) != -1){
$(this).fadeIn(450);
}
});
I need to somehow say if it includes searchQuery AND input data, etc... same thing when the inputs, I need basically this whole search function to act on all the data input not just one piece. Any suggestions?
You can do something like this:
function searchPage() {
var search = $('#search-criteria').val().toUpperCase();
var city = $("#city-select option:selected").text().toUpperCase();
$('.secondary-container').each(function(){
var text = $(this).text().toUpperCase();
$(this).hide();
if((!search || text.indexOf(search) !== -1) && (!city || text.indexOf(city) !== -1)) {
$(this).fadeIn(450);
}
});
};
I also added !searchand !city to make sure the result is shown if the string is empty.
Since the above ignores the selects if they are empty, but initially they have a default value of "Filter By...", I made a function that checks if the value of the select is "Filter By..." and if so, it sets the city variable to being empty, so that it will get ignored (via !search and !city), and if the value has been changed, then it executes how it normally would.
var search = $('#search-criteria').val().toUpperCase();
var city = $("#city-select option:selected").text().toUpperCase();
var cityStart = "Filter By City";
if(city.indexOf(cityStart.toUpperCase()) != -1){
console.log("city untouched");
console.log(cityStart);
var city = "";
console.log(city);
} else {
console.log("city not default");
}
$('.secondary-container').each(function(){
var text = $(this).text().toUpperCase();
$(this).hide();
if((!search || text.indexOf(search) !== -1) && (!city || text.indexOf(city) !== -1)) {
$(this).fadeIn(450);
}
});
What I am trying to achieve here is when a user clicks an element it becomes hidden, once this happens I want to prepend inside the containing element another Element to make all these items visible again.
var checkIfleft = $('#left .module'),checkIfright = $('#right .module');
if(checkIfleft.hasClass('hidden')) {
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if(checkIfright.hasClass('hidden')) {
right.prepend('<span class="resetRight">Reset Right</span>');
}
I tried multiple ways, and honestly I believe .length ==1 would be my best bet, because I only want one element to be prepended. I believe the above JS I have will prepend a new element each time a new item is hidden if it worked.
Other Try:
var checkIfleft = $('#left .module').hasClass('hidden'),
checkIfright = $('#right .module').hasClass('hidden');
if(checkIfleft.length== 1) {
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if(checkIfright.length== 1) {
right.prepend('<span class="resetRight">Reset Right</span>');
}
else if(checkIfleft.length==0){
$('.resetLeft').remove()
} else if (checkIfright.length==0){
$('.resetRight').remove()
}
Basically if one element inside the container is hidden I want a reset button to appear, if not remove that reset button...
hasClass() only works on the first item in the collection so it isn't doing what you want. It won't tell you if any item has that class.
You can do something like this instead where you count how many hidden items there are and if there are 1 or more and there isn't already a reset button, then you add the reset button. If there are no hidden items and there is a reset button, you remove it:
function checkResetButtons() {
var resetLeft = $('#left .resetLeft').length === 0;
var resetRight = $('#left .resetRight').length === 0;
var leftHidden = $('#left .module .hidden').length !== 0;
var rightHidden = $('#right .module .hidden').length !== 0;
if (leftHidden && !resetLeft) {
// make sure a button is added if needed and not already present
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if (!leftHidden) {
// make sure button is removed if no hidden items
// if no button exists, this just does nothing
$('#left .resetLeft').remove();
}
if (rightHidden && !resetRight) {
$('#right').prepend('<span class="resetRight">Reset Right</span>');
} else if (!rightHidden) {
$('#right .resetRight').remove();
}
}
// event handlers for the reset buttons
// uses delegated event handling so it will work even though the reset buttons
// are deleted and recreated
$("#left").on("click", ".resetLeft", function() {
$("#left .hidden").removeClass("hidden");
$("#left .resetLeft").remove();
});
$("#right").on("click", ".resetRight", function() {
$("#right .hidden").removeClass("hidden");
$("#right .resetRight").remove();
});
FYI, if we could change the HTML to use more common classes, the separate code for left and right could be combined into one piece of common code.
Add the reset button when hiding the .module, if it's not already there :
$('#left .module').on('click', function() {
$(this).addClass('hidden');
var parent = $(this).closest('#left');
if ( ! parent.find('.resetLeft') ) {
var res = $('<span />', {'class': 'resetLeft', text : 'Reset Left'});
parent.append(res);
res.one('click', function() {
$(this).closest('#left').find('.module').show();
$(this).remove();
});
}
});
repeat for right side !
I've recently experimented with using CSS to do some of this stuff and I feel that it works quite well if you're not trying to animate it. Here is a jsfiddle where I can hide a module and show the reset button in one go by adding/removing a 'hideLeft' or 'hideRight' class to the common parent of the two modules.
It works by hiding both reset button divs at first. Then it uses .hideLeft #left { display:none;} and .hideLeft #right .resetLeft { display: block; } to hide the left module and display the reset button when .hideLeft has been added to whichever element both elements descend from. I was inspired by modernizr a while back and thought it was a neat alternative way to do things. Let me know what you think, if you find it helpful, and if you have any questions :)
UPDATE 2:
Thanks so much for all your help. While all three solutions worked, I like Bill's in terms of readability and performance. As always, I'm amazed by the level of expertise and help here. REALLY appreciate the help.
UPDATE:
Put demo up on jsfiddle: http://jsfiddle.net/FC4QE/17/
I need to create a filter. Users click on a brand name link and if there is a match then I need to filter out the other products. The brand is contained in a product name, so I'm searching for a match and if there is one or many, I need to hide the other products.
I have the following javascipt/jquery code:
$(function(){
$('#filter-by-brand li a').click(function(){
// get html string of clicked item
var brandNameSelected = $(this).html();
var productContainer = $('#product-collection div.productBoxWrapper');
// reset products in the view
if (brandNameSelected == 'All Brands'){
productContainer.fadeIn("slow");
}
// for each product title (a tag)
$("#product-collection h4 a").each(function(){
var productTitle = jQuery(this).html();
// if item clicked is contained inside product title, hide all
// products and only show the ones where the title matched
if(productTitle.indexOf(brandNameSelected) != -1){
// hide container of all products, this hides all products
productContainer.fadeOut("slow");
// then show only ones that match. the problem is that only the one product is
// displayed since we're inside the .each. How can I show all products where product title contains the item clicked?
$(this).parent().parent().parent().parent().fadeIn("slow");
}
});
});
});
I explained everything in the comments inside the code, but basically, while the code works, because I'm showing the products where item clicked is contained inside the .each method, it only shows the last item matched. How can I show all the matched ones inside the .each or is this impossible and is there another way?
Hope this makes sense and that someone might have some advice!
Thanks.
I got the nicest looking results from this:
$('#filter-by-brand li a').click(function()
{
var brandNameSelected = $(this).html();
var productContainer = $('#product-collection .product-container');
if (brandNameSelected == 'All Brands')
{
productContainer.fadeIn("slow");
}
else {
$(".product-container")
.fadeOut(100)
.delay(100)
.filter(function() {
return $(this).html().indexOf(brandNameSelected) > -1;
})
.each(function(index, item) {
$(item).fadeIn("slow");
});
}
});
You can play with it at http://jsfiddle.net/tu8tc/1/;
For "all brands", bail out. For specific brand names, hide all productContainers unconditionally then selectively fadeIn those that meet the criterion.
$(function() {
$('#filter-by-brand li a').click(function() {
var brandNameSelected = $(this).html();
var productContainer = $('#product-collection .product-container');
if (brandNameSelected == 'All Brands') {
productContainer.fadeIn("slow");
return;
}
productContainer.hide();
$("#product-collection h4 a").each(function() {
var productTitle = $(this).html();
if(productTitle.indexOf(brandNameSelected) != -1) {
$(this).closest(".product-container").stop().fadeIn("slow");
}
});
});
});
See update of your fiddle
Note how jQuery's .closest() avoids the ugly .parent().parent().parent().
.stop() is precautionary, just in case a fadeout() is already running on the element. Not necessary if this is the only code that animates productContainers.
EDIT...
Or to be concise and more efficient, with judicious use of jQuery's .filter you can do almost everything in one statement (though readability suffers):
$(function() {
$('#filter-by-brand li a').click(function() {
var brandNameSelected = $(this).html();
$('#product-collection').find('.product-container').hide().end().find('h4 a').filter(function() {
return (brandNameSelected == 'All Brands') || ($(this).html().indexOf(brandNameSelected) != -1);
}).closest(".product-container").stop().fadeIn("slow");
});
});
See further update to fiddle
Why not simply hide products that you want filtered out?
if(productTitle.indexOf(brandNameSelected) == -1)
{
$(this).parent().parent().parent().fadeOut("slow");
}
See http://jsfiddle.net/2Sduq/1/ .
Answer in
how to make sort icons visible in all column headers in jqgrid regardless on sort status
describes how to add sortable indication to columns.
It is difficult to distinguish sorted and unsorted column by default sort indicator.
How to underline sorted column header text in addidion to sort indicator ?
I modified the demo from the previous answer to the following which display now
I used for the demo the CSS class where I additionally to underlining changed the color of the text
.sortedColumnHeader > div { text-decoration: underline; color: blue; }
If we play forward we can use just the 'ui-state-highlight' for the highlighting (see another demo). The column header will be probably even too much distinguish from the standard column:
The corresponding code is
var $grid = $("#list"), colModel, sortName;
// create the grid
$grid.jqGrid({
// all typical jqGrid parameters
onSortCol: function (index, idxcol, sortorder) {
if (this.p.lastsort >= 0 && this.p.lastsort !== idxcol
&& this.p.colModel[this.p.lastsort].sortable !== false) {
// show the icons of last sorted column
$(this.grid.headers[this.p.lastsort].el)
.find(">div.ui-jqgrid-sortable>span.s-ico").show();
$(this.grid.headers[this.p.lastsort].el).removeClass('sortedColumnHeader');
}
$(this.grid.headers[idxcol].el).addClass('sortedColumnHeader');
}
});
// show sort icons of all sortable columns
colModel = $grid.jqGrid('getGridParam', 'colModel');
sortName = $grid.jqGrid('getGridParam', 'sortname');
$('#gbox_' + $.jgrid.jqID($grid[0].id) +
' tr.ui-jqgrid-labels th.ui-th-column').each(function (i) {
var cmi = colModel[i], colName = cmi.name;
if (cmi.sortable !== false) {
// show the sorting icons
$(this).find('>div.ui-jqgrid-sortable>span.s-ico').show();
} else if (!cmi.sortable && colName !== 'rn' && colName !== 'cb' && colName !== 'subgrid') {
// change the mouse cursor on the columns which are non-sortable
$(this).find('>div.ui-jqgrid-sortable').css({cursor: 'default'});
}
if (cmi.name === sortName) {
$(this).addClass('sortedColumnHeader');
}
});
At the end I want to reference one more old answer where it's shown another sophisticated method to highlight the sorted column.