Passing a parameter in ng-click function - angularjs

I am trying to pass data to an API for the user e-mail subscription status as "Y"/"N".
In the controller code console.log(a.checked) is undefined. But in regular javascript a onclick event for the input element type="checkbox" has the this.checked to respond correspondingly as true or false. Why is it not happening here in AngularJS?
My html code with angular directive ng-click:
<label for="mail_sub">E-mail subscription</label>
<input id="mail_sub" type="checkbox" name=checkbox ng-click="mailsubscription(this)">
Code of the controller:
.controller("registerCtrl", function($scope, $state, userProcess) {
$scope.mailsubscription = function(a) {
console.log(a);
console.log(a.checked); // console output is: "undefined"
signupinfo = {};
if (a.checked) {
signupinfo.u_mail_subscription = 'Y';
} else {
signupinfo.u_mail_subscription = 'N';
}
console.log(signupinfo);
};
/*$scope.registerProcess = function(signupinfo){
console.log(signupinfo);
userProcess.signup(signupinfo).sucess(function(response){
if(response.status){
}
})
};*/
});

There is no checked defined in your scope. You have do to something like this:
$scope.checked = false
$scope.mailsubscription = function () {
$scope.checked = !$scope.checked;
console.log($scope.checked)
};
Or you can use ngModel directive in your template
<input id="mail_sub" type="checkbox" name=checkbox ng-click="mailsubscription(this)" ngModel="checked">
If you go this way you dont need to toggle the variable checked by your self.

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= '';

Pass toggling Boolean from service to controller

