add a class to element in ng-repeat after some event - javascript

I'm making a playlist. I have this ng-repeat where the current song is highlighted
<div ng-repeat="song in songs_list">
<div ng-class="{'true':'current-song'}[song == current_song]">
{{song.title}}
</div>
</div>
now in JS I change the value of current_song. I want to apply the class current-song to the new element which is now playing currently.

On change of song set $scope.current_song to the new song and in the HTML:
<div ng-repeat="song in songs_list">
<div ng-class="{'current-song':song===current_song}">
{{song.title}}
</div>
</div>

you should write like this
<div ng-repeat="song in songs_list">
<div ng-class="{'current-song': song == current_song}">
{{song.title}}
</div>
</div>

Use this syntax, Try with this
<div ng-repeat="song in songs_list">
<div ng-class="{'current-song':song.title == current_song}">
{{song.title}}
</div>
</div>
I suggest, use song.id instead of to song.title and keep id of current_song as song id.

The way ng-repeat works is, it creates a child scope which is prototypically inherited from current scope. Therefore inner current_song value would not update per that. I don't want to repeat answer again why it is not working, you can find explanation here. You have to use Dot Rule in order to get correct selected current_song value inside ng-repeat, & while having condition you should compare it with its unique_id (assuming you have id prop here).
$scope.model = {
current_song: null
};
HTML
<div ng-repeat="song in songs_list">
<div ng-class="{'current-song': song.id == model.current_song.id}">
{{song.title}}
</div>
</div>

Related

Trigger ng-click inside ng-repeat when ng-repeat item.length=1

I want to trigger automatic loadProduct function when products.length==1
Bellow my angular code.
<div class="prodItem prodItem-nos-{{products.length}} prodItem-item-number-{{$index}}"
ng-repeat="product in products track by $index"
ng-click="loadProduct(product.id)"
uib-tooltip="{{ product.name }}">
<div class="prodMeta">
<div class="prodName" ng-bind="product.name"></div>
<div class="prodDescr" ng-bind="product.description"></div>
</div>
<div class="prodBuyNow">
<button ng-click="loadProduct(product.id)">Choose</button>
</div>
</div>
If you want to trigger function when item in scope changes you can use scope.$watch()
for example :
scope.$watch('products',function(oldValue,newValue){
if(newValue.length === 1){
executeFunction();
}
});
See :
https://docs.angularjs.org/api/ng/type/$rootScope.Scope
ng-click="if(products.length === 1){ loadProduct(product.id); }"
I don't like too much conditions inside ng-click. Being products a scope variable, you can just add this logic inside your loadProduct function, adding a condition at the beginning like
if($scope.products.length === 1)
and then execute your code.
If, you want to call loadProduct() is only one product is there call it in api which fetched the products
Eg:
$http.get("/api/products")
.then(function(response) {
$scope.products = response.data;
if($scope.products.length == 1)
{
$scope.loadProduct($scope.products[0].id)
}
});
you can use ng-init function
and check your prodt list in the function
<div ng-repeat="product in products track by $index" ng-init="yourFunctionName()">
<div class="prodMeta">
<div class="prodName" ng-bind="product.name"></div>
<div class="prodDescr" ng-bind="product.description"></div>
</div>
<div class="prodBuyNow"><button ng-click="loadProduct(product.id)">Choose</button></div>
</div>
</div>

jQuery ID Return is undefined although HTML ID is defined

