AngularJS ng-class not working for conditions - angularjs

This is very straightforward but I am not able to change the class.
I am basically verifying if the date is in correct format (DD-MMM-YYYY hh:mm:ss).
<input type="text" style="width : 80%" ng-model="startTime" ng-class="{invalid: !isValid ,valid: isValid}" />
where isValid is a scope variable which evaluates to true and false. The css class is not applied.
Here is the plnkr.

It is working. Inspect the element. Your bootstrap classes are overwriting it. Try this:
.invalid {
background-color: #FA787E !important;
}
.valid {
background-color: #78FA89 !important;
}

Related

How would I override the tickIcon for multiple selections in bootstrap-select and change to highlighting the selections instead?

The example given in bootstrap-select works by adding a tickicon to every selection. How would I override this feature so I can highlight my selections instead of adding a tickicon? I tried setting data-show-tick to false, but that doesn't seem to work for multiple selections.
I'm not sure where to go. Would appreciate advice.
<select class="selectpicker" multiple>
<option>Mustard</option>
<option>Ketchup</option>
<option>Relish</option>
</select>
I've resolved this by hidding the tick icons with CSS.
For this, you may use the following css rule in your own css file (declared after the original bootstrap-select.css file) :
.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark { display: none !important; }
Or you can alter the original rule of the bootstrap-select.css file by changing it for :
.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark { position: absolute; display: none; right: 15px; margin-top: 5px; }

Showing validation message with Angular JS

I have the following field defined in my HTML code:
<label for="firstname" class="field prepend-icon"
ng-class="{ 'state-error': submitted && helpForm.firstname.$error.required }">
<input type="text" name="firstname" id="firstname" required=""data-ng-model="firstname"
class="gui-input" placeholder="First name...">
<label for="firstname" class="field-icon"><i class="fa fa-user"></i></label>
</label>
<span ng-show="{submitted && helpForm.firstname.$error.required}"
class="state-error">Enter first name</span>
Here is the CSS class:
.smart-forms span.state-error {
display: block !important;
margin-top: 6px;
padding: 0 3px;
font-family: Arial, Helvetica, sans-serif;
font-style: normal;
line-height: normal;
font-size: 0.85em;
color: #DE888A;
}
The first part of the validation works well. That is, I am able to add the class 'state-error' to the Label upon validation error. I am using the condition:
ng-class="{ 'state-error': submitted && helpForm.firstname.$error.required }
and it works fine.
However, I am trying to use the same condition with 'ng-show' in order to HIDE the error message until there is a validation error, but I am not able to hide it. Here is the line of code that is responsible for it.
ng-show="{submitted && helpForm.firstname.$error.required}"
I also tried without the curly brackets like so:
ng-show="submitted && helpForm.firstname.$error.required"
In both cases the results were the same.
So the same condition works to add a class but doesn't work to show/hide element, what am I missing?
remove {}?
ng-show="{submitted && helpForm.firstname.$error.required}
OK. So the problem was in the CSS class.
I have defined:
display: block !important;
I removed this line and the problem was solved. Not sure, but i guess ng-show uses
'display:none'
and that my css class was overriding it. Anyway, it works now. So if you have the same problem, make sure to check your CSS class.

How can I fade in and out the visibility of a DIV using ng-show with AngularJS 1.3 beta?

