Cannot get input value from md-input - angularjs

I have this md-dialog which has an input. I'm passing the model of the input when I click the top up button but on my controller, it is undefined.
<md-dialog aria-label="Top Up User" ng-cloak>
<md-dialog-content>
<div class="md-dialog-content">
<form>
<md-input-container class="md-block">
<label>Amount</label>
<input required type="number" name="amount" ng-model="topup.amount" min="1"
ng-pattern="/^1234$/" />
</md-input-container>
<md-dialog-actions layout="row" ng-show="!vm.loading">
<md-button ng-click="vm.closeDialog()">
Cancel
</md-button>
<md-button ng-click="vm.topUp(topup.amount)" style="margin-right:20px;">
Top Up
</md-button>
</md-dialog-actions>
<div layout="row" layout-align="space-around">
<md-progress-circular md-mode="indeterminate" ng-show="vm.loading"></md-progress-circular>
</div>
</form>
</div>
</md-dialog-content>
</md-dialog>
Controller:
(function(){
angular
.module('app')
.controller('MainController', [
'navService', '$mdSidenav', '$mdDialog', '$log', '$q', '$state', '$mdToast', 'Pubnub', 'mongolabService', '$scope',
MainController
]);
function MainController(navService, $mdSidenav, $mdDialog, $log, $q, $state, $mdToast, Pubnub, mongolabService, $scope) {
var vm = this;
function showActions($event) {
var self = this;
$mdDialog.show({
controller: [ '$mdDialog', TopUpController],
controllerAs: 'vm',
templateUrl: 'app/views/partials/topup.html',
targetEvent: $event,
bindToController : true,
clickOutsideToClose:true
});
function TopUpController () {
var vm = this;
vm.topUp = topUp;
vm.loading = false;
vm.closeDialog = closeDialog;
function closeDialog() {
$mdDialog.hide();
}
function querySearch (query) {
return query ? $scope.users.filter( createFilterFor(query) ) : $scope.users;
}
function topUp(amount) {
var topUpCallback = {
error: function(response){
vm.loading = false;
showSimpleToast("Error occurred");
console.log(response);
}, success: function(response){
showSimpleToast("Top up success");
}
}
//Amount is undefined
showSimpleToast("amount: " + amount);
}
}
}
function showSimpleToast(title) {
$mdToast.show(
$mdToast.simple()
.content(title)
.hideDelay(2000)
.position('bottom right')
);
}
}
})();

Its strange. change
showSimpleToast("amount: " + amount);
to
showSimpleToast("amount: " + vm.amount);
and let see what happens

Can you change the way you're using topup property like this (just for 1 style coding vm/$scope):
In input
<input required type="number" name="amount" ng-model="vm.topup.amount" min="1" ...
In button:
<md-button ng-click="vm.topUp(topup.amount)" style="margin-right:20px;">
And init topup object in your controller:
vm.topup = {amount: ''};
I think the problem is you didn't init your topup object before use its amount property

I noticed that the amount is just getting undefined when I type on the input. I added allowInvalid to the <input> and it worked.
ng-model-options="{allowInvalid: true}"

Related

Angularjs How to get value of input[text] in controller

I want to get value of input[text] in my controller when data is changed as this source code:
(function () {
'use strict';
var app = angular.module('app', ['ngMaterial']);
app.controller('ScanDataCtrl', function ($scope) {
$scope.getScannedData = function () {
console.log($scope.formScanData.scanDataIReceipt);
};
});
app.directive('scanDataBScan', function ($mdDialog, $sce, $http) {
return {
restrict: 'C',
link: function (scope, element, attrs) {
element.on('click', function () {
scope.getScannedData();
// => the value always undefined
});
}
};
});
});
<div ng-controller="ScanDataCtrl">
<form accept-charset="UTF-8" class="form-inline formScanData" name="formScanData">
<input ng-model="formScanData.scanDataIReceipt" type="text" required>
<md-input-container>
<md-button ng-model="scanDataBScan" class="md-raised md-primary scanDataBScan">Scan</md-button>
</md-input-container>
</form>
</div>
the result of this source code is always undefine
Please help me.
If I ask wrong or bad with my English, I am sorry.
Thank you!
Use the ng-change directive:
<input ng-model="formScanData.scanDataIReceipt" type="text"
ng-change="getScannedData()" required>
For more information, see AngularJS ng-change Directive API Reference.
(function () {
'use strict';
var app = angular.module('app', ['ngMaterial']);
app.controller('ScanDataCtrl', function ($scope) {
$scope.getScannedData = function (data) {
console.log(data);
};
});
app.directive('scanDataBScan', function ($mdDialog, $sce, $http) {
return {
restrict: 'C',
link: function (scope, element, attrs) {
element.on('click', function () {
scope.getScannedData();
// => the value always undefined
});
}
};
});
});
<div ng-controller="ScanDataCtrl">
<form accept-charset="UTF-8" class="form-inline formScanData" name="formScanData">
<input ng-model="formScanData.scanDataIReceipt" type="text" required>
<md-input-container>
<md-button ng-model="scanDataBScan" ng-click="getScannedData(formScanData.scanDataIReceipt)" class="md-raised md-primary scanDataBScan">Scan</md-button>
</md-input-container>
</form>
</div>

