ngClass not working? - javascript

I am new to AngularJS and I understand that the ngClass directive can be used to insert classes dynamically into elements like:
<input ng-class="{some-class: condition, another-class: anotherCondition}">
And angular will automatically evaluate which conditions are true and will insert those particular classes in the element.
Now I am trying to do something like:
<div class="form-group" ng-class="{has-success: form.email.$valid}">
Since I have bootstrap, it will automatically color the label and the input green if the email is valid. But it doesn't work and I am getting this particular error in the console:
Error: [$parse:syntax] http://errors.angularjs.org/1.2.27/$parse/syntax?p0=-&p1=is%20unexpected%2C%20expecting%20%5B%3A%5D&p2=5&p3=%7Bhas-success%3A%20form.email.%24valid%7D&p4=-success%3A%20form.email.%24valid%7D
z/<#http://ajax.googleapis.com/ajax/libs/angularjs/1.2.27/angular.min.js:6:450
and so on....
What am I doing wrong? Is it a syntax issue?

Theres a dash in your class name, so use single quotes!
ng-class="{'has-success': form.email.$valid}"

It is clearly a parser error, you have invalid syntax due to the presence of - in the property name # {has-success: form.email.$valid}. You would need to wrap them in quotes.
Try:-
<div class="form-group" ng-class="{'has-success': form.email.$valid}">

If you use '-' in the class name you should cover the class name using single quotes.
[ngClass] = "{'some-class': condition}"
otherwise can be use
[ngClass] = "{someClass : condition}"

This worked for me
[ngClass] = "{ 'color-red': isRed}"

Though its late and the actual reason for this problem was mentioned by #tymeJV, in some cases, ngClass, ngStyle and related directives work if the browser tab's cache is cleared. Clear Cache and Hard reload or opening in a new tab will work, if you feel the directive is properly defined.

Related

Angular JS : ng-style is not working while passing data to directive

I am using ng-style for populating width of an element.
Code:
<div ng-style="{'width':'{{cols}}'+'px'}" id="autocompleteSuggestions" class="autocompleteSuggestionsDropdown" ng-show="autoSuggestion && searchText.length>2">
developer option preview
<div ng-style="{'width':'445'+'px'}" id="autocompleteSuggestions" class="autocompleteSuggestionsDropdown" ng-show="autoSuggestion && searchText.length>2">
The issue is my cols valiable is getting printed on the html (while looking from the developer options) but style is not getting applied on it.
Can someone help me out in this ?
I have found the way tosolve this problem, I don't have to use the expression tag as ng-style is a angular directive and digest cycle will anyway parse it. Although wirting an expression was still resolving the variable but it was giving error to the ng-style syntax. So, I have used the variable without using expression and it worked.
<div ng-style="{width: cols+'px'}" id="autocompleteSuggestions" class="autocompleteSuggestionsDropdown" ng-show="autoSuggestion && searchText.length>2">

Using templateUrl breaks my code, but using inline template instead works . Why?

Ok, I've seen similar questions on SO but still don't understand this issue.
I have a directive for date input, using ngModelController. I have another directive, to which you can pass the model controller, and it checks if the model has errors, and sets appropriate classes to the element.
So the markup looks like this:
<form name="myForm">
<div class-validation="myForm.date">
<date-input ng-model="date" name="date"></date-input>
</div>
</form>
Since we have date-input inside of our form, and it has the name attribute and ng-model, the ngModelController will be added to myForm under the name date, which is exactly what we pass to class-validation directive.
Now the problem is, if I use templateUrl for my date-input directive, the class-validation directive receives undefined. But when I use inline template instead, everything works as expected.
Here is a Plunker that demonstrates the problem exactly.
http://plnkr.co/edit/Cygawxjp4WN9xRbTEXWU?p=preview
Comment out line 41 and uncomment line 42 in script.js to see the problem. The validation doesn't work and if you open browser console, you'll see that class-validation parsed myForm.date as undefined.
Why is this happening? I am guessing that requiring template from an url is async operation, but it shouldn't make a difference to the developer. I wasted hours and hours trying to find out what's causing this. Thanks.

why use ng-hide when ng-show can work for both situations

