$scope.man="A"; //default text
<div ng-app="myApp" ng-controller="myCtrl">
<p>person clicked {{man}}</p>
<button ng-click="man('b')">B</button><br>
<button ng-click="man('c')">C</button>
</div>
var app=angular.module("myApp",[]);
app.controller("myCtrl",function($scope){
$scope.man="A";
$scope.man=function(value)
{
$scope.man=value;
}
});
i am new to angularjs i wanted to change text by arguments but text is not changing and the default text A is also not getting displayed can some one help me out with this
check this link
https://jsfiddle.net/nikhila/31gz56tn/
Your $scope variable and function are same. Change your function like this,
HTML:
<div ng-app="myApp" ng-controller="myCtrl">
<p>person clicked {{man}}</p>
<button ng-click="change('b')">B</button><br>
<button ng-click="change('c')">C</button>
</div>
Controller:
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.man = "A";
$scope.change = function(value) {
$scope.man = value;
}
});
DEMO
Related
basically i want to change the attribute value based on the button i clicked,
these are the two buttons
<button ng-click="fn(a)"></button>
<button ng-click="fn(b)"></button>
and then i have a prebuilt directive who takes value as input,
<div directive-name="" id="abc"></div>
if i click on first button,i want the value of directive based on button clicked.
What i did earlier;
$scope.go = function(data){
if(data==a){
var b = document.querySelector( 'div' );
b.setAttribute("directive-name","value");
}
else{}
}
here the problem is that it is selecting the first div of document and setting attribute value for that.
I also tried to pass it with id like
var b = angular.element(document.querySelector('#abc'));
I also saw some custom directives to do so, but they are not working
AngularJS DOM Manipulation through Directives
If possible provide me a demo in plunkr or fiddle
and also if i want to change css property of div based on button clicked
Thanks in advance
You can do it like this.
Assign the directive-name value to a $scope.variable and then use variable as the value in HTML.
HTML - 1:
<button ng-click="go(a)"></button>
<button ng-click="go(b)"></button>
HTML - 2:
<div directive-name="{{directive}}" id="abc"></div>
JS:
$scope.go = function(data){
if(data==a){
$scope.directive = "directive-1";
}else if(data==b){
$scope.directive = "directive-2";
}
}
To assign class name to div you can define other $scope.classVar and then use that in HTML like below:
<div directive-name="{{directive}}" id="abc" ng-class="classVar"></div>
I hope this will solve your problem.
This should work, (you had some errors in your code):-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.fn = function(data,id) {
if (data == 'a') {
var b = document.querySelector('#'+id);
b.setAttribute("directive-name", "value");
} else {
}
}
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div directive-name="" id="abc"></div>
<button ng-click="fn('a','abc')">A</button>
</div>
"Basically I want to change the attribute value based on the button I clicked."
You can do this by changing the attribute value the angular way, referencing a property of $scope or the controller instance in your template. When clicking a button, set the variable to the value you require to be passed to your directive.
Note: When you pass a value into your ngClick directive, you need to pass it as a string unless a and b are declared as properties of $scope.
Here's a basic example:
// app.js
(function() {
'use strict';
angular.module('app', []);
})();
// main.controller.js
(function() {
'use strict';
angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$scope'];
function MainController($scope) {
$scope.fn = fn;
function fn(data) {
// set the value so it's accessable in the view
// therefore we can pass it into our directive
$scope.myVar = data;
}
}
})();
// directive-name.directive.js
(function() {
'use strict';
angular.module('app').directive('directiveName', directiveNameDirective);
function directiveNameDirective() {
return {
restrict: 'A',
scope: {
directiveName: '='
},
template: '<span>directiveName: {{ directiveName }}</span>'
};
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MainController as MainCtrl">
<!-- here we pass a and b as strings otherwise they get evaluated as variables -->
<button ng-click="fn('a')">Set a</button>
<button ng-click="fn('b')">Set b</button>
<hr>
<!-- here we pass myVar which is declared as a property of $scope when the fn function is called -->
<div directive-name="myVar" id="abc"></div>
<hr> myVar: {{ myVar }}
</div>
</div>
I am trying that on a button click, a div and and input tag are created and the input tag contain ng-model and the div has binding with that input.
Kindly suggest some solution.
You can create the div and input beforehand and and do not show it by using ng-if="myVar". On click make the ng-if="true".
<button ng-click="myVar = true">
In controller : $scope.myVar = false;
$scope.addInputBox = function(){
//#myForm id of your form or container boxenter code here
$('#myForm').append('<div><input type="text" name="myfieldname" value="myvalue" ng-model="model-name" /></div>');
}
Here is another solution, in which there's no need to create a div and an input explicitly. Loop through an array of elements with ng-repeat. The advantage is that you will have all the values of the inputs in that array.
angular.module('app', [])
.controller('AppController', AppController);
AppController.$inject = ['$scope'];
function AppController($scope) {
$scope.values = [];
$scope.add = function() {
$scope.values.push('');
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="AppController">
<button ng-click="add()">Click</button>
<div ng-repeat="value in values track by $index">
<input type="text" ng-model="values[$index]"/>
<div>{{values[$index]}}</div>
</div>
<pre>{{values}}</pre>
</div>
UPDATE. And if you want only one input, it's even simpler, using ng-show.
angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<button ng-click="show = true">Click</button>
<div ng-show="show">
<input type="text" ng-model="value"/>
<div>{{value}}</div>
</div>
</div>
You should use $compile service to link scope and your template together:
angular.module('myApp', [])
.controller('MyCtrl', ['$scope', '$compile', '$document' , function MyCtrl($scope, $compile, $document) {
var ctrl = this;
var inputTemplate = '<div><span ng-bind="$ctrl.testModel"></span>--<span>{{$ctrl.testModel}}</span><input type="text" name="testModel"/></div>';
ctrl.addControllDynamically = addControllDynamically;
var id = 0;
function addControllDynamically() {
var name = "testModel_" + id;
var cloned = angular.element(inputTemplate.replace(/testModel/g, name)).clone();
cloned.find('input').attr("ng-model", "$ctrl." + name); //add ng-model attribute
$document.find('[ng-app]').append($compile(cloned)($scope)); //compile and append
id++;
}
return ctrl;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.angularjs.org/1.6.2/angular.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl as $ctrl">
<input type="button" value="Add control dynamically" ng-click="$ctrl.addControllDynamically()"/>
</div>
</div>
UPDATE: to add a new compiled template each time the button is clicked, we need to make a clone of the element.
UPDATE 2: The example above represents a dirty-way of manipulating the DOM from controller, which should be avoided. A better (angular-)way to solve the problem - is to create a directive with custom template and use it together with ng-repeat like this:
angular.module('myApp', [])
.controller('MyCtrl', ['$scope', function MyCtrl($scope) {
var ctrl = this;
ctrl.controls = [];
ctrl.addControllDynamically = addControllDynamically;
ctrl.removeControl = removeControl;
function addControllDynamically() {
//adding control to controls array
ctrl.controls.push({ type: 'text' });
}
function removeControl(i) {
//removing controls from array
ctrl.controls.splice(i, 1);
}
return ctrl;
}])
.directive('controlTemplate', [function () {
var controlTemplate = {
restrict: 'E',
scope: {
type: '<',
ngModel: '='
},
template: "<div>" +
"<div><span ng-bind='ngModel'></span><input type='type' ng-model='ngModel'/></div>" +
"</div>"
}
return controlTemplate;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.angularjs.org/1.6.2/angular.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl as $ctrl">
<input type="button" value="Add control dynamically" ng-click="$ctrl.addControllDynamically()"/>
<div ng-repeat="control in $ctrl.controls">
<control-template type="control.type" ng-model="control.value"></control-template>
</div>
</div>
</div>
Say, I have multiple directives, on click how can i add the "directive" what i want to "popup". i have number of scenario, but using only one pop-up for all. whenever the appropiate element is clicked, using the same pop-up, i would like to update the other 'directives'
for sample, i created only one. click on the red bordered title
here is my code :
<div ng-controller="main">
{{name}}
<div class="info" ng-click="popIt()">
<info-board></info-board>
</div>
<div class="popup" ng-if="show" ng-click="popIt()">
//add directive dynamically - how?
</div>
</div>
</body>
<script type="text/ng-template" id="modalPopup.html">
<div class='ng-modal'>
some information here.
</div>
</script>
js:
var myApp = angular.module("myApp", []);
myApp.controller("main", function($scope) {
$scope.name = "Mo!";
$scope.show = false;
$scope.popIt = function (show) {
$scope.show = !$scope.show;
}
})
myApp.directive("infoBoard", function() {
return {
replace : true,
templateUrl: "modalPopup.html",
scope : {},
link : function (scope, element, attrs) {
element.append("Hi there!")
}
}
})
Demo Onlie
I'm looking for an explanation of how angular binding works behind the curtain. I only want $scope.values to be updated on ng-click, but once its clicked once it bound to the form forever. woah. Why?
First example is NOT working as I expected it to work. The values should only be reflected in the span everytime I click on my button.
http://jsfiddle.net/webmandman/Ls4g4yLn/12/
html:
<div ng-app="app" ng-controller="myCtrl">
<div>
<span ng-repeat="value in values">{{value.text}}</span><br>
<input ng-repeat="field in fields" type="text" name="{{field.name}}" ng-model="field.text"/>
</div>
<button ng-click="display()">display</button>
</div>
controller:
var app = angular.module('app', []);
angular.module('app').controller("myCtrl", function($log,$scope, $http) {
$scope.fields = [
{name:"Name", text:null},
{name:"Phone", text:null}
];
$scope.display = function(){
$log.log("display has been called...");
$scope.values = $scope.getValues()
};
$scope.getValues = function(){
$log.log('getValues was called.');
var list = [];
angular.forEach($scope.fields, function(value, index){
//$log.log(item);
$log.log(value);
$log.log(index);
this.push(value);
//this.push(item);
},list);
return list;
};
});
This example is working like I want it too, but it is not using ng-repeat.
http://jsfiddle.net/webmandman/Ls4g4yLn/13/
html:
<div ng-app="app" ng-controller="myCtrl">
<div>
<span>{{values.join(',')}}</span><br>
<input ng-repeat="field in fields" type="text" name="{{field.name}}" ng-model="field.text"/>
</div>
<button ng-click="display()">display</button>
</div>
controller:
var app = angular.module('app',[]);
angular.module('app').controller("myCtrl", function($log,$scope, $http) {
$scope.fields = [
{name:"Name", text:null},
{name:"Phone", text:null}
];
$scope.display = function(){
$log.log("display has been called...");
$scope.values = $scope.getValues()
};
$scope.getValues = function(){
var list = [];
angular.forEach($scope.fields, function(value, index){
//$log.log(item);
$log.log(value);
$log.log(index);
this.push(value.text);
//this.push(item);
},list);
return list;
};
});
That's because in your $scope.values, you push refercnes to your $scope.fields, hence then when you edit a field text, it is rendered in both places.
Instead, you can simply push the text in your values, as String are passed by copy and not reference (that's pure Javascript not related to Angular).
Here is a working fiddle:
http://jsfiddle.net/zrwq6cmu/
I'm displaying a message when the user clicks on the button.
I want to show this message for 10 seconds and then hide it.
My code is the following:
<script>
function Ctrl($scope, $window) {
$scope.greeting = 'Hello, World!';
$scope.doGreeting = function() {
$scope.msg="hi";
};
}
</script>
<div ng-controller="Ctrl">
<input type="text" ng-model="greeting" />
<button ng-click="doGreeting()">click</button>
{{msg}}
</div>
You can set a variable that determines whether to show the message or not and hide it and after 10,000 seconds. You will have to inject $timeout as shown below. Then in your view you will need to wrap {{msg}} in a span in order to use ng-show
<script>
function Ctrl($scope, $window, $timeout) {
$scope.greeting = 'Hello, World!';
$scope.showGreeting = false;
$scope.doGreeting = function() {
$scope.msg="hi";
$scope.showGreeting = true;
$timeout(function(){
$scope.showGreeting = false;
}, 10000);
};
}
</script>
<div ng-controller="Ctrl">
<input type="text" ng-model="greeting" />
<button ng-click="doGreeting()">click</button>
<span ng-show="showGreeting ">{{msg}}</span>
</div>
The way I did to show a message for a certain time in angularjs was using AngularJS-Toaster library
To use the library follow this steps:
<link href="https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/0.4.9/toaster.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js" ></script>
<script src="https://code.angularjs.org/1.2.0/angular-animate.min.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/0.4.9/toaster.min.js"></script>
Add toaster container directive:
<toaster-container></toaster-container>
Prepare the call of toaster method:
// Display an info toast with no title
angular.module('main', ['toaster'])
.controller('myController', function($scope, toaster) {
$scope.pop = function(){
toaster.pop('success', "title", "text");
};
});
Call controller method on button click:
<div ng-controller="myController">
<button ng-click="pop()">Show a Toaster</button>
</div>
Here you can see a Plunker showing many kinds of toasts showing differents messages
Add the $timeout dependency to your controller. Here's a fiddle:
<div ng-app>
<div ng-controller="Ctrl">
<input type="text" ng-model="greeting" />
<button ng-click="doGreeting()">click</button>
<div class="ng-hide" ng-show="showMessage">{{msg}} {{ greeting }}</div>
</div>
</div>
function Ctrl($scope, $window, $timeout) {
var messageTimer = false,
displayDuration = 5000; // milliseconds (5000 ==> 5 seconds)
$scope.showMessage = false;
$scope.msg = "hi";
$scope.doGreeting = function () {
if (messageTimer) {
$timeout.cancel(messageTimer);
}
$scope.showMessage = true;
messageTimer = $timeout(function () {
$scope.showMessage = false;
}, displayDuration);
};
}