I'm unable to get a form to trigger a Polymer function when it's being submitted:
<form onsubmit="return _submit()"> //_submit is not defined
<form onsubmit="return this._submit()"> //this._submit is not a function
<form onsubmit="_submit"> //_submit is not defined
<form onsubmit="{{_submit}}"> //no output
<form on-submit="{{_submit}}"> //no output
<form on-submit="_submit"> //no output
How do I bind to Polymer function?
Use iron-form:
<form is="iron-form" id="form" method="post" action="/form/handler">
<paper-input name="name" label="name"></paper-input>
<input name="address">
...
</form>
And then add a listener for iron-form-submit which is fired after the form is submitted:
Polymer({
listeners: {
'iron-form-submit': '_handleSubmit'
},
_handleSubmit: function(e) {
// Do something
}
})
See iron-form docs for more info.
Related
I have a form called ganesConfig and based on some condition i want to show the error message.
<form method="post" name="gamesConfig" novalidate>
<p ng-show="gamesConfig.selectedGames.$invalid.gamesduplicate">Already Exists. Please try another</p>
</form>
the condition is as follows
$scope.gamesConfig.selectedGames.$setValidity("gamesduplicate", false);
But not showing the error message.
Here is a sample example I've made out from what you have provided.You didn't provide the 'name' attribute to the input field which takes the game value by which we decide the duplicates.
$scope.game = {};
$scope.checkName = function() {
if ($scope.game.name == 'Test') {
$scope.gamesConfig.selectedGames.$setValidity("gamesduplicate", false);
}
};
Your HTML should look like below
<ng-form method="post" name="gamesConfig" novalidate>
<input type="text" name="selectedGames" ng-model="game.name" ng-change="checkName()"/>
<p ng-show="gamesConfig.selectedGames.$invalid">Already Exists. Please try another</p>
</ng-form>
<form novalidate name="frm1" autocomplete="off">
//UI elements
<div class="col-sm-3 col-sm-offset-6">
<button ng-click="MyFunc()">Next Step</button>
</div>
</form>
Can you tell me how to fire MyFunc() method when click the enter key.On the above form where there is no submit button. Thanks in advance.
Try this:
<input ng-keyup="$event.keyCode == 13 ? MyFunc() : null" >
At form level you can use this:
<form ng-submit="myFunc()" ...>
I have written below mentioned directive and it works.
Directive :
angular.module('app.directives')
.directive('ngEnter', function () { //a directive to 'enter key press' in elements with the "ng-enter" attribute
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if (event.which === 13) {
scope.$apply(function () {
scope.$eval(attrs.ngEnter);
});
event.preventDefault();
}
});
};
})
HTML
<form novalidate name="frm1" autocomplete="off">
//UI elements
<input name="userName" type="text" ng-enter="MyFunc()"/>
<div class="col-sm-3 col-sm-offset-6">
<button ng-click="MyFunc()">Next Step</button>
</div>
</form>
Simply write (keyup.enter)="your_function_name()" in your html file in same way you write (click).
Below is a code snippet.
<input type="text" [(ngModel)]="modelSearchedData" (keyup.enter)="getModelList()">
What you should do is binding your function on submit event instead of enter key. You should not focus on enter, because for exemple on the iPhone there is a keyboard button to execute form, which behave like enter but is not enter event ... and the iPhone is just one exemple :D
So you should change your <button> by an input <type="submit"/>
This way enter key will automatically fire the form submit event.
Then in your submit event, return false; to prevent HTML action (which send the form) and execute your code.
HTML
<form novalidate name="frm1" autocomplete="off">
//UI elements
<div class="col-sm-3 col-sm-offset-6">
<input type="submit" value="Next Step" />
</div>
</form>
JS
$('form').submit(function () {
MyFunc();
return false;
});
I hope this answer your question.
PS : you can use ng-submit instead of jQuery selector, if you do not want to use jQuery.
I found a solution that does not require a directive. I was already using ng-change to capture each keypress and perform a search, but clicking Enter would throw my SharePoint page into Edit mode. SharePoint doesn't let you access the form tag, so most of these solutions didn't work for me.
This solution was much simpler and kept my code in the same place, I have an ng-change AND an ng-keypress event that point to the same event handler, vm.txtSearchChange():
HTML
<input id="txtSearch" type="text" style="width: 400px;" ng-change="vm.txtSearchChange()"
ng-keypress="$event.keyCode == 13 ? vm.txtSearchChange($event) : null"
ng-model="vm.Search" ng-model-options="{debounce: 200}"/>
Note the ng-change event does not pass the $event attribute, and handles the legitimate key presses, while the ng-keypress event is only for the enter key.
SCRIPT
vm.txtSearchChange = function ($event) {
if ($event) {
$event.preventDefault();
return;
}
console.log("Search: " + vm.Search);
vm.showResults();
} // end vm.txtSearchChange
When $event is not null, it's the enter key, we call preventDefault() and don't process further. When $event is null, it's a valid key, and we pass it along to vm.showResults() for processing.
Most of the answers here involve additional workarounds that simply are not needed, you can work with the standard form submission by making these two small changes and the Enter key will function as desired.
Move the ng-click from the button to the form, and make it an ng-submit
Add a type="submit" to the button
For more complex forms with multiple buttons you might need to try some of the workarounds, but for the majority of cases this will work.
<form novalidate name="frm1" autocomplete="off" ng-submit="MyFunc()">
//UI elements
<div class="col-sm-3 col-sm-offset-6">
<button type="submit">Next Step</button>
</div>
</form>
<input type="text" name="Inputvalue" id="Inputvalue" ng-change="EnableDisableCheckButton()" ng-model="enteredInputValue" ng-disabled="isDisabledInputvalueTextbox" ng-blur="" data-ng-keypress="onEnterKeyPress($event)" />
<button type="button" class="btn btn-primary" ng-disabled="isDisabledCheckButton" ng-click="ValidateInputvalue()">Check</button>
And in your JavaScript file, add below:
$scope.onEnterKeyPress = function (event) {
if (event.charCode == 13) //if enter is hot then call ValidateInputvalue().
$scope.ValidateInputvalue();
}
This example worked for me:
HTML Code:
<input matInput type="text" [(ngModel)]="searchString" ng-change="startSearch()" ng-keypress="$event.keyCode == 13 ? startSearch($event) : null">
Typescript:
#HostListener('document:keypress', ['$event'])
startSearch(event: KeyboardEvent) {
if (event.code === "Enter") {
//Code that you need to run
}
}
https://go.tiny.cloud/blog/angular-5-tutorial-step-step-guide-first-angular-5-app/
I have questions about Angular directives. The following is my code:
main controller & the directive:
<div ng-controller='ShopsController'>
<update-createform shop="shop" action='update()'></update-createform>
</div>
directive js:
(this way the direction action will take the 'action' input argument)
angular.module('app')
.directive('updateCreateform', function(){
return {
templateUrl: '/form.html',
restrict : 'E',
scope: {
shop: '=',
action: '&'
}
}
})
form.html template:
<form name="shopForm" ng-submit='action(shopForm.$valid)' novalidate>
<input type='text' name='name' required/>
<input type='text' name='description' required/>
</form>
ShopsController has a method:
exports.update = function(isValid) {
if (isValid) { /* update the shop*/ }
}
What I am doing is I am passing the shop data I get from the server, send it into the form so I can view and/or update the shop info.
It's also that I want to create shop info using the same form. In this case I just send in shop = [] and action='create()' instead.
My controller has an update method that takes the argument isValid. I don't know how to pass the directive shopForm.$valid outside and send it to server.
Two questions:
how do I get isValid variable from the directive?
Following Ari Lerner's ng-book: He said it's possible to do the following:
http://www.scribd.com/doc/215682987/NG-Book-The-Complete-Book-on-AngularJS-2013
instead of using directive above we use
<update-createform shop="shop" on-update='update()' on-create='create()'></update-createform>
and the directive 'action' will change to 'update' when shop is not empty otherwise action equals to 'create'? I tried his code but I cannot get it to work..
Any help would be greatly appreciated!
You can add an argument to action=update(isValid). This then gets resolved on the form submit.
So your html would look like this
<div ng-controller='ShopsController as shopCtrl'>
<update-createform shop="shop" action='shopCtrl.update(isValid)'></update-createform>
</div>
And your form would look like like this
<form name="shopForm" ng-submit='action({isValid:shopForm.$valid})' novalidate>
<input type='text' name='name' required/>
<input type='text' name='description' required/>
<button type="submit">Submit</button>
</form>
and controller would be
.controller('ShopsController', function() {
var exports = this;
exports.update = function(isValid) {
console.log(isValid)
if (isValid) { /* update the shop*/ }
}
})
http://plnkr.co/edit/Qh3HzKGnOo1NTP9Pfsmh?p=preview
OR
There's another way, although personally i find the syntax a little odd. Not that the first solution feels that intuitive either.
http://plnkr.co/edit/CRN9ruRekJiozJIBTe80?p=preview
Found that one in an excellent post about directives by Dan Wahlin
http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters
I'm new to Angular and I have a simple retrieve password form with 1 email field and a submit button. I want to clear the form after the form has been submitted, but I can't seem to do it even after following tutorials/answers online.
I think it might be something I'm not understanding fundamentally, so if you could please let me know that would be great.
I'm using Angular v1.2.22
HTML (signin.forgotpassword.html)
<form name="forgotPasswordForm" class="form" role="form" ng-submit="forgetPasswordSubmit(forgetForm.email)" novalidate >
<div>
<label for="input-email" class="col-sm-2 control-label">Email</label>
<div>
<input name="email" ng-model="forgetForm.email" type="email" class="form-control" id="input-email" />
</div>
</div>
<div class="form-group">
<div>
<button name="submit" type="submit">Reset Password</button>
</div>
</div>
</form>
Angular (AuthController)
var forgetPasswordClear = function(){
var defaultForm = {
email: ''
};
// clear input
$scope.forgetForm = defaultForm; // Doesn't clear
// set form as pristine
$scope.forgotPasswordForm.$setPristine(); // Get Cannot read property '$setPristine' of undefined
};
$scope.forgetPasswordSubmit = function(email){
forgetPasswordClear();
};
----------EDIT----------
I'm not sure if it's because my form is sitting in a different ui view? My structure looks something like this:
HTML
<section data-ng-controller="AuthController">
<div data-ui-view>
Some content in there originally
<a ui-sref="signin.forgetpassword">Click here to get password</a>
</div>
</section>
Ui router
.state('signin.forgotpassword', {
url: '/signup/forgot-password',
templateUrl: 'modules/core/templates/signin.forgotpassword.html'
})
You set the wrong model:
Your model is 'forgetForm'
<input name="email" ng-model="forgetForm.email" type="email" class="form-control" id="input-email" ng-pattern="/.+\#.+\..+/" autofocus required />
current:
$scope.forget = defaultForm;
should be:
$scope.forgetForm = defaultForm;
EDIT TO ADDRESS NEW PROBLEM
It's because this is a child scope.
You need to use event emitters and listeners.
$broadcast -- dispatches the event downwards to all child scopes,
$emit -- dispatches the event upwards through the scope hierarchy.
Read more here: Working with $scope.$emit and $scope.$on
I'm using Angular.js on one of my projects and I want to combine it with Polymer. I have some problems with the comunication between Angular.js controllers and the Polymer custom elements.
What is my problem...
For example I have an AuthService, an AuthController which uses the AuthService to send requests to the backend (Node.js with Express) and a simple login form like this:
<form role="form" ng-submit="login()">
<div>
<label for="usernameInput">Username: </label>
<input type="text" name="usernameInput" id="usernameInput" placeholder="Username" ng-model="usernameInput" required>
</div>
<div>
<label for="passwordInput">Password: </label>
<input type="password" name="passwordInput" id="passwordInput" placeholder="Password" ng-model="passwordInput" required>
</div>
<div>
<label for="rememberMeInput">Remember me: </label>
<input type="checkbox" name="rememberMeInput" id="rememberMeInput" ng-model="rememberMeInput">
</div>
<input type="submit" name="loginSubmit" value="Log in">
</form>
Everiting is working fine in this format but I want to move the form inside a Polymer custom element like this:
<polymer-element name="cg-login-form">
<template>
<div layout vertical>
<div class="error hidden">{{ error }}</div>
<form role="form" layout vertical center>
<div>
<paper-input type="text" floatinglabel label="Username" value="{{ inputData.username }}"></paper-input>
</div>
<div>
<paper-input type="password" floatinglabel label="Password" value="{{ inputData.password }}"></paper-input>
</div>
<div layout horizontal center>
<paper-checkbox role="checkbox" checked="{{ inputData.rememberBe }}"></paper-checkbox>
<div>Remember me</div>
</div>
<paper-button label="Log in" raisedbutton role="button" on-click="??????"></paper-button>
</form>
</div>
</template>
<script>
Polymer('cg-login-form', {
inputData: {
username: undefined,
password: undefined,
rememberMe: false
}
});
</script>
</polymer-element>
My problem is: How to call the login method of the AuthController on form submit and I want the Polymer element to stay Angular.js independent.
I was thinking to fire a login event with the input data and to listen for this event inside the AuthController. Then the login event handler can call the AuthContoller's login method, but I can't get the sent data with the event.
This is how I'm firing the event inside the:
<paper-button label="Log in" raisedbutton role="button" on-click="{{ login }}"></paper-button>
Polymer('cg-login-form', {
inputData: {...},
login: function() {
this.fire('login', { loginData: this.inputData });
}
});
And this is how I'm listening for the login event inside the AuthController:
// In this way the detail and the data properties of the event object are undefined
angular.element("#loginForm").on('login', function(event) {
console.log(event.detail);
console.log(event.data);
});
// In this way the detail and the data properties of the event object are undefined
$('#loginForm').on('login', function(event) {
console.log(event.detail);
console.log(event.data);
});
// In this way the detail property of the event object is set with the sent data
document.getElementById('loginForm').addEventListener('login', function(event) {
console.log(event.detail);
console.log(event.data);
});
// In this way the detail property of the event object is set with the sent data
document.querySelector('#loginForm').addEventListener('login', function(event) {
console.log(event.detail);
console.log(event.data);
});
Why document.getElementById('loginForm').addEventListener() and document.querySelector('#loginForm').addEventListener() works and the other two ways doesn't work?
How can I get the sent data using jQuery or jqLite? I prefer to use them instead of using the html approach.
I will be glad if you tell me a better way for communication between Angular.js controllers and Polymer custom elements instead of events triggering.
Thank you very much and have a nice day
EDIT:
Also I can get the ng-login-form element from the DOM inside the AuthController and pass the AuthController's login method like a callback to some ng-long-form method. Then on form submit the ng-login-form can call the callback with the input data.
This will work too but I don't think that this is a good approach.
I solved it this way
In the paper-input add -- inputValue="{{ valData }}" --
for example
<paper-input label="name" id="name" class="label-input-full" inputValue="{{ valData }}">
</paper-input>
Add in button submit onclick event
for example
<paper-button class="btn-check" type="submit" icon="check" core-overlay-toggle on-click="{{fetchDataFromForm}}" >
</paper-button>
Finally in the scripts, add the function for send data to angular
For example
Polymer('name-element', {
fetchDataFromForm: function() {
USER_DATA = this.valData;
console.log(USER_DATA);
var scope = angular.element($("#angular-controller")).scope();
scope.$apply(function(){
scope.contacto = { varAngular: USER_DATA };
console.log(scope.contacto);
scope.angularFunction();
});
}
}
In Angular ... usually done
I hope to help you in something
Regards