How to add condition class in angularjs - angularjs

if (url.indexOf('master/confirm-account') > 0) {
$scope.accountInfo = 'Confirm Account';
$scope.page = 'confirm_account';
$scope.activeTab = true;
} else if (url.indexOf('master/master-profile') > 0) {
$scope.accountInfo = 'Confirm Account';
$scope.page = 'master_profile';
$scope.activeTab = true;
} else {
$scope.accountInfo = 'Create Account';
}
<div ng-class = "{'process-step' : true, '({{page}}=='confirm_account') ? 'active-tab' : ' '}" >
How can I add process-step and active-tab class
Expected result if condition match then it become like that

The ng-class works like
{'add_this_class' : (if_this_expression_is_true)}
and not in the other way.
try this
<div class="process-step" ng-class="{'active-tab' : (page =='confirm_account') }">

Seeing to the complexity of your class matching logic you could go for second way of implementing ng-class
** Inside HTML**
<div class="process-step" ng-class="ctrl.getPageBasedClass()">
Inside Controller
var self.getPageBasedClass = function(){
var yourClassNameAsString = // your logic for class name
return yourClassNameAsString;
}

Related

Display element in angular based on condition in array of objects

I have the following element.
<div> My element</div>
and the following object:
$scope.myObject = {'life_log' : [{status: 'ALIVE'},{status: 'DEAD'}]}
How can I display the element ONLY if all status is ALIVE.
I know how to use ng-show on a variable but what about a condition like this?
You'll have to create a function that loops through your array and checks if all the statuses are 'ALIVE'. Or just use a reduce method on the array:
$scope.allStatusesAreAlive = $scope.myObject.life_log.reduce(function(a, b) {
if (a === false) return false;
if (b.status === 'DEAD') return false;
return true;
}, true);
Then you can display your element if $scope.allStatusesAreAlive is true:
<div ng-if="allStatusesAreAlive"> My element</div>
You can do something like this
angular.forEach($scope.myObject.life_log, function(item){
if(item.status !=='ALIVE'){
$scope.isAlive = false;
break;
}else{
$scope.isAlive = true;
}
});
then in your html
<div data-ng-if="isAlive">My element</div>
Check the following link
https://plnkr.co/edit/ermeKk1dBX8D54pL7vHQ?p=preview
angular code:
$scope.myObject = {'life_log' : [{status: 'ALIVE'},{status: 'DEAD'}]}
$scope.val=true;
for(i=0;i<$scope.myObject.life_log.length;i++){
if($scope.myObject.life_log[i].status != "ALIVE")
$scope.val=false;
}
html code:
<div ng-show="val">My element</div>
// This is here to make it configurable
$scope.keys = Object.keys($scope.myObject);
// In this case you have the "life_log" key
$scope.keys.forEach(k => {
$scope.myObject[k].forEach((d) => {
// our object here is myObject["life_log"];
// obj is a temp array to check the amount of statuses that are dead
var obj = [];
d["allAlive"] = d.status.forEach( s =>{
if(s == 'DEAD'){
obj.push("Dead");
}
});
if(obj.length > 0){
d.allAlive = false
}else{
d.allAlive = true;
}
});
});
<div ng-if="myObject[o].allAlive>
ALL ALIVE
</div>

ng-class calling function on page load - AngularJS

This may be very simple but I can't seem to be able to successfully get the logic I want.
<div class="group-title" ng-class="{'group-hasError': !isValid(orderItem)}">
As you can see I'm adding a class group-hasError if the function isValid(orderItem) returns false.
Now the issue is that this is called on page load. But I don't want to call this function on page load rather when a submit button is called
<button id="add_modified_item" ng-click="isValid(orderItem)" class="btn btn-primary btn-fixed-medium pull-right">
How can I achieve this?
This is the function;
$scope.isValid = function(orderItem) {
var count = 0;
//By default make it true
var IsAllSelected = true;
angular.forEach(orderItem.menu_modifier_groups, function(group) {
var count = 0;
angular.forEach(group.menu_modifier_items, function(item) {
count += item.selected ? 1 : 0;
});
if (count == group.max_selection_points) {
IsAllSelected = true;
} else {
//if one item failed All select do return false
IsAllSelected = false;
}
});
return IsAllSelected;
}
Any advice appreciated
Defalut set
$scope.setValidClass=false;
View
<div class="group-title" ng-class="(setValidClass)? 'group-hasError':'')}">
set model with
//if IsAllSelected=false then set IsAllSelected to true
$scope.setValidClass=!IsAllSelected;
return IsAllSelected;

Controller function not applying to ng-include file

