jquery find element and add class to element - javascript

Trying to add a class to an element inside an li item when a function call is made. I can get the correct value outputted, however finding the child <i> is proving difficult. If I could find the correct nested <i> and add the class 'show' that would solve it :)
JS code:
filterMarkers = function(category) {
for (i = 0; i < markers1.length; i++) {
marker = gmarkers1[i];
// If is same category or category not picked
if (marker.category == category || category.length === 0) {
marker.setVisible(true);
// Show the tick icon
$(".filter").find("[data-value='" + category + "']").addClass('show');
}
// Categories don't match
else {
marker.setVisible(false);
}
}
}
HTML code:
<ul class="drop-down">
<li class="filter blue" data-value="" onclick="filterMarkers('');">All <i class="fi-check"></i></li>
<li class="filter yellow" data-value="test-one" onclick="filterMarkers('test-one');">Sales <i class="fi-check"></i></li>
<li class="filter red" data-value="test-two" onclick="filterMarkers('test-two');">Incentives <i class="fi-check"></i></li>
<li class="filter grey" data-value="test-three" onclick="filterMarkers('test-three');">Conferences <i class="fi-check"></i></li>
<li class="filter orange" data-value="test-four" onclick="filterMarkers('test-four');">Team building <i class="fi-check"></i></li>
</ul>

Looking at the filterMarkers method, you
Either want to simply show the category which is passed as argument and hide everything else
Or if no argument is passed then hide everything.
Simplify your code to
filterMarkers = function(category) {
$(".filter").removeClass("show"); //remove show class from all
if( category.length > 0 )
{
$(".filter[data-value='" + category + "']").addClass('show');
}
for (i = 0; i < markers1.length; i++)
{
marker = gmarkers1[i];
marker.category == category || category.length === 0 ? marker.setVisible( true ) : marker.setVisible( false );
}
}
}

$(".filter[data-value='" + category + "']").addClass('show');

Related

Selecting a specific class in jQuery

