best way to trigger AngularJS ng-show - angularjs

I'm building an autocomplete box in AngularJS. The relevant code looks like this
<input type="text" ng-model="tag">
<div ng-show="tag">
<ul>
<li ng-repeat="t in user.tags | filter:{name:tag}">
<a>{{t.name}}</a>
</li>
</ul>
</div>
I'd like to know what is the best way to show the list of suggestions when "tag" has no value (i.e. I want to show all the tags when the user press the down key. No need to mention the keypressing code on the answer).

ng-show works with any expression that results in a bool, so all you need to do is replace "tag" with "tag === ''", or some equivalent if your tag is going to be undefined or null.
If you only want to show when a certain key is pressed I would create another variable which you set to true when the down key is pressed and check for that also, e.g.
$scope.KeyPressed = false;
$scope.Tags = '';
$scope.ShowTags = function () {
return $scope.KeyPressed && $scope.Tags !== '';
};
Then in you div:
<div ng-show="ShowTags()">
See jsfiddle for example
If you need to change any of the variables from within a jquery plugin you may need to use
$scope.$apply()

I came across this question while I was setting up an angular project of my own.
When I did the accepted answer, I found the my browser kept on increase in memory. If you created the angular scope method "ShowTags()", this will continuously get polled. You can verify this by setting a breakpoint in this method, it will continuously keep getting hit. If you check the task manager and show the browser running your website, the memory keeps going up and won't stop.
In my opinion, scope functions should only be used when using event triggers: click event, change event, keypressed are some of the examples.
showing or hiding aren't events, so this is why it gets polled like that.
To fix and provide the same functionality, turn this into a scope variable.
change the html tag from:
<div ng-show="ShowTags()">
to
<div ng-show="ShowTags">
And in your controller:
$scope.KeyPressed = false;
$scope.Tags = '';
then create a watch event on what you want to watch for:
//initialize showtag when page loads
$scope.ShowTags = $scope.KeyPressed && $scope.Tags !== '';
//watch for any new changes on keypressed
$scope.$watch('KeyPressed', function (newValue, oldValue) {
if (newValue && $scope.Tags !== '') {
$scope.ShowTags = true;
} else {
$scope.ShowTags = false;
}
}
//watch for any new changes on keypressed
$scope.$watch('Tags', function (newValue, oldValue) {
if (newValue !== "" && $scope.KeyPressed) {
$scope.ShowTags = true;
} else {
$scope.ShowTags = false;
}
}
Or you can change to a "watchCollection" instead of having multiple watches like:
$watchCollection('[KeyPressed, Tags]', function (newValue) { }
but with this, newValue will be an array, and you'd have to access the specific indexes to get the newValues of whatever variable is being watched on.
like.. newValue[0] is the value of KeyPressed, and newValue[1] is the value of Tags
Or to go along with the accepted answer and minimize the amount of watches:
$scope.TruthyVal= function () {
return $scope.KeyPressed && $scope.Tags !== '';
};
$scope.$watch('TruthyVal', function (newValue, oldValue) {
if (newValue) {
$scope.ShowTags = true;
} else {
$scope.ShowTags = false;
}
}
Which looks at the values of KeyPressed and Tags, and changes the value of TruthyVal. If TruthyVal is changed, then it goes into the watched logic.

Related

Resetting the model values [duplicate]

I have a simple form like so:
<form name="add-form" data-ng-submit="addToDo()">
<label for="todo-name">Add a new item:</label>
<input type="text" data-ng-model="toDoName" id="todo-name" name="todo-name" required>
<button type="submit">Add</button>
</form>
with my controller as follows:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
}
}
what I'd like to do is clear the text input after submission so I simply clear the model value:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
$scope.toDoName = "";
}
}
Except now, because the form input is 'required' I get a red border around the form input. This is the correct behaviour, but not what I want in this scenario... so instead I'd like to clear the input and then blur the input element. Which leads me to:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
$scope.toDoName = "";
$window.document.getElementById('todo-name').blur();
}
}
Now, I know that modifying the DOM from the controller like this is frowned upon in the Angular documentation - but is there a more Angular way of doing this?
When you give a name to your form it automatically gets added to the $scope.
So if you change your form name to "addForm" ('cause I don't think add-from is a valid name for angular, not sure why), you'll have a reference to $scope.addForm.
If you use angular 1.1.1 or above, you'll have a $setPristine() method on the $scope.addForm. which should recursively take care of resetting your form. or if you don't want to use the 1.1.x versions, you can look at the source and emulate it.
For those not switching over to 1.1.1 yet, here is a directive that will blur when a $scope property changes:
app.directive('blur', function () {
return function (scope, element, attrs) {
scope.$watch(attrs.blur, function () {
element[0].blur();
});
};
});
The controller must now change a property whenever a submit occurs. But at least we're not doing DOM manipulation in a controller, and we don't have to look up the element by ID:
function MainCtrl($scope) {
$scope.toDos = [];
$scope.submitToggle = true;
$scope.addToDo = function () {
if ($scope.toDoName !== "") {
$scope.toDos.push($scope.toDoName);
$scope.toDoName = "";
$scope.submitToggle = !$scope.submitToggle;
}
};
}
HTML:
<input type="text" data-ng-model="toDoName" name="todo-name" required
blur="submitToggle">
Plnkr
I have made it work it as below code.
HTML SECTION
<td ng-show="a">
<input type="text" ng-model="e.FirstName" />
</td>
Controller SECTION
e.FirstName= '';

