AngularJS Dynamic Class - Background Image not working - angularjs

Unable to dynamically change class on "ng-repeat" list with background image contained in "style.css". Tried suggested solutions such as "ng-style="{ 'backgound-image': 'image_name.jpg' }" directly onto the element without much luck.
The class would need to change conditionally.

ng-class to the rescue. Managed to achieve the conditional effect without needing to modify my "style.css".
Within my template "ng-repeat (item in productList)" i used the following, note your repeat will need to use the "track by $index" syntax:
<div ng-class="{ 'no' : 'image_off', 'yes': 'image_on' }[item.isOn]" ng-click="switchOnOff($index, item.productId, item.isOn); $event.stopPropagation();"></div>
NOTE: "$event.stopPropagation()" prevents the page submitting.
"image_off/image_on" refers to two different classes under my stylesheet. Each with their own respective background image.
In your controller use the following to action the event on the UI inside a function e.g "switchOnOff" :
$scope.productList[index].isOn = $scope.productList[index].isOn == 'no' ? 'yes' : 'no';

Related

ng-class not updating inside of ng-repeat when array is changed

The code below is from a chat interface in an Angular application. The user will select the users they wish to send the message to by clicking on user bubbles which will add those users to an array selectedChatUsers
Lists out the users. Highlights the ones that are currently selected.
<div ng-repeat="user in PlayerController.chatUsers | orderBy:['type','name']"
class="chat-recipient"
ng-class="{'selected-recipient' : PlayerController.selectedChatUsers.indexOf(user) >= 0 }"
ng-click="PlayerController.selectRecipient(user)">
<div class="chat-recipient-name" ng-bind="user.name"></div>
<div class="chat-recipient-icon"></div>
</div>
Another feature of the application is the ability to click on a chat bubble from a sent message, and have the selectedChatUsers array be populated with the "to" property, which is an array of users that this message was sent to.
This functionality works, but the ng-class directive that should show those users are selected, does not function.
function chatReply(message){
/* one attempt was to try and manipulate the array rather than copy the information directly. This attempt had no more success. I'm including it here just to show that it was tried */
/****
self.selectedChatUsers.length = 0;
angular.forEach(message.to, function(recipient){
self.selectedChatUsers.push(recipient);
});
****/
/* Also tried wrapping the whole thing in $timeout and $scope.$apply, this also doesn't update the ng-class in the view */
$timeout(function() {
$scope.$apply(function(){
self.selectedChatUsers = angular.copy(message.to);
});
});
}
Suggestions on how I can make the ng-class in the view be updated when selectedChatUsers is changed?
Both class and ng-class will not work together, always apply class:
class="chat-recipient"
ng-class="{'selected-recipient' : condition }"
remove class and change it to:
ng-class="condition == true ? 'chat-recipient selected-recipient' : 'chat-recipient'"

Apply rowTemplate on Kendo grid without overriding current

