I want to execute a ng-include and show the content only after a button is clicked. I tried to use the ng-if directive and show the div when the ng-model is true, but his value is not changed in the myFunctionfunction.
<div ng-controller='myCtrl'>
<div ng-if='include==true' ng-include='"path"'></div>
<input type="button" ng-click='myFuntion()'/>
</div>
.controller('myCtrl', function($scope){
$scope.include = false;
$scope.myFunction = function(){
$scope.include = true;
}
})
There is a typo in your ng-click function. myFuntion should be myFunction. You can also just use ng-if='include' instead of ng-if='include==true'.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.include = false;
$scope.myFunction = function(){
$scope.include = true;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-if='include'>Clicked</div>
<input type="button" ng-click='myFunction()'/>
</div>
I would simply create a function that change the variable path for a valid one, no need to do a ng-if
$scope.myFunction = function(newPath){
$scope.path = newPath;
}
<div ng-include="path"></div>
<input ng-click="myFunction('path/to/file.html')" type="button />"
Related
I'm posting my html and directive code. I have two spans, which I have attached ng-click to. On ng-click I want to check the classes of their parents parent item (.parent-portlet), but what I have so far is not working correctly as all of the parent portlets get selected instead of only the current one.
<div class="parent-portlet {{portlet.class}} {{portlet.class2}}" ng-mouseenter="hoverIn($event)" ng-mouseleave="hoverOut($event)">
<div class="portlet-titlebar" ng-click="toggleCollapsed($event)">
<span class="remove" ng-click="removePortlet(portlet)">
Remove
</span>
<span class="add-back" ng-click="addPortlet(portlet)">
Add Back
</span>
</div>
</div>
this is what I have in my directive:
scope.removePortlet = function(portlet) {
var port = $('.remove').parent().parent();
port.addClass('removed');
port.addClass('edit-portlet');
};
scope.addPortlet = function(portlet) {
var port = $('.add-back').parent().parent();
if (portlet.hasClass('removed')) {
port.removeClass('removed');
port.removeClass('edit-portlet');
}
};
The problem with this code is that var portlet catches all of the portlets(parents) and I want to catch only the one related to the click action. How can I achieve that? I tried to pass this to my jquery select like so:
var portlet = $('.add-back', this).parent().parent();
but that didn't work. Any ideas how this can be achieved?
Thanks in advance.
Pass in the $event to the ng-click like this:
<span ng-click="removePortlet($event)"></span>
Then, just modify your code like this:
scope.removePortlet = function(ev) {
var port = $(ev.target).parent().parent();
port.addClass('removed');
port.addClass('edit-portlet');
};
scope.addPortlet = function(ev) {
var port = $(ev.target).parent().parent();
if ($(ev.target).hasClass('removed')) {
port.removeClass('removed');
port.removeClass('edit-portlet');
}
};
Grabbing the "event's target" will ensure that you are only addressing the item that was actually clicked. And note that angular uses $event to pass the event to a function.
I would also clean it up a bit combining the class modification lines and targeting the specific parent (in case you ever modify the DOM) using .closest():
scope.removePortlet = function(ev) {
var port = $(ev.target).closest('.parent-portlet');
port.addClass('removed, edit-portlet');
};
scope.addPortlet = function(ev) {
var port = $(ev.target).closest('.parent-portlet');
if (portlet.hasClass('removed')) {
port.removeClass('removed, edit-portlet');
}
};
You can inject the $element to your controller, then, use it as the context for the $ selector.
angular.module('app', []).controller('ctrl', function($scope, $element) {
$scope.addPortlet = function(portlet) {
console.log($('.add-back', $element));
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div class="parent-portlet">
<div class="portlet-titlebar" ng-click="toggleCollapsed($event)">
<span class="remove" ng-click="removePortlet(portlet)">
Remove
</span>
<span class="add-back" ng-click="addPortlet(portlet)">
Add Back
</span>
</div>
</div>
</div>
For more info about it
Use ng-class instead. Here's an example of changing background colors with classes:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.portlet = {
classes: {
"parent-portlet": true,
"edit-portlet": false,
"removed": false
}
}
$scope.removePortlet = function(portlet) {
portlet.classes.removed = true;
portlet.classes["edit-portlet"] = true;
};
$scope.addPortlet = function(portlet) {
portlet.classes.removed = false;
portlet.classes["edit-portlet"] = false;
};
});
/* Put your css in here */
.parent-portlet {
background-color: #ccc;
padding: 20px;
}
.parent-portlet.removed {
background-color: #c00;
}
.parent-portlet button {
padding: 10px;
margin: 0 10px;
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-class="portlet.classes">
<div class="portlet-titlebar">
<button class="remove" ng-click="removePortlet(portlet)">
Remove
</button>
<button class="add-back" ng-click="addPortlet(portlet)">
Add Back
</button>
</div>
</div>
</body>
</html>
I am rendering HTML text in a div, which I make then editable. The user can modify the text, but is there a way to get back the text modified in HTML?
This is the fiddle I am trying to make working:
<div ng-controller="MyCtrl">
Hello, {{name}}!
<div class="editable" ng-bind-html="documentBody"></div>
</div>
Controller:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.documentBody = '<p align="center"><font size="2">Ciao</font></p><br><p align="center"><font size="2">Bello!</font></p>';
$('.editable').each(function () {
this.contentEditable = true;
});
}
http://jsfiddle.net/sirfabio80/5sr8wnzv/
Thanks in advance
Fabio
Use directive like below. We can't edit like you expect, We must use ng-model with some kind of simple way.
var myApp = angular.module('myApp',['ngSanitize']);
myApp.controller('MyCtrl',function ($scope, $sce) {
$scope.name = 'Superhero';
$scope.names = [{name:"Ciao"},{name:"Bello"},{name:"Allo"}];
});
myApp.directive('dirNew', function(){
return {
restrict:"EA",
scope:{repeats:"=",},
template:'<p align="center" ng-repeat="n in repeats"><span size="2" ng-click="click($index)" ng-hide="n.enabled">{{n.name}}</span><input type="text" ng-show="n.enabled" ng-model="n.name"><button ng-show="n.enabled" ng-click="click($index)">Ok</button></p><br>',
link: function(scope) {
scope.click = function(index){
scope.repeats[index].enabled = !scope.repeats[index].enabled;
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular-sanitize.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">{{names}}
<br>
Hello, {{name}}!<br>
Click the text and Edit......
<dir-new repeats="names"></dir-new>
</div>
</body>
The code only seems to hide it when I click on the element but when I click the element again, it does not reappear.
HTML (AngularJS)
<div ng-click="showIt();">Click Me!</div>
<div style="visible:{{tog}};">Hide Me...Then Show Me Again</div>
Controller:
$scope.showIt=function(){
if($scope.tog="visible"){
$scope.tog="hidden";
}
else{
$scope.tog="visible";
}
}
$scope.tog="visible";
Thanks in advance:)
What about ng-show directive?
<div ng-click="tog = !tog">Click Me!</div>
<div ng-show="tog">Hide Me...Then Show Me Again</div>
The style is called visibility also in the if condition you need to use == not =.
But a better solution will be to use the ng-style directive or use a class based solution
var app = angular.module('my-app', [], function() {})
app.controller('AppController', function($scope) {
$scope.showIt = function() {
if ($scope.tog.visibility == "visible") {
$scope.tog.visibility = "hidden";
} else {
$scope.tog.visibility = "visible";
}
}
$scope.showIt2 = function() {
$scope.hidden = !$scope.hidden;
}
$scope.tog = {
visibility: "visible"
};
$scope.hidden = false;
})
.hidden {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app">
<div ng-controller="AppController">
<div ng-click="showIt()">Click Me!</div>
<div ng-style="tog">Hide Me...Then Show Me Again</div>
<hr />
<div ng-click="showIt2()">Click Me!</div>
<div ng-class="{hidden: hidden}">Hide Me...Then Show Me Again</div>
</div>
</div>
Working Plnkr
You cal also do it with ng-if directive:
<div ng-click="showIt();">Click Me!</div>
<div ng-if="tog">Hide Me...Then Show Me Again</div>
JavaScript:
angular.module('myApp', [])
.controller('MyController', function($scope) {
$scope.tog = true;
$scope.showIt=function(){
$scope.tog=!$scope.tog
}
});
I am a beginner in angularjs and currently I am facing an issue with ng-include.
I have a test app using partials.
Here is my code.
<html ng-app ="TextboxExample">
<head>
<title>Settings</title>
<script src="angular.js"></script>
</head>
<body ng-controller="ExampleController">
<div ng-include src = "'view.html'"></div>
<script>
angular.module('TextboxExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.textboxVal = 'fddfd';
$scope.ReadGeneralSettings = function() {
alert($scope.textboxVal);
}
$scope.ResetGeneralSettings = function() {
$scope.textboxVal = 'fddfd';
}
}]);
</script>
<button class="pull-right" ng-click = "ReadGeneralSettings()">Read</button>
<button class="pull-right" ng-click = "ResetGeneralSettings()">Cancel</button>
</body>
</html>
The partial code view.html is
<input type="text" ng-model="textboxVal">
For some reason, textboxVal set to ng-model doesn't get updated when I enter the value in the text box.
But this works fine if I don't use ng-include and directly add the content of view.html into the main html file.
Please help.
Thanks
Sunil
Use $parent to access the scope of the controller
Demo
<input type="text" ng-model="$parent.textboxVal">
The problem is that ngInclude creates new scope, so the model you define inside partial template with ngModel works with local scope value, and outer ExampleController can't see it.
The simple solution is to use prototypical chain of scope objects, then inner scope will inherit and use model value from the outer scope:
<body ng-controller="ExampleController">
<div ng-include src = "'view.html'"></div>
<script>
angular.module('TextboxExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.model.textboxVal = 'fddfd';
$scope.ReadGeneralSettings = function() {
alert($scope.model.textboxVal);
}
$scope.ResetGeneralSettings = function() {
$scope.model.textboxVal = 'fddfd';
}
}]);
</script>
<button class="pull-right" ng-click = "ReadGeneralSettings()">Read</button>
<button class="pull-right" ng-click = "ResetGeneralSettings()">Cancel</button>
</body>
and then use it in partial as
<input type="text" ng-model="model.textboxVal">
I was just doing this tutorial which makes a lot of sense - http://onehungrymind.com/angularjs-sticky-notes-pt-2-isolated-scope/. A fiddle provided is here: http://jsfiddle.net/simpulton/SPMfT/
It shows how to bind attributes to the parent controllers scope using #, =, &.
I wanted to change the fiddle to use "controller as syntax", but can't seem to get it to work, my fiddle is here - http://jsfiddle.net/SPMfT/304/
Any thoughts on why this wouldn't work?
View:
<div ng-controller="MyCtrl as ctrl">
<h2>Parent Scope</h2>
<input ng-model="ctrl.foo"> <i>// Update to see how parent scope interacts with component scope</i>
<br><br>
<!-- attribute-foo binds to a DOM attribute which is always
a string. That is why we are wrapping it in curly braces so
that it can be interpolated.
-->
<my-component attribute-foo="{{ctrl.foo}}" binding-foo="ctrl.foo"
isolated-expression-foo="ctrl.updateFoo(newFoo)" >
<h2>Attribute</h2>
<div>
<strong>get:</strong> {{isolatedAttributeFoo}}
</div>
<div>
<strong>set:</strong> <input ng-model="isolatedAttributeFoo">
<i>// This does not update the parent scope.</i>
</div>
<h2>Binding</h2>
<div>
<strong>get:</strong> {{isolatedBindingFoo}}
</div>
<div>
<strong>set:</strong> <input ng-model="isolatedBindingFoo">
<i>// This does update the parent scope.</i>
</div>
<h2>Expression</h2>
<div>
<input ng-model="isolatedFoo">
<button class="btn" ng-click="isolatedExpressionFoo({newFoo:isolatedFoo})">Submit</button>
<i>// And this calls a function on the parent scope.</i>
</div>
</my-component>
</div>
JS:
var myModule = angular.module('myModule', [])
.directive('myComponent', function () {
return {
restrict:'E',
scope:{
/* NOTE: Normally I would set my attributes and bindings
to be the same name but I wanted to delineate between
parent and isolated scope. */
isolatedAttributeFoo:'#attributeFoo',
isolatedBindingFoo:'=bindingFoo',
isolatedExpressionFoo:'&'
}
};
})
.controller('MyCtrl', ['$scope', function ($scope) {
this.foo = 'Hello!';
var self = this;
this.updateFoo = function (newFoo) {
self.foo = newFoo;
}
}]);
Thanks JoseM for the heads up. I've rewritten this fiddle using angular 1.2 and "controller as" syntax here: - http://plnkr.co/edit/nUXWrj4yzypaQmtJShl9?p=preview
Not sure where to start with issue with the previous version:
In 1.2 isolated scope variables can't be used directly in the DOM,
they have to be in the template of the directive.
I made sure mydata was an object to avoid prototypical inheritance issues.
When evaluating an attribute with # you have to make sure you pass it
inside {{}}.
var app = angular.module("drinkApp", []);
app.controller("AppCtrl", function($scope) {
this.ctrlFlavor = {
data: "blackberry"
}
var self = this;
this.updateFoo = function(newFoo) {
self.ctrlFlavor.data = newFoo;
}
})
app.directive("drink", function() {
return {
scope: {
isolatedBindingFoo: "=",
isolatedAttributeFoo: "#",
isolatedExpressionFoo: '&'
},
template: '<h2>Isolated Binding</h2><div>{{isolatedBindingFoo}}</div><input ng-model="isolatedBindingFoo"></input><br><h2>Isolated Attribute</h2><div>{{isolatedAttributeFoo}}</div><input ng-model="isolatedAttributeFoo"></input><h2>Isolated Expression</h2><input ng-model="isolatedFoo"></input><button class="btn" ng-click="isolatedExpressionFoo({newFoo:isolatedFoo})">Submit</button>'
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Video Embed</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.2.4" src="http://code.angularjs.org/1.2.3/angular.js" data-require="angular.js#1.2.x"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-app="drinkApp">
<div ng-controller="AppCtrl as drinkCtrl">
<h2>AppCtrl Scope</h2>
{{drinkCtrl.ctrlFlavor.data}}
<br>
<input type="text" ng-model="drinkCtrl.ctrlFlavor.data">
<div drink isolated-binding-foo="drinkCtrl.ctrlFlavor.data" isolated-attribute-foo="{{drinkCtrl.ctrlFlavor.data}}" isolated-expression-foo="drinkCtrl.updateFoo(newFoo)">
</div>
</div>
</div>
</body>
</html>