Ionic 2 Updating Button Text and Event on Click - forms

Sorry if this sounds very obvious but I am new to Ionic 2 / Angular 2. Upon submitting a form, I need to update the button text and click event, ie:
first click on button = submit form + update button text to "Next"
second click on button = trigger goToNext()
I managed to update the button text but not update the click event (to goToNext() ).
.html
<form (ngSubmit)="logForm(i)">
<ion-item>
<ion-input type="text" [(ngModel)]="form.userinput[i]" name="userinput[i]"></ion-input>
</ion-item>
<button ion-button block type="submit" (click)="setNext($event.target, 'Next')">Check</button>
</form>
.ts
setNext(element, text){
element.textContent = 'Next';
}
goToNext(){
// go to Next Page
}

Ideally you change your design a bit to keep a variable that stores state of your 'Controller'. e.g. stores PageNumber. and then behave differently based on what page you are on. So I suggest change design a bit.
But to answer your current question without major change, you can bind the handler dynamically the same way you bind the text. then in the first handler, change the handler for the next click. the default values for handler and text will decide which one is going the be used initially
handler = this.setNext;
text = 'first text';
setNext(){
alert('handler1 called');
this.handler = this.goToNext;
this.text = 'other text';
}
goToNext(){
alert('second called');
// go to Next Page
}
and in your html you go like
<button ion-button block type="submit" (click)="handler()">{{text}}</button>

You can use n00b answer or something like this:
in html file:
<button ion-button block type="submit" (click)="check()">{{btn_txt}}</button>
in ts file:
btn_txt = 'Check';
check() {
if (this.btn_txt == 'Check') {
//do some logic
this.btn_txt = 'Next';
} else {
console.log('go to next page');
}
}

Related

Prevent closing browser tab when form is dirty in Angular 2

How to prevent closing browser tab when form is dirty in Angular 2?
My html body contains a component:
<body>
<my-app>Loading, please wait...</my-app>
</body>
which contains a router navigation and a router outlet:
<nav>
(...)
</nav>
<router-outlet></router-outlet>
and when the router navigates to the edit page, I have some form there:
<form #myForm="ngForm">
<button pButton type="text" label="Save" (click)="onSave()" [disabled]="!myForm.valid || myForm.pristine"></button>
</form>
Now, if the form is not 'pristine', I want to ask for confirmation when the user tries to close the browser tab:
window.onbeforeunload = function() {
if (form.dirty) {
return "You have unsaved data changes. Are you sure to close the page?"
}
}
How can I access the dirty state of Angular form in canonical way from there? I could register an event to field change on each field and set the global dirty flag, but I'd have to put that code on every from and by every navigation and then maintain that code so that the message stays consistent. Is there any other way to check out if there's an angular form on the page, which is in dirty state?
Perhaps
#HostListener('window:beforeunload', ['$event'])
handleBeforeUnload(event) {
if (connected) {
return "You have unsaved data changes. Are you sure to close the page?"
}
}
Add a Hostlistener decorator. If there are unsaved changes on the form confirm dialog appears.
#HostListener('window:beforeunload', ['$event'])
handleBeforeUnload(event: Event) {
event.returnValue = false;
}
This works. Implement the hasUnsavedData() function accordingly.
hasUnsavedData(){
return this.myForm.dirty;
}
#HostListener('window:beforeunload', ['$event'])
handleBeforeUnload($event: any) {
if (this.hasUnsavedData()) {
$event.returnValue = true;
}
}
Simply you can use Jquery to get state of ng-form.
#HostListener('window:beforeunload', ['$event'])
beforeUnloadHandler(event) {
if($('form').hasClass('ng-touched')) { //You can check with ng-dirty based on your requirements.
let confirmMessage = 'You have unsaved data changes. Are you sure to close the page?'
event.returnValue = confirmMessage;
return confirmMessage;
}
}
In my case am just showing warning dialog if that the form has been touched.
Try this directive https://github.com/extremeprog-com/ng-prevent-navigation.
So it should be simple
<div ng-prevent-navigation="vm.pageShouldBeReloaded"
ng-prevent-navigation-text="Payment form has unsaved changes.
If you leave the page now you will lose those changes."
></div>