I'm trying to filter different posts kinda page. Each post has many different categories. But the search filter is two-layered, the main filter and then below a more specific selection of filters where I used checkboxes. The problem is that all categories are on the same level. How can I access each selected class based on the user filter input and then output the right post?
Categories and their classes are listed like this:
<span class="category">
<span class="cat Event">Event</span>
<span class="cat Developing">Developing</span>
<span class="cat SQL">SQL</span>
</span>
Where "Event" is in the main filter and the other two are in the second checkbox filter
The project is done in MVC .NET and for filtering functionality, I'm using jQuery
This is how to get each post in my view:
<div class="novice-list">
#foreach (var item in Model.Articles)
{
<div class="novica-container">
<a href="#DataContext.Current.RouteUrlManager.GetModuleLink("article", null, "details", item.Id, item.Title)">
<div class="media">
#{
string slika = string.Empty;
if (item.Id > 166 || item.Id == 159)
{
slika = $"{WellKnownStrings.StorageBaseUrl}{WellKnownStrings.ArticleImageContainer}/{item.FeaturedImage}";
}
else
{
slika = item.FeaturedImageUrl;
}
}
<div class="slika" style="background-image: url('#if (item.FeaturedImageUrl != "") { #slika }');">
</div>
<div class="media-body">
#*content*#
<div class="meta">
<span class="published">#item.DateFormated</span>
<span class="category">
#foreach (var cat in #item.Category)
{
<span class="cat #cat.Title">#cat.Title</span>
}
</span>
</div>
<h2>#item.Title</h2>
<p>#item.Summary</p>
</div>
</div>
</a>
</div>
}
</div>
this is how I get matches from first (Main) filtering:
isCheckedMain = true;
if (isCheckedMain) {
var selectedClass = $(this).attr('class');
// reset the active class on all the buttons
$('#filterOptions li').removeClass('show');
// update the active state on our clicked button
$(this).parent().addClass('show');
if (selectedClass == 'all') {
// show all our items
$('.novica-container').slideDown(1000, "linear");
}
else {
// hide all elements that don't share ourClass
$('.novica-container').hide();
// show all elements that do share ourClass
$('.novica-container').find('span.cat.' + selectedClass).parents('.novica-container').slideDown(1000, "linear");
}
}
And matches for checkbox filter:
$(".checkbox-filter :checkbox").click(function () {
isBoxChecked = true;
if (isCheckedMain && isBoxChecked) {
var selectedBox = $(this).attr('id');
var selectedMain = selectedClass;
if ($('input#' + selectedBox).is(':checked')) {
if ($('span.cat').hasClass(selectedMain)) {
$('.novica-container').hide();
$('span.cat.'+selectedMain).addClass(selectedBox);
$('.checkbox-filter :checkbox:checked').each(function () {
//Get the selected checkbox value
var selectedBox = $(this).attr('id');
$('.novica-container').find('span.cat.' + selectedMain ,'.'+selectedBox).parents('.novica-container').slideDown(700);
});
}
}
else if ($(this).is(':not(checked')) {
$('.novica-container').find('span.cat.' + selectedBox).parents('.novica-container').slideUp(700);
if (($('input[type="checkbox"]:checked').length === 0)) {
isBoxChecked = false;
$('.novica-container').slideDown(1000, "linear");
This is what I have so far, I'm trying to do something with true-false( if one is true, search only with the main filter, if both are true search more accurately with other categories. And I've been stuck here for days trying to merge both sides of the code. They both work separately but not together
Picture of filter
Found a solution for this.
I added all of the categories names one level higher in my View. So that class="category" now has values of all the other categories.
Example: class="category Event Developing SQL"
And then I could just use this jQuery to filter selected posts
$('span.category.' + selectedMain + '.' + selectedBox).parents('.novica-container').slideDown(700);

Setting and unsetting active class in bootstrap pagination

I have this bit of Javascript that handles clicks on my navbar. It is working for the most part the disable style is being applied where it should be the previous next, first, and last buttons all take you to the correct page. For some reason the same technique applied to the active style is not working. Ideally I never want any buttons to show as active except the current page button. Whichever button I click shows as active though and the current page doesn't get the active style unless you click on it. Any help on the correct syntax to set and unset active on my Navbar buttons would be appreciated.
var current_page;
var total_pages;
function fnPage_click(multiplyer) {
//make all buttons inactive and enabled
for (var i = 0; i < total_pages; i++)
$('#li' + i).removeClass("active");
$('#li.prev').removeClass("active");
$('#li.prev').removeClass("disabled");
$('#li.next').removeClass("active");
$('#li.next').removeClass("disabled");
$('#li.first').removeClass("active");
$('#li.last').removeClass("active");
$.ajax({
url: '/Home/Browsing?' + multiplyer,
type: 'POST',
error: function (xhr) {
alert('Error: ' + xhr.statusText);
},
success: function (result) {
$("#divLocGrid").html(result);
current_page = multiplyer;
switch (current_page) {
case 1: {
//Previous is disabled/inactive, First is inactive, the current_page is active
$("#li.prev").removeClass("active").addClass("disabled");
$("li.first").removeClass("active");
$('#li' + current_page).addClass("active");
break;
}
case total_pages: {
//Next is disabled/inactive, Last is inactive, the current_page is active
$('#li.next').removeClass("active").addClass("disabled");
$("li.last").removeClass("active");
$('#li' + current_page).addClass("active");
break;
}
default: {
//Previous and Next are enabled but inactive the current_page is active
$('#li.prev').removeClass("active");
$('#li.next').removeClass("active");
$('li' + current_page).addClass("active");
break;
}
}
},
async: true,
processData: false
});
}
function fnPrevNxt(strDir) {
var multiplyer;
if (strDir == 'Nxt') {
multiplyer = current_page + 1;
if (multiplyer > total_pages) {
$('#li.next').removeClass("active").addClass("disabled");
return;
}
}
else {
multiplyer = current_page - 1;
if (multiplyer < 1) {
$('#li.prev').removeClass("active").addClass("disabled");
return;
}
}
fnPage_click(multiplyer);
}
function fnOnNavBtnsLoad(model) {
total_pages = model;
fnPage_click(1);
}
<body onload="fnOnNavBtnsLoad(#Model)">
<div id="dvNavBtns">
<nav class="navbar navbar-expand-lg bg-gray-light navbar-dark" aria-label="Locations pages">
<ul id="ulNavBtns" class="pagination">
<li id="li.first" class="page-item">
First
</li>
<li id="li.prev" class="page-item">
<a href="javascript:void(0)" id="btnPrev" aria-label="<<" class="page-link" onclick="fnPrevNxt('Prev')">
<span aria-hidden="true">«</span>
</a>
</li>
#{int pages = Model;
int num = 0;
while (num < pages)
{
num++;
<li id="li" +#(num) class="page-item">
<a href="javascript:void(0)" aria-label=#num class="page-link" onclick="fnPage_click(#(num))">
#(num)
</a>
</li>
}
}
<li id="li.next" class="page-item">
<a href="javascript:void(0)" id="btnNxt" aria-label=">>" class="page-link" onclick="fnPrevNxt('Nxt')">
<span aria-hidden="true">»</span>
</a>
</li>
<li id="li.last" class="page-item">
Last
</li>
</ul>
</nav>
</div>
Its kind of convoluted but this is the syntax that finally worked for me. I had to go through the document.context.all collection of elements to find the element then add or remove from the classList collection of the element.
$(document).context.all['li.id'].classList.add("classname");
$(document).context.all['li.id'].classList.remove("classname");

how to apply active class using ng-class for list elements(mutli-select)?

I have a scenario,that I have static list elements,where I need to add active class using ng-class,when I click on list element,the active class would be added.
Here is my code:
vm.idArry = [];
vm.selectedFunc = function (item) {
item.selected = !item.selected;
if(vm.idArry.indexOf(item) == -1){
vm.idArry.push(item);
}
else {
var index = vm.idArry.indexOf(item);
vm.idArry.splice(index, 1);
}
}
Html:
<ul>
<li id="one"><a ng-class="{'active':item.selected}" ng-click="selectedrFunc(1)" ></a></li>
<li id="two"><a ng-class="{'active':item.selected}" ng-click="selectedFunc(2)" ></a></li>
<li id="three"><a ng-class="{'active':item.selected}" ng-click="selectedFunc(3)"></a></li>
<li id="four"><a ng-class="{'active':item.selected}" ng-click="selectedFunc(4)" ></a></li>
<li id="five"><a ng-class="{'active':item.selected}" ng-click="selectedFunc(5)"></a></li>
<li id="six"><a ng-class="{'active':item.selected}" ng-click="selectedFunc(6)" ></a></li>
for the above code,I have to get append active class when I click on list elements(i.e; multiple list must be added active class when I clicked on multiple list elements).
Thanks in advance.
Any help would be appreciated.
Remove usage of item.selected and use following code:
<li id="one"><a ng-class="{'active': vm.idArry.indexOf(1) != -1}" ng-click="selectedFunc(1)" >A</a></li>
This checks for item existence in vm.idArray; Also remove item.selected on vm.selectedFunc
So your vm.selectedFunc should look like this:
vm.selectedFunc = function (item) {
if(vm.idArry.indexOf(item) == -1){
vm.idArry.push(item);
}
else {
var index = vm.idArry.indexOf(item);
vm.idArry.splice(index, 1);
}
}

How to make ng-click works only on click event

I am new to angular and trying to toggle a class on click only on current link.
But on click it is working on all links. I want it works only on current element.
For which we use (this) in jquery.
script:
var data = '<td id="'+index+'" class="drag drop"><div class="ui-resizable tac"><div class="ui-resizable">' + header[index].description + '<br>' + header[index].name +'</div></div><div id="div'+index+'" class="report-container" style="display:inline-block;float:left;"><ul class="report-list">';
for( var key = 0; key < listTemp.length; key ++){
data+= "<li class='bg-l-grey' ng-class='{ opened: selectedIndex == 0}' style='background:" + listTemp[key].color +"'><span><em class='left'>" + listTemp[key].mpValue + "</em><em class='right'>" + parseInt(listTemp[key].yield) + "</em></span>"+
'<div class="list-swiper bg-black" ng-click="selectedIndex = 0"><span class="swipe-left"></span><span class="swipe-right"></span></div><div class="report-icon-list bg-l-green"><span><i class="cht-sprite"></i></span><span><i class="cht-sprite"></i></span><span><i class="cht-sprite"></i></span></div></li>';
}
data+= '</ul></div></td>';
$scope.openSwap = function($event) {
// body...
var elementParent = $event.currentTarget.parentElement.offsetParent;
angular.element(elementParent).toggleClass("opened");
if ($(elementParent).hasClass("opened")) {
}else {
console.log(false);
}
$event.stopPropagation();
}
I want click event on ".list-swiper" class and class toggle on parent li.
You can toggle a class and use ng-class with this:
<div class="list-swiper bg-black"
ng-class="{ opened: thisElementClicked }"
ng-click="thisElementClicked = true">..</div>
This will add a class 'opened' to the div element when you click it.
You can of course also add the ng-class to the parent, which will add the class on the parent:
<li ng-class="{ opened: thisElementClicked }">
<div class="list-swiper bg-black"
ng-click="thisElementClicked = true">..</div>
</li>
You probably have multiple li elements, where you might want to do this more dynamically:
<ul>
<li ng-class="{ opened: selectedIndex == 0 }">
<div class="list-swiper bg-black"
ng-click="openSwap(0)">..</div>
</li>
<li ng-class="{ opened: selectedIndex == 1 }">
<div class="list-swiper bg-black"
ng-click="openSwap(1)">..</div>
</li>
</ul>
controller:
$scope.openSwap = function (index) {
$scope.selectedIndex = index;
// .. more
}
Even simpler, if you can build the li's dynamically:
$scope.swipers = [
{ title: "first swiper"},
{ title: "second swiper"},
// ..
}
$scope.openSwap = function (index) {
$scope.selectedIndex = index;
// or toggle, depends what you want:
// if ($scope.selectedIndex == index) {
// $scope.selectedIndex = -1;
// } else {
// $scope.selectedIndex = index;
// }
}
view:
<ul>
<li ng-repeat="swiper in swipers"
ng-class="{ opened: selectedIndex == $index }">
<div class="list-swiper bg-black"
ng-click="openSwap($index)">{{ swiper.title }}</div>
</li>
</ul>
"jqLite" (defined on the angular.element page) provides DOM traversal methods like children(), parent(), contents(), find(), next() (but not previous()). There is no selector-like method.
You can try core JavaScript's querySelector, follow link:
https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector.
There is no any $(this) concept in angular what you do in jquery, instead you have to traverse till the element through javascripts querySelector or angular.element(document).find(...) or $document.find()
for documentation find the checkout below link:
https://docs.angularjs.org/api/ng/function/angular.element
Use ng-class to change the class on this particular link.
<ANY class="ng-class: expression;"> ... </ANY>

Ask for multiple id's with the same data attribute

I'm trying to check for a data attribute in multiple list items.
My HTML:
<ul id="year">
<li id="2006">2006</li>
<li id="2007">2007</li>
<li id="2008">2008</li>
<li id="2009">2009</li>
<li id="2010">2010</li>
<li id="2011">2011</li>
<li id="2012">2012</li>
<li id="2013">2013</li>
<li id="2014">2014</li>
</ul>
And this is the jQuery:
jQuery('#year li').click(function()
{
var year = jQuery(this).attr('id');
if ((jQuery(this).data('state') === undefined) || (jQuery(this).data('state') == "off"))
{
jQuery(this).data('state', 'on');
}
else
{
jQuery(this).data('state', 'off');
}
});
Now i am trying to check if there are any list items where the "state" == "on"
Like this:
if ((jQuery('#year li').data('state') == "on"))
But it does not seem to be working...
EDIT: So i tried all the different snippets you gave me: none of them worked so i made a simple for loop that looks in every list point itself:
for ( var y = 2006, l = 2015; y < l; y++ )
{
if ((jQuery('#year #'+y).data('state') == "on"))
{
alert('data found');
}
Another problem was that i didnt had any event before my code!
Thanks for the support!
the jQuery('#year li') will return an array of jquery objects.
you will need to loop each one
$('#year li').each(function () {
if ((jQuery(this).data('state') === "on")){
alert("on state found");
}
});
You can use .filter() then check length property
var list = jQuery('#year li').filter(function(){
return $(this).data('state') == "on";
//OR, using native dataset
//return this.dataset.state == 'on'
});
if (list.length){
//li with state on exits
}
The reason this doesn't work for you is that jQuery doesn't store data values in the "standard" element dataset. You can acheive your goal by doing that yourself:
$('#year li').click(function() {
this.dataset.state = this.dataset.state === 'off' ? 'on' : 'off';
if($('#year li[data-state="on"]').length > 0) {
alert('Found!')
}
});
#year li[data-state="on"] {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="year">
<li id="2006">2006</li>
<li id="2007">2007</li>
<li id="2008">2008</li>
<li id="2009">2009</li>
<li id="2010">2010</li>
<li id="2011">2011</li>
<li id="2012">2012</li>
<li id="2013">2013</li>
<li id="2014">2014</li>
</ul>

Categories

Resources