ngx-file-required
Version:
Angular input file required directive
193 lines (187 loc) • 14.9 kB
JavaScript
import { Directive, ElementRef, Input, HostListener, NgModule } from '@angular/core';
import { NG_VALIDATORS } from '@angular/forms';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class NgxFileRequiredDirective {
/**
* @param {?} element
*/
constructor(element) {
this.requiredErrorMsg = 'File is required';
this._required = false;
this._multiple = false;
this._element = element;
}
/**
* @return {?}
*/
get required() {
return this._required || this._element.nativeElement.hasAttribute('required');
}
/**
* @param {?} value
* @return {?}
*/
set required(value) {
this._required = value || this._element.nativeElement.hasAttribute('required');
}
/**
* @return {?}
*/
get multiple() {
return this._element.nativeElement.hasAttribute('multiple');
}
/**
* @param {?} value
* @return {?}
*/
set multiple(value) {
this._multiple = value === '' || !!value;
}
/**
* @return {?}
*/
ngOnInit() {
this._mutationObserver = new MutationObserver((mutations) => {
this._setValidity(this._getInputValue(/** @type {?} */ (this._element.nativeElement)));
});
this._mutationObserver.observe(this._element.nativeElement, {
attributes: true,
attributeOldValue: true,
attributeFilter: ['required']
});
}
/**
* @return {?}
*/
ngOnDestroy() {
this._mutationObserver.disconnect();
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (this.required &&
(changes["requiredErrorMsg"] && !changes["requiredErrorMsg"].firstChange)) {
this._setValidity(this._getInputValue(/** @type {?} */ (this._element.nativeElement)));
}
}
/**
* @param {?} control
* @return {?}
*/
validate(control) {
if (!this._control) {
this._control = control;
}
if (this._hasError(this._control.value)) {
return /** @type {?} */ ({
required: this.requiredErrorMsg
});
}
}
/**
* @param {?} eventTarget
* @return {?}
*/
onChange(eventTarget) {
/** @type {?} */
const value = this._getInputValue(/** @type {?} */ (eventTarget));
this._setValidity(value);
}
/**
* @param {?} value
* @return {?}
*/
_setValidity(value) {
/** @type {?} */
const errors = Object.assign({}, this._control.errors);
if (this._hasError(value)) {
errors["required"] = this.requiredErrorMsg;
}
else {
if (this._control.hasError('required')) {
delete errors["required"];
}
}
this._control.setErrors(Object.keys(errors).length ? errors : null);
}
/**
* @param {?} value
* @return {?}
*/
_hasError(value) {
return this.required && !this._hasValue(value);
}
/**
* @param {?} value
* @return {?}
*/
_hasValue(value) {
return this.multiple ?
value instanceof FileList && !!value.length :
value instanceof File;
}
/**
* @param {?} eventTarget
* @return {?}
*/
_getInputValue(eventTarget) {
return this.multiple ? eventTarget.files : eventTarget.files.item(0);
}
}
NgxFileRequiredDirective.decorators = [
{ type: Directive, args: [{
selector: `
input[type="file"][attr.required][formControlName],
input[type="file"][attr.required][formControl],
input[type="file"][attr.required][ngModel],
input[type="file"][required][formControlName],
input[type="file"][required][formControl],
input[type="file"][required][ngModel]
`,
exportAs: 'ngxFileRequiredDirective',
providers: [
{
provide: NG_VALIDATORS,
useExisting: NgxFileRequiredDirective,
multi: true
}
]
},] },
];
/** @nocollapse */
NgxFileRequiredDirective.ctorParameters = () => [
{ type: ElementRef }
];
NgxFileRequiredDirective.propDecorators = {
requiredErrorMsg: [{ type: Input }],
multiple: [{ type: Input }],
onChange: [{ type: HostListener, args: ['change', ['$event.target'],] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class NgxFileRequiredModule {
}
NgxFileRequiredModule.decorators = [
{ type: NgModule, args: [{
imports: [],
declarations: [NgxFileRequiredDirective],
exports: [NgxFileRequiredDirective]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { NgxFileRequiredDirective, NgxFileRequiredModule };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWZpbGUtcmVxdWlyZWQuanMubWFwIiwic291cmNlcyI6WyJuZzovL25neC1maWxlLXJlcXVpcmVkL2xpYi9uZ3gtZmlsZS1yZXF1aXJlZC5kaXJlY3RpdmUudHMiLCJuZzovL25neC1maWxlLXJlcXVpcmVkL2xpYi9uZ3gtZmlsZS1yZXF1aXJlZC5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgT25Jbml0LFxuICBPbkRlc3Ryb3ksXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBJbnB1dCxcbiAgSG9zdExpc3RlbmVyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgTkdfVkFMSURBVE9SUyxcbiAgVmFsaWRhdG9yLFxuICBBYnN0cmFjdENvbnRyb2wsXG4gIFZhbGlkYXRpb25FcnJvcnNcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5leHBvcnQgdHlwZSBIVE1MRmlsZUlucHV0QXR0cmlidXRlID0gYW55IHwgYm9vbGVhbjtcbmludGVyZmFjZSBGaWxlSW5wdXRFdmVudFRhcmdldCBleHRlbmRzIEV2ZW50VGFyZ2V0IHtcbiAgZmlsZXM6IEZpbGVMaXN0O1xufVxuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6IGBcbiAgICBpbnB1dFt0eXBlPVwiZmlsZVwiXVthdHRyLnJlcXVpcmVkXVtmb3JtQ29udHJvbE5hbWVdLFxuICAgIGlucHV0W3R5cGU9XCJmaWxlXCJdW2F0dHIucmVxdWlyZWRdW2Zvcm1Db250cm9sXSxcbiAgICBpbnB1dFt0eXBlPVwiZmlsZVwiXVthdHRyLnJlcXVpcmVkXVtuZ01vZGVsXSxcbiAgICBpbnB1dFt0eXBlPVwiZmlsZVwiXVtyZXF1aXJlZF1bZm9ybUNvbnRyb2xOYW1lXSxcbiAgICBpbnB1dFt0eXBlPVwiZmlsZVwiXVtyZXF1aXJlZF1bZm9ybUNvbnRyb2xdLFxuICAgIGlucHV0W3R5cGU9XCJmaWxlXCJdW3JlcXVpcmVkXVtuZ01vZGVsXVxuICBgLFxuICBleHBvcnRBczogICduZ3hGaWxlUmVxdWlyZWREaXJlY3RpdmUnLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiAgICAgTkdfVkFMSURBVE9SUyxcbiAgICAgIHVzZUV4aXN0aW5nOiBOZ3hGaWxlUmVxdWlyZWREaXJlY3RpdmUsXG4gICAgICBtdWx0aTogICAgICAgdHJ1ZVxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBOZ3hGaWxlUmVxdWlyZWREaXJlY3RpdmUgaW1wbGVtZW50cyBWYWxpZGF0b3IsIE9uSW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuXG4gIHB1YmxpYyBnZXQgcmVxdWlyZWQoKTogSFRNTEZpbGVJbnB1dEF0dHJpYnV0ZSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlcXVpcmVkIHx8IHRoaXMuX2VsZW1lbnQubmF0aXZlRWxlbWVudC5oYXNBdHRyaWJ1dGUoJ3JlcXVpcmVkJyk7XG4gIH1cblxuICBwdWJsaWMgc2V0IHJlcXVpcmVkKHZhbHVlOiBIVE1MRmlsZUlucHV0QXR0cmlidXRlKSB7XG4gICAgdGhpcy5fcmVxdWlyZWQgPSB2YWx1ZSB8fCB0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuaGFzQXR0cmlidXRlKCdyZXF1aXJlZCcpO1xuICB9XG5cbiAgQElucHV0KClcbiAgcHVibGljIHJlcXVpcmVkRXJyb3JNc2cgPSAnRmlsZSBpcyByZXF1aXJlZCc7XG5cbiAgQElucHV0KClcbiAgcHVibGljIGdldCBtdWx0aXBsZSgpOiBIVE1MRmlsZUlucHV0QXR0cmlidXRlIHtcbiAgICByZXR1cm4gdGhpcy5fZWxlbWVudC5uYXRpdmVFbGVtZW50Lmhhc0F0dHJpYnV0ZSgnbXVsdGlwbGUnKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXQgbXVsdGlwbGUodmFsdWU6IEhUTUxGaWxlSW5wdXRBdHRyaWJ1dGUpIHtcbiAgICB0aGlzLl9tdWx0aXBsZSA9IHZhbHVlID09PSAnJyB8fCAhIXZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVxdWlyZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIF9tdWx0aXBsZSA9IGZhbHNlO1xuXG4gIHByaXZhdGUgX2VsZW1lbnQ6IEVsZW1lbnRSZWY7XG5cbiAgcHJpdmF0ZSBfY29udHJvbDogQWJzdHJhY3RDb250cm9sO1xuXG4gIHByaXZhdGUgX211dGF0aW9uT2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEVsZW1lbnRSZWYpIHtcbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9tdXRhdGlvbk9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKG11dGF0aW9uczogTXV0YXRpb25SZWNvcmRbXSk6IHZvaWQgPT4ge1xuICAgICAgdGhpcy5fc2V0VmFsaWRpdHkodGhpcy5fZ2V0SW5wdXRWYWx1ZSh0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQgYXMgRmlsZUlucHV0RXZlbnRUYXJnZXQpKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX211dGF0aW9uT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIHtcbiAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXG4gICAgICBhdHRyaWJ1dGVPbGRWYWx1ZTogdHJ1ZSxcbiAgICAgIGF0dHJpYnV0ZUZpbHRlcjogWydyZXF1aXJlZCddXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fbXV0YXRpb25PYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIHRoaXMucmVxdWlyZWQgJiZcbiAgICAgIChjaGFuZ2VzLnJlcXVpcmVkRXJyb3JNc2cgJiYgIWNoYW5nZXMucmVxdWlyZWRFcnJvck1zZy5maXJzdENoYW5nZSlcbiAgICApIHtcbiAgICAgIHRoaXMuX3NldFZhbGlkaXR5KHRoaXMuX2dldElucHV0VmFsdWUodGhpcy5fZWxlbWVudC5uYXRpdmVFbGVtZW50IGFzIEZpbGVJbnB1dEV2ZW50VGFyZ2V0KSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHZhbGlkYXRlKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMge1xuICAgIGlmICghdGhpcy5fY29udHJvbCkge1xuICAgICAgdGhpcy5fY29udHJvbCA9IGNvbnRyb2w7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2hhc0Vycm9yKHRoaXMuX2NvbnRyb2wudmFsdWUpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXF1aXJlZDogdGhpcy5yZXF1aXJlZEVycm9yTXNnXG4gICAgICB9IGFzIFZhbGlkYXRpb25FcnJvcnM7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignY2hhbmdlJywgWyckZXZlbnQudGFyZ2V0J10pXG4gIHB1YmxpYyBvbkNoYW5nZShldmVudFRhcmdldDogRXZlbnRUYXJnZXQpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZTogRmlsZXxGaWxlTGlzdHx1bmRlZmluZWQgPSB0aGlzLl9nZXRJbnB1dFZhbHVlKGV2ZW50VGFyZ2V0IGFzIEZpbGVJbnB1dEV2ZW50VGFyZ2V0KTtcbiAgICB0aGlzLl9zZXRWYWxpZGl0eSh2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9zZXRWYWxpZGl0eSh2YWx1ZTogRmlsZXxGaWxlTGlzdHx1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBjb25zdCBlcnJvcnM6IFZhbGlkYXRpb25FcnJvcnMgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9jb250cm9sLmVycm9ycyk7XG5cbiAgICBpZiAodGhpcy5faGFzRXJyb3IodmFsdWUpKSB7XG4gICAgICBlcnJvcnMucmVxdWlyZWQgPSB0aGlzLnJlcXVpcmVkRXJyb3JNc2c7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLl9jb250cm9sLmhhc0Vycm9yKCdyZXF1aXJlZCcpKSB7XG4gICAgICAgIGRlbGV0ZSBlcnJvcnMucmVxdWlyZWQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fY29udHJvbC5zZXRFcnJvcnMoT2JqZWN0LmtleXMoZXJyb3JzKS5sZW5ndGggPyBlcnJvcnMgOiBudWxsKTtcbiAgfVxuXG4gIHByaXZhdGUgX2hhc0Vycm9yKHZhbHVlOiBGaWxlfEZpbGVMaXN0fHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVpcmVkICYmICF0aGlzLl9oYXNWYWx1ZSh2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9oYXNWYWx1ZSh2YWx1ZTogRmlsZXxGaWxlTGlzdHx1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tdWx0aXBsZSA/XG4gICAgICB2YWx1ZSBpbnN0YW5jZW9mIEZpbGVMaXN0ICYmICEhdmFsdWUubGVuZ3RoIDpcbiAgICAgIHZhbHVlIGluc3RhbmNlb2YgRmlsZTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldElucHV0VmFsdWUoZXZlbnRUYXJnZXQ6IEZpbGVJbnB1dEV2ZW50VGFyZ2V0KTogRmlsZXxGaWxlTGlzdHx1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm11bHRpcGxlID8gZXZlbnRUYXJnZXQuZmlsZXMgOiBldmVudFRhcmdldC5maWxlcy5pdGVtKDApO1xuICB9XG5cbn1cbiIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ3hGaWxlUmVxdWlyZWREaXJlY3RpdmUgfSBmcm9tICcuL25neC1maWxlLXJlcXVpcmVkLmRpcmVjdGl2ZSc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgXSxcbiAgZGVjbGFyYXRpb25zOiBbTmd4RmlsZVJlcXVpcmVkRGlyZWN0aXZlXSxcbiAgZXhwb3J0czogW05neEZpbGVSZXF1aXJlZERpcmVjdGl2ZV1cbn0pXG5leHBvcnQgY2xhc3MgTmd4RmlsZVJlcXVpcmVkTW9kdWxlIHsgfVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztnQkF3RXFCLE9BQW1CO2dDQXJCWixrQkFBa0I7eUJBV3hCLEtBQUs7eUJBRUwsS0FBSztRQVN2QixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQzs7Ozs7UUEvQmYsUUFBUTtRQUNqQixPQUFPLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDOzs7Ozs7UUFHckUsUUFBUSxDQUFDLEtBQTZCO1FBQy9DLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQzs7Ozs7SUFNakYsSUFDVyxRQUFRO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBQzdEOzs7OztRQUVVLFFBQVEsQ0FBQyxLQUE2QjtRQUMvQyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQzs7Ozs7SUFpQnBDLFFBQVE7UUFDYixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxDQUFDLFNBQTJCO1lBQ3hFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGNBQWMsbUJBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFxQyxFQUFDLENBQUMsQ0FBQztTQUM3RixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFO1lBQzFELFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGlCQUFpQixFQUFFLElBQUk7WUFDdkIsZUFBZSxFQUFFLENB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