I am trying to navigate between different html templates on click of the button.
I have main html and sub html.
Main.html:
<div id="main"></div>
Sub.html:
<div id="sub"></div>
Index.html:
<my-clicker on-click="ButtonClicked($event)">
<button class="new_btn">Click Me</button>
</my-clicker>
Directive Code:
app.directive('myClicker', function () {
return {
restrict: 'E',
scope: {
onClick: "&"
},
link: function($scope, element, attrs) {
var button = $('.new_btn');
button.bind("click", $scope.onClick);
element.append(button);
}
};
});
Controller:
$scope.ButtonClicked = function($event) {
alert('hai');
};
Now how do I add my template urls to the button click event. Can anyone please help me out with the sample how we can achieve this scenario.
So according to the comments the usecase here is to swap out one specific part of the DOM when clicking a button.
In this case you don't need a custom directive, you should use ng-include. The ng-include directive is placed on a div (or other dom element) and makes that element load its content from a specified template. You can specify this template as a variable and when you want to swap the content of the div you just change the variable.
Here is an example:
<div id="swappable-content-area" ng-include src="currentTemplate">
<!-- The content will appear here -->
</div>
<button ng-click="currentTemplate = 'mytemplate.html'">Template 1</button>
<button ng-click="currentTemplate = 'myothertemplate.html'">Template 2</button>
The buttons could of course be a part of the included template.
Related
I want to have an angular function fire after an element has displayed on the page.
The element is part of a SPA where what is displayed is controlled by a whole bunch of events (so doing things on page load won't work). The display of this element's parent (and therefore the element itself) is controlled by an ng-if which calls a separate function. As the parent doesn't display until that function has returned, there's no logical place to include the logic to alter this child element within that function, and since it's called by angular because of the ng-if, there's no parent function to place the code in once the previous function has returned.
I am currently achieving this by putting the function with my logic in it that always returns true within an ng-if on a child element of the element that has the proper, useful ng-if on it, as this will run as soon as the element has the option of being displayed. While this does work, I feel it's a very dodgy solution to the problem. Is there a more "proper" method of achieving this?
Snippet of the HTML (function names changed for the sake of the question):
<div data-ng-if="shouldTheButtonDisplay()">
<a class="btn"
data-ng-click="irrelevantToQuestion()"
data-ng-if="functionToPerformOnceElementLoaded()"
href="#">
button text
</a>
</div>
Snippet of JS (details changed because irrelevant to question):
$scope.shouldTheButtonDisplay() {
return booleanThatIsRelevantInContext;
}
$scope.functionToPerformOnceElementLoaded = function() {
// Edit state of button (technically an anchor)
var firstRowButton = document.querySelector("a.btn");
firstRowButton.style.background = "green";
return true;
}
I would have done so:
angular
.module('yourModuleName', [])
.controller('yourControllerName', yourControllerNameCtrl)
.directive('yourDirectiveName', yourDirectiveNameDirective);
yourControllerNameCtrl.$inject = ['$scope'];
function yourControllerNameCtrl($scope)
{
$scope.message = 'In controller';
$scope.irrelevantToQuestion = function() {};
}
function yourDirectiveNameDirective()
{
function doSomethingElse(scope)
{
scope.message = 'In directive';
}
return {
restrict: 'A',
scope: 'falsy',
link: function(scope, element)
{
element.find('a').addClass('green');
doSomethingElse(scope);
}
};
}
.btn {
background-color: red;
}
.btn.green {
background-color: green;
}
<html ng-app="yourModuleName">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
</head>
<body ng-controller="yourControllerName">
<div>{{ message }}</div>
<div your-directive-name>
<a class="btn"
data-ng-click="irrelevantToQuestion()"
href="#">
button text
</a>
</div>
</body>
</html>
I want to add dynamic directive inside another directive tempalte.
As you see I want to add another directive inside a directive template
How do add those dynamic directive there
Please help
return {
restrict: 'AE',
require :'^awkGrid',
templateUrl: 'views/shutter.html',
link : function(scope, element, attr, controllerInstance){
//Set the header
scope.items = [];
angular.forEach(scope.rowData, function(value, key) {
var obj = {
key : key,
value : value
};
template = <country name="'+value.country+'" id="'+key+'"></country>;
scope.items.push(template);
});
};
//Inside shutter.html file
<div data-ng-repeat="item in items" class="ag-row action-row"
ng-class-odd="'ag-row-even'"
ng-class-even="'ag-row-odd'"
ng-class="{'ag-row-selected':$index == selectedRow}"
ng-click="setClickedRow($index,$event)">
<div class="ag-cell">
{{item}} //Not working ,Prinitng the string
<country name="india" id="-1"></country> //Working
</div>
To dynamically switch out the entire template of a directive you have to set the element's html to the desired new template and then pass the element's contents into $compile to bind it with the $scope.
element.html('<h1>Dynamic Content</h1>').show();
$compile(element.contents())($scope);
This should all be defined in the link function of the directive in question.
You must have to recompile your directive. Add folowing code at the end of link function:
$compile(element.contents())(scope);
Answer is in here.
Of course, you have to add service $compile to your directive as a dependency.
I've this very simplified html:
<div ng-controller="Ctrl">
<div ng-include="template"></div>
</div>
My template1.html only contains:
<div id="i1" ng-click="clickFunction()">Content of template1.html</div>
The template2.html:
<div id="i2"> Content of template2.html </div>
And the following JS :
function Ctrl($scope) {
$scope.template = 'template1.html';
$scope.clickFunction = function () {
$scope.template = 'template2.html';
}
}
When I click on my included template my second template is loaded in place of the first one.
What is the clean Angular method to replace back the template2 with the template 1 when I click everywhere else on my page (but not in my ng-include div)?
Here a basic fiddle if it can help.
Edit :
I've tested to add the following code into my controller but the template view isn't updated (but the console.log yes, very strange behaviour...):
jQuery('html').click(function() {
console.log('Click on HTML')
$scope.template = 'template1.html';
});
jQuery('#i2').click(function(event){
event.stopPropagation();
});
If you are modifying the model outside angular environment, you have to use apply() method of scope to update.
$scope.template = 'template1.html';
$scope.$apply();
Also I updated the fiddle such that it meets your requirement.
Fiddle
I'm using angular js bootstrap tooltip to show tooltips on a set of elements.
Plunker: http://plnkr.co/edit/9xk41f3CR0wnajN71bSi
I need to inject into the tooltip html compiled by angular, but i don't really get how. The tooltip tutorial is not useful to me because it gets the html from the scope as variable, but for a set of elements this is not possible.
How can i fill tooltip-html-unsafe?
You can do something like this:
HTML:
<li ng-repeat="phone in phones">
<div phone-info index="{{$index}}">
<p tooltip-html-unsafe="{{tooltips[$index] }}">A tooltip should appear on top of this line ({{ phone.name }} - {{ phone.snippet }})</p>
<div>
</li>
Add to controller:
$scope.tooltips = [];
Directive:
app.directive('phoneInfo', function($compile, $timeout) {
/* wrap in root element so we can get final innerHTML*/
var tipTemplate = '<div><p> This will be the content of {{phone.name}} injected in the tooltip </p><div>';
return {
link: function(scope, el, attrs) {
var tipComp = $compile(tipTemplate)(scope)
$timeout(function() {
scope.tooltips[attrs.index] = tipComp.html()
});
}
}
})
Used index to avoid creating an isolated scope. Can also be done with isolated scope and create a property of phone instead of using scope.tooltips[index]
DEMO
So, I'm new to AngularJS and I'm trying to change a div content after another is clicked (this one holds a div with the content that I want to put on the first one).
HTML
<div ng-controller="dCtrl">
<ul ng-repeat="product in products">
<li change>
{{product.name}}
<div class="hide">{{product.description}}</div>
</li>
</ul>
</div>
<div id="test"></div>
Javascript
var app = angular.module("dt", []);
app.directive("change", function() {
return function(scope, element) {
element.bind("click", function() {
var message = element.children("div").text();
console.log("breakpoint");
angular.bind("#test", function() {
this.text(message);
});
})
}
})
app.controller("dCtrl", function($scope) {
$scope.products = [
{ "name" : "Escova XPTO", "description": "Lava tudo num instante"},
{ "name" : "Pasta de Dentes YMZ", "description": "Dentifrico do camandro"}
];
})
I know that I could just say:
$("#test").html(message);
But I'm still confused about mixing jQuery and AngularJS, I dont know if that is a correct way of doing it
Thanks
Setup ng-click:
ngClick is for doing things such as the scary jQuery-esque stuff you have going on in your change directive. Place ng-click in your clickable div's attributes and pass in a method that changes the $scope variable accepted by...
ngShow and ngHide.
When true these directives, as the name states, show or hide the associated html object. You can pass in $scope variables determine the boolean value. When the $scope updates these methods automatically update the DOM to show/hide the element.