I want to submit the form on the button click as well as navigate to the next page, but it shows an error : "Form submission canceled because the form is not connected".
Can anyone help me with this problem ?? I am using nebular.
This is the html code
<nb-step [label]="labelOne" [stepControl]="formOne">
<ng-template #labelOne>Device type</ng-template>
<form class="form-inline" #formOne="ngForm" >
// Code goes here...
<div class="buttonHolder">
<button nbButton routerLink="/dashboard" nbStepperNext>Cancel</button>
<button nbButton outline status="primary" (ngSubmit)="onSubmit(formOne)"
nbStepperNext [disabled]="!formOne.valid">Next</button>
</div>
</form>
</nb-step>`
This is the .ts code
onSubmit(form: NgForm) { console.log(form.value); form.reset(); }
To change page after submitting the form try to import Router and register it in constructor(private _router: Router) in your .ts file.
At the end of onSubmit() method add this._router.navigateByUrl('/pathOfYourNextPage'); and in this way you'll make redirect throught your .ts file.
Hope that will help!
You can try to below way
ts file
onSubmit(formOne: NgForm) {
console.log(formOne.value);
this._router.navigate(['/navigation page link']); // navigation url link
formOne.reset();
}
constructor(){
private _router: Router,
}
HTML file
<nb-step [label]="labelOne" [stepControl]="formOne">
<ng-template #labelOne>Device type</ng-template>
<form class="form-inline" #formOne="ngForm" (ngSubmit)="onSubmit(formOne)" >
// Code goes here...
<div class="buttonHolder">
<button nbButton routerLink="/dashboard" nbStepperNext>Cancel</button>
<button nbButton type= "submit" outline status="primary"
nbStepperNext [disabled]="!formOne.valid">Next</button>
</div>
</form>
Related
I am trying to close modal from home component.my close button is in home component.If i click close button i want to close modal.If i click close button from home component how to set visible value is false from home component. How can i use service for that? or any other way is there? How do it?
dialog.component.html
<div [#dialog] *ngIf="visible" class="dialog">
<ng-content></ng-content>
<button *ngIf="closable" (click)="close()" aria-label="Close" class="dialog__close-btn">X</button>
<app-home></app-home>
</div>
<div *ngIf="visible" class="overlay" (click)="close()"></div>
home.component.ts:
<button (click)="showDialog = !showDialog" class="btn">Close</button>
Demo: https://stackblitz.com/edit/angular-7zdnwy?file=src%2Fapp%2Fdialog%2Fdialog.component.html
I followed this approach from Angular Documentation and it works ok.
You Parent is Dialog and child is app-home. So emitter is defined in child class like this
export class HomeComponent implements OnInit {
#Output() close = new EventEmitter<boolean>();
...
// <button (click)="onClose()" in html
onClose() {
this.close.emit(true)
}
}
and listen for the event in parent dialog class like this
// html
<app-home (close)="onCloseClick($event)"></app-home>
// Class code
export class DialogComponent implements OnInit {
...
onCloseClick(close: Boolean) {
if(close){
this.close()
}
}
...
}
Hope it helps.
I am working on a angular application, currently to upload a file I am using this :
<label class="btn btn-default">
<input type="file" (change)="selectFile($event)">
</label>
<button class="btn btn-success" [disabled]="!selectedFiles"
(click)="upload()">Upload</button>
with methods on my .ts file, it is working well.
I want to upgrade this to material angular components raised button like that right now :
<button mat-raised-button>
<input type="file" (change)="selectFile($event)">
</button>
<button mat-button disabled [disabled]="!selectedFiles" (click)="upload()">Upload</button>
the disabled button is doing well but the input file part doesnt work , it prints baddly and does not open a file folder search window. any ideas?
Won't advise using input field within a button, better you hide the file input and then a button to trigger it. The below example will show a minimal example of it
#Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}} is for Uploading</h2>
</div>
<button mat-raised-button (click)="openInput()">
Select File to Upload
</button>
<input id="fileInput" hidden type="file" (change)="fileChange($event.target.files)" >
<button mat-button [disabled]="!ourFile" (click)="upload()">Upload</button>
`
})
export class App {
name:string;
ourFile: File; // hold our file
constructor() {
this.name = `Angular! v${VERSION.full}`
}
/**
* this is used to trigger the input
*/
openInput(){
// your can use ElementRef for this later
document.getElementById("fileInput").click();
}
fileChange(files: File[]) {
if (files.length > 0) {
this.ourFile = files[0];
}
}
/**
* this is used to perform the actual upload
*/
upload() {
console.log('sending this to server', this.ourFile);
}
}
Check this plnk
With the above example, you should be able to style your button without distorting HTML semantics
I am trying to fire click event (or any other event) on element programatically , In other word I want to know the similar features as offered by jQuery .trigger() method in angular2.
Is there any built in method to do this? ..... if not please suggest how can i do this
Consider the following code fragment
<form [ngFormModel]="imgUploadFrm"
(ngSubmit)="onSubmit(imgUploadFrm)">
<br>
<div class="input-field">
<input type="file" id="imgFile" (click)="onChange($event)" >
</div>
<button id="btnAdd" type="submit" (click)="showImageBrowseDlg()" )>Add Picture</button>
</form>
Here when user click the btnAdd it should fire the click event on imgFile
Angular4
Instead of
this.renderer.invokeElementMethod(
this.fileInput.nativeElement, 'dispatchEvent', [event]);
use
this.fileInput.nativeElement.dispatchEvent(event);
because invokeElementMethod won't be part of the renderer anymore.
Angular2
Use ViewChild with a template variable to get a reference to the file input, then use the Renderer to invoke dispatchEvent to fire the event:
import { Component, Renderer, ElementRef, ViewChild } from '#angular/core';
#Component({
...
template: `
...
<input #fileInput type="file" id="imgFile" (click)="onChange($event)" >
...`
})
class MyComponent {
#ViewChild('fileInput') fileInput:ElementRef;
constructor(private renderer:Renderer) {}
showImageBrowseDlg() {
// from http://stackoverflow.com/a/32010791/217408
let event = new MouseEvent('click', {bubbles: true});
this.renderer.invokeElementMethod(
this.fileInput.nativeElement, 'dispatchEvent', [event]);
}
}
Update
Since direct DOM access isn't discouraged anymore by the Angular team this simpler code can be used as well
this.fileInput.nativeElement.click()
See also https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
I also wanted similar functionality where I have a File Input Control with display:none and a Button control where I wanted to trigger click event of File Input Control when I click on the button, below is the code to do so
<input type="button" (click)="fileInput.click()" class="btn btn-primary" value="Add From File">
<input type="file" style="display:none;" #fileInput/>
as simple as that and it's working flawlessly...
This worked for me:
<button #loginButton ...
and inside the controller:
#ViewChild('loginButton') loginButton;
...
this.loginButton.getNativeElement().click();
To get the native reference to something like an ion-input, ry using this
#ViewChild('fileInput', { read: ElementRef }) fileInput: ElementRef;
and then
this.fileInput.nativeElement.querySelector('input').click()
Günter Zöchbauer's answer is the right one. Just consider adding the following line:
showImageBrowseDlg() {
// from http://stackoverflow.com/a/32010791/217408
let event = new MouseEvent('click', {bubbles: true});
event.stopPropagation();
this.renderer.invokeElementMethod(
this.fileInput.nativeElement, 'dispatchEvent', [event]);
}
In my case I would get a "caught RangeError: Maximum call stack size exceeded" error if not. (I have a div card firing on click and the input file inside)
If you want to imitate click on the DOM element like this:
<a (click)="showLogin($event)">login</a>
and have something like this on the page:
<li ngbDropdown>
<a ngbDropdownToggle id="login-menu">
...
</a>
</li>
your function in component.ts should be like this:
showLogin(event) {
event.stopPropagation();
document.getElementById('login-menu').click();
}
I have used ng-csv-import to import a css file from desktop and i have submit button which uploads the csv. My requirements to disable the submit button until the user select a css file. Thanks in advance.
<ng-csv-import name="uploadCsv" content="MyCsv"
separator="csv.separator"
result="csv.results"
accept="csv.accept" required>
</ng-csv-import>
<div class="col-xs-12 col-sm-12">
<button type="submit" class="btn-top btn-rectangle" ng-click="submit()">Submit</button>
</div>
You could use ng-disabled on the button like so:
<button type="submit" class="btn-top btn-rectangle" ng-click="submit()" ng-disabled="yourDisabledVariable">Submit</button>
Then watch for the ng-csv-import content in your controller
//Default is disabled
$scope.yourDisabledVariable = true;
// Watch for changes on $scope.MyCsv
$scope.$watch('MyCsv', function(newVal,oldVal){
// see if user uploaded a csv by looking at $scope.MyCsv
if(newVal){
// Enable the button
$scope.yourDisabledVariable = false;
}
})
You can try this.
$('input[type="submit"]').prop('disabled', true);
$('input[type="text"]').keyup(function() {
if($(this).val() != '') {
$('input[type="submit"]').prop('disabled', false);
}
});
Why is this Upload File form example working in Index.html and does not work in any component.html file?
If i move it to any component.html clicking Add File does not even open the browse dialog.
<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">
<div id="drop">
<a>Add File</a> Drag and Drop
<input type="file" name="upl" />
</div>
<ul id="uploadList"></ul>
</form>
Edit: I must mention that i import the js files only in Index.html, and i'm not importing also in System.js or angular-cli.build.js
In Index.html one of the references is:
<script src="assets/js/uploadScript.js"></script>
And this is the code from uploadScript.js that should open the browser dialog:
$('#drop a').click(function(){
$(this).parent().find('input').click();
});
Your code in uploadScript.js is (I guess) initialized when the DOM is ready, thats basic how JQuery initialization works. But since your component is not yet in the DOM, nothing is found.
You need to put the initialization code directly into your component, so its called at the correct time, when the form is actually rendered in DOM.
Try to change your to component something like this:
import { Component, ElementRef } from '#angular/core';
// reference to jQuery
declare var $: any;
#Component({
selector: 'my-component',
template: `
<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">
<div id="drop">
<a (click)="addFile()">Add File</a> Drag and Drop
<input type="file" name="upl" />
</div>
<ul id="uploadList"></ul>
</form>
`
})
export class JQueryComponent
{
// get the ElementRef
constructor(private _elRef: ElementRef)
{
}
public addFile(): void
{
$(this._elRef.nativeElement).find('#drop a').parent().find('input').click();
}
}
The important part is to use Angular 2 (click) bound directly to the Add File anchor. ElementRef provides a reference to your html DOM element, which can be used to simulate actual click event on the input type="file"