I want to show/hide an element based on the Boolean value that is changing in my service. I want the change of this Boolean to happen in my service so multiple controllers can access the true or false value, but I am having trouble returning this value to one or more controllers. Currently I'm only able to pass one value which is false, although the value does show it's changing in my service. Here is an example of my controller...
angular.module('myApp')
.service('ThisService', function(){
function toggleDisplay(){
return displayElement = !displayElement;
}
});
.controller('ThisCtrl', function (thisService, $scope) {
function init(){
$scope.displayElement = ThisService.toggleDisplay();
}
$scope.toggleElement = function(){
$scope.displayElement = ThisService.toggleDisplay();
}
init();
});
My HTML...
<div ng-show="displayElement">Show hide me</div>
<button ng-click='toggleElement()'></button>
Can you please tell me how to return the true/false value to my controller correctly?
You can use a value and then toggle that in your service. However, your service definition is not valid, you have a semi-colon in the middle of your chain of modules and you define your service with the name "ThisService", but then you try to reference it in your controller as "thisService" (it's case sensitive).
JS:
angular.module("myApp", [])
.value("DisplayElement", { value: true })
.service("ThisService", function(DisplayElement) {
this.toggleDisplay = function() {
return DisplayElement.value = !DisplayElement.value;
}
})
.controller("ThisCtrl", function(ThisService, $scope) {
function init() {
$scope.displayElement = ThisService.toggleDisplay();
}
$scope.toggleElement = function() {
$scope.displayElement = ThisService.toggleDisplay();
}
init();
});
HTML:
<div ng-app="myApp">
<div ng-controller="ThisCtrl">
<div ng-show="displayElement">Show hide me</div>
<button ng-click="toggleElement()">Toggle Display</button>
</div>
</div>
jsFiddle
You could even eliminate the service and just access the value directly in your controller (you'd have to inject it first).

Unchecking an angular bound checkbox programmatically

I'm trying to uncheck a checkbox bound using ng-model to a scope variable. Basically the below doesn't uncheck after 2 seconds.
html
<div ng-controller="AppCtrl">
<input type="checkbox" ng-model="checked">
</div>
js
var app = angular.module('app',[]);
function AppCtrl($scope) {
$scope.checked = true;
setTimeout(function(){
$scope.checked = false;
alert('should be unchecked!');
},2000);
}
https://jsfiddle.net/thomporter/tcVhN/
Try to use angular $timeout service instead of javascript's setTimeout
Becuase if you use setTimeout in angularjs you need use $scope.$apply() to ensure the changes in scope. check this fiddle
But $timeout will do this work for you.
Like this
$timeout(function(){
$scope.checked = false;
alert('should be unchecked!');
},2000);
JSFIDDLE
This work fine for me!
HTML FILE
<input type="checkbox" [(ngModel)]="checked" [checked]="checked" (change)="onChange(checked? 'block':'none')">
.TS FILE
export class TopBarComponent implements OnInit {
checked: boolean;
constructor(public dados: DadosService) { }
ngOnInit() {
if(this.dados.meusChamados == 'block')
this.checked = true;
else
this.checked = false;
}
onChange(event : any){
this.dados.meusChamados = event;
}
}
checked = variable created on .ts file
onChange = a function created on .ts file to change the status of a div to display: none|block
You need to set your checked variable to the selected attribute.
<div ng-controller="AppCtrl">
<input type="checkbox" selected="{{checked}}">
</div>

scope variable inside directive is not updating - angularjs

I have a simple directive for a table with pagination. The Pagination has a dropdown & a button. User can either select a page in the dropdown or click on the button to navigate.
Say, the dropdown lists page numbers 1, 2, 3 and the selected page is 1. When user clicks on 'Next', the selected value in the dropdown should become 2.
Issue:
When Next is clicked, though the scope variable SelectedPage is seen updated in the console, it is not reflecting in the view.
report.html:
<div>
<ul>
<li>
<select ng-model="$scope.state.SelectedPage" ng-change="ShowPageResult()">
<option ng-repeat="num in PageNumbers value="{{num}}">{{num}}</option>
</select>
</li>
<li ng-click="ShowNextPage();">Next</li>
</ul>
<table>
...//some html
</table>
</div>
directive
app.directive('Report', function () {
return {
restrict: 'AE',
replace: 'true',
templateUrl: '/views/report.html'
};
});
controller:
$scope.state={};
$scope.ShowPageResult = function () {
GetReport($scope.state.SelectedPage);
}
$scope.ShowNextPage = function () {
$scope.state.SelectedPage = $scope.state.SelectedPage + 1;
GetReport($scope.state.SelectedPage);
}
//get report data to bind to table
function GetReport(pageNumber) {
$scope.UserReport = [];
var promise = ReportsFactory.GetData();
promise.then(function (success) {
if (success.data != null && success.data != '') {
$scope.UserReport = success.data;
BindPageNumbers($scope.UserReport[0].TotalRows, pageNumber);
}
},
function (error) {
console.log(error);
});
}
//bind page numbers to dropdown in pagination
function BindPageNumbers(totalRows, selectedPage) {
$scope.PageNumbers = [];
$scope.LastPageNumber = Math.ceil((totalRows / 10));
for (var i = 1; i <= Math.ceil((totalRows / 10)) ; i++) {
$scope.PageNumbers.push(i);
}
$scope.state.SelectedPage = selectedPage; //can see the no. becomes 2 here.
}
My guess:
ng-change="ShowPageResult()" is declared in the directive template and because your directive declares its own scope, then it looks for the definition of ShowPageResult() in the directive's scope and not in the controller.
Therefore the change handler function is null and does nothing.
Try putting SelectedPage in an object. So in your controller
$scope.state = {
SelectedPage: 1
};
You need to initialise the SelectedPage.
Then reference SelectedPage with state.SelectedPage in your controller and in your directive template:
<select ng-model="state.SelectedPage" ng-change="ShowPageResult()">
Because of javascript prototypical inheritance, the SelectedPage in your directive will be different to the one in your controller. See Understanding Scopes
And it's not clear to me why you're binding BindPageNumbers to your directive scope. Firstly, there is no controller in your directive so it never gets called there and there is no call in the template either.
Second, BindPageNumbers is not bound to the parent scope so the directive wont get that function anyway.

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