Can't Select Elements After Routing Completed in Angular - angularjs

I want to validate my form just like this pen. But I'm also using ui-router and my form fields are in another partial page. So I can't select my form as selected as in pen(below).
if ($scope.userForm.$valid) {
alert('our form is amazing');
}
In console I'm getting this error. "TypeError: Cannot read property '$valid' of undefined".
So what should I do for catch my form fields which are come from partials?
By the way theese are my codes
var app = angular.module("App",['ui.router']);
app.controller("Controller", function($scope){
$scope.Go = function(){
alert($scope.name);
if($scope.userForm.$valid){
alert("Valid");
}
else{
alert("No Valid");
}
}
});
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('/', {
url: '/',
templateUrl: 'input.html'
})
});
This is my index.html
<div ng-controller="Controller">
<ui-view></ui-view></div>
And this is my partial.html
<form name="userForm">
<input type="text" ng-model="name"/>
<button ng-click="Go()">Go</button></form>

Basically you need to point your form to the parent scope like $parent.userForm & to get access to the form value do initialize form object inside parent controller of ui-view like $scope.form = {}. Then we will place all form level values in it.
HTML
<body ng-controller="Controller">
<ui-view></ui-view>
</body>
CODE
app.controller("Controller", function($scope) {
$scope.form = {};
$scope.Go = function() {
alert($scope.form.name);
if ($scope.userForm.$valid) {
alert("Valid");
} else {
alert("No Valid");
}
}
});
input.html
<form name="$parent.userForm">
<input type="text" ng-model="form.name" />
<button ng-click="Go()">Go</button>
</form>
Working Plunkr
Hope this could help you, Thanks.

You can do what #pankajparkar said. Or you need to modify your state:
$stateProvider
.state('/', {
url: '/',
templateUrl: 'input.html',
controller: 'Controller'
});
and remove the ng-controller="Controller".
UI Router will automatically load the specified controller for that given state and bind it the input.html.

Related

How to force a view to load model values prior to loading controller in AngularJS?

I am trying to auto post a form from a controller without any user interaction on the form. I have a private init() function in the controller that triggers a button click on the form.
But the hidden form fields did not get the values yet. How can I make sure the hidden fields will have values populated before the form submits?
Thank you for any suggestions.
<div>
<form name="myForm" method="post" action="#Model.Settings["URL"]" ng-controller="MyCtrl">
<input type="hidden" name="userid" value="{{UserSettings.Settings.UserId}}">
<input type="hidden" name="amount" value="{{Payment.Amount}}">
<button id="payButton" type="submit" class="action blue"><span class="label">Pay</span></button>
<script language="javascript">
var UserSettings = (function (o) {
return o;
})(#Html.Raw(JsonConvert.SerializeObject(#Model)));
</script>
</form>
</div>
myControllers.controller('MyCtrl', ['$scope', '$state', '$element', 'dataService',
function ($scope, $state, $element, service) {
$scope.Payment = service.GetPayment());
$scope.UserSettings = UserSettings;
function init() {
// How can I force to have values in the hidden form fields before the button click that submits the form ?
$element.find('#payButton').trigger("click");
};
init();
}]);
Here is the ui-router states configuration.
var app = angular.module('pay', ['ui.router', 'pay.controllers', 'pay.services', 'exceptionOverride', 'ngSanitize']);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('home', {
url: '/' ,
templateUrl: 'search'
})
.state('payment', {
url: '/payment',
templateUrl: 'Payment'
});
//setting html5 removes the # from URL but causes routing problems at the moment.
//$locationProvider.html5Mode(true);
$urlRouterProvider.rule(function ($injector, $location) {
//what this function returns will be set as the $location.url
var path = $location.path(), normalized = path.toLowerCase();
if (path != normalized) {
$location.replace().path(normalized);
}
else if (path == '') {
$location.path('/');
}
});
}]);
You can put the populations in the point you define the state which has MyCtrl as follows:
.state('myState', {
// ...
resolve: {
Payment: ['dataService', function (dataService) {
return dataService.GetPayment();
}],
// Same for other objects needed
}
})
And then in your Controller:
myControllers.controller('MyCtrl', ['$scope', '$state', '$element', 'Payment',
function ($scope, $state, $element, Payment) {
$scope.Payment = Payment;
// Same for other objects needed
// Rest code
}
The code in the Controller would not start running before all actions and promises in the resolve section finish.
Update:
You can put init call inside a $timeout.
$timeout(function(){
init();
});
Of course, you have to inject $timeout in Controller function along with the other dependencies.

status undefined when try to fetch data on json and place it on single page of each data

heres my code, i try to show my selected product form my product page by id.
for example when i click a product it go to right url like /#/product/2 and it show all the attribute of product id:2. please take a look this code
app.js
angular
.module('app', [
'ui.router',
'app.directives.productCard'
])
.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/pages/home.html',
controller: 'homeCtrl'
})
.state('product', {
url: '/product',
templateUrl: 'templates/pages/product.html',
controller: 'productCtrl'
})
.state('productDetails', {
url: '/product/:id',
templateUrl: 'templates/pages/productDetails.html',
controller: 'productDetailsCtrl'
})
}])
my services
angular
.module('app')
.factory('Product', ['$http', function($http) {
return {
get: function() {
return $http.get('https://raw.githubusercontent.com/vicariosinaga/learn/master/products.json').then(function(response) {
return response.data;
});
}
};
}])
productCtrl
angular
.module('app')
.controller('productCtrl',['$scope', 'Product', function($scope,Product) {
$scope.title="List Product";
Product.get().then(function(data) {
$scope.products = data;
});
$scope.products=Product.get();
}]);
productdetailsCtrl
angular
.module('app')
.controller('productDetailsCtrl',['$scope','$stateParams', 'Product', function($scope,$stateParams,Product){
$scope.id=$stateParams.id;
Product.get().then(function(data) {
var singleProduct = data.filter(function(entry){
return entry.id === $scope.id;
})[0];
console.log(singleProduct);
console.log($stateParams);
});
}]);
product.html
<div class="col-lg-3 col-md-4 col-sm-6">
<div class="card">
<img class="card-img-top" ng-src="{{item.image}}" alt="{{item.name}}">
<div class="card-block">
<strong class="card-title">{{item.name}}</strong>
</div>
<div class="card-block">
Buy
</div>
</div>
</div>
product detail.html
<p>{{id}}</p>
<p>{{name}}</p>
<p>{{image}}</p>
after all this code,when i try to check via console. i get Object {id: "2"}, but when i try to show all the attribute from product 2 i get on console undefined. why i got undifined. yeah i didnt use and local server. but if its the problem. does all the code is right to print all the attribut of product 2
here the link of the json https://raw.githubusercontent.com/vicariosinaga/learn/master/products.json
Change product details state url to make id parameter as a int which will allow you to pass return entry.id === $scope.id;(strict equality check).Here you have id value as string which makes singleProduct as undefined.
.state('productDetails', {
url: '/product/{id:int}',
templateUrl: 'templates/pages/productDetails.html',
controller: 'productDetailsCtrl'
})
otherwise you have to change your strict check to return entry.id == $scope.id;