Cancel a file upload in ng-file-upload

I have ng-file-upload with form submit running. I would like to add a button to cancel the upload after the user selects a file.
I have tried:
<button class= "btn btn-warning btn-cancel" ng-disabled="!myForm.$valid"
ng-click="cancelPic(picFile)">Cancel</button>
and in the controller:
$scope.cancelPic = function() {
myForm.reset();
file: '';
}
The form does seem to reset as I get a "please select a file" message but the image remains - in the dev tools Elements:
<img ng-show="myForm.file.$valid" ngf-src="!picFile.$error && picFile" class="thumb" src="blob:http%3A//localhost%3A3000/85f1b27c-a92e-447d-b760-8cfe17bbd6b7" style="">
Obviously I'm barking up the wrong tree here. Can anyone help?
Ok I found what I sought at:
https://github.com/danialfarid/ng-file-upload/issues/12
The code that works is:
$scope.cancelPic = function(file) {
myForm.reset();
$scope.picFile = undefined;
}
Now I need to apply this to individual images so a user can choose which to cancel and not reset the whole form. That's for another day.

AngularJS and Tab Order (Disabled Buttons)

I have a form, and I'm navigating only with TAB. Tab order should be input > select > button, but because of the ng-disable on the SUBMIT, on certain browsers the TAB out of the select will kick you somewhere else.
HTML
<div ng-app="myApp">
<div ng-controller="FirstCtrl">
<form name="myForm" ng-submit="submit()" novalidate>
First Name: <input type="text" ng-model="Data.FirstName" required><br>
Last Name: <select ng-model="Data.LastName" required>
<option value="Bigglesworth">Bigglesworth</option>
<option value="Burgermeister">Burgermeister</option>
</select><br>
<input type="submit" value="Submit" ng-disabled="myForm.$invalid" />
</form>
</div>
</div>
JS
var myApp = angular.module('myApp', []);
myApp.factory('Data', function(){
return {
FirstName: '',
LastName: ''
};
});
myApp.controller('FirstCtrl', function( $scope, Data ){
$scope.Data = Data;
$scope.submit = function() {
console.log('you just submitted, foolio');
}
});
JsFiddle here.
On Mac FF the final tab kicks you to the address bar before enabling the submit button. Mac Chrome works as you'd expect, focusing on the submit button after final tab. I know Windows is janky, but don't have exact specs to post.
Thoughts? How can I do this in a fool-proof fashion?
EDIT
I've selected #David B.'s answer as it's the best Angular solution. I ended up using a somewhat hidden element right after the the submit button so the focus would stay in the same general area. Lame and hacky, I know, but for a tight deadline it worked.
<h3><button class="fakebtn_hack">Confirmation</button></h3>
<style>.fakebtn_hack {background:none; border:none; color: #FF6319; cursor: default; font-size: 1em; padding: 0;}</style>
This happens because Firefox doesn't send a change event on key-driven changes of the select. Angular doesn't see the change until the tab is hit, so the submit button isn't enabled until after the tab has been processed by the browser (and focus sent to some other element, e.g., the address bar). The W3C standard suggests not sending the event until the control loses focus, although Chrome sends one for any change and Firefox does if the change was mouse-driven.
See the angularjs issue tracker for more: https://github.com/angular/angular.js/issues/4216
As suggested in the issue tracker, solve it by manually issuing the change event via the following select directive (http://jsfiddle.net/j5ZzE/):
myApp.directive("select", function () {
return {
restrict: "E",
require: "?ngModel",
scope: false,
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
return;
}
element.bind("keyup", function () {
element.trigger("change");
})
}
}
})
You'll need JQuery loaded before AngularJS to have the trigger function available on the element object.
Manually include an empty option (<option value=""></option>) in your select or the first option will be auto-selected when the control receives focus.
Unlike the default behavior, this empty option will not disappear after selecting a real option. I suppose you could remove the empty option by declaring all the options via ng-options or ng-repeat and then removing the empty one from the bound scope once a real option has been selected, but I've never tried it.

jQuery Stop .blur() event when clicking "submit" button