I'm using Angular 1.4 typescript, with Kendo (using angular directives).
I'm trying to make a RowTemplate for each row, to change the color based on a property of the item.
I know there are some approaches with jQuery, but I find them very displeasing... If I'm using angular, I would like to reference items with angular.
This is my HTML:
<div id="resultSubTasksGrid"
kendo-grid="resultGrid"
k-options="vm.gridOptions"
k-columns="vm.columns">
</div>
This is my gridOptions:.
gridOptions: kendo.ui.GridOptions = {
rowTemplate : "<tr data- uid='#: uid #' ng-class='sent: item.IsSent'></tr>"
}
My problem comes here: I don't want to override the full row. This approach does so. I have lot of columns, and almost all of them have celltemplates I don't want to lose (but I don't want to have them all in the RowTemplate either).
I would like to know if is it possible to have something like:
rowTemplate : "<tr data- uid='#: uid #' ng-class='sent: item.IsSent'>{{RENDERCONTENT}}</tr>"
Well, it seems that by how Kendo it's developed, once you set up a row-template, you need to go all in. There is not such thing as partial template or wrapper.
More information here.

ui select placeholder text with search disabled

I am using angular ui-select Selectize Theme. I want to disable search but would like to show place holder text so that user know what is this select field is used for.
I tried modifying selectize/match.tpl.html to
<div ng-hide=\"($select.open || $select.isEmpty())\" class=\"ui-select-match\" ng-transclude=\"\">{{$select.placeholder}}</div>
But this always rending as
<div ng-hide="($select.open || $select.isEmpty())" class="ui-select-match ng-hide" ng-transclude="" placeholder="Select or search a country in the list..."><span class="ng-binding ng-scope"></span></div>
How to modify template to show place holder text in Span/Div and show it by default.
Or is there any better way to disable search and show placeholder text ?
Example Plunker
i have created a wrapper directive over this and modifying inside a link line below
angular.element(angular.element($element[0])).find('span').text($scope.placeholder)
and again in controller
angular.element(angular.element($element[0])).find('span').text(scope.name)
I wrote a wrapper directive around this, updated match template like below, and using search-enable = false
$templateCache.put("selectize/match.tpl.html","<div class=\"ui-select-match\" ng-transclude=\"\"></div>");
using "link" in wrapper directive i am updating above template with palceholder text
angular.element(angular.element($element[0])).find('span').text($scope.placeholder)
using controller in wrapper directive, updating selected string
angular.element(angular.element($element[0])).find('span').text(scope.name)
I have modified select.tpl.html like below
$templateCache.put("selectize/select.tpl.html","<div class=\"selectize-control single\"><div class=\"selectize-input\" ng-class=\"{\'focus\': $select.open, \'disabled\': $select.disabled, \'selectize-focus\' : $select.focus}\" ng-click=\"$select.activate()\"><div class=\"ui-select-match\"></div><div class=\"ui-select-placeholder\" ng-hide=\"!$select.isEmpty()\">{{$select.placeholder}}</div><input type=\"text\" autocomplete=\"off\" tabindex=\"-1\" class=\"ui-select-search ui-select-toggle\" ng-click=\"$select.toggle($event)\" placeholder=\"{{$select.placeholder}}\" readonly ng-model=\"$select.search\" ng-hide=\"!$select.searchEnabled || ($select.selected && !$select.open)\" ng-disabled=\"$select.disabled\"></div><div class=\"ui-select-choices\"></div></div>");}]);
Which adds a div with placeholder when selection is empty. Else it will be hidden

change button style according to state angularjs