How do i navigate one page to another in angularjs

i tried to navigate one page to another page but it didn't work.i used angularjs as front end.
My angularjs file is
var app = angular.module('loginApp', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
// default route
$urlRouterProvider.otherwise("/");
// app routes
$stateProvider
.state('home', {
url: '/tokken/s/',
templateUrl: 'templates/register.html',
controller: 'loginCtrl'
});
});
// Controller function and passing $http service and $scope var.
app.controller('loginCtrl', function($scope, $state, $http) {
// create a blank object to handle form data.
$scope.user = {};
// calling our submit function.
$scope.submitForm = function() {
// Posting data to file
$http.post('/tokken/login/', $scope.user).then(function (response) {
//$httpProvider.defaults.headers.common["X-AUTH-TOKEN"] = response.data;
if (response.errors) {
// Showing errors.
$scope.errorName = response.errors.name;
$scope.erroPassword = response.errors.password;
} else {
//$scope.message = response.data;
$state.go('home');
}
});
};
// calling our submit function.
$scope.regForm = function() {
// Posting data to file
$http.post('/tokken/s/', $scope.user).then(function (response) {
//$httpProvider.defaults.headers.common["X-AUTH-TOKEN"] = response.data;
if (response.errors) {
// Showing errors.
$scope.errorName = response.errors.name;
$scope.erroPassword = response.errors.password;
} else {
$scope.message = response.data;
}
});
};
});
/////////////
My html files is
<!DOCTYPE html>
<html ng-app="loginApp">
<head>
</head>
<body ng-controller="loginCtrl" ui-view="content">
<form ng-submit="submitForm()">
<br> user name:
<input type="text" ng-model="user.name">
<br>
<br> password:
<input type="text" ng-model="user.password">
<br>
<input type="submit" value="login">
</form>
</body>
<script src="/js/angular.min.js"></script>
<script src="/controller/login.js"></script>
<script src="/js/angular-ui-router.min.js"></script>
</html>
above code post a value. but didn't navigate to another page.
while i using $location provider in it. post didn't work. help me please
You should rather put the index contents into another template so that the state can return to "/" if the state changed, and because you set it as the default state: $urlRouterProvider.otherwise("/");
Add this to your stateProvider:
.state('login', {
url: '/',
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
});
Also since your state is already assigning a controller the ng-controller="loginCtrl" in the body tag does not belong there.
Please check this code
.state('home', {
url: '/token/s',
views: {
'content#': {
templateUrl: 'templates/register.html',
controller: 'loginCtrl'
}
}
})
Instead of
.state('home', {
url: '/tokken/s/',
templateUrl: 'templates/register.html',
controller: 'loginCtrl'
});

