Component binding not working : Angularjs - 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>

Related

how to display data in input field using angular js

First off all, I want to show the json data from my codeigniter controller in view page through $http post method.
The problem is that I'm facing some problems, then I can't make it works.
Code:
.state('GetData', {
url: "/getdata",
templateUrl: base_url + "loadl/getdata",
data: {
pageTitle: 'Datapage'
},
controller: "Mycontroller",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'Myapp',
files: [
base_url + 'application/assets/js/controllers/Mycontroller.js'
]
});
}]
}
})
Controller:
angular.module('Myapp')
.controller('Mycontroller', function($rootScope, $scope, $http, $timeout) {
$http.get(base_url + "getData/show").
success(function(response) {
$scope.data1 = response.data;
});
});
CI controller
public function show() {
echo '{"data":[{"sl_num":"1","name":"James","category":"1"}]}';
}
View:
<div class="form-group">
<label class="control-label">Name</label>
<input type="text" placeholder="John" class="form-control" ng-model="data1.name" />
</div>
Upadate with the my answer i will work
angular.module('Myapp')
.controller('Mycontroller', function($rootScope, $scope, $http, $timeout) {
$http.get(base_url + "getData/show").
success(function(response) {
console.log(response);
$scope.data1 = response.data[0].name;
console.log($scope.data1);
});
});
View:
<div class="form-group">
<label class="control-label">Name</label>
<input type="text" placeholder="John" class="form-control" ng-model="data1" />
</div>

Cannot get input value from md-input

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}"

Why my angular controller donĀ“t find my form - $scope.form undefined

