ng-class apply outside of ng-repeat? - javascript

<ul class="listing listing-sm small" ng-class="{'divider': (model.selections | filter:filter).length > 0}">
<li ng-repeat="selection in model.selections | filter:filter" ng-class="{highlight: selection.on}">
Is there a better way to add the class on the ul without running the data through the filter 2x (on the ul and the ng-repeat)?

You can create the filter in a callback function and check the length their and change a flag accordingly to the result.
<ul class="listing listing-sm small" ng-class="{'divider':hasResults}">
<li ng-repeat="selection in manualFilter(model.selections)" ng-class="{highlight: selection.on}">
And in the js:
$scope.manualFilter = function(selections) {
var result = $filter('filter')(selections);
if (result.length > 0 ) {
$scope.hasResults = true;
} else {
$scope.hasResults = false;
}
}

You can use something like $index and a variable called $scope.selected and use
ng-class = "'highlight': $index === selected"

Related

jquery append where trigger is bigger then

I'm trying to append child to listing but what I want to do is to append it in the place ordering by data-price.
my template:
<ul>
<li data-price="18"></li>
<li data-price="27"></li>
<li data-price="28"></li>
<li data-price="31"></li>
<li data-price="99"></li>
<li data-price="101"></li>
<li data-price="191"></li>
</ul>
my js what I've tried so far:
var template = '<li data-price="100"></li>';
$('ul').find('li').filter(function() {
return $(this).attr("data-price") > 99;
}).after(template);
so if the price is 100 it should be appended by price ordering and in this case where price is greater then 99 but less then 101, but i dont have any working solution for that.
I'm not sure if this is the best way to do it and if it'll always work, but it works for your question. Try it out
var template = '<li data-price="100">100</li>';
var checkPrice = $(template).attr("data-price");
var appendBefore = $('ul li').filter(function(){
return parseInt($(this).attr("data-price")) > checkPrice-1;
})[0];
console.log(appendBefore);
$(appendBefore).before(template);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li data-price="18">18</li>
<li data-price="27">27</li>
<li data-price="28">28</li>
<li data-price="31">31</li>
<li data-price="99">99</li>
<li data-price="101">101</li>
<li data-price="191">191</li>
</ul>
check if that is what you need:
https://jsfiddle.net/3er0da9c/
var template = '<li data-price="100"></li>';
var itemValue = parseInt($(template).attr('data-price')); //Getting value that we should compare
var value, smaller = 0, smallerItem; //We will need those variables to know where to place our "template"
smallerItem = $('ul > li:first-of-type'); //Set the smaller item in our list to be the first one. Change that if your list wont be always asc sorted
$('ul > li').each(function(){ //run through the given list
value = parseInt($(this).attr('data-price'));
if ((itemValue == value) || ( itemValue > value )){ //if the actual item is equal, put our item right after it. If the item is smaller then our number, we save it and keep running
smaller = value;
smallerItem = $(this);
}
});
if (smaller != 0) //This will happens when we have at least one item smaller then our number
smallerItem.after(template);
else
smallerItem.before(template); //else, we add our number at top

How do I pass the DOM object (this) that contains an ng-repeat statement into the ng-if function? (Javascript/AngularJS)

I have an ng-repeat on my page, and I need to filter the items that are in it. For the purposes of filtering I've included the hidden field above it which contains a key that I need to use.
<div class="filterProductsContainer">
<asp:HiddenField runat="server" ID="FilterKey"/>
<ul class="product_listing_component--results-list">
<li ng-if="isInCategory(product, $event)" ng-repeat="product in filterProducts">
<a href="{{product.link}}">
<img src="{{product.image}}" /></a>
</li>
</ul>
</div>
$scope.isInCategory = function (product, $event) {
console.log(product);
console.log($event);
var filterKey = $($event.target).parent(".filterProductsContainer").find("input[type='hidden'").val();
console.log(filterKey);
var targetProduct = $scope.products[product];
var foundMatch = false;
for (var tag in targetProduct.tags) {
var targetTag = targetProduct.tags[tag];
if (filterKey === targetTag.id) {
foundMatch = true;
}
if (foundMatch) {
break;
}
}
return foundMatch;
}
$event ends up being null, though.
Try using the filter directly in ng-repeat
<li ng-repeat="product in filterProducts | filter: {id: '<FilterKeyValue>'}" >
Where id is the property name of your product object you want use to filter by.

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>

Angular JS - Multiple ngrepeat and filters issue

I have a problem with two ng-repeat and a custom filter. This is my code:
HTML
<ul class="dropdown-menu">
<li ng-repeat="L in prontoSoccorsoLista">{{L.prontoSoccorso}}</li>
</ul>
<div class="prontosoccorso" ng-repeat="PS in prontoSoccorso | myFilter:azione" >
data to show not important
</div>
JS
.filter('myFilter', function () {
return function (items, search) {
var result = [];
console.log(search);
angular.forEach(items, function(friendData){
if(friendData.prontoSoccorso == search) {
result.push(friendData);
} else if(search == undefined) {
result.push(friendData);
}
});
return result;
}
});
I have to set the value of azione. Whitout ngrepeat on the list I can succesfully set "azione" and catch the correct value of "search" in filter. This is the example:
<ul class="dropdown-menu">
<li>{{ps1}}</li>
<li>{{ps2}}</li>
<li>{{ps3}}</li>
</ul>
When I insert ngrepeat and try to set "azione", in filter it returns me the value of "search" as "undefined". How can I resolve??
myFilter:azione refers to $scope.azione, while the ng-click doesn't
Try to make a function in your controller:
$scope.setAzione = function (L) {
if (L.prontoSoccorso) {
$scope.azione = object.prontoSoccorso;
}
}
and then call
ng-click="setAzione(L)"

Categories

Resources