Component binding not working : Angularjs

Hi I'm trying to create a component, it works fine in controller, however not binding values to view.
My Component is as below
app.component("bdObjects", {
templateUrl: "app/templates/components/BusinessObjects.html",
controller: ["$scope", "$http", "$log", "API_ROOT", "VisDataSet",
function ($scope, $http, $log, API_ROOT, VisDataSet) {
$scope.fnAdd = function() {
$scope.objectId = "";
$scope.objectName = "Test Object";
console.log($scope.objectName);
}
$scope.cancelAdd = function() {
if($scope.items.length > 0) {
$log.info($scope.items[0]);
$scope.fnPopulateForm($scope.items[0]);
}
}
}],
bindings: {
data: "=",
objectId: "=",
objectName: "="
}
});
My Template
<div class="general-form">
<input type="hidden" name="id" ng-model="objectId">
<label>Name:</label>
<br>
<input class="form-control" name="name" placeholder="Name" ng-model="objectName">
<br>
</div>
So on add button I tried to assign value to input box. but it's not taking. and I want to make that two way binding. so later I'll have save button, so changing the value in TextBox will replace in Controller.
Thanks.
In controller, change $scope by this or some alias, e.g.
controller: ["$scope", "$http", "$log", "API_ROOT", "VisDataSet",
function ($scope, $http, $log, API_ROOT, VisDataSet) {
var ctrl = this;
ctrl.fnAdd = function() {
ctrl.objectId = "";
ctrl.objectName = "Test Object";
console.log(ctrl.objectName);
}
// Not sure about items: you haven't defined it,
// neither fnPopulateForm...
ctrl.cancelAdd = function() {
if(ctrl.items.length > 0) {
$log.info($scope.items[0]);
ctrl.fnPopulateForm(ctrl.items[0]);
}
}
}],
And in view, use the default controller binding i.e $ctrl
<div class="general-form">
<input type="hidden" name="id" ng-model="$ctrl.objectId">
<label>Name:</label>
<br>
<input class="form-control" name="name" placeholder="Name" ng-model="$ctrl.objectName">
<br>
</div>
You can also change $ctrl into whatever you want in a controllerAs declaration of the component, i.e.
app.component("bdObjects", {
templateUrl: "app/templates/components/BusinessObjects.html",
controller: ["$scope", "$http", "$log", "API_ROOT", "VisDataSet",
function ($scope, $http, $log, API_ROOT, VisDataSet) {
//...
}],
controllerAs: 'bd',
bindings: {
//...
}
});
and in the view:
I tried with $timeout() and it got working.
Hey check this JS fiddle
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<input type="hidden" name="id" ng-model="objectId">
<label>Name:</label>
<br>
<input class="form-control" name="name" placeholder="Name" ng-model="objectName">
<br>
<button ng-click="fnAdd()">
button
</button>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.fnAdd = function() {
$scope.objectId = "";
$scope.objectName = "Test Object";
console.log($scope.objectName);
}
$scope.cancelAdd = function() {
if ($scope.items.length > 0) {
$log.info($scope.items[0]);
$scope.fnPopulateForm($scope.items[0]);
}
}
});
</script>

Pushing item to array after close md-dialog not working

