How to get the attribute value in template html with angularjs - angularjs

I wrote a directive but I don't know how to get the attribute of the directive in template html, those attributes are used in ngIf to determine which div elements will be displayed, pls take a look at below code snippet.
directive use:
<geo-country-selector type="WGC"></geo-country-selector>
template html:
<div ng-if="type.indexOf('W')>0">
...
</div>
<div ng-if="type.indexOf('G')>0">
...
</div>
I need to get the attribute type's value in the template html. I did lots of research on that, but no luck. Any ideas? Thanks
The directive can be like Anik said :
link : function(scope,element,attr){
...
},
scope: {
type: '#'
}

In your directive add a link function then add attrs value to scope then you can check condition in your template like that
try like this
link : function(scope,element,attr){
scope.type=attr.type
}
There is another way by creating isolate scope like this
scope: {
type: '#'
}

Related

Run 'ng-click' inside a directive's isolated scope

Thanks in advance for taking the time to look into this question
I have serverside generated code that renders a directive wrapped around pre-rendered content.
<serverside-demo color="blue">
<p><strong>Content from Server, wrapped in a directive.</strong></p>
<p>I want this color to show: <span ng-style="{color: color}">{{color}}</span></p>
<button ng-click="onClickButtonInDirective()">Click Me</button>
</serverside-demo>
This means that 1.) the directive tag, 2.) the content inside the directive tag, 3.)the ng-click and 4.) The curly braces syntax are all generated by the server.
I want AngularJs to pick up the generated code, recompile the template and deal with the scope.
The problem is that I am having trouble getting it working. I understand that because the ng-click is inside the controller block, it is picked up not by the directive isolated scope, but the parent controllers. Instead I want the opposite... to pick up the onClickButtonInDirective scope function inside the serversideDemo link
I have created a jsfiddle best explaining my problem, which aims to clearly demonstrate the working "traditional" way of loading the template separately (which works) comparing it to the server-side way.
https://jsfiddle.net/stevewbrown/beLccjd2/3/
What is the best way to do this?
Thank you!
There are two major problem in your code
1- directive name and dom element not matched, - missing in dom element
app.directive('serverSideDemo', function() {
use <server-side-demo color="blue"> instead of <serverside-demo color="blue">
2- you need to compile the html code of server-side-demo dom with directive scope in link function
$compile(element.contents())(scope);
Working jsfiddle
Use templateUrl instead of template to fetch the content of directive from server:
app.directive('serverSideDemo', function() {
return {
restrict: 'AE',
scope: {
color: '='
},
templateUrl: 'link/that/returns/html/content',
link: function(scope, element, attrs) {
scope.onClickButtonInDirective = function() {
console.log('You clicked the button in the serverside demo')
scope.color = scope.color === 'blue' ? 'red' : 'blue';
}
}
};
});
Have a look at angular docs for more details

In directive template, inside ng-repeat scope not working

I have a directive as follows,
angular.module("sample").directive("sampleDir", [
"$compile", function($compile) {
return {
restrict: "E",
replace: true,
scope: {
options: '=',
source: '='
},
templateUrl: "sample.html"
};
}
]);
sample.html
<div ng-repeat="row in source" class="{{$parent.options.Class}}">
<label value="{{row.label}}">{{row.label}}</label>
</div>
Here inside template "source" parameter i can use as such. However, "options" parameter need to be fetched from parent scope. If i am creating another div outside, then options parameter i can get as such.
I tried adding another div outside this ng-repeat div and tried to access "options" parameter is working fine.
<div class="{{options.Class}}">
<div ng-repeat="row in source">
<label value="{{row.label}}">{{row.label}}</label>
</div>
</div>
But why it is not working with ng-repeat div?
How can i remove $parent and use "options" parameter as such?
Please help,
Thanks.
It's a known issue. It's happening when you use replace: true and ngRepeat on the top element of the directive. So the ngRepeat is bound to the outer scope instead of the isolated scope.
You can resolve it by either not using replace or adding an element to the top of the directive.
I think the scope variable name "options" might be conflicting. Try changing the scope variable of the directive to something else.
For eg: Your scope definition can change to this
scope: {
sampleOptions: '=',
source: '='
},
in case you are stuck with any syntax related issue doing this, this article will be helpful

Dynamically initialize a ng-model directive

I'm dynamically building a form with angular depending of the kind of input:
<div ng-controller="formController" ng-repeat="field in formFields" ng-switch="field.type">
<div ng-switch-when="text">
<!-- Something -->
</div>
<div ng-switch-when="dropdown">
<myDirective my-data="field.param" ng-model="field.model"></myDirective>
</div>
</div>
I've got two problems with my directive which builds a custom dropdown input:
Ng-model directive interprated the name field.model as plain text, whereas I would like the attributs ng-model="field.model" would be replaced by the value contained into field.model. Curly brackets don't seems to work here. Any idea?
How to let the ng-model value accessible both in my form controller, and into my custom directive's controller?
Exemple of a field object:
{
label : "Name",
model : "employeeName",
type : "dropdown",
param : {
dropdownArray : result,
dropdownName : 'Nom',
dropdownFieldValue : 'nameUUID',
dropdownVisibleValue : [ 'employeeSS', 'employeeName' ]
}
}
Then in my controller I should be able to access this dropdown value with: $scope.employeeName.
It sounds like you're accessing field.model via the attributes input parameter supplied to the link function in your directive. Instead, you should be accessing it via the scope variable.
link: function(scope, element, attributes) {
// attributes.ngModel will yield 'field.model'
// scope.ngModel will contain the actual value of field.model
}
If you don't explicitly define an isolate scope for your directive, then ng-model assigned to field.model should be available in your directive via the scope variable as I mentioned above.
scope: false // This is the default
// Define an isolate scope with field.model available through scope.ngModel
scope: {
ngModel: '='
}
Hope that helps.

angularjs: click on a tag to invoke a function and pass the current tag to it

I need to handle a click on a tag that enables the opening of a popover.
I try to figure out the best way to do this with angularjs and naturally used hg-click.
<div ng-repeat="photo in stage.photos"
ng-click="openPopoverImageViewer($(this))"
>
$scope.openPopoverImageViewer = function (source) {
alert("openPopoverImageViewer "+source);
}
The issue is that I cannot manage to pass the $(this) to it.
Q1) How to pass the jQuery element?
Q2) In addition, ng-click sounds
to require the function being part of the controller: is it possible
to invoke a function in the partial instead?
You need to stop "thinking in jQuery" :)
Like #oori says, you can pass in photo.
Or better yet, create a custom directive. Directives is the way to go when you need new functionality in your dom, like an element that you can click to open an overlay. For example:
app.directive('popOver', function() {
return {
restrict: 'AE',
transclude: true,
templateUrl: 'popOverTemplate.html',
link: function (scope) {
scope.openOverlay = function () {
alert("Open overlay image!");
}
}
};
});
You can then use this as a custom elemen <pop-over> or as an attribute on regular HTML elements. Here is a plunker to demonstrate:
http://plnkr.co/edit/P1evI7xSMGb1f7aunh3G?p=preview
Update: Just to explain transclusion: When you say that the directive should allow transclusion (transclude:true), you say that the contents of the tag should be sent on to the directive.
So, say you write <pop-over><span>This will be passed on</span></pop-over>, then the span with "This will be passed on" is sent to the directive, and inserted wherever you put your ng-transclude element in your template. So if your pop-over template looks something like this:
<div>
<ng-transclude/>
</div>
Then your resulting DOM after the template has compiled will look like this:
<div>
<span>This will be passed on</span>
</div>
Pass it "photo"
<div ng-repeat="photo in stage.photos" ng-click="openPopoverImageViewer(photo)">
or the current $index
<div ng-repeat="photo in stage.photos" ng-click="openPopoverImageViewer($index)">

Set templateUrl base on attribute in directive

I'm working on a set of angular directives and I want to load the correct template based on the presence or value of an attribute.
<my-form horizontal> </my-form>
<my-form vertical> </my-form>
If horizontal, templateUrl should be /partials/horizontal-form and
If vertical, templateUrl should be /partials/vertical-form
I'm interested in the templateUrl because I can't use template since the html depends on the attributes. In the compile.pre function, the html has already been loaded.
If there is another way of achieving this, I'm open to it since I'm now starting with angular and the more info the better.
Thanks
fyi this is now properly fixed in angular 1.1.4
you can pass a function to templateUrl. input parameters are element, attributes. and returns a string (the templateUrl you wish to use)
docs here: http://code.angularjs.org/1.1.4/docs/guide/directive
One of the solutions for this is to use an ng-include inside the template file.
The first attribute inside of the template file will have something like :
<div ng-include = "getTemplate()">
</div>
In your directive code you would write something like :
scope : {direction : "="},
link : function(scope,element,attrs)
{
scope.getTemplate = function(){
if(scope.direction === "horizontal")
{
return "horizontal.html";
}
return "vertical.html";
}
}
Hope this helps!

Resources