My code looks like this:
<div class="block-border"
data-ng-show="qty > 0">
xxx
</div>
I know there have been a lot of changes with Animation in AngularJS. Can someone tell me the easiest way for me to make it take 500ms to show and 50ms to hide the xxx when the value of qty changes. Note that I am using the very latest AngularJS.
Reference angular-animate.js
Add ngAnimate as a dependent module:
var app = angular.module('app', ['ngAnimate']);
Pick a name for your transition, for example 'fade', and then define the appropriate CSS classes based on the naming convention described in the documentation:
.fade.ng-hide {
opacity: 0;
}
.fade.ng-hide-remove,
.fade.ng-hide-add {
display: block !important; /* or inline-block, as appropriate */
}
.fade.ng-hide-remove {
transition: all linear 1000ms;
}
.fade.ng-hide-add {
transition: all linear 500ms;
}
Add the class to your element:
<div class="block-border fade" ng-show="qty > 0">
Demo: http://plnkr.co/edit/HWi0FfDOsHeSOkcrRtN2?p=preview
I couldn't get the accepted answer to work, but the following did work (taken largely from this ng-nuggets post):
.fade {
transition: all linear 500ms;
opacity: 1;
}
.fade.ng-hide {
opacity: 0;
}
and then my HTML element which I wanted to fade in and out looked something like this:
<span data-ng-show="copyLinkClicked" class="fade">some text here</span>
As #MichaelNguyen mentioned, Bootstrap does appear to have a style already called fade, and we are using Bootstrap in our application, yet the above styles worked nonetheless. If you already have a style named fade, then change the name to something unique before using the above code.
If you want to fade in using ng-if as a boolean angular has some nice documentation here https://docs.angularjs.org/api/ngAnimate . I used ng-if for my fading purposes here's an example below:
form.html
<form name="exampleForm" ng-submit="submit()">
<input type="email" placeholder="Email Address" ng-model="email" required>
<input type="text" placeholder="Name" ng-model="name" required>
<input class="invalid-btn" ng-if="exampleForm.$invalid" type="submit" value="Invalid" />
<input class="valid-btn" ng-if="exampleForm.$valid" type="submit" value="Valid">
</form>
form.css
/* css for button that will show when form is invalid */
.invalid-btn {
border: 1px solid #222;
width: 100px;
height: 50px;
color: #222;
background: #fff;
}
.invalid-btn.ng-enter {
opacity: 1;
}
/* The finishing CSS styles for the enter animation */
.invalid-btn.ng-enter.ng-enter-active {
opacity: 0;
}
.valid-btn {
width: 100px;
height: 50px;
background: #F26623;
color: #fff;
}
/* The starting CSS styles for the enter animation */
.valid-btn.ng-enter {
transition:0.5s linear all;
opacity: 0;
}
.valid-btn.ng-enter-stagger {
/* this will have a 100ms delay between each successive leave animation */
transition-delay: 0.3s;
/* As of 1.4.4, this must always be set: it signals ngAnimate
to not accidentally inherit a delay property from another CSS class */
transition-duration: 0s;
}
/* The finishing CSS styles for the enter animation */
.valid-btn.ng-enter.ng-enter-active {
width: 100px;
height: 50px;
background: #F26623;
color: #fff;
opacity:1;
}
The way this works is if you want to fade in a button with a different color or text and different text color you can fade in a button when the form is filled out and valid and the invalid button will fade out leaving only one button depending on the state of the form. Kind of a hack but it works and looks smooth. I had to set a delay using .ng-enter-stagger because loading the animations at the same time was causing the buttons to blink and jump and not animate smoothly. So in this case we let invalid button hide first then load valid button when form is valid and all input fields have been filled out correctly.

How do I ngShow and ngHide two different elements at the same time with AngularJS?