I am building a small landing page with a simple demo e-mail signup form. I want to have the form field open up when focused, and then shrink back down on blur.
However the problem I'm facing is when you click the submit button this instigates the blur function, hiding the button and shrinking the form. I need to find a way to stop the .blur() method only when the user is clicking to focus on the submit button. Is there any good workaround for this?
Would appreciate any help I can get!
I know this question is old but the simplest way to do it would be to check event.relatedTarget. The first part of the if statement is to prevent throwing an error if relatedTarget is null (the IF will short circuit because null is equivalent to false and the browser knows that it doesn't have to check the second condition if the first condition is false in an && statement).
So:
if(event.relatedTarget && event.relatedTarget.type!="submit"){
//do your animation
}
It isn't the prettiest solution, but it does work. Try this:
$("#submitbtn").mousedown(function() {
mousedownHappened = true;
});
$("#email").blur(function() {
if (mousedownHappened) // cancel the blur event
{
mousedownHappened = false;
}
else // blur event is okay
{
$("#email").animate({
opacity: 0.75,
width: '-=240px'
}, 500, function() {
});
// hide submit button
$("#submitbtn").fadeOut(400);
}
});​
DEMO HERE
Try this inside .blur handler:
if ($(':focus').is('#submitbtn')) { return false; }
why not rely on submit event instead of click? http://jsbin.com/ehujup/5/edit
just couple changes into the html and js
wrap inputs into the form and add required for email as it obviously suppose to be
<form id="form">
<div id="signup">
<input type="email" name="email" id="email" placeholder="me#email.com" tabindex="1" required="required">
<input type="submit" name="submit" id="submitbtn" value="Signup" class="submit-btn" tabindex="2">
</div>
</form>
in js, remove handler which listen #submitbtn
$("#submitbtn").on("click", function(e){
e.stopImmediatePropagation();
$("#signup").fadeOut(220);
});
and use instead submit form listerer
$("#form").on("submit", function(e){
$("#signup").fadeOut(220);
return false;
});
you may use $.ajax() to make it even better.
Doing this you gain point in terms of validation and the native browser's HTML5 validator will make check email format where it is supported.

Chrome extension - open multiple tabs after filling in the form

I am trying to create a chrome extension - when an user clicks on a icon, the popup window with the form appears. The textarea in the form can contain more parameters which comes to URL. After filling in and clicking the GO button, multiple tabs with URLs with this parameters needs to be opened.
Example: popup.html
<form name="myform">`
<textarea id="params" name="params" style="width: 170px;height: 270px;"></textarea>`
<input id="edit" checked="checked" type="radio" name="edit" value="1" /> option 1 <input id="edit" type="radio" name="edit" value="2" /> option 2`
<div id="clicked">GO</div>`
</form>`
Then in popup.js I have:
function click(e) {
chrome.tabs.executeScript(null, {
code: "alert('starting');"
});
opener();
}
document.addEventListener('DOMContentLoaded', function () {
var divs = document.getElementById("red");
divs.addEventListener('click', click);
});
So when an user clicks on GO button, the opener() function needs to be started.
Here is the opener function - it only determines the values of textarea and radio buttons and opens as many new tabs as manz parameters are in the textarea.
function opener() {
alert('working');
var parameter = document.myform.getElementById("params").value;
for (index = 0; index < document.myform.edit.length; index++) {
if (document.myform.edit[index].checked) {
var radioValue = document.myform.edit[index].value;
break;
}
var Result = parameter.split("\n");
if (radioValue == 1) {
for (i = 0; i < Result.length; i++) {
window.open('http://mypage.com?param=' + Result[i]);
}
}
}
}
So the Result is the value of textarea splitted by \n and radio value is the value of radio button selected.
This works fine - after clicking a browser icon the popup with form comes up, but when I fill in the textarea and select the first radiobutton, then I click GO, the opener funvtion works not...
The only thing that works is the popup alert with working word and then the alert starting from the click(e) function.
So the opener function starts, writes the alert, but nothing else... no tabs will open, nothing happens...
Can someone help me please?
I've found that using the chrome.tabs.create function works much better within the extension than the window.open function does.
chrome.tabs.create({url:"https://www.facebook.com/PSChrome"});