I'm trying to retrieve the ID of one element, store it as a variable and then use that ID value to interact with other elements in that section with the same ID.
<div class="mainContent">
<div class="articleContent">
<h1>header1</h1>
<p class="articlePara" id="one">para1</p>
</div>
<div class="articleFooter" id="one" onclick="readMore()">
</div>
</div>
<div class="mainContent">
<div class="articleContent">
<h1>header2</h1>
<p class="articlePara" id="two">para2</p>
</div>
<div class="articleFooter" id="two" onclick="readMore()">
</div>
</div>
And then the JS/jQuery
function readMore() {
var subID = event.target.id;
var newTarget = document.getElementById(subID).getElementsByClassName("articlePara");
alert(newTarget.id);
}
At this point I'm only trying to display the ID of the selected element but it is returning undefined and in most cases people seem to notice that jQuery is getting confused because of the differences between DOM variables and jQuery ones.
jsfiddle: https://jsfiddle.net/dr0f2nu3/
To be completely clear, I want to be able to click on one element, retrieve the ID and then select an element in the family of that clicked element using that ID value.
just remove the getElementsByClassName("articlePara"); in end of the newTarget .already you are call the element with id alert the element of the id is same with target.id
function readMore() {
var subID = event.target.id;
var newTarget = $('[id='+subID+'][class="articlePara"]')
console.log(newTarget.attr('id'));
console.log(newTarget.length);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="mainContent">
<div class="articleContent">
<h1>header</h1>
<p class="articlePara" id="one"></p>
</div>
<div class="articleFooter" id="one" onclick="readMore()">click
</div>
</div>
As you have read before, you should keep your id's unique, and you should avoid using onclick in html, but you could do it like this.
With querySelector you get the element and then with parentElement you can retrieve the parent of that element.
function readMore(el) {
var articleFooterId = el.id;
var articlePara = document.querySelector(".articleContent #"+articleFooterId);
var articleContent = articlePara.parentElement;
console.log('articleFooter', articleFooterId);
console.log('articlePara', articlePara);
console.log('articleContent', articleContent);
}
In your html you can return the 'this' object back to the function by doing readMore(this).
<div class="mainContent">
<div class="articleContent">
<h1>header1</h1>
<p class="articlePara" id="one">para1</p>
</div>
<div class="articleFooter" id="one" onclick="readMore(this)">footertext</div>
</div>
<div class="mainContent">
<div class="articleContent">
<h1>header2</h1>
<p class="articlePara" id="two">para2</p>
</div>
<div class="articleFooter" id="two" onclick="readMore(this)">footertext</div>
</div>
jsfiddle
if you're using Jquery:
$(function () {
$('div.articleFooter').click(function () {
var para = $(this).prev().find('p.articlePara').text();
alert('T:' + para);
});
})
$('.articleFooter').click(function() {
var b=subId; //can be any
var a="p[id="+b+"]"+"[class='articlePara']";
$(a).something;
});
You have forgotten to pass in event as parameter in your onclick= call in html.
In your javascript, you need to include event in the parenthesis as well.
window.readMore = function(event) {...}
if you write document.getElementById(subID).getElementsByClassName("articlePara"); That's saying you want to get your clicked element's CHILD elements that have class equal to articlePara . There is none. So you get undefined.
If you want to find all element with a ID one and a class articlePara, it can be done easily with jQuery:
newtarget = $("#one.articlePara");
You can insert a line: debugger; in your onclick handler function to trigger the browser's debugging tool and inspect the values of variables. Then you will know whether you are getting what you want.

ng-click not working with ng-if angularjs

I am trying to toggle a div on button click like as bellow.
This is working.
<div>
<button ng-click='x = ! x'>toggle</button>
</div>
<div ng-include="'pages/include/search.html'" ng-show='x'></div>
This is not working.
<div ng-if="$state.current.url!='/splash'" >
<button ng-click='x = ! x'>toggle</button>
</div>
<div ng-include="'pages/include/search.html'" ng-show='x'></div>
Why it is not working, when I add ng-if="$state.current.url!='/splash'" ?
Well,
Every angular directive create new scope
In the code below
<div ng-if="$state.current.url!='/splash'" >
<button ng-click='x = ! x'>toggle</button>
</div>
<div ng-include="'pages/include/search.html'" ng-show='x'></div>
The ng-if directive create new scope.And withing this scope
the value of x is updated on button click.But this new value of x is not accessible outside this ng-if div as it is local to that scope and it is primitive type.
Since this x is primitive type so there is no data update as reference are differant.
You should use object model instead.
Here is the updated HTML
<div ng-if="$state.current.url!='/splash'" >
<button ng-click='x.showHide = ! x.showHide'>toggle</button>
</div>
<div ng-include="'pages/include/search.html'" ng-show='x.showHide'>This is div</div>
define x like this one in your controller.
$scope.x = {showHide:false}
EDIT-
In your first woking HTML, there is not directive on div.So, both these DIV come under same scope.So,x accessible across this two DIV with updated value.
<div>
<button ng-click='x = ! x'>toggle</button>
</div>
<div ng-include="'pages/include/search.html'" ng-show='x'></div>

trigger ng-click by element id?

Ok i have a ng-repeat iterating over a array passing the $index to a ng-click inside the ng repeat like so:
<div class="animate-repeat row" ng-repeat="items in sortedTypes">
<div class="allinfo" id="idwrap-{{items.id}}" ng-click="shohidifelse($index)">
<div class="allinfo" id="idwrap-{{items.id}}" ng-click="shohidifelse($index)">
<div class="groupcontent row" ng-hide="showhideinfo[$index]">
<div class="large-2 columns">
<p>{{items.phoneTwo}}</p>
</div>
</div>
<div class="row fullprofile" ng-show="showhideinfo[$index]">
<p>{{items.ContactFirst}}</p>
</div>
</div>
</div>
I need to call a click on this
<div class="allinfo" id="idwrap-{{items.id}}" ng-click="shohidifelse($index)">
programatically. i am scroll to this item by the {{items.id}} and i need to call this ng-click from the scroll function.
Is there a clean way to do this, that I've just missed?
answered my own question!
jQuery("#accntselect").on("change", function(e) {
if (!e.added){
}else{
angular.element('#idwrap-'+e.added.id).triggerHandler('click');
jQuery('#idwrap-'+e.added.id).trigger('click').trigger('click');
scrollToAnchor('idwrap-'+e.added.id);
}
});
Where e.added.id is the rest of the element's id!
Try this:
Call the function shohidifelse(), from the jquery scroll function. If you need the $index value to be passed on to shohidifelse(), then pass it on to the jquery function and pass it as a parameter.

Jquery add class if a element exists within div

I want Jquery to add a class .pointer to .staff-container if <a href=""> exists within .staff-picture.
My Jquery:
if($('.staff-container').find('.staff-picture').closest('a').length) {
$(this).addClass('pointer');
}
No class is being added with the above jquery, what am I doing wrong?
My Css:
.pointer {
cursor:pointer !important;
}
My HTML:
<div class="teachers">
<div class="span12">
<div class="scroll transparent">
<div class="staff-outer-container">
<div class="staff-container">
<div class="staff">
<div class="staff-picture">
<img src="img/people/teachers/ahmed.png" />
</div>
<p><span class="bold">Mr. Ahmed</span><br />
Ext. 13417<br />
Room 417/323<br />
Ahmed#wcskids.net</p>
</div>
</div>
<div class="staff-container">
<div class="staff">
<div class="staff-picture">
<img src="img/people/teachers/aiello.png" />
</div>
<p><span class="bold">Mr. Aiello</span><br />
Ext. 13328<br />
Room 328/323<br />
ASusan#wcskids.net</p>
</div>
</div>
<div class="staff-container">
<div class="staff">
<div class="staff-picture">
<img src="img/people/teachers/aiosa.png" />
</div>
<p><span class="bold">Mr. Aiosa</span><br />
Ext. 13419<br />
Room 419/323<br />
BAiosa#wcskids.net</p>
</div>
</div>
</div>
</div>
</div>
</div>
You can do this :
$('.staff-picture a').closest('.staff-container').addClass('pointer');
I hope the logic is obvious from the code.
I would first iterate through the .staff-container divs, then use a conditional to determine which ones have an a tag using the this object as context:
//Goes through all the .staff-picture divs
$('.staff-container').each(function(){
//If the a tag exists within the current .staff-picture (returned object isn't undefined)
if($('a', this).html() != undefined){
//Add the class if a exists
$(this).addClass('pointer');
}
});
http://jsfiddle.net/y9ZKG/
EDIT
Sorry, I meant staff-container, not staff-picture. But, either will work.
2nd EDIT
Also, if you are curious why your original methodology wasn't working, it is because the conditional you use (the first if) does not instantiate the this object. That is, this does not exist inside your function.
Try this:
var $selector = $('.staff-container');
if($selector.find('.staff-picture').has('a')) {
$selector.addClass('pointer');
}
$.closest() traverses up not down the tree, therefore you are not finding anything. see the jQuery API
I like to approach these types of problems with "reverse" logic:
$('.staff-picture a').parent().parent().parent().addClass('pointer);
There's probably a way to "choose" your staff-container parent, but if the DOM structure doesn't change, this works great.
This starts by selecting all the a-links and then ONLY applies those up which uses jQuery's powerful selection code. It doesn't rely on tests with if-statements.

Categories