Reworked application.form.main to comply with Reactive forms standards and...

Reworked application.form.main to comply with Reactive forms standards and Redux patterns. Connected course.fields.select form with application.form.main. Other fixes and restructuring
parent 2fb612e0
......@@ -175,8 +175,8 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['name'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('User Id από Drupal Users '))
......@@ -221,7 +221,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userTaxId'] = BaseFieldDefinition::create('string')
->setLabel(t('Tax id χρήστη'))
->setDescription(t('Δώσε το tax id / ΑΦΜ του χρήστη.'))
......@@ -241,7 +241,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userFirstname'] = BaseFieldDefinition::create('string')
->setLabel(t('Όνομα χρήστη'))
->setDescription(t('Δώσε το μικρό όνομα του χρήστη.'))
......@@ -261,7 +261,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userSurname'] = BaseFieldDefinition::create('string')
->setLabel(t('Επώνυμο χρήστη'))
->setDescription(t('Δώσε το επώνυμο του χρήστη.'))
......@@ -281,7 +281,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userFatherName'] = BaseFieldDefinition::create('string')
->setLabel(t('Όνομα πατέρα χρήστη'))
->setDescription(t('Δώσε το όνομα του πατέρα του χρήστη.'))
......@@ -301,7 +301,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userMothername'] = BaseFieldDefinition::create('string')
->setLabel(t('Όνομα μητέρας χρήστη'))
->setDescription(t('Δώσε το όνομα της μητέρας χρήστη.'))
......@@ -321,9 +321,9 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userAddress'] = BaseFieldDefinition::create('string')
->setLabel(t('Διεύθυνση κατοικίας'))
->setDescription(t('Δώσε τη διεύθυνση κατοικίας.'))
......@@ -343,7 +343,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userAddressTK'] = BaseFieldDefinition::create('string')
->setLabel(t('ΤΚ'))
->setDescription(t('Δώσε τον ΤΚ κατοικίας.'))
......@@ -363,7 +363,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userAddressArea'] = BaseFieldDefinition::create('string')
->setLabel(t('Πόλη/Περιοχή διεύθυνσης κατοικίας'))
->setDescription(t('Δώσε την πόλη/περιοχή διεύθυνσης.'))
......@@ -383,7 +383,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['accessToken'] = BaseFieldDefinition::create('string')
->setLabel(t('Access-Token από taxis'))
->setDescription(t('Access-Token από taxis.'))
......@@ -403,7 +403,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['offToken'] = BaseFieldDefinition::create('string')
->setLabel(t('Off-Token'))
->setDescription(t('Off-Token που δημιουργείται από εμάς.'))
......@@ -423,12 +423,12 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['timeLogin'] = BaseFieldDefinition::create('timestamp')
->setLabel(t('timeLogin'))
->setDescription(t('timeLogin.'))
;
$fields['timeRegistration'] = BaseFieldDefinition::create('timestamp')
->setLabel(t('timeRegistration'))
->setDescription(t('timeRegistration.'))
......@@ -444,13 +444,15 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'integer',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'integer',
'weight' => -4,
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['userIP'] = BaseFieldDefinition::create('string')
->setLabel(t('userIP'))
->setDescription(t('userIP.'))
......@@ -470,7 +472,7 @@ class EpalUsers extends ContentEntityBase implements EpalUsersInterface {
))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the Epal users is published.'))
......
......@@ -14,9 +14,9 @@ export class StudentDataFieldsActions {
getStudentDataFields = () => {
const { studentdataFields } = this._ngRedux.getState();
const { studentDataFields } = this._ngRedux.getState();
//console.log(studentdataFields);
if (studentdataFields.size === 0) {
if (studentDataFields.size === 0) {
return this._hds.getStudentDataFields().then(studentdataFields => {
return this._ngRedux.dispatch({
type: STUDENTDATAFIELDS_RECEIVED,
......@@ -40,25 +40,12 @@ export class StudentDataFieldsActions {
};
*/
saveStudentDataFields = (studentdataFieldsFirstname, studentdataFieldsSurname, studentdataFieldsGuardianFirstname,
studentdataFieldsGuardianSurname, studentdataFieldsStudentAmka,
studentdataFieldsRegionAddress, studentdataFieldsRegionTK, studentdataFieldsRegionArea,
studentdataFieldsCertificateType, studentdataFieldsRelationToStudent,) => {
saveStudentDataFields = (studentDataFields) => {
return this._ngRedux.dispatch({
type: STUDENTDATAFIELDS_SAVE,
payload: {
studentdataFieldsFirstname,
studentdataFieldsSurname,
studentdataFieldsGuardianFirstname,
studentdataFieldsGuardianSurname,
studentdataFieldsStudentAmka,
studentdataFieldsRegionAddress,
studentdataFieldsRegionTK,
studentdataFieldsRegionArea,
studentdataFieldsCertificateType,
studentdataFieldsRelationToStudent,
studentDataFields
}
});
......
export class AppSettings {
public static get API_ENDPOINT(): string {
// return 'http://localhost/dist';
return 'http://localhost/drupal-8.2.5';
return 'http://localhost/dist';
// return 'http://eepal.dev/drupal';
// return 'http://eduslim2.minedu.gov.gr/drupal';
}
}
<form novalidate [formGroup]="studentDataGroup">
<div *ngFor="let studentDataField$ of studentDataFields$ | async; "> </div>
<label>ΑΜΚΑ μαθητή</label><input type="text" formControlName="studentAmka">
<label>Όνομα μαθητή</label><input type="text" formControlName="studentFirstname">
<div class="alert alert-danger" *ngIf="studentDataGroup.get('studentFirstname').touched && studentDataGroup.get('studentFirstname').hasError('required')">
Το πεδίο δεν μπορεί να αφεθεί κενό!
</div>
<div class="alert alert-danger" *ngIf="studentDataGroup.get('studentFirstname').touched && studentDataGroup.get('studentFirstname').hasError('pattern')">
Δεν επιτρέπονται ψηφία ή άλλοι μη έγκυροι χαρακτήρες σε αυτό το πεδίο!
</div>
<label>Επώνυμο μαθητή</label><input type="text" formControlName="studentSurname">
<div class="alert alert-danger" *ngIf="studentDataGroup.get('studentSurname').touched && studentDataGroup.get('studentSurname').hasError('required')">
Το πεδίο δεν μπορεί να αφεθεί κενό!
</div>
<div class="alert alert-danger" *ngIf="studentDataGroup.get('studentSurname').touched && studentDataGroup.get('studentSurname').hasError('pattern')">
Δεν επιτρέπονται ψηφία ή άλλοι μη έγκυροι χαρακτήρες σε αυτό το πεδίο!
</div>
<label>Όνομα κηδεμόνα</label><input type="text" formControlName="guardianFirstname">
<div class="alert alert-danger" *ngIf="studentDataGroup.get('guardianFirstname').touched && studentDataGroup.get('guardianFirstname').hasError('required')">
Το πεδίο δεν μπορεί να αφεθεί κενό!
</div>
<div class="alert alert-danger" *ngIf="studentDataGroup.get('guardianFirstname').touched && studentDataGroup.get('guardianFirstname').hasError('pattern')">
Δεν επιτρέπονται ψηφία ή άλλοι μη έγκυροι χαρακτήρες σε αυτό το πεδίο!
</div>
<label>Επώνυμο κηδεμόνα</label><input type="text" formControlName="guardianSurname">
<div class="alert alert-danger" *ngIf="studentDataGroup.get('guardianSurname').touched && studentDataGroup.get('guardianSurname').hasError('required')">
Το πεδίο δεν μπορεί να αφεθεί κενό!
</div>
<div class="alert alert-danger" *ngIf="studentDataGroup.get('guardianSurname').touched && studentDataGroup.get('guardianSurname').hasError('pattern')">
Δεν επιτρέπονται ψηφία ή άλλοι μη έγκυροι χαρακτήρες σε αυτό το πεδίο!
</div>
<table>
<tr>
<td>
<div class="form-group">
<label>Διεύθυνση κατοικίας</label><input type="text" formControlName="regionAddress">
</div>
</td>
<td>
<div class="form-group">
<label>TK </label><input type="text" formControlName="regionTK">
</div>
</td>
<td>
<div class="form-group">
<label>Πόλη/Περιοχή</label><input type="text" formControlName="regionArea">
</div>
</td>
</tr>
</table>
<label for="certificateType">Τύπος απολυτηρίου</label><br/>
<select formControlName="certificateType">
<option value="">Παρακαλώ επιλέξτε..</option>
<option value="Απολυτήριο Γυμνασίου">Απολυτήριο Γυμνασίου</option>
<option value="Απολυτήριο Λυκείου">Απολυτήριο Λυκείου</option>
</select>
<br/>
<div class="alert alert-danger" *ngIf="studentDataGroup.get('certificateType').touched && studentDataGroup.get('certificateType').hasError('required')">
Η επιλογή από αυτή τη λίστα είναι απαραίτητη!
</div>
<label for="relationToStudent">Η αίτηση γίνεται από:</label><br/>
<select formControlName="relationToStudent">
<option value="">Παρακαλώ επιλέξτε..</option>
<option value="Γονέας/Κηδεμόνας">Γονέας/Κηδεμόνας</option>
<option value="Μαθητής">Μαθητής</option>
</select>
<div class="alert alert-danger" *ngIf="studentDataGroup.get('relationToStudent').touched && studentDataGroup.get('relationToStudent').hasError('required')">
Η επιλογή από αυτή τη λίστα είναι απαραίτητη!
</div>
<h4 style="margin-top: 20px; line-height: 2em; background: #dddddd;">Επιλεγμένες Ειδικότητες</h4>
<ul class="list-group" style="margin-bottom: 20px;">
<div *ngFor="let courseField$ of courseFields$ | async">
<li class="list-group-item" *ngIf="courseField$.selected === true">
{{courseField$.name}}
</li>
</div>
</ul>
<div class="row">
<div class="col-md-2 col-md-offset-4">
<button type="button" class="btn-primary btn-lg pull-center" (click)="saveSelected()" [routerLink]="['/course-fields-select']">
<span class="glyphicon glyphicon-menu-left"></span>Πίσω
</button>
</div>
<div class="col-md-2">
<button type="button" class="btn-primary btn-lg pull-center" (click)="saveSelected()" [disabled]="studentDataGroup.invalid">
Αποστολή<span class="glyphicon glyphicon-menu-right"></span>
</button>
</div>
</div>
</form>
import {Component, OnInit} from '@angular/core';
import { Observable } from 'rxjs/Rx';
import {Injectable, ChangeDetectionStrategy} from "@angular/core";
import {StudentDataFieldsActions} from '../../actions/studentdatafields.actions';
import { DevToolsExtension, NgRedux, select } from 'ng2-redux';
import { IStudentDataFields } from '../../store/studentdatafields/studentdatafields.types';
import { ICourseFields } from '../../store/coursefields/coursefields.types';
import { IAppState } from '../../store/store';
import { VALID_NAMES_PATTERN } from '../../constants';
import {
FormBuilder,
FormGroup,
FormControl,
Validators,
} from '@angular/forms';
@Component({
selector: 'application-form-main',
templateUrl: './application.form.main.html'
})
@Injectable() export default class StudentApplicationMain implements OnInit {
private studentDataFields$: Observable<IStudentDataFields>;
private courseFields$: Observable<ICourseFields>;
public studentDataGroup: FormGroup;
constructor(private fb: FormBuilder, private _sdfa: StudentDataFieldsActions, private _ngRedux: NgRedux<IAppState>) {
this.studentDataGroup = this.fb.group({
studentAmka: ['12345', Validators.required],
studentFirstname: ['', [Validators.pattern(VALID_NAMES_PATTERN),Validators.required]],
studentSurname: ['', [Validators.pattern(VALID_NAMES_PATTERN),Validators.required]],
guardianFirstname: ['', [Validators.pattern(VALID_NAMES_PATTERN),Validators.required]],
guardianSurname: ['', [Validators.pattern(VALID_NAMES_PATTERN),Validators.required]],
regionAddress: ['', [Validators.pattern(VALID_NAMES_PATTERN),Validators.required]],
regionTK: ['', [Validators.pattern(VALID_NAMES_PATTERN),Validators.required]],
regionArea: ['', [Validators.pattern(VALID_NAMES_PATTERN),Validators.required]],
certificateType: ['', Validators.required],
relationToStudent: ['', Validators.required],
});
};
ngOnInit() {
this.studentDataFields$ = this._ngRedux.select(state => {
if (state.studentDataFields.size > 0) {
state.studentDataFields.reduce(({}, studentDataField) => {
this.studentDataGroup.setValue(studentDataField);
return studentDataField;
}, {});
}
return state.studentDataFields;
});
this.courseFields$ = this._ngRedux.select(state => {
//console.log("test2");
state.courseFields.reduce(({}, courseField) =>{
// this.cfs.push(new FormControl(courseField.selected, []));
//console.log(courseField.selected);
return courseField;
}, {});
return state.courseFields;
});
}
saveSelected() {
this._sdfa.saveStudentDataFields([this.studentDataGroup.value]);
}
}
......@@ -33,7 +33,9 @@ import {AppSettings} from '../../app.settings';
</div>
<div class="row">
<div class="col-md-2 col-md-offset-5">
<button class="btn-primary btn-lg pull-center" (click)="saveSelected()">Συνέχεια</button>
<button class="btn-primary btn-lg pull-center" (click)="saveSelected()" [routerLink]="['/student-application-form-main']">
Συνέχεια<span class="glyphicon glyphicon-menu-right"></span>
</button>
</div>
</div>
</form>
......
......@@ -3,3 +3,5 @@ export const COURSEFIELDS_SELECTED_SAVE = 'COURSEFIELDS_SELECTED_SAVE';
export const STUDENTDATAFIELDS_RECEIVED = 'STUDENTDATAFIELDS_RECEIVED';
export const STUDENTDATAFIELDS_SAVE = 'STUDENTDATAFIELDS_SAVE';
export const VALID_NAMES_PATTERN = '[Α-ΩΆΈΉΊΎΌΏα-ωάέήίύόώ ]*$';
.ng-valid[required], .ng-valid.required {
/*border-left: 3px solid #42A948;*/ /* green */
}
.ng-invalid:not(form) {
border-left: 3px solid #a94442; /* red */
}
#outer
{
width:100%;
text-align: center;
}
.inner
{
display: inline-block;
}
......@@ -6,16 +6,16 @@ import {
import {CamelCasePipe} from '../pipes/camelcase';
import Form3 from '../components/form-controls/form3';
//import ApplicantInfoFormComponent from '../components/form-controls/applicantinfo-form.component';
import StudentDataFieldsSelect from '../components/student-application-form/studentData-fields-select';
import StudentApplicationMain from '../components/student-application-form/application.form.main';
import StudentsList from '../components/students/students-list';
import Home from '../components/home';
import CourseFieldsSelect from '../components/student-application-form/course-fields-select';
import CourseFieldsSelect from '../components/student-application-form/course.fields.select';
export const MainRoutes: Routes = [
{ path: '', component: Home },
{ path: 'form3', component: Form3 },
// { path: 'applicant-data-form', component: ApplicantInfoFormComponent },
{ path: 'applicant-data-form', component: StudentDataFieldsSelect },
{ path: 'student-application-form-main', component: StudentApplicationMain },
{ path: 'students-list', component: StudentsList },
{ path: 'course-fields-select', component: CourseFieldsSelect }
];
......@@ -27,5 +27,5 @@ export const MainDeclarations = [
StudentsList,
Home,
CourseFieldsSelect,
StudentDataFieldsSelect
StudentApplicationMain
];
......@@ -25,15 +25,15 @@ import {
<li [ngClass]="{active: path=='course-fields-select'}">
<a [routerLink]="['/course-fields-select']">Επιλογή Ειδικότητας</a>
</li>
<li [ngClass]="{active: path=='form3'}">
<a [routerLink]="['/form3']">Αίτηση</a>
<li [ngClass]="{active: path=='student-application-form-main'}">
<a [routerLink]="['/student-application-form-main']">Αίτηση μαθητή / Καταχώρηση προσωπικών στοιχείων</a>
</li>
<li [ngClass]="{active: path=='applicant-data-form'}">
<a [routerLink]="['/applicant-data-form']">Αίτηση μαθητή / Καταχώρηση προσωπικών στοιχείων</a>
</li>
<li [ngClass]="{active: path=='students-list'}">
<a [routerLink]="['/students-list']">Μαθητές</a>
</li>
<li [ngClass]="{active: path=='form3'}">
<a [routerLink]="['/form3']">Αίτηση</a>
</li>
</ul>
</div>
<div class="col-md-9">
......
......@@ -4,7 +4,6 @@
<meta charset="utf-8">
<title>Angular 2 με Drupal backend RESTful server</title>
<link rel="stylesheet" href="https://bootswatch.com/paper/bootstrap.min.css">
<link rel="stylesheet" href="../source//containers/forms.css">
</head>
<body>
<h3 class="text-center">Angular 2 με Drupal backend RESTful server</h3>
......
import { combineReducers } from 'redux';
import * as courseFields from './coursefields';
import * as studentdataFields from './studentdatafields';
import * as studentDataFields from './studentdatafields';
/*
* This is where we 'assemble' the full store out of its modules.
......@@ -8,18 +8,18 @@ import * as studentdataFields from './studentdatafields';
export interface IAppState {
courseFields?: courseFields.ICourseFields;
studentdataFields?: studentdataFields.IStudentDataFields;
studentDataFields?: studentDataFields.IStudentDataFields;
};
export const rootReducer = combineReducers<IAppState>({
courseFields: courseFields.courseFieldsReducer,
studentdataFields: studentdataFields.studentdataFieldsReducer,
studentDataFields: studentDataFields.studentDataFieldsReducer,
});
export function deimmutify(state: IAppState): Object {
return {
courseFields: courseFields.deimmutifyCourseFields(state.courseFields),
studentdataFields: studentdataFields.deimmutifyStudentDataFields(state.studentdataFields),
studentdataFields: studentDataFields.deimmutifyStudentDataFields(state.studentDataFields),
};
}
......
import { IStudentDataField, IStudentDataFields } from './studentdatafields.types';
import { studentdataFieldsReducer } from './studentdatafields.reducer';
import { studentDataFieldsReducer } from './studentdatafields.reducer';
import { deimmutifyStudentDataFields } from './studentdatafields.transformers';
export {
IStudentDataField,
IStudentDataFields,
studentdataFieldsReducer,
studentDataFieldsReducer,
deimmutifyStudentDataFields,
};
......@@ -7,7 +7,8 @@ import {
STUDENTDATAFIELDS_SAVE
} from '../../constants';
export function studentdataFieldsReducer(state: IStudentDataFields = INITIAL_STATE, action): IStudentDataFields {
export function studentDataFieldsReducer(state: IStudentDataFields = INITIAL_STATE, action): IStudentDataFields {
switch (action.type) {
case STUDENTDATAFIELDS_RECEIVED:
let newStudentDataFields = Array<IStudentDataField>();
......@@ -23,23 +24,18 @@ export function studentdataFieldsReducer(state: IStudentDataFields = INITIAL_STA
return Seq(newStudentDataFields).map(n => n).toList();
case STUDENTDATAFIELDS_SAVE:
let selectedStudentDataFields = Array<IStudentDataField>();
let studentDataFields = Array<IStudentDataField>();
let ind=0;
//let testvar = "nikos";
state.forEach(studentdataField => {
selectedStudentDataFields.push(<IStudentDataField>{studentFirstname: action.payload.studentdataFieldsFirstname, studentSurname: action.payload.studentdataFieldsSurname,
guardianFirstname: action.payload.studentdataFieldsGuardianFirstname, guardianSurname: action.payload.studentdataFieldsGuardianSurname,
studentAmka: studentdataField.studentAmka, regionAddress: action.payload.studentdataFieldsRegionAddress,
regionTK: action.payload.studentdataFieldsRegionTK, regionArea: action.payload.studentdataFieldsRegionArea,
certificateType: action.payload.studentdataFieldsCertificateType, relationToStudent: action.payload.studentdataFieldsRelationToStudent});
action.payload.studentDataFields.forEach(studentDataField => {
studentDataFields.push(<IStudentDataField>studentDataField);
ind++;
//console.log(action.payload.studentdataFieldsFirstname);
});
return Seq(selectedStudentDataFields).map(n => n).toList();
return Seq(studentDataFields).map(n => n).toList();
default: return state;
}
};
......@@ -64,7 +64,7 @@ module.exports = {
loader: 'tslint'
}],
loaders: [
{ test: /\.ts$/, loaders: ['ts', 'angular2-router-loader'], exclude: /node_modules/ },
{ test: /\.ts$/, loaders: ['ts', 'angular2-router-loader', 'angular2-template-loader'], exclude: /node_modules/ },
{ test: /\.js$/, exclude: [/bower_components/, /node_modules\/@angular\/compiler\/bundles\/.+/], loader: 'babel-loader', query: {presets: ['es2015']} },
{ test: /\.html$/, loader: 'raw' },
// { test: /\.css$/, loader: 'style-loader!css-loader?sourceMap' },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment