Angularjs ng-click clear input and update scope - javascript

1. Directive:
app.directive('inputField', function() {
return {
restrict: 'E',
require: 'ngModel',
scope: {
words: '=ngModel'
},
transclude: true,
template: "<input type='text' ng-model='words' placeholder='Translate' />"
};
});
2. ng-click function:
$scope.clear = function() {
$scope.words = { word: '' };
};
3. View looks like this:
<input-field id='inputWord' value='' name="data1" ng-model="words.word"></input-field>
After click clear() {{words.word}} and value in input still exist and $scope is broken.
Please tell me how I can clear all inputs ng-repeat and update scope?

Try like this.
var app = angular.module('app',[])
app.controller('ctrl',function($scope){
$scope.words = [ {word : 'input1'}, {word : 'input2'}, {word : 'input3'}];
$scope.clear = function() {
$scope.words =[ {word : ''}, {word : ''}, {word : ''}];
};
});
app.directive('inputField', function() {
return {
restrict: 'E',
require: 'ngModel',
scope: {
words: '=ngModel'
},
transclude: true,
template: "<input type='text' ng-model='words' placeholder='Translate' />"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="word in words">
<input-field id='inputWord' name="data1" ng-model="word.word"></input-field>
</div>
<button ng-click="clear()">Clear</button>
</div>

Related

Angular js : how to use loop in directive

I am creating directive for form controls, there is fix json with all possible from question and there options.
Html
<text-control-dir data="que.QuestionData" default="{{[_attributename]}}"></text-control-dir>
controlDirective.js
(function () {
"use strict";
angular
.module("autoQuote")
.directive('textControlDir', [textControlDir])
.directive('selectControlDir', [selectControlDir])
.directive('radioControlDir', [radioControlDir])
.directive('hiddenControlDir', [hiddenControlDir]);
function textControlDir()
{
return {
transclude: true,
restrict: 'E',
scope: {
data: '=data'
},
template: "<div ng-transclude></div><label>{{data._text}} </label><input type='text' name='{{data._attributeName}}' id='{{data._attributeName}}' value='' >"
,
link: function (scope, element, attrs)
{
//console.log(scope.data);
}
};
}
function selectControlDir()
{
return {
transclude: true,
restrict: 'E',
scope: {
data: '=data',
default: '=default'
},
template: ""
,
link: function (scope, element, attrs)
{
consoile.log('link data');
console.log(scope.default);
}
};
}
function radioControlDir()
{
console.log('here in radio directive');
return {
transclude: true,
template: "<h1>Made by a radio directive!</h1>"
};
}
function hiddenControlDir()
{
return {
transclude: true,
restrict: 'E',
scope: {
data: '=data'
},
template: "<div ng-transclude></div><label>{{data._text}} </label><input type='hidden' name='{{data._attributeName}}' id='{{data._attributeName}}' value='' >"
,
link: function (scope, element, attrs)
{
//console.log(scope.data);
}
};
}
}());
I am not getting how to loop to create select options.
In your template's ng-repeat you have to use in instead of as here:
template: "<div ng-transclude></div><label>{{data._text}} </label><select type='text' name='{{data._attributeName}}' id='{{data._attributeName}}' >\n\
<option ng-repeat='ans in data.QuestionData._answerOptions'>{{ans._promptText}}</option></select>",
Your updated plnkr.
Here's a working plunker
http://plnkr.co/edit/bc7cii5gkyNhhT4NS3uv?p=preview
It's better to use ngOptions directive because it's much faster!
Avoid options with label 'Please Select' - look at my example.

Nested directives with ng-repeat causes to strange behaviour

Let's assume that i have a 2 directives: outer and inner. In first directive, i have some data and i want to insert second directive with ng-repeat in it. So my directives looks like:
outer.js
directive('outer', function($compile) {
return {
restrict: 'E',
template: '<div class="options"></div>',
scope: true,
bindToController: {
options: '='
},
link: function(scope, element) {
var list = $(element).find('.options');
// Here we dynamically insert html for second directive
$('<inner><span ng-bind="$select.getValue(item)"></span></inner>').appendTo(list);
$compile(list.contents())(scope);
},
controllerAs: '$select',
controller: function($rootScope) {
this.items = ['aaa', 'bbb'];
this.getValue = function(item) {
$rootScope.log += '\n' + item;
return item;
};
}
};
}
inner.js
directive('second', function($compile) {
return {
restrict: 'E',
require: '^first',
replace: true,
transclude: true,
template: '<ul><li><span></span></li></ul>',
link: function(scope, element, attrs, $select, transclude) {
var choices = $(element.find('li')[0]);
choices.attr('ng-repeat', 'item in $select.items');
var inner = $(choices.find('span')[0]);
transclude(scope, function(clone) {
inner.append(clone);
});
$compile(choices)(scope);
}
};
});
So, in my example, in each $digest cycle $select.getValue should be called twice: for 'aaa' and for 'bbb'. But actually it calls 3 times and first time is called for undefined, but i can't understand why
Any ideas?
See example:
var myApp = angular.module('myApp', []);
myApp.directive('outer', function($compile) {
return {
restrict: 'E',
template: '<div class="options"></div>',
scope: true,
bindToController: {
options: '='
},
link: function(scope, element) {
var list = $(element).find('.options');
$('<inner><span ng-bind="$select.getValue(item)"></span></inner>').appendTo(list);
$compile(list.contents())(scope);
},
controllerAs: '$select',
controller: function($rootScope) {
this.items = ['aaa', 'bbb'];
this.getValue = function(item) {
$rootScope.log += '\n' + item;
return item;
};
}
};
})
.directive('inner', function($compile) {
return {
restrict: 'E',
require: '^outer',
replace: true,
transclude: true,
template: '<ul><li><span></span></li></ul>',
link: function(scope, element, attrs, $select, transclude) {
var choices = $(element.find('li')[0]);
choices.attr('ng-repeat', 'item in $select.items');
var inner = $(choices.find('span')[0]);
transclude(scope, function(clone) {
inner.append(clone);
});
$compile(choices)(scope);
}
};
});
.log {
white-space: pre;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body ng-app="myApp">
<span class="log" ng-bind="log"></span>
<outer></outer>
</body>

Directive inside a Directive with transclude?

Hey Stackoverflow peep.
This works:
angular.module('demoApp', [])
.controller('MainController', function($scope) {
$scope.Data = {
name: "Bob"
}
}).directive("formText", function() {
return {
template: '<div><input type="text" ng-model="data" name="{{key}}" id="{{key}}"></div>',
restrict: 'EA',
scope: {
label: "#label",
key: "#key",
data: "="
}
};
});
https://jsfiddle.net/ownmph09/4/
That fiddle works. You can change controller scope value. Pretty straight forward.
But this one does not:
angular.module('demoApp', [])
.controller('MainController', function($scope) {
$scope.Data = {
name: "Bob"
}
}).directive("formText", function() {
return {
template: '<div form-input label="{{label}}"><input type="text" ng-model="data" name="{{key}}" id="{{key}}"></div>',
restrict: 'EA',
scope: {
label: "#label",
key: "#key",
data: "="
}
};
}).directive('formInput', function() {
return {
template: '<div class="form-group"><label class="col-sm-4 control-label">{{label}}</label><div class="col-sm-8" ng-transclude></div></div>',
restrict: 'EA',
transclude: true,
scope: {
label: "#label"
}
};
});
https://jsfiddle.net/ownmph09/3/
I'm sure it has to do with the transclude and isolated scopes but I don't quite understand what's going on. Hoping someone that knows this stuff better than me can help.

How to specify model in AngularJS custom directives?

I want to generate the following code using an AngularJS custom directive:
<body ng-app="">
<label>Number 1: <input type="number" ng-model="a2"/></label> +<br/>
<label>Number 2: <input type="number" ng-model="b2"/></label> =<br/>
<hr/>
<span>Total: {{a2+b2}}</span>
</body>
Therefore, I wrote the following code:
<script>
var app = angular.module('my-total', []);
app.directive('myNumber', function() {
return {
restrict: 'E',
scope: {
myLabel: '=',
ngModel: '=',
},
template: '<label>{{myLabel}}: <input type="number" value="{{ngModel}}"/></label>',
}
});
</script>
<body ng-app="my-total">
<my-number my-label="'Number 1'" ng-model="a1"/></my-number> +<br/>
<my-number my-label="'Number 2'" ng-model="b1"/></my-number> =<br/>
<hr/>
<span>Total: {{a1+b1}}</span>
</body>
When the user types the numbers, the total is not shown.
How can I make it work? I mean, how can I pass the model variables "a1" and "b1" out of the directive?
You should make change to your input field inside your template, it should use ng-model="ngModel" instead of value="{{ngModel}}"
app.directive('myNumber', function() {
return {
restrict: 'E',
scope: {
myLabel: '=',
ngModel: '=',
},
template: '<label>{{myLabel}}: '+
'<input type="number" ng-model="ngModel"/>'+ //<-- change here
'</label>',
}
});
Hey Please find working fiddle for the same.
angular.module('test', [])
.directive('myDir', function() {
return {
restrict: 'E',
scope: {
ngModel: '='
},
template: '<label>Enter value: '+
'<input type="number" ng-model="ngModel"/>'+
'</label>',
};
});

How to have dynamic template in angularjs directive

I want to create a directive that be dynamic. In this directive define a template that have an input element. In fact this element ng-model must be dynamic, and use $scope.name in controller.
app.directive('helloWorld', function() {
return {
restrict: 'E',
replace: true,
scope: {
name: '#',
path:'#',
},
template: '<input\
type="text"\
name="{{name}}"\
ng-model="{{name}}"\
/>\,
link: function(scope, elem, attrs) {
},
controller:{
$scope.$watch($scope.name, function (newValue, oldValue) {
}
}
});
A working JSFiddle
Code
var app = angular.module('app',[])
app.directive('helloWorld', function() {
return {
restrict: 'E',
scope: {
name: '#',
path:'#',
},
template: '<input type="text" name="{{name}}" ng-model="name"/> {{name}}',
controller: function($scope) {
$scope.name = "initial value";
$scope.$watch('name', function (newValue, oldValue) {
console.log("newValue: ",newValue);
})
}
}
});
Firstly, your directive syntax is wrong, here is the right one:
app.directive('helloWorld', function() {
return {
restrict: 'E',
scope: {
name: '#',
path:'#',
},
template: '<input type="text" name="{{name}}" ng-model="name">',
link: function(scope, elem, attrs) {
},
controller: function($scope) {
$scope.name = 'asd';
$scope.$watch('name', function (newValue, oldValue) {
})
}
}
});
Secondly, if you are looking to have a dynamic model, you should use scope: {name: '='} as # is for one-time binding
edit
changed name="name in template to name="{{name}}"
And here is a demo

Categories