Handling IE's clear button with AngularJS binding

IE has an "X" in each text input that will clear the input. However, when clicking this button, while it clears the textbox, it does not update the Angular model that the input is bound to.
<input type="text" ng-model="name" />
See http://jsfiddle.net/p5x1zwr9/ for an example of the behavior.
See http://youtu.be/LFaEwliTzpQ for a video of the behavior.
I am using IE 11.
EDIT: There does seem to be a solution for Knockout, but I don't know how to apply it to AngularJS: Handle IE 9 & 10's clear button with Knockout binding
UPDATE: Jonathan Sampson helped me realize that this actually worked in AngularJS versions prior to 1.3.6 so this may be a new Angular bug.
UPDATE: Opened issue: https://github.com/angular/angular.js/issues/11193
The X button in input forms is native for IE10+ and you can`t do anything about it, but only hide it with CSS:
input[type=text]::-ms-clear {
display: none;
}
Then you can create your own directive to mimic this kind of behaviour. Just create a span, position it inside of an input and add ng-click to it, which will clear the model value of the input.
I created this Angular directive for input text elements, which manually calls the element's change() event when the clear ('X') button is clicked. This fixed the problem on our project. I hope it helps others.
angular.module('app')
.directive('input', function () {
return {
restrict: 'E',
scope: {},
link: function (scope, elem, attrs) {
// Only care about textboxes, not radio, checkbox, etc.
var validTypes = /^(search|email|url|tel|number|text)$/i;
if (!validTypes.test(attrs.type)) return;
// Bind to the mouseup event of the input textbox.
elem.bind('mouseup', function () {
// Get the old value (before click) and return if it's already empty
// as there's nothing to do.
var $input = $(this), oldValue = $input.val();
if (oldValue === '') return;
// Check new value after click, and if it's now empty it means the
// clear button was clicked. Manually trigger element's change() event.
setTimeout(function () {
var newValue = $input.val();
if (newValue === '') {
angular.element($input).change();
}
}, 1);
});
}
}
});
With thanks to this answer (Event fired when clearing text input on IE10 with clear icon) for the JavaScript code to detect the clear button click.
I was able to solve this using the following directive - derived from 0x783e's answer above. It may provide better compatibility with later versions of angular. It should work with $watches or parsers in addition to ng-change.
angular
.module('yourModuleName')
.directive('input', FixIEClearButton);
FixIEClearButton.$inject = ['$timeout', '$sniffer'];
function FixIEClearButton($timeout, $sniffer) {
var directive = {
restrict: 'E',
require: '?ngModel',
link: Link,
controller: function () { }
};
return directive;
function Link(scope, elem, attr, controller) {
var type = elem[0].type;
//ie11 doesn't seem to support the input event, at least according to angular
if (type !== 'text' || !controller || $sniffer.hasEvent('input')) {
return;
}
elem.on("mouseup", function (event) {
var oldValue = elem.val();
if (oldValue == "") {
return;
}
$timeout(function () {
var newValue = elem.val();
if (newValue !== oldValue) {
elem.val(oldValue);
elem.triggerHandler('keydown');
elem.val(newValue);
elem.triggerHandler('focus');
}
}, 0, false);
});
scope.$on('$destroy', destroy);
elem.on('$destroy', destroy);
function destroy() {
elem.off('mouseup');
}
}
}
While hiding using CSS
Instead of 'type=text' use 'type=search' in search fields.By doing this only inputs marked as 'type=search' will not have 'X' but other inputs will still have 'X' which is required on many other fields in IE.
input[type=search]::-ms-clear {
display: none;
}
<input type="text" ng-model="name" id="search" />
This solution works for me
$("#search").bind("mouseup", function(e){
var $input = $(this),
oldValue = $input.val();
if (oldValue == "") return;
// When this event is fired after clicking on the clear button
// the value is not cleared yet. We have to wait for it.
setTimeout(function(){
var newValue = $input.val();
if (newValue == ""){
$scope.name="";
$scope.$apply();
}
}, 1);
});
The solution I came up with, while doesn't update the model immediately like removing the X and implementing you own solution, It does solve for what i needed. All I did was add ng-model-options to include blur. So when the input is blurred it will update the scope value.
<input type="text" ng-model="name" ng-model-options="{ updateOn: 'default blur'}" />

AngularJS - preloader for ngRepeat

I'm using the infinite scroll technique in conjunction with ng-repeat. I want to display a preloader up until the directive has finished adding the items to the DOM. What would be the simplest way of achieving that?
Try this live DEMO I set up for reference.
It depends on your infinite scroll implementation. And for best answer you should set up a plunker or jsbin.
But what about just setting a loader and using ng-if directive to only show it while the item container is empty ?
Imagine we have a template like
<div id="data-container" when-scrolled="loadMore()">
<img ng-if="!items.length" ng-src="http://placehold.it/100x395&text=Loading">
<div class="item" ng-repeat="item in items">{{item.id}}</div>
<img ng-if="items.length && busy" ng-src="http://placehold.it/85x50&text=Loading">
</div>
Here when-scrolled is our infinite-scroll directive which just monitors the scroll position and calls the supplied handler when it is time to load more items.
app.directive('whenScrolled', function() {
return function(scope, element, attr) {
var containerNode = element[0];
element.bind('scroll', function() {
if (containerNode.scrollTop + containerNode.offsetHeight >= containerNode.scrollHeight) {
scope.$apply(attr.whenScrolled);
}
});
};
});
Handler is called when the scroll hits the bottom of the content area.
loadMore() method in the controller could be defined like this:
$scope.items = [];
$scope.busy = false;
$scope.loadMore = function() {
if (true === $scope.busy) {
return;
}
$scope.busy = true;
$timeout(function() {
var currentLength = $scope.items.length;
for (var i = currentLength; i < currentLength + 10; i++) {
$scope.items.push({id: i + 1});
}
$scope.busy = false;
}, 350); // Imitating the long remote request.
};
We first initialize the $scope.items and while it's length is 0 the loading image is shown in the template as it is shown while "!items.length" is true. When the first items are added to the collection preloader gets hidden.
Then there's a local loading image which could be replaced with a spinner or whatever you like. It is shown then the $scope.busy var is set to true and is hidden when it's false. We change the $scope.busy value at the start and end of the aync request. Timeouts are used here for simple of async request demo.

Pro/con of using Angular directives for complex form validation/ GUI manipulation

I am building a new SPA front end to replace an existing enterprise's legacy hodgepodge of systems that are outdated and in need of updating. I am new to angular, and wanted to see if the community could give me some perspective. I'll state my problem, and then ask my question.
I have to generate several series of check boxes based on data from a .js include, with data like this:
$scope.fieldMappings.investmentObjectiveMap = [
{'id':"CAPITAL PRESERVATION", 'name':"Capital Preservation"},
{'id':"STABLE", 'name':"Moderate"},
{'id':"BALANCED", 'name':"Moderate Growth"},
// etc
{'id':"NONE", 'name':"None"}
];
The checkboxes are created using an ng-repeat, like this:
<div ng-repeat="investmentObjective in fieldMappings.investmentObjectiveMap">
...
</div>
However, I needed the values represented by the checkboxes to map to a different model (not just 2-way-bound to the fieldmappings object). To accomplish this, I created a directive, which accepts a destination array destarray which is eventually mapped to the model. I also know I need to handle some very specific gui controls, such as unchecking "None" if anything else gets checked, or checking "None" if everything else gets unchecked. Also, "None" won't be an option in every group of checkboxes, so the directive needs to be generic enough to accept a validation function that can fiddle with the checked state of the checkbox group's inputs based on what's already clicked, but smart enough not to break if there is no option called "NONE". I started to do that by adding an ng-click which invoked a function in the controller, but in looking around stack overflow, I read people saying that its bad to put DOM manipulation code inside your controller - it should go in directives. So do I need another directive?
So far:
(html):
<input my-checkbox-group
type="checkbox"
fieldobj="investmentObjective"
ng-click="validationfunc()"
validationfunc="clearOnNone()"
destarray="investor.investmentObjective" />
Directive code:
.directive("myCheckboxGroup", function () {
return {
restrict: "A",
scope: {
destarray: "=", // the source of all the checkbox values
fieldobj: "=", // the array the values came from
validationfunc: "&" // the function to be called for validation (optional)
},
link: function (scope, elem, attrs) {
if (scope.destarray.indexOf(scope.fieldobj.id) !== -1) {
elem[0].checked = true;
}
elem.bind('click', function () {
var index = scope.destarray.indexOf(scope.fieldobj.id);
if (elem[0].checked) {
if (index === -1) {
scope.destarray.push(scope.fieldobj.id);
}
}
else {
if (index !== -1) {
scope.destarray.splice(index, 1);
}
}
});
}
};
})
.js controller snippet:
.controller( 'SuitabilityCtrl', ['$scope', function ( $scope ) {
$scope.clearOnNone = function() {
// naughty jQuery DOM manipulation code that
// looks at checkboxes and checks/unchecks as needed
};
The above code is done and works fine, except the naughty jquery code in clearOnNone(), which is why I wrote this question.
And here is my question: after ALL this, I think to myself - I could be done already if I just manually handled all this GUI logic and validation junk with jQuery written in my controller. At what point does it become foolish to write these complicated directives that future developers will have to puzzle over more than if I had just written jQuery code that 99% of us would understand with a glance? How do other developers draw the line?
I see this all over stack overflow. For example, this question seems like it could be answered with a dozen lines of straightforward jQuery, yet he has opted to do it the angular way, with a directive and a partial... it seems like a lot of work for a simple problem.
I don't want this question to violate the rules, so specifically, I suppose I would like to know: how SHOULD I be writing the code that checks whether "None" has been selected (if it exists as an option in this group of checkboxes), and then check/uncheck the other boxes accordingly? A more complex directive? I can't believe I'm the only developer that is having to implement code that is more complex than needed just to satisfy an opinionated framework. Is there another util library I need to be using?
I posted this on Programmers.StackExchange.com as per Jim's suggestion. In the meantime, I settled on a solution for handling all the tricky DOM manipulations.
I tried it both ways - handling the DOM event in the controller, and handling it via a directive:
(Via Controller) - .js code:
$scope.clearOnNone = function(groupName, $event) {
var chkboxArr = $('input[name^=' + groupName + ']'),
nonNoneValChecked = false,
targetElem = null,
labelText = "";
// get the target of the click event by looking at the <label> sibling's text
targetElem = event.target.nextElementSibling.textContent.trim();
// if target was the None option, uncheck all others
if (targetElem === "None") {
chkboxArr.each(function() {
labelText = this.nextElementSibling.textContent.trim();
if (labelText !== "None") {
this.checked = false;
}
});
}
// if the target was anything BUT the None option, uncheck None
else {
chkboxArr.each(function() {
labelText = this.nextElementSibling.textContent.trim();
if (labelText === "None") {
this.checked = false;
}
});
}
};
(Via Controller) - html code:
<div ng-repeat="investmentObjective in fieldMappings.secondaryInvestmentObjectiveMap">
<input checkbox-group
type="checkbox"
name="secondaryInvestmentObjective"
ng-click="validationfunc('secondaryInvestmentObjective', $event)"
validationfunc="clearOnNone('secondaryInvestmentObjective', $event)"
fieldobj="investmentObjective"
destarray="suitabilityHolder.suitability.secondaryInvestmentObjective" />
<label class="checkbox-label"
popover-title="{{investmentObjective.name}}"
popover="{{investmentObjective.help}}"
popover-trigger="mouseenter">{{investmentObjective.name}}
</label>
</div>
(Via Controller) - directive code:
.directive("checkboxGroup", function () {
return {
restrict: "A",
scope: {
destarray: "=", // the source of all the checkbox values
fieldobj: "=", // the array the values came from
validationfunc: "&" // the function to be called for validation (optional)
},
link: function (scope, elem, attrs) {
if (scope.destarray.indexOf(scope.fieldobj.id) !== -1) {
elem[0].checked = true;
}
elem.bind('click', function () {
var index = scope.destarray.indexOf(scope.fieldobj.id);
if (elem[0].checked) {
if (index === -1) {
scope.destarray.push(scope.fieldobj.id);
}
}
else {
if (index !== -1) {
scope.destarray.splice(index, 1);
}
}
});
}
};
})
I then decided that I hated the event.target.nextElementSibling.textContent.trim() lines... I feel like I should be double checking that all of those methods exist, or using a try/catch. So I rewrote the directive to include the logic from the controller:
(via directive) - html code:
<div ng-repeat="otherInvestment in fieldMappings.otherInvestmentsMap">
<input type="checkbox"
checkbox-group
groupname="otherInvestment"
labelvalue="{{otherInvestment.name}}"
fieldobj="otherInvestment"
destarray="suitabilityHolder.suitability.otherInvestment" />
<label class="checkbox-label"
popover-title="{{otherInvestment.name}}"
popover="{{otherInvestment.help}}"
popover-trigger="mouseenter">{{otherInvestment.name}}
</label>
</div>
(via directive) - directive code:
.directive("checkboxGroup", function () {
return {
restrict: "A",
scope: {
destarray: "=", // the source of all the checkbox values
fieldobj: "=", // the array the values came from
groupname: "#", // the logical name of the group of checkboxes
labelvalue: "#" // the value that corresponds to this checkbox
},
link: function (scope, elem, attrs) {
// Determine initial checked boxes
// if the fieldobj.id exists in the destarray, check this checkbox
if (scope.destarray.indexOf(scope.fieldobj.id) !== -1) {
elem[0].checked = true;
}
// Update array on click
elem.bind('click', function () {
// store the index where the fieldobj.id exists in the destarray
var index = scope.destarray.indexOf(scope.fieldobj.id),
// get the array of checkboxes that form this checkbox group
chkboxArr = $('input[groupname^=' + scope.groupname + ']');
// Add if checked
if (elem[0].checked) {
if (scope.labelvalue === "None") {
// loop through checkboxes and uncheck all the ones that are not "None"
chkboxArr.each(function() {
// have to noodle through the checkbox DOM element to get at its attribute list
// - is there a cleaner way?
var tmpLabelValue = this.attributes.labelvalue.nodeValue.trim();
if (tmpLabelValue !== "None") {
this.checked = false;
}
});
}
// if the target was anything BUT the None option, uncheck None
else {
chkboxArr.each(function() {
var tmpLabelValue = this.attributes.labelvalue.nodeValue.trim();
if (tmpLabelValue === "None") {
this.checked = false;
}
});
}
if (index === -1) {
// add the id to the end of the dest array
// **will not maintain original order if several are unchecked then rechecked**
scope.destarray.push(scope.fieldobj.id);
}
}
// Remove if unchecked
else {
if (index !== -1) {
scope.destarray.splice(index, 1);
}
}
});
}
};
})
In retrospect, I suppose I prefer to house all the code in a directive, even though I think it's less intuitive and more complex than tossing all the handling in the controller via jQuery. It cuts out the clearOnNone() function from the controller, meaning that all the code that deals with this functionality it in the html markup and the directive.
I am not a fan of code like this.attributes.labelvalue.nodeValue.trim(), which I still ended up with in my directive. For scenarios like mine, where the business unit has certain requirements that (no other way to put it) are tedious and cumbersome, I don't know that there is really a 'clean' way to code it all up.
I'm still new to AngularJS but I this case I think I would solve it by using either an ng-click handler or $scope.$watch to update the state of the NONE model whenever the other models change.
Using ng-click
I've whipped up a jsFiddle that shows how it could work with ng-click:
http://jsfiddle.net/Dzj6K/1/
HTML:
<div ng-controller="myCtrl">
<div ng-repeat="objective in objectives">
<label><input type="checkbox" ng-model="objective.selected" ng-click="click(objective)" /> {{objective.name}}</label>
</div>
</div>
JavaScript:
var app = angular.module('myApp', []);
function myCtrl($scope) {
$scope.objectives = [
{'id':"CAPITAL PRESERVATION", 'name':"Capital Preservation"},
{'id':"STABLE", 'name':"Moderate"},
{'id':"BALANCED", 'name':"Moderate Growth"},
{'id':"NONE", 'name':"None"}
];
$scope.click = function(objective) {
if (objective.id === "NONE") {
if (objective.selected) {
angular.forEach($scope.objectives, function(objective) {
if (objective.id !== "NONE") {
objective.selected = false;
}
});
}
} else {
angular.forEach($scope.objectives, function(objective) {
if (objective.id === "NONE") {
objective.selected = false;
}
});
}
};
}
Using $scope.$watch
And a version of the jsFiddle that shows how it could work with $scope.$watch:
http://jsfiddle.net/Dzj6K/
HTML:
<div ng-controller="myCtrl">
<div ng-repeat="objective in objectives">
<label><input type="checkbox" ng-model="objective.selected" /> {{objective.name}}</label>
</div>
</div>
JavaScript:
var app = angular.module('myApp', []);
function myCtrl($scope) {
$scope.objectives = [
{'id':"CAPITAL PRESERVATION", 'name':"Capital Preservation"},
{'id':"STABLE", 'name':"Moderate"},
{'id':"BALANCED", 'name':"Moderate Growth"},
{'id':"NONE", 'name':"None"}
];
$scope.$watch('objectives', function() {
var anySelected = false;
var noneModel = null;
angular.forEach($scope.objectives, function(objective) {
if (objective.id === "NONE") {
noneModel = objective;
} else {
anySelected = anySelected || objective.selected;
}
});
if (noneModel) {
noneModel.selected = !anySelected;
}
}, true);
}

Angular - clear form input after submit

I have a simple form like so:
<form name="add-form" data-ng-submit="addToDo()">
<label for="todo-name">Add a new item:</label>
<input type="text" data-ng-model="toDoName" id="todo-name" name="todo-name" required>
<button type="submit">Add</button>
</form>
with my controller as follows:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
}
}
what I'd like to do is clear the text input after submission so I simply clear the model value:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
$scope.toDoName = "";
}
}
Except now, because the form input is 'required' I get a red border around the form input. This is the correct behaviour, but not what I want in this scenario... so instead I'd like to clear the input and then blur the input element. Which leads me to:
$scope.addToDo = function() {
if ($scope.toDoName !== "") {
$scope.toDos.push(createToDo($scope.toDoName));
$scope.toDoName = "";
$window.document.getElementById('todo-name').blur();
}
}
Now, I know that modifying the DOM from the controller like this is frowned upon in the Angular documentation - but is there a more Angular way of doing this?
When you give a name to your form it automatically gets added to the $scope.
So if you change your form name to "addForm" ('cause I don't think add-from is a valid name for angular, not sure why), you'll have a reference to $scope.addForm.
If you use angular 1.1.1 or above, you'll have a $setPristine() method on the $scope.addForm. which should recursively take care of resetting your form. or if you don't want to use the 1.1.x versions, you can look at the source and emulate it.
For those not switching over to 1.1.1 yet, here is a directive that will blur when a $scope property changes:
app.directive('blur', function () {
return function (scope, element, attrs) {
scope.$watch(attrs.blur, function () {
element[0].blur();
});
};
});
The controller must now change a property whenever a submit occurs. But at least we're not doing DOM manipulation in a controller, and we don't have to look up the element by ID:
function MainCtrl($scope) {
$scope.toDos = [];
$scope.submitToggle = true;
$scope.addToDo = function () {
if ($scope.toDoName !== "") {
$scope.toDos.push($scope.toDoName);
$scope.toDoName = "";
$scope.submitToggle = !$scope.submitToggle;
}
};
}
HTML:
<input type="text" data-ng-model="toDoName" name="todo-name" required
blur="submitToggle">
Plnkr
I have made it work it as below code.
HTML SECTION
<td ng-show="a">
<input type="text" ng-model="e.FirstName" />
</td>
Controller SECTION
e.FirstName= '';

Resources