I have gone through so many questions like this but got this only solutions that ng-show by default hides the element and show it if condition is true and on the other hand ng-hide by default show the element and hide it when condition is true.
But my concern is the condition can be taken care of with ng-show or ng-hide only then why we use different things.
For example
I saw this somewhere in this code user is using ng-show and ng-hide both
<div ng-init="isShow = 'one'">
<a href="#" ng-click="isShow == 'one' ? isShow = 'two' : isShow = 'one'">
<div ng-show="isShow=='one'">
If One show this
</div>
<div ng-hide="isShow=='one'">
If Two show this
</div>
</div>
But according to me this can be achieved also with this code
<div ng-init="isShow = 'one'">
<a href="#" ng-click="isShow == 'one' ? isShow = 'two' : isShow = 'one'">
<div ng-show="isShow=='one'">
If One show this
</div>
<div ng-show="isShow=='two'">
If Two show this
</div>
</div>
So what exactly is the difference between both the codes. There must be some specific difference if ng-show and ng-hide both exists. Anyone know it?
Thanks in advance!
I don't see any reason for this question to be downvoted - it's a valid thought. The reason is simple, though. AngularJS has "declarative" as one of its core philosophies. If 90% of the time you want an element shown, but occasionally it should be hidden, ng-hide="thatcondition" clearly indicates when it should be hdiden. If most of the time it should be HIDDEN, then ng-show="thatrarecondition" is more readable.
Clear, readable code is an important principle in any framework, and especially in AngularJS. The ! operator is narrow and easily missed, far more than any of the other comparisons like >, <, >=, <=, etc. Providing positive- and negative-visibility operators makes it much more readable what's going on here.
An important detail to note is that both directives look for "truthy" values, not exactly-equal ones. JS is pretty vague about this, and sometimes that's an advantage. For example, suppose you have an object that may have a sub-object (a detail element). You might have the detail-display DIV written as follows:
<div ng-show="{{ object.details }}">
<!-- Render object.details here -->
</div>
This "truthy" comparison is also handy for the negative case. Suppose you want to HIDE an order-cancellation block in a sales system if the order has been shipped. Consider:
<div ng-hide="{{ order.shipped }}">
Want to cancel this order? click here
</div>
Why is this important? Well, it means ANY non-undefined/null value for order.shipped will hide this block! That means if today, you set it as a true/false, it will work. But tomorrow you change it to a DATE that the order was shipped? The rule will still work! This makes it easy to code (and maintain) displays like this.
This is actually pretty good explained in the docs. AngularJS ngShow
Here's a quote from the docs: "The ngShow directive shows or hides the given HTML element based on the expression provided to the ngShow attribute. The element is shown or hidden by removing or adding the .ng-hide CSS class onto the element. The .ng-hide CSS class is predefined in AngularJS and sets the display style to none (using an !important flag)."
Regarding ngHide: AngularJS ngHide
Quote: "The ngHide directive shows or hides the given HTML element based on the expression provided to the ngHide attribute. The element is shown or hidden by removing or adding the ng-hide CSS class onto the element. The .ng-hide CSS class is predefined in AngularJS and sets the display style to none (using an !important flag)."
Also check out this for short but accurate explanation about different Angular DOM handling: http://www.w3schools.com/angular/angular_htmldom.asp
So in the end they actually do the same thing. And as far as I know, you should not use them in combination. If you would like to create multiple boolean values as parameters to either one of them you could do it like this: <div ng-show="value1 && !value2">Something</div>. Still I suggest that if you need more paramter values you should go with a function.
<div ng-show="ShowMe()">Content</div>
$scope.ShowMe = function(){
return $scope.value && !$scope.value2;
}

using angular ng-style to call out a background image

I am having an with using the ng-style directive. I want to create add a button to my ng-repeat which is css sprite. If i include the sprite normal way my element inspector has a good old moan. from the information i gather from the Angular documentation
i thought it was as simple as the following:
<button ng-style="{'background-image':'url:('/img/Myimage.png')'}">test</button>
However i am receiving a snytax error message from this line of code. Does anyone know the correct method?
<button ng-style="{'background-image':'url(\'img/MyImage.png\')'}">test</button>
is the correct way to do it. was missing the escape the quotes in url 'url:(\'/img/Myimage.png\')'
Your CSS syntax is incorrect for url, you have extra : and I would remove quotes for the src so the whole property is one string
<button ng-style="{'background-image':'url(/img/Myimage.png)'}">test</button>
I really don't undertsand why you would use ng-style for this. A simple CSS rule and class would make more sense since you aren't evaluating anything
oh,{color:' something',background:'something '}
ng-style="{background:'url(something)'}"
or
ng-style="{'background-image':'url(something)'}"

Can't access element attribute when it is clearly set

I have a problem that I haven't been able to solve.
In my class I set:
text.Attributes.Add("oldValue", text.Text);
Debugging the code I can see the value is being set properly. When I view the page source with chrome I see the following:
<input name="astextMon" type="text" value="4,25"
id="textMon" class="inputText"
autocomplete="on"
onfocus="ValidateReadStatus(this.id,this.ValueId);SetFocus(this.id);"
valueid="408412"
oldvalue="4,25"
onchange="return GridOnChange('0;0',this,'textMon',1,true);"
onkeydown="return GridOnKeyDown(this.id,'0;0');"
ondblclick="SetTextPos('0;0');"
>
As you can see, the oldvalue attribute is set and has the correct value, but if I try to access it I always get undefined. Even when accessing the element from the Chrome console.
What am I missing here?
EDIT. The typo in the name attribute happened when placing the code here. That is not the problem. I think case sensitivity is also not the issue, because when I remove:
text.Attributes.Add("oldValue", text.Text);
from my class, the oldvalue="4,25" property dissapears from the element. I also tried to change oldValue to oldvalue, but the same problem remains.
I am trying to access the object by using
alert(element.oldvalue) or alert(element["oldvalue"]) or
alert(element["oldValue"]) or alert(element["oldValue"]) none work.
If I type alert(element.value) It correctly alerts the value attribute.
Maybe the problem is that in your code snippet the input tag is not valid, after name attribute you must add a quote char.
<input name="astextMon" ...>
missing the first quote in name=astextMon" change it to name="astextMon"
JavaScript is case sensitive:
... oldvalue="4,25" ...
and
text.Attributes.Add("oldValue", text.Text);
refer to 2 different attributes.
You can use something like this to get the attribute define by you:
document.getElementById('textMon').attributes['oldvalue'].value;
Where you will get: oldvalue: 4,25
Few more things:
name=astextMon" should be name="astextMon"
Okay, so I solved my problem by using
$(element).attr("oldValue");
I have no idea why when using JQuery I can access the attribute just fine, but without it it is undefined. If anyone has an answer I would love to hear it.

Categories

Resources