This seems like a really simple question but, for whatever reason my submit() method is not being invoked in JS.
HTML:
<ion-view title="Register" hide-nav-bar="true" nav-transition="none" id="page9">
<ion-content padding="true" class="manual-ios-statusbar-padding" scroll="false">
<form id="register-form4" ng-submit="register()" class="list">
<ion-list id="register-list4">
<label class="item item-input" id="register-input7">
<input type="text" ng-model="registration.email" placeholder="Email" required>
</label>
<label class="item item-input" id="register-input9">
<input type="password" ng-model="registration.password" placeholder="Password" required>
</label>
</ion-list>
</form>
<a id="register-button7" ng-click="document.getElementById('register-form4').submit();" class="button button-positive button-block">Create Account</a>
<a ui-sref="login" id="register-button8" class="button button-positive button-block button-clear">Back</a>
<div ng-show="isError">{{ loginError }}</div>
</ion-content>
</ion-view>
Controller:
.controller('registerCtrl', ['$scope', '$stateParams', "$firebaseAuth", "$location",
function ($scope, $stateParams, $firebaseAuth, $location) {
$scope.register = function() {
var email = $scope.registration.email,
password = $scope.registration.password,
confirmPassword = $scope.registration.confirmPassword;
console.log("Being submitted");
}
}])
I cannot change the <a> tag even though it would be easier just to have a form submit input but the HTML is auto-generated by Ionic Creator and I can't mess it up.
EDIT: The reason I want to submit the form in this way and not just trigger register() on click of the button is that I want to trigger the HTML required's in the form so that checks the fields have been entered so I don't have to do it manually
EDIT 2: I have changed the <a> tag to a submit button. However, this is still not invoking the register() method which suggests the form is not being submitted:
<input type="submit" value="Create Account" id="register-button7" class="button button-positive button-block">
Looking at these docs, it should work as it's pretty much the same format
I have read that 1 user things that the standard HTML submit and ng-submit do not work together. Anyone know if this is true?
You can use html input of type submit or a button inside your form. Here is a working demo at JSFiddle: https://jsfiddle.net/ydbhb5dL/
Controller:
angular
.module('App', [])
.controller('ExampleController', function ($scope) {
$scope.registration = {};
$scope.register = function () {
var email = $scope.registration.email,
password = $scope.registration.password;
console.log('Email:', email);
console.log('Password:', password);
console.log('Being submitted!');
};
});
Html:
<div ng-app="App" ng-controller="ExampleController">
<ion-view title="Register" hide-nav-bar="true" nav-transition="none" id="page9">
<ion-content padding="true" class="manual-ios-statusbar-padding" scroll="false">
<form id="register-form4" ng-submit="register()" class="list">
<ion-list id="register-list4">
<label class="item item-input" id="register-input7">
<input type="text" ng-model="registration.email" placeholder="Email" required>
</label>
<label class="item item-input" id="register-input9">
<input type="password" ng-model="registration.password" placeholder="Password" required>
</label>
</ion-list>
<input type="submit" class="button-like-link" value="Create Account (button)">
</form>
</ion-content>
</ion-view>
</div>
To solve your problem change the <a> element that submits the form to
<a id="register-button7" ng-click="register()" class="button button-positive button-block">Create Account</a>
The reason ngClick wasn't working before is because it was looking at $scope for document, which is not defined. You could add the following line to your controller, but it's not necessary.
$scope.document = document;
If you insist on not changing the form structure, you can create a new directive for your submit "button" similar to the one below (untested).
angular.module('moduleName').directive('submitForm', function() {
return {
restrict: 'A',
scope: {
formId: '='
},
link: function($scope, $elem) {
$elem.on('click', function() {
document.getElementById($scope.formId).submit();
});
}
};
});
Which you would then use as follows:
<a id="register-button7" submit-form form-id="register-form4" class="button button-positive button-block">Create Account</a>
If you still don't want to change the <a> tag to use the new directive, your only other option is defining $scope.document = document.
Or, as #J Orbe mentioned, you could use onclick instead of relying on an Angular directive (i.e. ngClick and submitForm). I'm not sure this qualifies as the "Angular way" TM, though, and you may want to avoid mixing Angular and regular JavaScript attributes as it can result in confusion. Typically, if you're using Angular, you should try to solve things using Angular.
Related
I am not very familiar with the directives in the AngularJS as I'm used on relying on controllers. Is it possible to set validity on other inputs via directive? Here is the case, I have a button and when it is clicked.. It should set a validity on a certain input text. But I just can not seem to get the code that will set the validity.
Here is the HTML code:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<div class="container">
<div id="login-container">
<div class="form-group">
<span class="glyphicon glyphicon-user"></span>
</div>
<form name="loginForm" novalidate>
<div class="form-group">
dasdas -- {{ loginForm.student_code.$error.codeValidity }}
<input type="text" class="form-control text-center" name="student_code" ng-model="studentCode" placeholder="Enter Exam Code" required />
<span class="errors" id="error-student-code" ng-if="loginForm.student_code.$error.codeValidity">{{ errors }}</span>
</div>
</form>
<login-button form="loginForm"></login-button>
<button class="btn btn-primary">Register</button>
</div>
</div>
</body>
</html>
Here is the JS Code:
var app = angular.module("myApp", []);
app.directive('loginButton', loginButton);
loginButton.$inject = ["$http", "$window"];
function loginButton($http, $window){
return {
template: '<button type="button" class="btn btn-primary">Take Exam</button>',
link: function(scope, element, attrs, ctrl){
element.on('click', function(){
form = attrs.form;
form.student_code.$setValidity('codeValidity', true);
scope.errors = "Code is Invalid";
});
}
}
}
Here is a sample on plunker: http://plnkr.co/edit/kcdDgZpStQixTpGWqxOp?p=preview
PS.
I know this can be easily achieved using controllers but I would like to achieve this using directives as my practice to get used to it.
Yes, it is possible and you almost got it right. What you wanna do is pass form to isolated scope and then use in directive controller.
There is no need to add event manually, as you can use ng-click.
Otherwise you would need to use $scope.$apply.
In directives you can use linking function, but you don't have to.
In general it is good practice to keep light logic in controller and DOM manipulation in linking function.
var app = angular.module("myApp", []);
app.directive('loginButton', loginButton);
loginButton.$inject = ["$http", "$window"];
function loginButton($http, $window){
return {
template: '<button type="button" class="btn btn-primary" ng-click="click()">Take Exam</button>',
scope: {
form: '='
},
controller: function($scope){
$scope.click = function(){
form = $scope.form;
form.student_code.$setValidity('codeValidity', false);
};
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app="myApp">
<div class="container">
<div id="login-container">
<div class="form-group">
<span class="glyphicon glyphicon-user"></span>
</div>
<form name="loginForm" novalidate>
<div class="form-group">
dasdas -- {{ loginForm.student_code.$error }}<br>
<input type="text" class="form-control text-center" name="student_code" ng-model="studentCode" placeholder="Enter Exam Code" required />
<span class="errors" id="error-student-code" ng-if="errors">{{ errors }}</span>
</div>
</form>
<login-button form="loginForm"></login-button>
<button class="btn btn-primary">Register</button>
</div>
</div>
</div>
I set the values of textboxes via a ajax request in my controller like this :
$http({method: 'GET', url: url}).success(function(data) {
$scope.valzz = data;
$scope.company = $scope.valzz[0].Company;
});
Then in my html :
<label class="item item-input item-stacked-label">
<span class="input-label">Company :</span>
<input type="text" placeholder="Company" value="" ng-model="company">
</label>
<button class="button button-positive" style="margin-top:10px;" ng-click="saveChanges()">
Save Changes
</button>
This correctly puts the company name in the company textbox. But when make a change to that textbox and press the save button, the new value of the textbox isnt showing - it still gets the original. This is the button click in the controller :
$scope.saveChanges=function(){
alert($scope.company);
};
Why is $scope.company not the new value of the textbox? am i doing something wrong? (sorry if basic i am new to angular)
Try removing value=""
HTML:
<label class="item item-input item-stacked-label">
<span class="input-label">Company :</span>
<input type="text" placeholder="Company" ng-model="company">
</label>
<button class="button button-positive" style="margin-top:10px;" ng-click="saveChanges()">
Save Changes
</button>
In corresponding CONTROLLER:
$scope.saveChanges = function() {
alert($scope.company);
};
You don't have a watcher for that model.
$scope.$watch('company', function(company) {
console.log(company);
}
Or in your template, you can interpolate the value:
{{company}}
And then you can see it changing on the html page, because angular make a watcher for it behind the scene
Needed to put this.company not $scope
Please define $scope.company before $http call
app.controller('myCtrl', function($scope, $http){
$scope.company = null; // <--
$http({method: 'GET', url: url}).success(function(data) {
$scope.valzz = data;
$scope.company = $scope.valzz[0].Company;
});
}
Because, once the partials has rendered, it gets only the defined properties in $scope. After that if any property is added inside $scope it needs to call the $apply.
Hope this may help you.
I would assume that you have $scope working properly, and that you have initialized the controller in your app, as well as linked to the proper controller file. Please compare your code to what I have here, as this is working properly.
HTML:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src ="controller.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="testController">
<form>
<label class="item item-input item-stacked-label">
<span class="input-label">Company :</span>
<input type="text" placeholder="Company" ng-model="company">
</label>
<button class="button button-positive" style="margin-top:10px;" ng-click="saveChanges()">
Save Changes
</button>
</form>
</div>
</body>
</html>
Controller:
(function(){
'use strict';
var app = angular.module('myApp', []);
app.controller('testController', [ '$scope', function ($scope){
$scope.saveChanges=function(){
alert($scope.company);
};
}]);
})();
Edit: Fiddle
I need to send route params with the URL when the user clicks on submit button.
Here is my simple form
<form action="#/chat/{{username}}">
<input type="text" placeholder="enter a username..." ng-model="username" required autofocus><br/>
<input type="submit" value="submit">
</form>
But this doesn't work as the 'username' variable doesn't bind and it goes to /chat/%7B%7Busername%7D%7D instead (somebody enlighten me on why this happens)
Currently, the workaround I am following is using a hyperlink instead of a submit button
<div>
<input type="text" class="form-control" placeholder="enter a username..." ng-model="username" required autofocus><br/>
<a href="#/chat/{{username}}" class="btn btn-lg btn-primary btn-block" >Start Chatting</a>
</div>
But the problem with the above approach is that it doesn't work when the user presses ENTER key (as it is not the submit button)
So what is the correct way to achieve this?
Markup:
<form ng-submit="onSubmit()">
<input type="text" placeholder="enter a username..." ng-model="username" required autofocus><br/>
<button type="submit">submit</submit>
</form>
JavaScript Controller:
app.controller('ctrl', function($location) {
$scope.username = '';
$scope.onSubmit = function() {
$location.url('/chat/' + $scope.username);
};
});
Or something like that :)
HTML:
<form ng-submit="onSubmit()">
<input type="text" placeholder="enter a username..." ng-model="username" required autofocus><br/>
<button type="submit">submit</submit>
</form>
Controller:
app.controller('ctrl', function($state) {
$scope.username = 'example name';
$scope.onSubmit = function() {
$state.go('/chat/' + $scope.username);
};
});
Docs:
Angular Ui
$state.go('$scope.username') - will go to the state according to user name
$state.go('^') - will go to a parent state
$state.go('^.sibling') - will go to a sibling state
$state.go('.child.grandchild') - will go to grandchild state
Per another post on stack:
the $location service is on the angular.js framework out of the box and allow you to manage location object (similar in pure javascript). The $state service is part of ui-router module and allow you to manage routes in an advanced mode, throughout a state machine management of views.
If you use ui-router, you should prefer to use $state service to manages states/routes because state abstracts the concept of route and you could change the phisical routes without changing states.
Stack Post
I have a problem with my input fields in my modal view.
When I take a change in the input fields then it is updating the table list but when I leave the page and go back to this page with the table list then die changes are disappeared.
This is my modal view:
<form class="form-horizontal" name="editForm" novalidate>
<div class="modal-body">
<div class="form-group-sm has-feedback">
<label class="control-label">Firstname</label>
<input type="text"
class="form-control"
name="Fname"
ng-model="selected.fname"
ng-model-options="{updateOn: 'updateItem'}"
ng-required="true"
/>
</div>
</div>
//the same input field for lastname
...
<div class="modal-footer">
<button class="btn btn-default" ng-click="createItem(selected)" type="submit">Erstellen</button>
<button class="btn btn-default" ng-click="updateItem(selected)"> Ă„ndern</button>
<button class="btn btn-default" ng-click="cancel()">Abbrechen</button>
</div>
</form>
Modal Ctrl:
$scope.cancel = function () {
$scope.editForm.$rollbackViewValue();
$modalInstance.dismiss('cancel');
}
$scope.updateItem = function (updateItem) {
CrudService.update(updateItem);
$scope.ok();
}
Crud Service:
...
update: function (updateItem) {
updateItem.$update();
},
...
I have only seen examples of $rollbackViewValue() with one input field and the code: $scope.myForm.inputName.$rollbackViewValue() but I have more than one input fields?
you should call $rollbackViewValue() through the form name:
editForm.$rollbackViewValue()
call it in your template:
{{editForm.$rollbackViewValue.toString()}}
and you will see how it actually works:
function () {
forEach(controls, function(control) {
control.$rollbackViewValue();
});
}
A little late but for others reference (I came across this looking for another issue with $rollbackViewValue).
Using $rollbackViewValue in controller: to use $scope to reference the form from the controller, you have to use the ng-form attribute on a child element of the form (like for instance the form-group div in your example).
That makes $scope.editForm.$rollbackViewValue() available in the controller and resets the entire form.
For cases where buttons are inside the form, using ng-submit and ng-model-options="{ updateOn: 'submit' }" on input fields, then adding 'type=button' attribute to cancel button element (so submit isn't triggered) is a quick solution.
Example:
https://embed.plnkr.co/IQ4vvutC3tcHvVBH0821/
I have this weird problem. When I clear the model in the controller, the input field binded to the model with ng-model wont clear when the form is submitted.
Controller
angular.module('starter.controllers', [])
.controller('DashCtrl', ["$scope", function($scope) {
$scope.clearInput = function() {
console.log("I get there...");
//Here's the issue!!! It's not working as expected!
$scope.message = "";
};
}]);
Template
<ion-view title="Dashboard">
<ion-content class="padding">
<form name="myform" ng-submit="clearInput()">
<label class="item item-input">
<input type="text" ng-model="message"/>
</label>
<button type="submit" class="button button-positive" >
button-positive
</button>
</form>
</ion-content>
</ion-view>
I get the console output "I get there", so the function gets activated. What am I missing here?
clearInput() and ng-model refer to different scopes after the value of input has changed. Please see this SO answer for deeper explanation.