So I have two elements that are exclusive:
<span>foo</span>
<span>bar</span>
And I added ngShow and ngHide to them:
<span ng-show="fooTime">foo</span>
<span ng-hide="fooTime">bar</span>
But now when these render, there is a split second where they both show.
How can I make them show/hide at the same time?
Use a ngSwitch rather than an ngShow/ngHide:
<span ng-switch="fooTime">
<span ng-switch-when="true">foo</span>
<span ng-switch-when="false">bar</span>
</span>
Why?
When using the separate ngShow/ngHides, each element is getting a separate $watch which execute asynchronously leaving the potential for a gap between the events. By using ngSwitch, only one $watch is setup so they must render at the same time.
How I got to ngSwitch?
On my first attempt, I realized the watches were not tied together, so I resorted to letting CSS tie the changes together:
<style>
[first] .fooTime {
display: inline;
}
[second] .fooTime, [first] {
display: none;
}
</style>
<span ng-class="{'fooTime':fooTime}">
<span first>foo</span>
<span second>bar</span>
</span>
But ngSwitch is much more clean.
Edit:
It seems ngSwitch triggers enter and leave animations so if you are using ngAnimate, there is a default of a .2 second transition. I haven't found a way around this yet.
You can solve this problem pretty elegantly with some CSS.
*[ng-switch] *[ng-switch-when] + *[ng-switch-when],
*[ng-switch] *[ng-switch-when] + *[ng-switch-default] {
display: none;
}
This uses the wildcard selector (*) and attribute selector for ng-switch-when to make this a general solution that should work in any instance where ng-switch is used.
Upvoted and commented on #eternalmatt's answer ... here is my solution based on the css part of his solution. In my experience ng-swtich will not solve this problem. I am using scss but you can convert scss to css here http://www.sassmeister.com/. The template of my button directive that toggles button text and ajax spinner based on the value of showSpinner.
template
<button class="fin-button no-outline" ng-class="{disabled: state==='disabled'}" ng-click="action()">
<span ng-class="{'showSpinner': showSpinner}">
<span class="text-first" fin-button-text>{{text}}</span>
<span class="glyphicon glyphicon-repeat spinner" fin-button-spinner></span>
</span>
</button>
scss
.fin-button {
[fin-button-text] {
display: inline;
}
[fin-button-spinner] {
display: none
}
.showSpinner {
[fin-button-text] {
display: none;
}
[fin-button-spinner] {
display: inline;
}
}
}
css .. generated from conversion via the above link
.fin-button [fin-button-text] {
display: inline;
}
.fin-button [fin-button-spinner] {
display: none;
}
.fin-button .showSpinner [fin-button-text] {
display: none;
}
.fin-button .showSpinner [fin-button-spinner] {
display: inline;
}
and is here be dragons comment that I have above the scss in my code
// .... HERE BE DRAGONS ... ///
// The following is used to hide show the spinner or the
// button text. Needs to be done like this because ng-hide, ng-show,
// ng-if, and ng-switch all put seperate watches even if you are conditioning
// on the same vairable ... see this SO // http://stackoverflow.com/questions/20341288/how-do-i-ngshow-and-nghide-two-different-elements-at-the-same-time-with-angularj

How can I implement a style switcher with AngularJS?

I have an idea to change the theme on my web page. Here is my CSS that I am using:
html.darkBlue {
.block-content.light-tint-bg {
background: #fefefe;
border: 1px solid #777777;
color: #7b7b7b;
}
}
html.black {
.block-content.light-tint-bg {
background: #333333;
border: 1px solid #111111;
}
}
The idea is that I add a class to the HTML and depending on the class that is used it will use one theme or another.
But with Angular how could I make it switch? I was thinking of having an address kind of link but I am not sure how to switch between two classes?
I use a similar approach to #Davin Tryon, except like like this:
In the controller:
$scope.applied = false;
Then in the ng-class
ng-class="{true: 'applied', false: 'notApplied'}[applied]"
So based on the value of applied being true or false, it will apply the value of the property in the expression applied when true, and notApplied when false.
Edit:
Ok based on your comment:
http://jsfiddle.net/muLPT/
<div ng-app ng-class="background">
Hello World
<input type="button" ng-click="background = 'black'" value="black">
<input type="button" ng-click="background = 'red'" value="red">
<input type="button" ng-click="background = 'blue'" value="blue">
</div>
.black {
background: black;
}
.red {
background: red;
}
.blue {
background: blue;
}
This should do what you want.
Basically just changes the value of 'background' class to what ever value was clicked.
The sample is done on a div since I can't demo it on html from jdfiddle. Should work the same if its applied to html
You can use ng-class. Here are the docs.
ng-class allows you to resolve the class using an expression.
The example here shows usage:
<p ng-class="{applied: 1 == 1, notApplied: 1 == 0}">Example</p>
The expression 1 == 1 will resolve to true and the class 'applied' will be added to the class attribute.
In order to handle a click and toggle the class, you would create a scoped variable. For example this will toggle a clicked field that will add/remove the class:
<div ng-click="clicked = !clicked" ng-class="{black: clicked, darkBlue: !clicked}"></div>

Resources