Filtering based on two conditions - javascript

I have eight cards with two parameters on each of them. The first parameter is year (2011, 2012, 2013, 2014), the second is category (studio, house, personal, commercial). It looks like this:
Studio 2011
House 2012
Commercial 2013
Personal 2012
Studio 2014
Commercial 2011
House 2014
Personal 2013
I need to sort them out, making needed cards bright, and not needed faded. By default all of them are bright. HTML:
<div class="card card-studio card-2011 card-bright">Studio 2011</div>
<div class="card card-house card-2012 card-bright">House 2012</div>
<div class="card card-commercial card-2013 card-bright">Commercial 2013</div>
<div class="card card-personal card-2012 card-bright">Personal 2012</div>
<div class="card card-studio card-2014 card-bright">Studio 2014</div>
<div class="card card-commercial card-2011 card-bright">Commercial 2011</div>
<div class="card card-house card-2014 card-bright">House 2014 </div>
<div class="card card-personal card-2013 card-bright">Personal 2013</div>
I add buttons with years:
2011
2012
2013
2014
When user clicks a year button, we take cards with needed year class and remove their "bright/faded" classes just in case. Then we add "bright" class to these cards. Then we take all the cards that do not have needed year and add them "faded" class (also removing previous classes just in case). And we also make the button underlined, and its siblings not underlined. It all looks like this:
$(".button").on("click", function(event){
event.preventDefault();
if($(this).hasClass("button-2011")){
$(".card-2011").removeClass("card-bright card-faded").addClass("card-bright");
$(".card").not(".card-2011").removeClass("card-bright card-faded").addClass("card-faded");
$(this).siblings().removeClass("button-active").end().addClass("button-active");
}
JSfiddle: https://jsfiddle.net/6vLzyowc/
Now it all seems simple, but trouble comes up when I try to add the second sorting condition, category.
On the one hand, I certainly need to do the same thing, as in the first case, i. e. make needed category bright, not needed faded:
if($(this).hasClass("button-house")){
$(".card-house").removeClass("card-bright card-faded").addClass("card-bright");
$(".card").not(".card-house").removeClass("card-bright card-faded").addClass("card-faded");
}
But it will make "bright" all cards with the needed category, and I also have the previous year sorting results. It seems that I need to sort them out first. So, I take the first year sorting results (i. e. "bright" cards) and make ones without needed category "faded":
if($(this).hasClass("button-house")){
$(".card-bright").not("card-house").addClass("card-faded");
}
It helps a little, but I still don't know how I can add the remaining cards with needed category now, so that both conditions are satisfied. So, how can I combine sorting previous sorting results and sorting all the items?
Fiddle with all the buttons: https://jsfiddle.net/hm1emr8p/

I think your approach is a bit over-complicated. The following works for any number of filters. The trick is to keep state of what is selected, and on any change just re-apply this state to the card-elements.
(function () {
var active = [];
$('.filter').each(function (idx, el) {
var $el = $(el);
active.push('');
$el.on('click', '.button', function () {
var $this = $(this);
active[idx] = $this.data('toggle');
$el.find('.button').removeClass('button-active');
$this.addClass('button-active');
update();
});
});
function update()
{
var a = active.join('');
if (a.length === 0) {
$('.card').removeClass('card-faded');
}
else {
$('.card').addClass('card-faded').filter(active.join('')).removeClass('card-faded');
}
}
})();
a {
text-decoration: none;
color: black;
}
.buttons {
margin-top: 40px;
}
.time {
margin-bottom: 20px;
}
.card-faded {
opacity: 0.3;
}
.button-active {
text-decoration: underline;
}
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<div class="card card-2011 card-studio">Studio 2011</div>
<div class="card card-2012 card-house">House 2012</div>
<div class="card card-2013 card-commercial">Commercial 2013</div>
<div class="card card-2012 card-personal">Personal 2012</div>
<div class="card card-2014 card-studio">Studio 2014</div>
<div class="card card-2011 card-commercial">Commercial 2011</div>
<div class="card card-2014 card-house">House 2014 </div>
<div class="card card-2013 card-personal">Personal 2013</div>
<div class="buttons">
<div class="filter time">
<a class="button button-2011" data-toggle=".card-2011">2011</a>
<a class="button button-2012" data-toggle=".card-2012">2012</a>
<a class="button button-2013" data-toggle=".card-2013">2013</a>
<a class="button button-2014" data-toggle=".card-2014">2014</a>
<a class="button button-all button-active" data-toggle="">All time</a>
</div>
<div class="filter category">
<a class="button button-studio" data-toggle=".card-studio">Studio</a>
<a class="button button-house" data-toggle=".card-house">House</a>
<a class="button button-commercial" data-toggle=".card-commercial">Commercial</a>
<a class="button button-personal" data-toggle=".card-personal">Personal</a>
<a class="button button-all button-active" data-toggle="">All</a>
</div>
</div>

I suggest saving the selected category and the selected timespan in variables:
var lastCategory = '';
var lastYear = '';
In your case you can use data- attributes to store information like this:
2011
and:
Studio
And perform actions based on the value of the data element in your click handler:
$(".category > .button").on("click", function(event){
event.preventDefault();
var tmpCat = $(this).data('cat');
lastCategory = tmpCat;
$(".card").removeClass("card-faded");
if (tmpCat == 'all') {
if (lastYear == 'alltime') {
$(".card").addClass("card-faded");
} else {
$(".card-"+lastYear).addClass("card-faded");
}
} else {
if (lastYear == 'alltime') {
$(".card-" + tmpCat).addClass("card-faded");
} else {
$(".card-" + tmpCat + ".card-"+lastYear).addClass("card-faded");
}
}
$(this).siblings()
.removeClass("button-active")
.end()
.addClass("button-active");
});
$(".time > .button").on("click", function(event){
event.preventDefault();
var tmpYear = $(this).data('year');
lastYear = tmpYear;
$(".card").removeClass("card-faded");
if (tmpYear == 'alltime') {
if (lastCategory == 'all') {
$(".card").addClass("card-faded");
} else {
$(".card-" + lastCategory).addClass("card-faded");
}
} else {
if (lastCategory == 'all') {
$(".card-" + tmpYear).addClass("card-faded");
} else {
$(".card-" + lastCategory + ".card-"+tmpYear).addClass("card-faded");
}
}
$(this).siblings()
.removeClass("button-active")
.end()
.addClass("button-active");
});
There a zillion ways that lead to rome, this is not ideal, but try to avoid if (1) then, if (2) then, if (3) then, etc.... code. I forked your fiddle and made a working demo.

Related

How to hide an item?

var r1=Math.floor(Math.random()*255)
var g1=Math.floor(Math.random()*255)
var b1=Math.floor(Math.random()*255)
$(".color1").click(function (){
$(this).css("background", "rgb(" + r1 + "," + g1 + "," + b1 + ")")
})
$(document).ready(function () {
$(document).on('click', function (event) {
$target = $(event.target);
$target.addClass('clicked');
});
})
var numItems
var getfirstclass
var getsecondclass
$('div').click(function saveclassnames(){
var getfirstclass=$(this).attr('class')
console.log(getfirstclass)
var getsecondclass=$(this).attr('class')
console.log(getsecondclass)
getfirstclass===null
getsecondclass===null
})
$('div').click(function remove(){
var numItems = $('.clicked').length
if(numItems===2 && getfirstclass === getsecondclass){
$('.clicked').css('opacity', '0')
}
else{
$('.clicked').css('background', 'black')
}
})
<body>
<div class="container">
<div class="row">
<div class="color1"></div>
<div class="color2"></div>
<div class="color3"></div>
<div class="color4"></div>
</div>
<div class="row">
<div class="color5"></div>
<div class="color3"></div>
<div class="color1"></div>
<div class="color6"></div>
</div>
<div class="row">
<div class="color7"></div>
<div class="color6"></div>
<div class="color8"></div>
<div class="color5"></div>
</div>
<div class="row">
<div class="color7"></div>
<div class="color8"></div>
<div class="color4"></div>
<div class="color2"></div>
</div>
</div>
</body>
I am trying to make a game called "Memory" (if 2 flipped cards are same, the cards will disappear, but if the cards are not the same, they will flip back). But there is a difference between the original one). I am using random colors instead of card pictures, but I cannot make <div> elements with the same background-color disappear, or flip back if they are not the same. Can someone explain to me why this code does not work?
Thanks.
opacity: 0; hiding generates a lot of space although the element is not visible.
background: black; – the element needs to blend in with the background, otherwise it will not work (technically it won't work)
You can either do this:
$('yourItem').css({
display: 'none'
});
Or, the "simplest way to hide an element":
$('yourItem').hide();
For more information see https://api.jquery.com/hide/
You could use
display: none
If that messes with other stuff, use
visiblity: hidden;

Using .width() returns undefined

I'm currently building a script to create a slider and stumbled upon an error I can't seem to solve. Basically I trying to get the width of a container and multiply it base on the number of slides inside.
Here is a snippet a of the code I'm working on. Whenever I try to use .width in order to fetch the width of a container it returns undefined on the console. I tried looking back and forth on my code but I can't seem to pinpoint the issue.
_setSliderWidth() {
this.sliderBanner = this.$el.find('.slider-banner');
this.sliderBannerWidth = this.sliderBanner.width();
console.log(this.sliderBannerWidth);
this.slides.width(this.sliderBannerWidth);
this.slidesContainer.width(this.sliderBanner.width() * this.slideCount);
}
-- -- -- -- --
'use strict';
(function($) {
/**
* Base Image Slider class
*/
class ImageSlider {
constructor(el) {
this.$el = $(el);
this._dom();
this.slideCount = this.slides.length;
this.currentSlide = 0;
this.arrows = {
prev: this.$el.find('.arrow.-prev'),
next: this.$el.find('.arrow.-next')
};
// image formatting and detection
this.$el.find('img').each(function(e, el) {
let $img = $(el);
if ($img.height() > $img.width())
$img.addClass('-portrait');
});
this._setSliderWidth();
}
_dom() {
this.slides = this.$el.find('.slides');
this.slidesContainer = this.$el.find('.slider-items');
}
init() {
this._bind();
this._evaluatePosition();
}
_bind() {
this.arrows.next.on('click', this._nextSlide.bind(this));
this.arrows.prev.on('click', this._prevSlide.bind(this));
}
_nextSlide() {
this.currentSlide++;
this._moveSlide();
}
_prevSlide() {
this.currentSlide--;
this._moveSlide();
}
_setSliderWidth() {
this.sliderBanner = this.$el.find('.slider-banner');
this.sliderBannerWidth = this.sliderBanner.width();
console.log(this.sliderBannerWidth);
this.slides.width(this.sliderBannerWidth);
this.slidesContainer.width(this.sliderBanner.width() * this.slideCount);
}
_moveSlide() {
// set the min and max range
if (this.currentSlide < 0) this.currentSlide = 0;
if (this.currentSlide > this.slideCount - 1) this.currentSlide = this.slideCount - 1;
this._evaluatePosition();
this._move();
}
_move() {
let position = this.currentSlide * -100;
this.slidesContainer.css({
transform: 'translate(' + position + '%, 0)'
});
}
_evaluatePosition() {
this.arrows.prev.toggleClass('-hide', (this.currentSlide === 0));
this.arrows.next.toggleClass('-hide', (this.currentSlide === this.slideCount - 1));
}
}
$(document).ready(function() {
//--------------------------------------------------
// Image Slider
let $imageSliders = $('.image-slider');
$imageSliders.each(function(e, el) {
let imageSlider = new ImageSlider(el);
imageSlider.init();
});
//--------------------------------------------------
// Slider Banner
let $bannerSliders = $('.slider-banner');
$bannerSliders.each(function(e, el) {
let bannerSlider = new ImageSlider(el);
bannerSlider.init();
});
});
})(jQuery);
HTML
<div class="slider-banner -alternate">
<span href="#" class="arrow -prev -hide"></span>
<span href="#" class="arrow -next"></span>
<div class="slider-items">
<div class="slides">
<div class="image" style="background-image:url(/iom/sites/default/files/2018-07/partnerships-2_0.jpg)">
<div class="banner-detail">
<div class="article-detail">
<div class="timestamp">
page
</div>
<h2 class="title">
Migrant Integration
</h2>
<div class="mini-caption">
IOM supports policies and strategies that promote the social, economic and cultural inclusion of migrants within existing legal frameworks in countries of destination.
</div>
More Details
</div>
</div>
</div>
</div>
<div class="slides">
<div class="image" style="background-image:url(/iom/sites/default/files/2018-07/definitional-issues_1.jpg)">
<div class="banner-detail">
<div class="article-detail">
<div class="timestamp">
page
</div>
<h2 class="title">
Forum on Migration, Trade and the Global Economy
</h2>
<div class="mini-caption">
IOM, together with partners ICTSD and Fundanción Foro del Sur will host the Forum on Migration, Trade & the Global Economy in Buenos Aires on 14 December.
</div>
More Details
</div>
</div>
</div>
</div>
<div class="slides">
<div class="image" style="background-image:url(/iom/sites/default/files/2018-07/identity-management_0.jpg)">
<div class="banner-detail">
<div class="article-detail">
<div class="timestamp">
page
</div>
<h2 class="title">
Comparative Research on the Assisted Voluntary Return and Reintegration of Migrants
</h2>
<div class="mini-caption">
Assisted Voluntary Return and Reintegration (AVRR) is an indispensable part of a comprehensive approach to migration management aiming at orderly and humane return and reintegration of migrants.
</div>
More Details
</div>
</div>
</div>
</div>
</div>
</div>
It seems from your screenshots and code that the this. sliderBanner object does NOT return a DOM object and thus the .width() would be undefined.
To resolve you can:
1) Retrieve the DOM object through a weird method of this.sliderBanner.prevObject. More information in this thread: What is prevObject and why is my selector returning that?
The main problem is that the .find from the $el object can't doesn't have the slider banner object within it's DOM, so...
2) Try using this.sliderBanner = $(".slider banner") to select the banner from the document object instead