cannot edit my document using ui-router within an angular-meteor app

I am building my first angular-meteor app using the ui-router.
From a bookList view you can access the bookDetail template:
here's the book detail page:
From the detail page I would like to access the 'edit page'. This page should return the same data of the document detail page so that the user is able to edit it and save it. But I am failing. Please check my code below:
1) The ui-router configuration
//Router
angular.module('bookshelf',['angular-meteor', 'ui.router']);
//Router configuration
angular.module('bookshelf').config(['$urlRouterProvider',
'$stateProvider','$locationProvider',
function($urlRouterProvider, $stateProvider, $locationProvider){
$locationProvider.html5Mode(true);
$stateProvider
.state('books', {
url: '/books',
templateUrl: 'bookList.ng.html',
controller: 'BookListCtrl'
})
.state('bookAdd', {
url: '/books/add',
templateUrl: 'addBook.ng.html',
controller: 'bookAddCtrl'
})
.state('bookDetail', {
url: '/books/:bookId',
templateUrl: 'bookDetail.ng.html',
controller: 'bookDetailCtrl'
})
.state('bookEdit', {
url: '/edit/books/:bookId',
templateUrl: 'bookEdit.ng.html',
controller: 'bookEditlCtrl'
});
$urlRouterProvider.otherwise('/books');
}]);
2) The html template 'bookEdit.ng.html':
<div class="container">
<form ng-controller="bookEditCtrl">
<label>Title</label>
<input ng-model="book.title">
<label>Author</label>
<input ng-model="book.author">
<label>Publisher</label>
<input ng-model="book.publisher">
<button type="button" class="btn btn-success"
ng-click="save(book)">Save</button>
</form>
</div>
3) The 'bookEditCtrl' controller from my app.js file:
angular.module('bookshelf').controller('bookEditCtrl',
['$scope','$stateParams','$meteor',
function($scope,$stateParams,$meteor){
$scope.book = $meteor.object(books, $stateParams.bookId);
$scope.save = function(){
$scope.book.save();
};
}]);
this is the result when I try to go to the edit page.
The console shows an error. How can I get the book details in the input fields so that I can edit them and save them? Am I doing something wrong with the routing? Probably I should add within the input fields an expression like {{book.title}},{{book.author}},{{book.publisher}} so that I can see the book details? Thank you for your support.
Its typo in controller name inside bookEdit state.
it should
controller: 'bookEditCtrl'
instead of
controller: 'bookEditlCtrl'
Corrected State
.state('bookEdit', {
url: '/edit/books/:bookId',
templateUrl: 'bookEdit.ng.html',
controller: 'bookEditCtrl' //<--change here
});

Creating a JSFiddle with Angular-ui-router and multiple views

I have a question I would like to ask the community, but am having trouble setting up the required JSFiddle to make it easier to demonstrate the issue. I want to create a fiddle with three views side by side using Angular's ui-router. Seems simple, but for some reason I can't get the views' controller's to initialize. The main app loads, as evidenced by console messages, but I'm stumped.
The Fiddle is here, and for completeness sake, the html and js are here:
HTML:
<div ui-view="top" class="top">
<br />
$scope.testmsg = {{testmsg}}
<br />
$scope.statename = {{statename}}
<br />
top!
</div>
<div ui-view="middle" class="middle">middle!</div>
<div ui-view="bottom" class="bottom">bottom!</div>
JS:
/* myApp module */
var myApp = angular.module('myApp', ['ui.router'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('home', {
url: "/",
views: {
'top': {
url: "",
template: '<div>top! {{topmsg}}</div>',
controller: function ($scope) {
$scope.topmsg = "loaded top!";
console.log("top ctrl!"); // this does NOT show in console
}
},
'middle': {
url: "",
template: '<div>middle! {{middlemsg}}</div>',
controller: function ($scope) {
$scope.middlemsg = "loaded middle!";
console.log("middle ctrl!"); // this does NOT show in console
}
},
'bottom': {
url: "",
templateUrl: '<div>bottom! {{bottommsg}}</div>',
controller: function ($scope) {
$scope.bottommsg = "loaded bottom!";
console.log("bottom ctrl!"); // this does NOT show in console
}
}
},
onEnter: function () {
console.log("entered home state"); // this does NOT show in console
}
});
}])
.controller('MyAppCtrl', function ($scope, $state/*, $stateParams*/) {
$scope.statename = $state.current.name;
$scope.testmsg = "app scope working!";
console.log("MyAppCtrl initialized!"); // this shows in console
$state.go("home");
});
My body tag has the correct (I believe) references to my app and controller: <body ng-app="myApp" ng-controller="MyAppCtrl"></body>... I'm stuck. Any help would be great.
Thanks in advance!
I think your only mistake is in the configuration for the 'bottom' view. You have templateUrl instead of template. After I made this change in your fiddle, all the controllers initialize correctly.
Here's an updated fiddle. But like I said, changing templateUrl to template is the only change. Hope this helps!

Resources