create a parent html element in angularjs which would be inherited - angularjs

I have an angularjs template where some of the ngModel variable are empty. They are all attached to a html element.
I am very confused as to how to create an angularjs element that all this html elements would inherit so that
if a variable is empty or does not have anything inside its content then it should display a default content.
This is what i have done currently.
<h3 ng-bind="name">Student's name</h3>
<p ng-bind="description"> More about the programme</p>
<h2 ng-bind="title">Details about the programme for the whole years</h2>
So instead of this area been empty because there is nothing there I would want it to display the default text shown.
I think it is a drirective matter but I am not really that good with it

You can apply below simple solutions-
1. Set an expression to ng-bind
<h3 ng-bind="name || 'Student\'s name'"></h3>
<p ng-bind="description || 'More about the programme'"></p>
<h2 ng-bind="title || 'Details about the programme for the whole years'"></h2>
Note: Escape character "" is added in the default text
2. Use expression as element content instead of ng-bind, but ng-bind is the preferred option.
<h3>{{name || "Student's name"}}</h3>
<p>{{description || "More about the programme"}}</p>
<h2>{{title || "Details about the programme for the whole years"}}</h2>
3. Writing getters in the Component/Controller class of the directive for all these properties.
In the getter function, you can decide to return default values as fallback when values are not to these properties.
About creating parent element/directive: even if you create a generic directive, the default values are distinct for each use case. So you will end up writing more or less similar code to set default values to new element/directive.

Related

how to use same component in multiple place with some logic in angularjs

Well I have a directive/component/controller i.e <app-form></app-form> I am using this html page into multiple place but I want to to remove some specific field from different in place component how can I do in angularjs
In reactjs we can do like this <app-form disableField></app-form> and if disabledField then disable particular field other wise nothing to do
Again for better understanding for example we have one form having name, email and dob same form is using multiple place but at one place we are not interesting to display dob how can we disable or remove from specific place ?
please guide
You have to use bindings in your component declaration. something on the lines of:
angular.module('app').component('appForm', {
controller: 'AppFormCtrl',
templateUrl: 'app-form.html',
bindings: {
disableField: "<", // use '<' to generate input on the component
}
});
then in your app-form.html you can access the input var using the $ctrl object:
<form>
<input ng-if="$ctrl.disableField == true" type="text"/>
</form>
And the you can pass whatever value you want in the scope of your root view:
<div>
<!-- displays the form input according to the passed property's value -->
<app-form disable-field="isFieldEnabled"></app-form>
<!-- displays the form input -->
<app-form disable-field="true"></app-form>
<!-- does NOT display the form input -->
<app-form disable-field="false"></app-form>
<!-- does NOT display the form input, as disableField is evaluated an NULL in the component instance -->
<app-form></app-form>
</div>
isFieldEnabled is the property in your root controller $scope that will control the enabling / disabling of the input field in your component, but you can simply pass true or false if no logic is used.
You can attach whatever property you want, it doesn't have to be a boolean (but in this case I think it makes sense).
Also, notice that when defining the binded property 'disableField' in the Javascript environment, we use camelCase. The same property will be defined in the view / html environment using kebab-case.
You can also check the following answer to see how to generate output from the component instances:
Angular.js, how to pass value from one component to any other

pass cmsfn value to a scope variable angularjs

I'm trying to pass a variable to angularjs from cmsfn. Did anyone managed to do it already?
<div ng-controller="someController">
[#assign currentNode = cmsfn.asJCRNode(content)]
[#assign rootPageNode = cmsfn.root(currentNode, "mgnl:page")!]
<div style="display: none">{{myVar='${rootPageNode}'}}</div>
</div>
In the above code, when i try to use myVar in angular, its value is empty.
So first, reduce your FM code to single line:
[#assign rootPage = cmsfn.root(content, "mgnl:page")!]
This way, what you get back is still ContentMap and not Node which is easier to manipulate in the template.
Second, get the name of the page (if that is what you want):
${rootPage.#name}
You can find list of other special properties of content map at the bottom of this page
Now, last about the angular part, what you have in your template is just angular expression, "print statement" if you will, which will not assign variable. You need to do the assignment using $scope.myVar=... in the someController controller itself. Which means that the .js file itself needs to be freemarker template.

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