jQuery - Detect when two html `<span>` contain same value

I have the following html structure in my web application.
This is a group of <div>s which contain information about items. Specifically there are two <span> tags with pending and done quantities (integer values).
Clicking on other page elements will modify pending and done values.
Is it possible to track those changes and apply a class to the whole <div> when those values are the same?
So the whole <div id="{{ item.id }}"> will have a green background when pending and done match and no color background when values do not match. The actual action to be done is not relevant, what I miss is understanding the right approach in jQuery to monitor values in two html fields.
<div id="{{ item.id }}" href="#" state="{{ item.state }}" class="item">
<div class="row">
<div class="col-xs-4">
<span name="pending">{{ item.pending }}</span>
</div>
<div class="col-xs-4">
<span name="done">{{ item.done }}</span>
</div>
</div>
</div>
Use find and text functions along with these selectors '[name="pending"]' '[name="done"]'.
To listen to javascript modifications (jQuery), an alternative is to override the .val function.
var originalValFn = jQuery.fn.val;
jQuery.fn.val = function(value) {
originalValFn.apply(this, arguments);
if (value !== undefined) {
$('#done').trigger('input');
$('#pending').trigger('input');
}
};
Look at this code snippet.
The function updateSection must be called when the user changes the values.
var target = $('#myId');
var originalValFn = jQuery.fn.val;
jQuery.fn.val = function(value) {
originalValFn.apply(this, arguments);
if (value !== undefined) {
$('#done').trigger('input');
$('#pending').trigger('input');
}
};
var updateSection = function() {
var pending = target.find('[name="pending"]').text();
var done = target.find('[name="done"]').text();
if (pending === done) {
target.addClass('green-class');
target.removeClass('red-class');
} else {
target.addClass('red-class');
target.removeClass('green-class');
}
}
$('#pending').on('input', function(e) {
target.find('[name="pending"]').text(e.target.value);
updateSection();
});
$('#done').on('input', function(e) {
target.find('[name="done"]').text(e.target.value);
updateSection();
});
$('#done').val('3');
$('#pending').val('4');
//updateSection();
.green-class {
background-color: green;
}
.red-class {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myId" href="#" state="{{ item.state }}" class="item">
<div class="row">
<div class="col-xs-4">
<span name="pending">222</span>
</div>
<div class="col-xs-4">
<span name="done">222</span>
</div>
</div>
</div>
<hr>
<p>Enter values to test:</p>
<input id='pending' placeholder='pending'>
<input id='done' placeholder='done'>
Resources
.find()
.text()
.on()
Sure. Place an input element inside each span and have the values actually be stored in the input. Then, set up input event handlers for those input elements that simply compare the values of the inputs. If they are the same. Apply a class.
// Get inputs
var $pending = $(".pending");
var $done = $(".done");
// Set up event handler
$pending.on("input", test);
$done.on("input", test);
function test(){
if($pending.val() === $done.val()){
$("div#parent").addClass("match");
} else {
$("div#parent").removeClass("match");
}
}
input { outline:none; border:none; }
.pending { background-color:rgba(255, 100, 100, .5); }
.done { background-color:rgba(255, 255, 100, .5); }
.match { background-color:rgba(100, 255, 100, .5); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>For testing, type different (and then the same) values into the two fields</h1>
<div id="parent" href="#" state="{{ item.state }}" class="item">
<div class="row">
<div class="col-xs-4">
<span name="pending"><input class="pending"></span>
</div>
<div class="col-xs-4">
<span name="done"><input class="done"></span>
</div>
</div>
</div>
First: the "name" attribute only applies to input elements, you probably want to use the "id" attribute.
I would also suggest creating a function to check for equality, something like this:
var pendingDone = function(){
if($("#pending").text() === $("#done").text()) {
$("#pending").addClass("green");
$("#done").addClass("green");
} else {
$("#pending").removeClass("green");
$("#done").removeClass("green");
}
}
I would suggest just calling this function in all instances that modify the values, since the change and input listener suggested in another answer will not fire if the value is modified by javascript instead of user interaction.

change a specific string inside html with a javascript variable

i know that there is similiar question like mine here, but sadly not of them seems to work, anyway this is my situation;
i have multiple specific html string that i would change with a variable
the var:
var modelstring="something";
the HTML:
<div class="caratteristichedesk" style="position: relative; text-align: center;font-family: 'corporate_s_reg';height:200px">
<img class="pointdesk" src="img/pointers.png">
<div style="position:absolute;top:60px;width:200px;left:5px;">Verrai ricontattato entro 24 ore per confermare i tuoi dati.</div>
<div style="position:absolute;top:60px;width:200px;left:235px;">Il dealer ti richiamerà per confermare l’appuntamento.</div>
<div style="position:absolute;top:60px;width:250px;left:435px;">Vivi l’esperienza di guida a bordo <br>della MODELLO.</div>
</div>
i was looking for a very simple way to change the "MODELLO" string with my var above, anyone have an advice? thank you
Here's a jquery free way to do it.
var modelstring = "something",
replaceSelector = document.querySelectorAll('.toReplace'),
replaceCount;
for(replaceCount = 0; replaceCount < replaceSelector.length; replaceCount++) {
replaceSelector[replaceCount].innerHTML = modelstring;
}
<div class="caratteristichedesk" style="position: relative; text-align: center;font-family: 'corporate_s_reg';height:200px">
<img class="pointdesk" src="img/pointers.png">
<div style="position:absolute;top:60px;width:200px;left:5px;">Verrai ricontattato entro 24 ore per confermare i tuoi dati.</div>
<div style="position:absolute;top:60px;width:200px;left:235px;">Il dealer ti richiamerà per confermare l’appuntamento.</div>
<div style="position:absolute;top:60px;width:250px;left:435px;">Vivi l’esperienza di guida a bordo
<br>della <span class="toReplace">MODELLO.</span></div>
</div>
There are many ways to make that,
var modelstring ="something";
$(document).ready ( function (){
$('div').each( function() {
var txt = $(this).text();
$(this).text( txt.replace("MODELLO", modelstring) );
});
});

Displaying div content below its row in responsive design

I have a 8 div at present and it may increase or decrease in count.Each of these div contain on clicking which it displays content relate to it.At a fixed with of 1024px and above it is working fine.But problem is all these div are responsive,at lower resolution the hidden div that is to be displayed are misaligned. Can any one help me in the same ?
This is the html core that i have wrote:-
<div class="client-details fl_left" style="display: none;"
id="citiCab2">
<span class="pointer" style="left: 73px;"></span> <a
class="close-button" href=""></a>
<div class="client-container fl_left">
<a href="http://citicabsinc.com/" target="_blank"><img
src="images/citicabs-big.png"></a>
</div>
<div class="client-container fl_right">
<h1>Citi Cabs</h1>
<p>The client is a progressive firm, providing eminent car rental
services to all kinds for travel requirements. It caters transport
and communication to its customers all over India.</p>
<p class="title">Client Requirement </p>
<p>The client wanted to come up with a website portal, that can be
navigated with ease by the visitor who is looking for the car
service within Bangalore and anywhere in India.</p>
<p class="title">Challenge</p>
<p>We the Maganiva Solutions Team had to predominantly understand
website workflow making it intuitive for the user to use it with
ease keeping in mind the visitor's page. </p>
<p class="title">What Maganiva Solutions delivered </p>
<p>Maganiva did a complete market study to get insights and came up
with a comprehensive model, wherein we not only designed the user
friendly website but also provided back-end support to the client
in Branding its online presence through SEO.</p>
</div>
</div>
Java script for the same.Also help to reduce the size of the code, as you can see i have simply repeated the same code again and again with only difference in the id to be called on mouse click to a particular div.
jQuery(function() {
$('#citiCab1').click(function() {
$(".client-details").addClass('display-none');
$('#citiCab2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#citiCab2").addClass('display');
});
$('#primus1').click(function() {
$(".client-details").addClass('display-none');
$('#primus2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#primus2").addClass('display');
});
$('#MantriEden1').click(function() {
$(".client-details").addClass('display-none');
$('#MantriEden2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#MantriEden2").addClass('display');
});
$('#DilDaruDosti1').click(function() {
$(".client-details").addClass('display-none');
$('#DilDaruDosti2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#DilDaruDosti2").addClass('display');
});
$('#chai1').click(function() {
$(".client-details").addClass('display-none');
$('#chai2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#chai2").addClass('display');
});
$('#mbnt1').click(function() {
$(".client-details").addClass('display-none');
$('#mbnt2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#mbnt2").addClass('display');
});
$('#act1').click(function() {
$(".client-details").addClass('display-none');
$('#act2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#act2").addClass('display');
});
$('#mathru1').click(function() {
$(".client-details").addClass('display-none');
$('#mathru2').attr('style', function(i, style) {
jQuery(this).removeClass('display-none');
return style.replace(/display[^;]+;?/g, '');
});
$("#mathru2").addClass('display');
});
});
Hope this what you are looking for, try the below html. Hope it helps you!!!
HTML:
<p><strong>Head1</strong></p>
<div class="desc" id="desc1" style="display: none;">
<h2>Description 1</h2>
<p>Content</p>
<p><a class="close" href="JavaScript:toggleMe('desc1');">Close</a></p>
</div>
<p><strong>Head2</strong></p>
<div class="desc" id="desc2" style="display: none;">
<h2>Description 2</h2>
<p>Content</p>
<p><a class="close" href="JavaScript:toggleMe('desc2');">Close</a></p>
</div>
CSS:
.close{
text-align:right;
display:block;
padding:10px;
}
.desc{
background:#dedede;
padding:10px;
}
Script:
<script>
function toggleMe(a) {
var e = document.getElementById(a);
if (!e) return true;
if (e.style.display == "none") {
e.style.display = "block"
} else {
e.style.display = "none"
}
}
</script>
Fiddle Demo

Categories

Resources