I am trying to use the "minisCtrlOverall" controller in my ng-include file, but none of the functionality in my controller works for the included file unless I put ng-controller in the actual overall.html file. What I am trying to do is access the "ring-fill" class that is in my overall.html file from my controller. I want to add the class "active" too all "ring-fills" but its not working. I'm guessing this isn't working because the included files comes after the controller runs? Anyone know how I can fix this?
Controller:
angular.module('ciscoImaDashboardAdmin',[])
.controller('minisCtrlOverall', function ($scope, $rootScope, dummyData) {
$scope.overallOn = true;
$scope.switchView = function(element) {
var value = element.target.attributes['value'].value;
if(value == "overall") {
$scope.overallOn = true;
$scope.swimlaneOn = false;
}
else if(value == "swimlane") {
$scope.swimlaneOn = true;
$scope.overallOn = false;
}
};
var totalRings = 9;
var maxScore = 10;
var data_overall = {
average_score: 6
}
var ringToHighlight = Math.floor((data_overall.average_score/maxScore)*totalRings); //round down
var i = 0;
var rings = [];
var ringClass = 'path.ring-fill:not(.ring-border)';
$(ringClass).each(function(){
rings.push($(this)[0]);
});
while( i < ringToHighlight) {
fillPath(i);
i = i + 1;
}
function fillPath(i) {
if(i < ringToHighlight) {
var selectedRing = $(rings[i]);
selectedRing.attr("class", "ring-fill active");
}
}
});
HTML:
<div class="row mini" ng-show="overallOn" ng-controller="minisCtrlOverall">
<div class="col-sm-3">
<div ng-include="'svgs/overall.html'"></div>
</div>
</div>

how to wrap text in angularjs and save the position

I would like to wrap text with span tag and save the position.
I know how to do it with JS but i dont know how to do it with angularjs
Here is what i have done:
http://jsfiddle.net/ymeaL06j/1/
This function gives me the position of the text in the DIV
function getSelectionPosition() {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(document.getElementById("code"));
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
}
};
I take the start and end positions and insert them as an attribute in the span tag
After this i would like to save all the marked positions and load it later, i have a function that select text and then i can wrap it (i hope that there is a better solution)
function setSelection(savedSel) {
var charIndex = 0, range = document.createRange();
range.setStart(document.getElementById("code"), 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
You can use the same code that you illustrated above and put it inside of your angularjs controller.
Refer to my plunker code; it is a simple angularjs version of your jsfiddle code.
For example, suppose that a snippet of the index.html looks like this:
<body ng-controller="MainCtrl">
<div id="code">This is <b>some text</b> bla bla bla</div>
<br />
<input type="button" value="Mark!" ng-click="markText()" />
<input type="button" value="Remove marks!" ng-click="removeMarks()" />
</body>
Then the example angularjs controller, MainCtrl, could look like this:
app.controller('MainCtrl', function($scope) {
var getSelectionPosition = function () {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(document.getElementById("code"));
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
}
}
$scope.markText = function() {
var currPosition = getSelectionPosition();
var selection = window.getSelection().getRangeAt(0);
var selectedText = selection.extractContents();
var span = document.createElement("span");
span.className = "Mark";
span.setAttribute("PosStart", currPosition.start);
span.setAttribute("PosEnd", currPosition.end);
span.appendChild(selectedText);
selection.insertNode(span);
};
$scope.removeMarks = function() {
$(".Mark").each(function () {
$(this).contents().unwrap();
});
};
});
Notice that the MainCtrl is the angularjs controller for the body. The ng-click on the buttons reference the markText and removeMarks functions in the controller's scope. The logic in the functions are exactly the same as you referenced in your question (and jsfiddle).
None of your JS code changed other than moving the functions inside of the controller. Again, check out the plunker above to see the actual code working.

count value in a array into ng-repeat

I have this data : http://www.monde-du-rat.fr/API/moulinette/radio/posts.json , from cakephp app, it's song by song, with attached votes
I use it as a service into a angularjs app, and i displayed it like this in html :
<div ng-repeat="song in songs | orderBy:'Radio.idSong' | notesong:'Radiovote'" class="list-group-item" id="{{song.Radio.idSong}}" ng-class="{ 'active' : songPlayed_name == song.Radio.name }" ng-if="songs">
<span>{{song.Radio.idSong}} - {{song.Radio.title}}</span><br />
<span>{{note}}%</span>
</div>
So, i want to count each attached vote, and define with values 'good' or 'bad', the % of likes
I try to made this filter :
/* notesong */
app.filter('notesong', function() {
return function(input) {
// counter init
var countGood = 0;
// if there is no votes, so note is zero
if (!angular.isArray(input)) {
var note = 0;
} else {
// loop for each vote (from Radiovote array, each value)
angular.forEach(input, function () {
if (input.value == 'good') {
countGood = countGood + 1;
}
});
var note = (countGood * input.length) / 100;
}
// final return
return note;
};
});
It's not working apparently (no errors, and no data displayed), so, what is the correct way ?
You are applying the filter in the wrong place. Instead of using it on the ng-repeat you should use it on the property you want to bind, like this:
<div ng-repeat="song in songs | orderBy:'Radio.idSong'" class="list-group-item" id="{{song.Radio.idSong}}" ng-class="{ 'active' : songPlayed_name == song.Radio.name }" ng-if="songs">
<span>{{song.Radio.idSong}} - {{song.Radio.title}}</span><br />
<span>{{song.Radiovote | notesong}}%</span>
</div>
There's also a problem with the way you are looping the votes in your filter. Update the following lines:
// loop for each vote (from Radiovote array, each value)
angular.forEach(input, function (item) {
if (item.value == 'good') {
countGood = countGood + 1;
}
});

Resources