The uploader component works with HTML form like default file input. The following configuration is must to make the uploader work inside the form.
* `saveUrl` and `removeUrl` must be null.
* `autoUpload` must be disabled.
* `name` attribute must be added in input element.
The selected or dropped files are received as a collection in form action when the form is submitted. The form action handles the server-side operations that manage the file upload process. When you reset the form, the file list and data will be cleared.
import { Component, ViewChild } from '@angular/core';
import { EmitType } from '@syncfusion/ej2-base';
import { Dialog } from '@syncfusion/ej2-popups';
import { FormValidator, FormValidatorModel } from '@syncfusion/ej2-inputs';
/**
* Default Uploader Default Component
*/
@Component({
selector: 'app-root',
templateUrl: 'formsupport.html',
styleUrls: ['formsupport.css']
})
export class AppComponent {
@ViewChild('Dialog')
public Dialog: DialogComponent;
public width: string = '335px';
public visible: boolean = false;
public content: string = 'Your details has been updated successfully, Thank you';
public target: string = '#control_wrapper';
public isModal: boolean = true;
public animationSettings: object = {
effect: 'Zoom'
}
public options: object = {
rules: {
'name': {
required: true
},
'email': {
required: true
},
'upload': {
required: true
}
}
}
@ViewChild('formElement') element: any;
ngAfterViewInit() {
let formObject: FormValidator = new FormValidator(this.element.nativeElement, this.options);
// validate all input elements in the form
}
browseClick() {
document.getElementsByClassName('e-file-select-wrap')[0].querySelector('button').click(); return false;
}
Submit() {
this.onFormSubmit();
}
public onFileSelect: EmitType<Object> = (args: any) => {
let inputElement: HTMLInputElement = document.getElementById('upload') as HTMLInputElement;
inputElement.value = args.filesData[0].name;
}
// Close the modal Dialog on overlay click
public overlayClick(): void {
this.Dialog.hide();
}
public onFormSubmit(): void {
let formObject: FormValidator = new FormValidator("#form1", this.options);
let formStatus: Boolean = formObject.validate();
if (formStatus) {
formObject.element.reset();
this.Dialog.show();
}
}
}
import { AppComponent } from './app.component';
import { HttpModule, JsonpModule } from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import 'rxjs/add/operator/map';
import { NgModule, ModuleWithProviders, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { UploaderModule } from '@syncfusion/ej2-angular-inputs';
import { DialogModule } from '@syncfusion/ej2-angular-popups';
/**
* Module
*/
@NgModule({
imports: [
UploaderModule, DialogModule, FormsModule, HttpModule, JsonpModule, BrowserModule
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {
}
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';
enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
By using ngModel
directive, you can bind the model to the uploader in template-driven forms.
For more details, refer to the Angular Documentation
The following sample demonstrates how to render uploader component with required validation inside the template-driven forms.
import { Component, OnInit, ViewChild } from '@angular/core';
import { DialogComponent } from '@syncfusion/ej2-angular-popups';
import { EmitType } from '@syncfusion/ej2-base';
@Component({
selector: 'app-root',
template: `<div class="control-section">
<div class="col-lg-12">
<h4 class="form-title">Photo Contest</h4>
<div class="control_wrapper" id="control_wrapper" style="margin: 10px auto;">
<form id="template_driven" #userForm="ngForm" novalidate>
<div class="form-group" style="padding-top: 11px;">
<div class="e-float-input">
<input type="text" id="name" #nameval='ngModel' name="name" required ngModel>
<span class="e-float-line"></span>
<label class="e-float-text e-label-top" for="name">Name</label>
<div *ngIf="(nameval.invalid && (nameval.dirty || nameval.touched))">
<div class="e-error" *ngIf="nameval.errors.required">
* Enter your name
</div>
</div>
</div>
</div>
<div class="form-group" style="padding-top: 11px;">
<div class="e-float-input upload-area">
<input type="text" id="upload" #uploadval='ngModel' [(ngModel)]="uploadInput" readonly name="upload" required ngModel>
<button id="browse" class="e-control e-btn e-info" (click)='browseClick()'>Browse...</button>
<span class="e-float-line"></span>
<label class="e-float-text e-label-top" for="upload">Choose a file</label>
<div *ngIf="(uploadval.invalid && (uploadval.dirty || uploadval.touched))">
<div class="e-error" *ngIf="uploadval.errors.required">
* Select a file
</div>
</div>
</div>
<ejs-uploader #defaultupload id='fileupload' allowedExtensions="image/*" [autoUpload]=false [multiple]='multiple' (selected)='onFileSelect($event)'></ejs-uploader>
</div>
<div class="form-group" style="padding-top: 11px;">
<div class="submitBtn">
<button class="submit-btn e-btn" id="submit-btn" [disabled]="userForm.invalid" type="reset" (click)= "Submit()">Submit</button>
<div class="desc"><span>*This button is not a submit type and the form submit handled from externally.</span></div>
</div>
</div>
</form>
<ejs-dialog id="confirmationDialog" #Dialog [buttons]='dlgButtons' [animationSettings]='animationSettings' [header]='formHeader' [showCloseIcon]='showCloseIcon' [content]='content' [target]='target' [width]='width' [visible]="visible" [isModal]="isModal" >
</ejs-dialog>
</div>
</div>
</div>`
})
export class AppComponent {
@ViewChild('Dialog')
public dialogObj: DialogComponent;
public width: string = '335px';
public visible: boolean = false;
public multiple: boolean = false;
public showCloseIcon: Boolean = true;
public formHeader: string = 'Success';
public content: string = 'Your details have been updated successfully, Thank you.';
public target: string = '#control_wrapper';
public isModal: boolean = true;
public animationSettings: object = {
effect: 'Zoom'
};
public uploadInput: string = '';
public dlgBtnClick: EmitType<object> = () => {
this.dialogObj.hide();
}
public dlgButtons: Object[] = [{ click: this.dlgBtnClick.bind(this), buttonModel: { content: 'Ok', isPrimary: true } }];
@ViewChild('formElement') element: any;
public browseClick() {
document.getElementsByClassName('e-file-select-wrap')[0].querySelector('button').click(); return false;
}
public Submit(): void {
this.onFormSubmit();
}
public onFileSelect: EmitType<Object> = (args: any) => {
this.uploadInput = args.filesData[0].name;
}
public onFormSubmit(): void {
this.dialogObj.show();
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DialogModule } from '@syncfusion/ej2-angular-popups';
import { UploaderModule } from '@syncfusion/ej2-angular-inputs';
@NgModule({
imports: [ BrowserModule, FormsModule, DialogModule, UploaderModule, ButtonModule, ReactiveFormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
// Ensure Angular destroys itself on hot reloads.
if (window['ngRef']) {
window['ngRef'].destroy();
}
window['ngRef'] = ref;
// Otherwise, log the boot error
}).catch(err => console.error(err));
#container {
visibility: hidden;
}
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}.control_wrapper {
max-width: 500px;
min-width: 245px;
margin: auto;
}
.address-field {
resize: none;
}
.e-error {
padding-top: 7px;
}
#control_wrapper {
max-width: 500px;
margin: auto;
border: 0.5px solid #BEBEBE;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.36);
padding: 1% 4% 0%;
background: #f9f9f9;
}
.highcontrast #control_wrapper {
background: #000000;
}
#template_driven .upload-area {
width: 100%;
}
#template_driven .form-group .submit-btn {
margin-top: 15px;
position: relative;
}
#template_driven .form-group .desc {
margin: 2% 23% 0% 18%;
}
@media only screen and (max-width: 500px) {
#template_driven .form-group .submitBtn .desc {
margin: 12px;
}
}
#template_driven .form-group .submitBtn {
position: relative;
text-align: center;
}
.bootstrap #template_driven .form-group .submit-btn {
margin-left: 8px;
}
.e-bigger.material #template_driven .form-group .submit-btn {
margin-left: -7px;
}
.fabric #template_driven .form-group .submit-btn, .highcontrast #template_driven .form-group .submit-btn {
margin-left: -11px;
}
.e-bigger.fabric #template_driven .form-group .submit-btn, .e-bigger.highcontrast #template_driven .form-group .submit-btn {
margin-left: -25px;
}
.e-bigger.bootstrap #template_driven .form-group .submit-btn {
margin-left: -8px;
}
.success .successmsg {
border: 0.5px solid green;
padding: 10%;
color: green;
}
form#template_driven {
position: relative;
top: 14%;
}
.material #template_driven .form-group .e-upload, #template_driven .form-group .e-upload {
display: none;
}
#template_driven .upload-area button#browse {
float: right;
margin-top: -28px;
}
.fabric #template_driven .upload-area button#browse,
.highcontrast #template_driven .upload-area button#browse {
float: right;
margin-top: -32px;
}
.bootstrap #template_driven .upload-area button#browse {
float: right;
margin-top: -35px;
}
.fabric.e-bigger #template_driven .upload-area button#browse,
.highcontrast.e-bigger #template_driven .upload-area button#browse,
.bootstrap.e-bigger #template_driven .upload-area button#browse {
margin-top: -40px;
}
.material.e-bigger #template_driven .upload-area button#browse {
margin-top: -36px;
}
.b
#template_driven .form-group .e-float-input.upload-area .e-float-line, .material .e-float-input.upload-area .e-float-line {
width: 70%;
margin-top: initial;
}
#template_driven .form-group .upload-area input {
width: 70%;
}
@media (min-width: 250px) and (max-width: 500px) {
#control_wrapper.control_wrapper {
padding: 1% 4% 12%;
}
}
@media (max-width: 300px) {
#control_wrapper.control_wrapper {
padding: 1% 4% 15%;
}
}
.bootstrap #template_driven .form-group .upload-area {
background: transparent;
}
.form-title {
text-align: center;
}
You can render the uploader component inside the reactive forms.
The reactive forms rendered with the help of FormGroup
.
For more details, refer to the Angular Documentation
The following sample demonstrates how to render uploader component with required validation inside the reactive forms
.
import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
import { EmitType } from '@syncfusion/ej2-base';
import { DialogComponent } from '@syncfusion/ej2-angular-popups';
@Component({
selector: 'app-root',
template: `<div class="control-section">
<div class="col-lg-12">
<h4 class="form-title">Photo Contest</h4>
<div class="control_wrapper" id="control_wrapper" style="margin: 25px auto;">
<form id="reactive" [formGroup]="form">
<div class="form-group" style="padding-top: 11px;">
<div class="e-float-input">
<input type="text" id="name" name="name" class="required" formControlName="name">
<span class="e-float-line"></span>
<label class="e-float-text e-label-top" for="name">Name</label>
</div>
<app-field-error-display [displayError]="isFieldValid('name')" errorMsg="* Please Enter your name">
</app-field-error-display>
</div>
<div class="form-group" style="padding-top: 11px;">
<div class="e-float-input upload-area">
<input type="text" id="upload" name="upload" [(ngModel)]="uploadInput" readonly formControlName="upload" class="required">
<button id="browse" class="e-control e-btn e-info" (click)='browseClick()'>Browse...</button>
<span class="e-float-line"></span>
<label class="e-float-text e-label-top" for="upload">Choose a file</label>
</div>
<app-field-error-display [displayError]="isFieldValid('upload')" errorMsg="* Select any file">
</app-field-error-display>
<ejs-uploader #defaultupload id='fileupload' allowedExtensions="image/*" [autoUpload]=false [multiple]='multiple' (selected)='onFileSelect($event)'></ejs-uploader>
</div>
<div class="form-group" style="padding-top: 11px;">
<div class="submitBtn">
<button class="submit-btn e-btn" id="submit-btn" [disabled]="form.invalid" (click)= "Submit()">Submit</button>
<div class="desc"><span>*This button is not a submit type and the form submit handled from externally.</span></div>
</div>
</div>
</form>
<ejs-dialog id="confirmationDialog" #Dialog [buttons]='dlgButtons' [animationSettings]='animationSettings' [header]='formHeader' [showCloseIcon]='showCloseIcon' [content]='content' [target]='target' [width]='width' [visible]="visible" [isModal]="isModal" >
</ejs-dialog>
</div>
</div>
</div>`
})
export class AppComponent {
@ViewChild('Dialog')
public dialogObj: DialogComponent;
public form: FormGroup;
public width: string = '335px';
public visible: boolean = false;
public multiple: boolean = false;
public showCloseIcon: Boolean = true;
public formHeader: string = 'Success';
public content: string = 'Your details have been updated successfully, Thank you.';
public target: string = '#control_wrapper';
public isModal: boolean = true;
public animationSettings: any = {
effect: 'Zoom'
};
private formSumitAttempt: boolean;
public dlgBtnClick: EmitType<object> = () => {
this.dialogObj.hide();
}
public dlgButtons: Object[] = [{ click: this.dlgBtnClick.bind(this), buttonModel: { content: 'Ok', isPrimary: true } }];
public uploadInput: string = '';
public browseClick() {
document.getElementsByClassName('e-file-select-wrap')[0].querySelector('button').click(); return false;
}
public Submit(): void {
this.onFormSubmit();
}
public onFileSelect: EmitType<Object> = (args: any) => {
this.uploadInput = args.filesData[0].name;
}
public onFormSubmit(): void {
this.formSumitAttempt = true;
if (this.form.valid) {
this.dialogObj.show();
this.form.reset();
} else {
this.validateAllFormFields(this.form);
}
}
constructor(@Inject(FormBuilder) public formBuilder: FormBuilder) {}
ngOnInit() {
this.form = this.formBuilder.group({
name: [null, Validators.required],
upload: [null, Validators.required],
});
}
isFieldValid(field: string) {
return ((!this.form.get(field).valid && this.form.get(field).touched) ||
(this.form.get(field).untouched && this.formSumitAttempt));
}
validateAllFormFields(formGroup: FormGroup) {
Object.keys(formGroup.controls).forEach(field => {
const control = formGroup.get(field);
if (control instanceof FormControl) {
control.markAsTouched({ onlySelf: true });
} else if (control instanceof FormGroup) {
this.validateAllFormFields(control);
}
});
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { UploaderModule } from '@syncfusion/ej2-angular-inputs';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DialogModule } from '@syncfusion/ej2-angular-popups';
import { FieldErrorDisplayComponent } from './field-error-display.component';
/**
* Module
*/
@NgModule({
imports: [ BrowserModule, FormsModule, DialogModule, UploaderModule, ButtonModule, ReactiveFormsModule ],
declarations: [ AppComponent, FieldErrorDisplayComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
import { Component, Input, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-field-error-display',
styleUrls: ['field-error-display.component.css'],
encapsulation: ViewEncapsulation.None,
template: `<div *ngIf="displayError" >
<div class="e-error">
{{ errorMsg }}
</div>
</div>`
})
export class FieldErrorDisplayComponent {
@Input() errorMsg: string;
@Input() displayError: boolean;
}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
// Ensure Angular destroys itself on hot reloads.
if (window['ngRef']) {
window['ngRef'].destroy();
}
window['ngRef'] = ref;
// Otherwise, log the boot error
}).catch(err => console.error(err));
#container {
visibility: hidden;
}
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.control_wrapper {
max-width: 500px;
min-width: 245px;
margin: auto;
}
.address-field {
resize: none;
}
#control_wrapper {
max-width: 500px;
margin: auto;
border: 0.5px solid #BEBEBE;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.36);
padding: 1% 4% 0%;
background: #f9f9f9;
}
.highcontrast #control_wrapper {
background: #000000;
}
#reactive .form-group .upload-area {
width: 100%;
}
.e-error {
padding-top:3px;
}
#reactive .form-group .submit-btn {
margin-top: 15px;
position: relative;
}
#reactive .form-group .submitBtn .desc {
margin: 2% 23% 0% 18%;
}
@media only screen and (max-width: 500px) {
#reactive .form-group .submitBtn .desc {
margin: 12px;
}
}
#reactive .form-group .submitBtn {
position: relative;
text-align: center;
}
.bootstrap #reactive .form-group .submit-btn {
margin-left: 8px;
}
.e-bigger.material #reactive .form-group .submit-btn {
margin-left: -7px;
}
.fabric #reactive .form-group .submit-btn, .highcontrast #reactive .form-group .submit-btn {
margin-left: -11px;
}
.e-bigger.fabric #reactive .form-group .submit-btn, .e-bigger.highcontrast #reactive .form-group .submit-btn {
margin-left: -25px;
}
.e-bigger.bootstrap #reactive .form-group .submit-btn {
margin-left: -8px;
}
.success .successmsg {
border: 0.5px solid green;
padding: 10%;
color: green;
}
form#reactive {
position: relative;
top: 14%;
}
.material #reactive .form-group .e-upload, #reactive .form-group .e-upload {
display: none;
}
#reactive .upload-area button#browse {
float: right;
margin-top: -28px;
}
.material.e-bigger #reactive .upload-area button#browse {
margin-top: -36px;
}
.fabric #reactive .upload-area button#browse,
.highcontrast #reactive .upload-area button#browse {
float: right;
margin-top: -32px;
}
.fabric.e-bigger #reactive .upload-area button#browse,
.highcontrast.e-bigger #reactive .upload-area button#browse,
.bootstrap.e-bigger #reactive .upload-area button#browse {
margin-top: -40px;
}
.bootstrap #reactive .upload-area button#browse {
float: right;
margin-top: -35px;
}
#reactive .form-group .e-float-input.upload-area .e-float-line, .material .e-float-input.upload-area .e-float-line {
width: 70%;
margin-top: initial;
}
#reactive .form-group .upload-area input {
width: 70%;
}
@media (min-width: 250px) and (max-width: 500px) {
#control_wrapper.control_wrapper {
padding: 1% 4% 12%;
}
}
@media (max-width: 300px) {
#control_wrapper.control_wrapper {
padding: 1% 4% 15%;
}
}
.bootstrap #reactive .form-group .upload-area {
background: transparent;
}
.form-title {
text-align: center;
}