Array does not refresh after pushing item through md-dialog, though I can save the item normally.
I tried to test which level I could push an item into the array manually and I could do so until $scope.showAddUsuario(), after that I can't push an item, even manually:
Usuario.html
<div flex-gt-sm="100" flex-gt-md="100" ng-controller="UsuarioCtrl">
<h2 class="md-title inset">Usuario</h2>
<md-card>
<md-list>
...
</md-list>
</md-card>
<md-button class="md-fab" aria-label="Add" ng-click="showAddUsuario($event)">
<md-icon md-svg-icon="content:ic_add_24px" aria-label="Plus"></md-icon>
</md-button>
</div>
md-dialog:
<md-dialog aria-label="Form">
<md-content class="md-padding">
<form name="userForm">
<div layout layout-sm="column">
<md-input-container flex> <label>Nome</label> <input ng-model="item.nome"> </md-input-container>
</div>
<div layout layout-sm="column">
<md-input-container flex> <label>E-mail</label> <input ng-model="item.email"> </md-input-container>
</div>
<div layout layout-sm="column">
<md-input-container flex> <label>Senha</label> <input ng-model="item.senha"> </md-input-container>
</div>
</form>
</md-content>
<div class="md-actions" layout="row">
<span flex></span>
<md-button ng-click="cancel()"> Cancel </md-button>
<md-button ng-click="saveUsuario(item)" class="md-primary"> Save </md-button>
</div>
</md-dialog>
Controller:
app.controller('UsuarioCtrl', function ($scope, $http, $mdDialog, $interval, $timeout) {
$scope.items = [];
$http({
method : 'GET',
url : 'UsuarioServlet'
})
.success(
function(data, status, headers,
config) {
$scope.items = data;
}).error(
function(data, status, headers,
config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
$scope.saveUsuario = function(item) {
$scope.items.push({id:100, nome:item.nome, email:item.email, senha:item.senha, status:1});
};
$scope.showAddUsuario = function(ev) {
$mdDialog.show({
controller: 'UsuarioCtrl',
templateUrl : 'CrudUsuario.html',
targetEvent : ev,
locals : {
item : null
}
})
};
});
Only now do I see that you were using $mdDialog and not $modal. So this answer will most likely not apply to your case.
You do however seem to be missing a .finally() part in your code.
From the manual ( https://material.angularjs.org/latest/api/service/$mdDialog )
$mdDialog
.show( alert )
.finally(function() {
alert = undefined;
});
So you could try that.
Otherwise, have you considered using $modal instead?
You don't seem to be handling the return of information from your modal.
(function (){
'use strict';
function myCtrl($modal){
var vm = this;
vm.myArray = [];
...
function openModal(){
var modalInstance = $modal.open({
templateUrl: 'path/to/modal/view.html',
controller: 'MyModalCtrl as vm',
size: 'lg',
resolve: {
data: function(){
return dataThatYouWantToSendFromHereToYourModal;
}
}
});
modalInstance.result.then(function (result){
vm.myArray.push(result);
});
}
...
}
...
})();
The modalIntsance.result.then will trigger when you in your modal-controller (in this case MyModalCtrl) issues a $modalInstance.close(sendThisDataBackToCallingController) call.
So the modal-controller should look along the lines of
...
function MyModalCtrl($modalInstance, data){
...
function init(){
doSomethingWithDataThatYouGotFromTheCallingController(data);
}
...
function save(){
var dataToSendBack = {...};
$modalInstance.close(dataToSendBack);
}
...
}
...
That should get you going in the right direction.
Thanks for the comments! The documentation say to use that:
}).then(function(item) {
$scope.items.push({id:100, nome:item.nome, email:item.email, senha:item.senha, status:1});
});
Works fine!
I solve this problem ,Please replace $mdDialog.show() as
$mdDialog.show({
controller: function (){
this.parent = $scope;
},
templateUrl: 'dialog1.tmpl.html',
scope:$scope.$new(),
targetEvent : ev,
bindToController: true,
clickOutsideToClose:true,
fullscreen: useFullScreen
})

Angularjs scope not working

I am using basic angular.js concept to show and hide a div. For some reasons I am unable to make it work.
While Uploading a file I am showing a div 'myFormSpinner' on the basis of registerStart value. I am creating a phone gap app.
Could someone please help me in finding the issue. Apart from showing/hiding div everything works fine. Below is the code snippet:
<div class="row" ng-controller="RegisterCtrl">
<div id="myFormSpinner" ng-show="registerStart">
<img src="img/ajax-loader.gif">
</div>
<div class="col-md-8">
<form class="ng-pristine ng-invalid ng-invalid-required" style="margin-top:5%;">
<div class="col-md-6">
<input class="form-control " type="text" ng-model="registerData.Email" id="Email" name="Email" required placeholder="Email">
</div>
<div class="col-md-offset-1 col-md-10 ">
<input type="submit" ng-click="register()" value="Register" class="btn btn-default btn-primary">
</div>
</form>
</div>
event.controller('RegisterCtrl', ['$scope', '$state', '$q', '$http', 'eventService', 'authService', '$stateParams', '$rootScope', 'tokenService', 'imageService', 'spinnerService', 'appBackgroundService',
function ($scope, $state, $q, $http, eventService, authService, $stateParams, $rootScope, tokenService, imageService, spinnerService, appBackgroundService) {
var userNumber = 0;
$scope.mediaUploadStart = false;
$scope.eventId = $state.params.id;
$scope.register = function () {
$scope.registerStart = true;
console.log('scope.Pic=' + $scope.pic);
if ($scope.registerData.Email) {
spinnerService.show('myFormSpinner');
$scope.mediaUploadStart = true;
var paramOptions = {
eventId: $state.params.id,
email: $scope.registerData.Email,
fb: {},
number: userNumber,
provider: "Form"
};
uploadPicAndData(paramOptions).then(function (result) {
var data = JSON.parse(result);
$scope.registerStart = false;
appBackgroundService.disableBackgroundMode();
},
function (error) {
spinnerService.hide('myFormSpinner');
$scope.registerStart = false;
appBackgroundService.disableBackgroundMode();
});
$scope.mediaUploadStart = false;
spinnerService.hide('myFormSpinner');
}
};
}])
You are setting the $scope element in an async mode.
the digest cycle is not able to determine that a change has been made to the scope element in an async mode.
You should use $apply to activate the digest cycle.
$scope.$apply(function () { $scope.registerStart = false; });
Read more about $apply here: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Angular updating and clearing factory variables

I'm creating a single page app in which a user searches for a term, the result gets saved in a variable, and a new page is routed that displays the result. I have this functionality working, however I want the variable to be cleared when the user returns to the previous page and most importantly when the user logs out. What's the proper way to do this? I want the factory to save things for certain pages that I want, and clear them for certain pages I don't want like "home" or "logout".
Factory:
angular.module('firstApp')
.factory('fact', function () {
var service = {};
var _information = 'Default Info';
service.setInformation = function(info){
_information = info;
}
service.getInformation = function(){
return _information;
}
return service;
});
Controller:
angular.module('firstApp')
.controller('InformationCtrl', function($scope, $http, $location, fact) {
$scope.message = 'Hello';
$scope.result = fact.getInformation();
$scope.sub = function(form) {
console.log($scope.name);
$scope.submitted = true;
$http.get('/wiki', {
params: {
name: $scope.name,
}
}).success(function(result) {
console.log("success!");
$scope.result = result;
fact.setInformation(result);
$location.path('/informationdisplay');
});;
}
});
Routes
angular.module('firstApp')
.config(function ($routeProvider) {
$routeProvider
.when('/information', {
templateUrl: 'app/information/input.html',
controller: 'InformationCtrl',
authenticate : true
})
.when('/informationdisplay', {
templateUrl: 'app/information/results.html',
controller: 'InformationCtrl',
authenticate : true
});
});
input.html
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<p>{{result}}</p>
<form class="form" name="form" ng-submit="sub(form)" novalidate>
<input type="text" name="name" placeholder="Name" class="form-control" ng-model="name">
</br>
<button class="btn btn-success" type="submit" class="btn btn-info">Check</button>
</div>
</div>
results.html
<div ng-include="'components/navbar/navbar.html'"></div>
<div class="row">
<div class="col-sm-4 col-sm-offset-4">
<h2>Information Results</h2>
<p>{{result}}</p>
</div>
</div>
</div>
If you want it to wipe the value when they change routes (which logout should change routes also, I assume), you can watch the $routeChangeStart event and have it wipe the value whenever it occurs. You put that function in the module.run block:
app.run(function ($rootScope, fact) {
$rootScope.$on("$routeChangeStart",function(event, next, current){
fact.setInformation(null);
});
});

Resources