mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
#632 date widget (basic implementation)
This commit is contained in:
parent
a00a1441d8
commit
b2e40162c6
@ -19,6 +19,7 @@
|
|||||||
<!-- Polyfill(s) for Safari (pre-10.x) -->
|
<!-- Polyfill(s) for Safari (pre-10.x) -->
|
||||||
<script src="node_modules/intl/dist/Intl.min.js"></script>
|
<script src="node_modules/intl/dist/Intl.min.js"></script>
|
||||||
<script src="node_modules/intl/locale-data/jsonp/en.js"></script>
|
<script src="node_modules/intl/locale-data/jsonp/en.js"></script>
|
||||||
|
<script src="node_modules/moment/min/moment.min.js"></script>
|
||||||
|
|
||||||
<!-- Polyfill(s) for older browsers -->
|
<!-- Polyfill(s) for older browsers -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
@ -73,6 +73,8 @@
|
|||||||
"pdfjs-dist": "1.5.404",
|
"pdfjs-dist": "1.5.404",
|
||||||
"flag-icon-css": "2.3.0",
|
"flag-icon-css": "2.3.0",
|
||||||
"intl": "1.2.4",
|
"intl": "1.2.4",
|
||||||
|
"moment": "2.15.1",
|
||||||
|
|
||||||
"alfresco-js-api": "^0.3.0",
|
"alfresco-js-api": "^0.3.0",
|
||||||
"ng2-alfresco-core": "0.3.2",
|
"ng2-alfresco-core": "0.3.2",
|
||||||
"ng2-alfresco-datatable": "0.3.2",
|
"ng2-alfresco-datatable": "0.3.2",
|
||||||
|
@ -60,8 +60,10 @@
|
|||||||
"systemjs": "0.19.27",
|
"systemjs": "0.19.27",
|
||||||
"zone.js": "^0.6.23",
|
"zone.js": "^0.6.23",
|
||||||
|
|
||||||
"alfresco-js-api": "^0.3.0",
|
|
||||||
"ng2-translate": "2.5.0",
|
"ng2-translate": "2.5.0",
|
||||||
|
"moment": "2.15.1",
|
||||||
|
|
||||||
|
"alfresco-js-api": "^0.3.0",
|
||||||
"ng2-alfresco-core": "0.3.2"
|
"ng2-alfresco-core": "0.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -56,6 +56,9 @@
|
|||||||
<div *ngSwitchCase="'people'">
|
<div *ngSwitchCase="'people'">
|
||||||
<people-widget [field]="field" (fieldChanged)="fieldChanged($event);"></people-widget>
|
<people-widget [field]="field" (fieldChanged)="fieldChanged($event);"></people-widget>
|
||||||
</div>
|
</div>
|
||||||
|
<div *ngSwitchCase="'date'">
|
||||||
|
<date-widget [field]="field" (fieldChanged)="fieldChanged($event);"></date-widget>
|
||||||
|
</div>
|
||||||
<div *ngSwitchDefault>
|
<div *ngSwitchDefault>
|
||||||
<span>UNKNOWN WIDGET TYPE: {{field.type}}</span>
|
<span>UNKNOWN WIDGET TYPE: {{field.type}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,6 +31,7 @@ export class FormFieldTypes {
|
|||||||
static PEOPLE: string = 'people';
|
static PEOPLE: string = 'people';
|
||||||
static BOOLEAN: string = 'boolean';
|
static BOOLEAN: string = 'boolean';
|
||||||
static NUMBER: string = 'integer';
|
static NUMBER: string = 'integer';
|
||||||
|
static DATE: string = 'date';
|
||||||
|
|
||||||
static READONLY_TYPES: string[] = [
|
static READONLY_TYPES: string[] = [
|
||||||
FormFieldTypes.HYPERLINK,
|
FormFieldTypes.HYPERLINK,
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
import { FormFieldModel } from './form-field.model';
|
import { FormFieldModel } from './form-field.model';
|
||||||
import { FormFieldTypes } from './form-field-types';
|
import { FormFieldTypes } from './form-field-types';
|
||||||
|
|
||||||
|
declare var moment: any;
|
||||||
|
|
||||||
export interface FormFieldValidator {
|
export interface FormFieldValidator {
|
||||||
|
|
||||||
isSupported(field: FormFieldModel): boolean;
|
isSupported(field: FormFieldModel): boolean;
|
||||||
@ -107,6 +109,106 @@ export class NumberFieldValidator implements FormFieldValidator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DateFieldValidator implements FormFieldValidator {
|
||||||
|
|
||||||
|
private supportedTypes = [
|
||||||
|
FormFieldTypes.DATE
|
||||||
|
];
|
||||||
|
|
||||||
|
// Validates that the input string is a valid date formatted as <dateFormat> (default D-M-YYYY)
|
||||||
|
static isValidDate(dateString: string, dateFormat: string = 'D-M-YYYY'): boolean {
|
||||||
|
if (dateString) {
|
||||||
|
let d = moment(dateString.split('T')[0], dateFormat, true);
|
||||||
|
return d.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isSupported(field: FormFieldModel): boolean {
|
||||||
|
return field && this.supportedTypes.indexOf(field.type) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
validate(field: FormFieldModel): boolean {
|
||||||
|
if (this.isSupported(field) && field.value) {
|
||||||
|
if (DateFieldValidator.isValidDate(field.value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
field.validationSummary = 'Invalid date format';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MinDateFieldValidator implements FormFieldValidator {
|
||||||
|
|
||||||
|
private supportedTypes = [
|
||||||
|
FormFieldTypes.DATE
|
||||||
|
];
|
||||||
|
|
||||||
|
isSupported(field: FormFieldModel): boolean {
|
||||||
|
return field &&
|
||||||
|
this.supportedTypes.indexOf(field.type) > -1 &&
|
||||||
|
!!field.minValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
validate(field: FormFieldModel): boolean {
|
||||||
|
if (this.isSupported(field) && field.value) {
|
||||||
|
const dateFormat = 'D-M-YYYY';
|
||||||
|
|
||||||
|
if (!DateFieldValidator.isValidDate(field.value, dateFormat)) {
|
||||||
|
field.validationSummary = 'Invalid date format';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove time and timezone info
|
||||||
|
let d = moment(field.value.split('T')[0], dateFormat);
|
||||||
|
let min = moment(field.minValue, dateFormat);
|
||||||
|
|
||||||
|
if (d.isBefore(min)) {
|
||||||
|
field.validationSummary = `Should not be less than ${field.minValue}`;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MaxDateFieldValidator implements FormFieldValidator {
|
||||||
|
|
||||||
|
private supportedTypes = [
|
||||||
|
FormFieldTypes.DATE
|
||||||
|
];
|
||||||
|
|
||||||
|
isSupported(field: FormFieldModel): boolean {
|
||||||
|
return field &&
|
||||||
|
this.supportedTypes.indexOf(field.type) > -1 &&
|
||||||
|
!!field.maxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
validate(field: FormFieldModel): boolean {
|
||||||
|
if (this.isSupported(field) && field.value) {
|
||||||
|
const dateFormat = 'D-M-YYYY';
|
||||||
|
|
||||||
|
if (!DateFieldValidator.isValidDate(field.value, dateFormat)) {
|
||||||
|
field.validationSummary = 'Invalid date format';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove time and timezone info
|
||||||
|
let d = moment(field.value.split('T')[0], dateFormat);
|
||||||
|
var max = moment(field.maxValue, dateFormat);
|
||||||
|
|
||||||
|
if (d.isAfter(max)) {
|
||||||
|
field.validationSummary = `Should not be greater than ${field.maxValue}`;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class MinLengthFieldValidator implements FormFieldValidator {
|
export class MinLengthFieldValidator implements FormFieldValidator {
|
||||||
|
|
||||||
private supportedTypes = [
|
private supportedTypes = [
|
||||||
|
@ -29,9 +29,13 @@ import {
|
|||||||
MaxLengthFieldValidator,
|
MaxLengthFieldValidator,
|
||||||
MinValueFieldValidator,
|
MinValueFieldValidator,
|
||||||
MaxValueFieldValidator,
|
MaxValueFieldValidator,
|
||||||
RegExFieldValidator
|
RegExFieldValidator,
|
||||||
|
DateFieldValidator,
|
||||||
|
MinDateFieldValidator,
|
||||||
|
MaxDateFieldValidator
|
||||||
} from './form-field-validator';
|
} from './form-field-validator';
|
||||||
|
|
||||||
|
declare var moment: any;
|
||||||
|
|
||||||
export class FormFieldModel extends FormWidgetModel {
|
export class FormFieldModel extends FormWidgetModel {
|
||||||
|
|
||||||
@ -152,7 +156,10 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
new MaxLengthFieldValidator(),
|
new MaxLengthFieldValidator(),
|
||||||
new MinValueFieldValidator(),
|
new MinValueFieldValidator(),
|
||||||
new MaxValueFieldValidator(),
|
new MaxValueFieldValidator(),
|
||||||
new RegExFieldValidator()
|
new RegExFieldValidator(),
|
||||||
|
new DateFieldValidator(),
|
||||||
|
new MinDateFieldValidator(),
|
||||||
|
new MaxDateFieldValidator()
|
||||||
];
|
];
|
||||||
|
|
||||||
this.updateForm();
|
this.updateForm();
|
||||||
@ -191,6 +198,19 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is needed due to Activiti desplaying/editing dates in d-M-YYYY format
|
||||||
|
but storing on server in ISO8601 format (i.e. 2013-02-04T22:44:30.652Z)
|
||||||
|
*/
|
||||||
|
if (json.type === FormFieldTypes.DATE) {
|
||||||
|
if (value) {
|
||||||
|
let d = moment(value.split('T')[0]);
|
||||||
|
if (d.isValid()) {
|
||||||
|
value = d.format('D-M-YYYY');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +261,14 @@ export class FormFieldModel extends FormWidgetModel {
|
|||||||
this.form.values[this.id] = null;
|
this.form.values[this.id] = null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FormFieldTypes.DATE:
|
||||||
|
let d = moment(this.value, 'D-M-YYYY');
|
||||||
|
if (d.isValid()) {
|
||||||
|
this.form.values[this.id] = `${d.format('YYYY-MM-DD')}T00:00:00.000Z`;
|
||||||
|
} else {
|
||||||
|
this.form.values[this.id] = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (!FormFieldTypes.isReadOnlyType(this.type)) {
|
if (!FormFieldTypes.isReadOnlyType(this.type)) {
|
||||||
this.form.values[this.id] = this.value;
|
this.form.values[this.id] = this.value;
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
.date-widget {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-widget__invalid .mdl-textfield__input {
|
||||||
|
border-color: #d50000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-widget__invalid .mdl-textfield__label {
|
||||||
|
color: #d50000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-widget__invalid .mdl-textfield__label:after {
|
||||||
|
background-color: #d50000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-widget__invalid .mdl-textfield__error {
|
||||||
|
visibility: visible !important;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label date-widget"
|
||||||
|
[class.date-widget__invalid]="!field.isValid">
|
||||||
|
<input class="mdl-textfield__input"
|
||||||
|
type="text"
|
||||||
|
[attr.id]="field.id"
|
||||||
|
[attr.required]="isRequired()"
|
||||||
|
[(ngModel)]="field.value"
|
||||||
|
(ngModelChange)="checkVisibility(field)"
|
||||||
|
[disabled]="field.readOnly">
|
||||||
|
<label class="mdl-textfield__label" [attr.for]="field.id">{{field.name}} (d-M-yyyy)</label>
|
||||||
|
<span *ngIf="field.validationSummary" class="mdl-textfield__error">{{field.validationSummary}}</span>
|
||||||
|
</div>
|
@ -0,0 +1,52 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, ElementRef } from '@angular/core';
|
||||||
|
import { WidgetComponent } from './../widget.component';
|
||||||
|
|
||||||
|
declare let __moduleName: string;
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
moduleId: __moduleName,
|
||||||
|
selector: 'date-widget',
|
||||||
|
templateUrl: './date.widget.html',
|
||||||
|
styleUrls: ['./date.widget.css']
|
||||||
|
})
|
||||||
|
export class DateWidget extends WidgetComponent {
|
||||||
|
|
||||||
|
constructor(private elementRef: ElementRef) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
setupMaterialComponents(componentHandler: any): boolean {
|
||||||
|
// workaround for MDL issues with dynamic components
|
||||||
|
if (componentHandler) {
|
||||||
|
componentHandler.upgradeAllRegistered();
|
||||||
|
if (this.elementRef && this.hasValue()) {
|
||||||
|
let el = this.elementRef.nativeElement;
|
||||||
|
let container = el.querySelector('.mdl-textfield');
|
||||||
|
if (container) {
|
||||||
|
container.MaterialTextfield.change(this.field.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -32,6 +32,7 @@ import { AttachWidget } from './attach/attach.widget';
|
|||||||
import { TypeaheadWidget } from './typeahead/typeahead.widget';
|
import { TypeaheadWidget } from './typeahead/typeahead.widget';
|
||||||
import { FunctionalGroupWidget } from './functional-group/functional-group.widget';
|
import { FunctionalGroupWidget } from './functional-group/functional-group.widget';
|
||||||
import { PeopleWidget } from './people/people.widget';
|
import { PeopleWidget } from './people/people.widget';
|
||||||
|
import { DateWidget } from './date/date.widget';
|
||||||
|
|
||||||
// core
|
// core
|
||||||
export * from './widget.component';
|
export * from './widget.component';
|
||||||
@ -56,6 +57,7 @@ export * from './attach/attach.widget';
|
|||||||
export * from './typeahead/typeahead.widget';
|
export * from './typeahead/typeahead.widget';
|
||||||
export * from './functional-group/functional-group.widget';
|
export * from './functional-group/functional-group.widget';
|
||||||
export * from './people/people.widget';
|
export * from './people/people.widget';
|
||||||
|
export * from './date/date.widget';
|
||||||
|
|
||||||
export const WIDGET_DIRECTIVES: any[] = [
|
export const WIDGET_DIRECTIVES: any[] = [
|
||||||
TabsWidget,
|
TabsWidget,
|
||||||
@ -73,5 +75,6 @@ export const WIDGET_DIRECTIVES: any[] = [
|
|||||||
AttachWidget,
|
AttachWidget,
|
||||||
TypeaheadWidget,
|
TypeaheadWidget,
|
||||||
FunctionalGroupWidget,
|
FunctionalGroupWidget,
|
||||||
PeopleWidget
|
PeopleWidget,
|
||||||
|
DateWidget
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user