I am trying do understand why my form is not recognize inside the maincontroller, if I put another controller outside, my form is recognize.
config.js
var myApp = angular.module('Myapp', ['ui.router','oc.lazyLoad','ui.bootstrap','kendo.directives','ngStorage',]);
function config($stateProvider, $urlRouterProvider, $ocLazyLoadProvider) {
$urlRouterProvider.otherwise("/index/main");
$stateProvider
.state('testing', {
url: "/testing",
controller: 'MyController',
templateUrl: "testing.html"
});
}
angular
.module('Myapp')
.config(config)
.run(function($rootScope, $state) {
$rootScope.$state = $state;
});
MyController.js
function MyController($scope) {
//do something
$scope.test = {name: 'das'};
$scope.sendTest = function () {
console.log($scope.form.$valid);
console.log($scope.form.testNumber.$valid);
console.log($scope.form.testName.$valid);
};
};
angular
.module('Myapp')
.controller('MyController', ["$scope"]);
testing.html
<form name="form" novalidate>
<p>
<label>Number: </label>
<input type="number" min="0" max="10" ng-model="test.number" name="testNumber" required />
</p>
<p>
<label>Name: </label>
<input type="text" ng-model="test.name" name="testName" required />
</p>
<button ng-click="sendTest()">Submit</button>
</form>
Like this a have this error
TypeError: Cannot read property '$valid' of undefined
but if I create another controller inside MyController.js and i move the code inside like this
function ChildController($scope,$timeout) {
$scope.test = {
name: 'das'
};
$scope.sendTest = function () {
console.log($scope.form.$valid);
console.log($scope.form.testNumber.$valid);
console.log($scope.form.testName.$valid);
};
};
function MyController($scope) { //do other stuff ...};
angular
.module('Myapp')
.controller('ChildController', ["$scope", ChildController])
.controller('MyController', ["$scope"]);
and add the ng-controller to the form like this
<form name="form" novalidate ng-controller='ChildController'>
the form is reconize correctly and working.
Can anyone explain what I am missing here, i would like to understand better, I am a novice.
Thanks you for the help.
Best regards.
Jolynice
As seen in Brad Barber's comment:
The form is being created on the child scope and not the controller
scope.
A good solution like he suggested would be to add the bindToController and controllerAs syntax to your route object:
function config($stateProvider, $urlRouterProvider, $ocLazyLoadProvider) {
$urlRouterProvider.otherwise("/index/main");
$stateProvider
.state('testing', {
url: "/testing",
controller: 'MyController',
controllerAs: 'viewCtrl',
bindToController: 'true',
templateUrl: "testing.html"
});
}
Now you can bind the name of the form as viewCtrl.form:
<form name="viewCtrl.form" novalidate>
<p>
<label>Number: </label>
<input type="number" min="0" max="10" ng-model="viewCtrl.test.number" name="testNumber" required />
</p>
<p>
<label>Name: </label>
<input type="text" ng-model="viewCtrl.test.name" name="testName" required />
</p>
<button ng-click="viewCtrl.sendTest()">Submit</button>
</form>
You can then notate it in your controller using this:
function MyController($scope) {
// Adding variables functions available to ctrl scope
// same as vm = this;
angular.extend(this, {
test: {name: 'das'},
sendTest: function() {
console.log(this.form.$valid);
console.log(this.form.testNumber.$valid);
console.log(this.form.testName.$valid);
}
});
};
angular
.module('Myapp')
.controller('MyController', ["$scope", MyController]);
Here is a codepen that I hacked together for you:
Check whether if the form is inside any div which has ng-if condition
Like
<div ng-if="condition">
<form name="viewCtrl.form">
.
</form>
</div>
If this is so, the form would return undefined since there is new scope created for the DOM containing ng-if condition. Then use ng-show instead of ng-if that would not create new scope. I got this solution from this answer

Pass variable to directive that is restricted to attribute

I have this directive:
.directive('myDate', ['$timeout', '$rootScope', '$locale',
function ($timeout, $rootScope, $locale) {
'use strict';
return {
restrict: 'A',
scope: {
customDate: '='
},
// the rest part of directive...
};
}
]);
I know how to pass a variable to directive that is restricted to element. But that approach doesn't work when the directive is given as attribute:
<div class="input-group date" my-date custom-date="testDate">
<input type="text" class="form-control" ng-model="dateFrom" />
</div>
Where:
scope.testDate= new Date('2015-01-13')
How can I get it work?
For the most part, your code should work. Here is a working plunker for the rest. There were just a few small issues with the OP. In the controller, the property that is bound to the directive attribute must be of the same name (scope.date should have been scope.testDate) etc.
The controller:
app.controller('Ctrl', function($scope) {
$scope.testDate = new Date('2015-01-13')
});
The directive:
app.directive('myDate', ['$timeout', '$rootScope',
function ($timeout, $rootScope) {
'use strict';
return {
restrict: 'A',
scope: {
customDate: '='
},
link(scope) {
console.log(scope.customDate);
}
};
}
]);
The HTML:
<body ng-app="myApp">
<div ng-controller="Ctrl">
<div class="input-group date" my-date custom-date="testDate">
<input type="text" class="form-control" ng-model="dateFrom" />
</div>
</div>
</body>

AngularJS check if form is valid in controller

I need to check if a form is valid in a controller.
View:
<form novalidate=""
name="createBusinessForm"
ng-submit="setBusinessInformation()"
class="css-form">
<!-- fields -->
</form>
In my controller:
.controller(
'BusinessCtrl',
function ($scope, $http, $location, Business, BusinessService,
UserService, Photo)
{
if ($scope.createBusinessForm.$valid) {
$scope.informationStatus = true;
}
...
I'm getting this error:
TypeError: Cannot read property '$valid' of undefined
Try this
in view:
<form name="formName" ng-submit="submitForm(formName)">
<!-- fields -->
</form>
in controller:
$scope.submitForm = function(form){
if(form.$valid) {
// Code here if valid
}
};
or
in view:
<form name="formName" ng-submit="submitForm(formName.$valid)">
<!-- fields -->
</form>
in controller:
$scope.submitForm = function(formValid){
if(formValid) {
// Code here if valid
}
};
I have updated the controller to:
.controller('BusinessCtrl',
function ($scope, $http, $location, Business, BusinessService, UserService, Photo) {
$scope.$watch('createBusinessForm.$valid', function(newVal) {
//$scope.valid = newVal;
$scope.informationStatus = true;
});
...
Here is another solution
Set a hidden scope variable in your html then you can use it from your controller:
<span style="display:none" >{{ formValid = myForm.$valid}}</span>
Here is the full working example:
angular.module('App', [])
.controller('myController', function($scope) {
$scope.userType = 'guest';
$scope.formValid = false;
console.info('Ctrl init, no form.');
$scope.$watch('myForm', function() {
console.info('myForm watch');
console.log($scope.formValid);
});
$scope.isFormValid = function() {
//test the new scope variable
console.log('form valid?: ', $scope.formValid);
};
});
<!doctype html>
<html ng-app="App">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
</head>
<body>
<form name="myForm" ng-controller="myController">
userType: <input name="input" ng-model="userType" required>
<span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
<tt>userType = {{userType}}</tt><br>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br>
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
/*-- Hidden Variable formValid to use in your controller --*/
<span style="display:none" >{{ formValid = myForm.$valid}}</span>
<br/>
<button ng-click="isFormValid()">Check Valid</button>
</form>
</body>
</html>
The BusinessCtrl is initialised before the createBusinessForm's FormController.
Even if you have the ngController on the form won't work the way you wanted.
You can't help this (you can create your ngControllerDirective, and try to trick the priority.) this is how angularjs works.
See this plnkr for example:
http://plnkr.co/edit/WYyu3raWQHkJ7XQzpDtY?p=preview
I like to disable the save/submit button if the form is invalid:
<form name="ruleForm">
<md-input-container>
<label>Priority</span>
<input name="description" ng-model="vm.record.description" required>
</md-input-container>
<md-button ng-click="vm.save()" ng-disabled="ruleForm.$invalid" class="md-primary md-raised">Save</md-button>
</form>

Resources