I have a problem finding the way to style a button according to it's state.
I have a question, and four answer tiles.
each tiles is coded like this:
<div class="button-default" ng-model="btn0" ng-click"evalAnswer(answer, btn0)">{{answer}}</div>
<div class="button-default" ng-model="btn1" ng-click"evalAnswer(answer, btn1)">{{answer}}</div>
<div class="button-default" ng-model="btn2" ng-click"evalAnswer(answer, btn2)">{{answer}}</div>
<div class="button-default" ng-model="btn3" ng-click"evalAnswer(answer, btn3)">{{answer}}</div>
On the controller side I have a function that, on click, look at the answer and return "good" if the answer is correct, and "nope" if the answer is not good.
What I would like is to add button styling within these good and nope states so the button become red in case the answer is nope, and green if it's the good answer. I already created the class and I only need to change "button-default" to "button-good" or "button-wrong". Also, It needs to change only the clicked button.
Any idea on the way to do that?
Use ng-class directive that should switch class according to any condition
In your case for two cases it should be something like:
<div ng-class="{'true':'button-default','false':'button-unique'}[btn0.state == 'One']"
ng-model="btn0"
ng-click="evalAnswer(answer, btn0)">{{answer}}</div>
If you want to use multiple cases:
<div ng-class="{'button-default':btn0.state == 'One','button-some':btn0.state == 'Two','button-else':btn0.state == 'Three'}"
ng-model="btn0"
ng-click="evalAnswer(answer, btn0)">{{answer}}
</div>
Demo Fiddle
There are multiple ways to accomplish what you are wanting:
ng-class use to set classes based on conditions
ng-style used when you can not define a class or just need to change simple css
I suggest using ng-class if the styling is complicated or multiple changes are needed in the css. the ng-class accepts an expression that can be evaluated to an array of class names, a string of delimited class names or a map of object names.
I think something like this should work for two classes:
<div ng-class="{{'someBoolean' && 'class-when-good' || 'class-when-nope'}}">{{answer}}</div>
or a ternary (using angular version above 1.1.5)
<div ng-class="'someBoolean' ? 'class-when-good' : 'class-when-nope'">{{answer}}</div>
Note if you need to apply a default class in addition to a conditional class this is how to would be done:
<div ng-class="{{'someBoolean' && 'class-default class-when-good' || 'class-default class-when-nope'}}">{{answer}}</div>
or a ternary with default
<div ng-class="'someBoolean' ? 'class-default class-when-good' : 'class-default class-when-nope'">{{answer}}</div>
The other option and the one I think might work best for your problem is the ng-style. Since you are only needing to change the button color in might be better to simply change that color rather then apply different classes.
<div ng-style="answer === 'good' && {'background-color' : 'green'} ||
answer === 'nope' && {'background-color' : 'red'}">{{answer}}</div>
assuming: that the {{answer}} is set to the values evaluated (answer is good or nope).
Edit:
For the style conditional it needs to be set in your controller, if answer can not be used in the conditional test. It looks like you have an object btn0, and each of those objects could have a property (btn0.isGood) the could be set in the evalAnswer(answer, btn0) click event and would result in the changing the style.

Complex angular js ng-class

I have the component and have a problem setting the css class to it.
I want it to always have a class of "box", then to have additional classes specified by the directive "class" argument and one conditional class "mini".
Conceptually what I want to achieve is something like this:
<div class="box {{class}}" data-ng-class="{mini: !isMaximized}">
...
</div>
The problem is that when I set the class html attribute, the ng-class attribute is omitted.
How to make my example work without changing the controller? Is it even possible, or should I set the class in the controller instead (which I wish to avoid)?
A quick solution would be define the box class inside ng-class attribute:
<div data-ng-class="{mini: !isMaximized, box: true}"></div>
If you want to include a scope variable as a class, you can't use ng-class:
<div class="{{class}} box {{!isMaximized && 'mini' || ''}}">
Angular expressions do not support the ternary operator, but it can be emulated like this:
condition && (answer if true) || (answer if false)
I needed multiple classes where one was $scope derived and others were literal classes. Thanks to the hint from Andre, below worked for me.
<h2 class="{{workStream.LatestBuildStatus}}"
ng-class="{'expandedIcon':workStream.isVisible, 'collapsedIcon':!workstream.isvisible}">{{workStream.Name}}</h2>
Edit: for newer versions of Angular see Nitins answer as it is the best one atm
For me, this worked (I'm working on AngularJS v1.2.14 at the moment so I guess 1.2.X+ should support this, not sure about the earlier versions):
<div class="box" data-ng-class="{ {{myScopedObj.classesToAdd}}: true, mini: !isMaximized }"></div>
I replaced your {{class}} with {{myScopedObj.classesToAdd}} to show that any scoped variable or even a bit more complex object can be used this way.
So, every DIV element crated this way will have "box" class and any class contained within myScopedObj.classesToAdd (useful when using ng-repeat and every element in the array needs to have a different class applied), and it will have the "mini" class if !isMaximized.
Another way to do this without double curly braces and includes scope variables, tested with angular v1.2+.
<div ng-class="['box',
aClass,
{true:'large': false: 'mini'}[isMaximized]]"></div>
It's also rather nice because the variable can use different types as a index without increasing complexity using ternaries. It can also remove any need for negations ;)
Here is a fiddle link
You can use simple expression given below
ng-class="{'active' : itemCount, 'activemenu' : showCart}"

Resources