Skip to content

Commit

Permalink
feat(page-slider): add disableRemoval mode in repeating slide
Browse files Browse the repository at this point in the history
disableRemoval allow  you to disable all correctly compiled slides of the repeating slide.
  • Loading branch information
peppedeka authored and trik committed Mar 24, 2021
1 parent 4e430ec commit 91bfeaa
Show file tree
Hide file tree
Showing 18 changed files with 125 additions and 26 deletions.
4 changes: 4 additions & 0 deletions src/core/forms/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ export abstract class AjfFormRenderer implements AfterViewChecked, AfterViewInit
this._formAction.complete();
}

scrollToSlide(slide: AjfSlideInstance): void {
this.formSlider.slide({to: slide.position - 1});
}

orientationChangeHandler(orientation: AjfPageSliderOrientation): void {
this.orientation = orientation;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface AjfRepeatingNodeInstance extends AjfNodeInstance {
node: AjfRepeatingNode;
formulaReps?: AjfFormula;
reps: number;
disableRemoval?: boolean;
canAdd?: boolean;
canRemove?: boolean;
}
8 changes: 8 additions & 0 deletions src/core/forms/interface/nodes/repeating-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ export interface AjfRepeatingNode extends AjfNode {

// min number of repetitions
minReps: number;

/**
* If true show all slides of repeating node in readonly mode.
* Except the last slide.
* In the last slide remove button is always disabled and add button is enabled
* only when the last slide is valid.
*/
disableRemoval?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function createRepeatingSlideInstance(instance: AjfRepeatingSlideInstance
node: instance.node,
slideNodes: [],
formulaReps: instance.formulaReps,
disableRemoval: instance.disableRemoval,
reps: 0,
nodes: [],
flatNodes: [],
Expand Down
2 changes: 1 addition & 1 deletion src/core/page-slider/page-slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export class AjfPageSlider implements AfterContentInit, OnDestroy {
} else if (opts.dir === 'forward' || opts.dir === 'down' || opts.dir === 'right') {
this._slideForward();
}
} else if (opts.to) {
} else if (opts.to != null) {
this._slideTo(opts.to);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/dev-app/ion-forms/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const formContext: any = {
};

export const formSchema: any = {
topBar: true,
choicesOrigins: [
{
type: 'fixed',
Expand Down
3 changes: 2 additions & 1 deletion src/dev-app/ion-forms/forms-demo.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<div class="demo-forms">
<h4 class="demo-section-header">Form</h4>
<ion-checkbox [(ngModel)]="readonly">readonly</ion-checkbox>
<ion-checkbox [(ngModel)]="topBar">topBar</ion-checkbox>
<section>
<ion-grid>
<ion-row>
Expand All @@ -23,7 +24,7 @@ <h5>Context</h5>
</ion-row>
</ion-grid>
<div class="demo-form-container">
<ajf-form [form]="form" [readonly]="readonly" hideTopToolbar></ajf-form>
<ajf-form [form]="form" [readonly]="readonly" [topBar]="topBar"></ajf-form>
</div>
</section>
</div>
8 changes: 8 additions & 0 deletions src/dev-app/ion-forms/forms-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ export class FormsDemo {
}
private _readonly = false;

get topBar() {
return this._topBar;
}
set topBar(value: boolean) {
this._topBar = value;
}
private _topBar = true;

constructor(private _formRendererService: AjfFormRendererService) {
this.form = AjfFormSerializer.fromJson(formSchema, formContext);
console.log(this.form);
Expand Down
32 changes: 29 additions & 3 deletions src/dev-app/mat-forms/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ export const formSchema: any = {
name: 'animals',
choicesType: 'string',
choices: [
{value: 'dog', label: 'Dog'},
{value: 'cat', label: 'Cat'},
{value: 'dog', label: 'Dog'}, {value: 'cat', label: 'Cat'},
{value: 'blackcat', label: 'Black Cat'}
]
},
Expand Down Expand Up @@ -280,7 +279,34 @@ export const formSchema: any = {
]
},
{
parent: 5,
parent: 4,
id: 500,
name: 'repeat',
label: 'Multiple Slide with history disabled',
nodeType: 4,
disableRemoval: true,
nodes: [
{
parent: 500,
id: 500001,
name: 'name',
label: 'Child\'s name',
nodeType: 0,
fieldType: 0,
validation: {notEmpty: true}
},
{
parent: 500001,
id: 500002,
name: 'birthweight',
label: 'Child\'s birthweight',
nodeType: 0,
fieldType: 2
}
]
},
{
parent: 500,
id: 6,
name: 'custom',
label: 'Custom field',
Expand Down
19 changes: 15 additions & 4 deletions src/ionic/forms/form.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
<ng-container *ngIf="formGroup|async as currentFormGroup">
<form novalidate [formGroup]="currentFormGroup!">
<div class="ajf-form-container">
<ion-toolbar *ngIf="!hideTopToolbar && topBar" class="ajf-btn-strip">
<div class="ajf-topbar-buttons">
<ng-container *ngFor="let slideInstance of (slides|async)">
<ion-button class="ajf-topbar-button"
*ngIf="slideInstance.node != null && slideInstance.node.label != null && slideInstance.node.label.length > 0"
(click)="scrollToSlide(slideInstance)">{{slideInstance.node.label | translate}}</ion-button>
</ng-container>
</div>
</ion-toolbar>
<ion-toolbar *ngIf="!hideTopToolbar">
{{ title | translate }}
<ion-buttons slot="end">
Expand Down Expand Up @@ -68,7 +77,8 @@ <h2>
<ion-icon *ngIf="(fieldInstance|ajfAsFieldInstance).node?.hint as hint"
[name]="(fieldInstance|ajfAsFieldInstance).node?.hintIcon || 'help-outline'"
(click)="openPopover($event, hint)"></ion-icon>
<ajf-field [instance]="fieldInstance|ajfAsFieldInstance" [readonly]="readonly"></ajf-field>
<ajf-field [instance]="fieldInstance|ajfAsFieldInstance" [readonly]="readonly">
</ajf-field>
</div>
</ng-container>
</ion-card-content>
Expand All @@ -90,10 +100,10 @@ <h2>
<ion-icon color="secondary" name="checkmark" *ngIf="(slideInstance|ajfValidSlide:idx)"></ion-icon>
</div>
<div *ngIf="lastSlide && !readonly" class="ajf-group-actions">
<ion-fab-button size="small" (click)="addGroup(slideInstance)" [disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canAdd">
<ion-fab-button size="small" (click)="addGroup(slideInstance)" [disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canAdd || ((slideInstance|ajfAsRepeatingSlideInstance).node?.disableRemoval && !slideInstance.valid)">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
<ion-fab-button size="small" (click)="removeGroup(slideInstance)" [disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canRemove">
<ion-fab-button size="small" (click)="removeGroup(slideInstance)" [disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canRemove || (slideInstance|ajfAsRepeatingSlideInstance).node?.disableRemoval">
<ion-icon name="remove"></ion-icon>
</ion-fab-button>
</div>
Expand All @@ -105,7 +115,8 @@ <h2>
<i [class]="(fieldInstance|ajfAsFieldInstance).node.fieldType | ajfFieldIcon" item-right></i>
<p>{{ (fieldInstance|ajfAsFieldInstance).node.description }}</p>
<ion-label [innerHTML]="fieldInstance.node.label | translate"></ion-label>
<ajf-field [instance]="fieldInstance|ajfAsFieldInstance" [readonly]="readonly"></ajf-field>
<ajf-field [instance]="fieldInstance|ajfAsFieldInstance"
[readonly]="readonly || (!lastSlide && (slideInstance|ajfAsRepeatingSlideInstance).node?.disableRemoval)"></ajf-field>
</div>
</ng-container>
<div *ngIf="lastSlide && longSlide" class="ajf-group-actions ajf-group-actions-bottom">
Expand Down
34 changes: 29 additions & 5 deletions src/ionic/forms/form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ ajf-form {
flex-direction: column;
height: 100%;

.ajf-topbar-buttons {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-content: stretch;
align-items: flex-start;
overflow-x: auto;

ion-button {
flex: 0 1 auto;
align-self: auto;
}
}
ion-toolbar {
flex: 0 0 auto;
height: 56px;
Expand Down Expand Up @@ -89,11 +103,21 @@ ajf-form {
width: 100%;
box-sizing: border-box;

&.ajf-normal { width: 100%; }
&.ajf-small { width: 50%; }
&.ajf-smaller { width: 33%; }
&.ajf-tiny { width: 25%; }
&.ajf-mini { width: 20%; }
&.ajf-normal {
width: 100%;
}
&.ajf-small {
width: 50%;
}
&.ajf-smaller {
width: 33%;
}
&.ajf-tiny {
width: 25%;
}
&.ajf-mini {
width: 20%;
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/ionic/forms/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnDestroy,
ViewEncapsulation
} from '@angular/core';
Expand All @@ -50,6 +51,8 @@ import {AjfPopover} from './popover';
* @implements : AfterViewInit
*/
export class AjfFormRenderer extends AjfCoreFormRenderer implements AfterViewInit, OnDestroy {
@Input() topBar: boolean = false;

private _longSlide = false;
get longSlide(): boolean {
return this._longSlide;
Expand Down
7 changes: 7 additions & 0 deletions src/material/forms/form.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,11 @@ describe('ajf-form test top toolbar input', () => {
const toolbars = await element.all(by.tagName('mat-toolbar')).getWebElements();
expect(toolbars.length).toBe(1);
});
it(`topbar input is not defined and hideTopToolbar is true:
should show one mat toolbar(pageSliderToolBar)`,
async () => {
await browser.get('/mat-form/?hidetoolbar=true');
const toolbars = await element.all(by.tagName('mat-toolbar')).getWebElements();
expect(toolbars.length).toBe(1);
});
});
17 changes: 11 additions & 6 deletions src/material/forms/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,16 @@ <h2>
</mat-card-header>
<mat-card-content>
<div *ngIf="lastSlide && !readonly" class="ajf-group-actions">
<button (click)="addGroup(slideInstance)"
[disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canAdd" mat-mini-fab>
<mat-icon>add</mat-icon>
<button
(click)="addGroup(slideInstance)"
[disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canAdd || ((slideInstance|ajfAsRepeatingSlideInstance).node?.disableRemoval && !slideInstance.valid)"
mat-mini-fab>
<mat-icon>add</mat-icon>
</button>
<button (click)="removeGroup(slideInstance)"
[disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canRemove" mat-mini-fab>
<button
(click)="removeGroup(slideInstance)"
[disabled]="!(slideInstance|ajfAsRepeatingSlideInstance).canRemove || (slideInstance|ajfAsRepeatingSlideInstance).node?.disableRemoval"
mat-mini-fab>
<mat-icon>remove</mat-icon>
</button>
</div>
Expand All @@ -127,7 +131,8 @@ <h2>
*ngIf="(fieldInstance|ajfAsFieldInstance).node?.hint as hint" [matTooltip]="hint"
matTooltipPosition="right">
{{(fieldInstance|ajfAsFieldInstance).node?.hintIcon || 'help'}}</mat-icon>
<ajf-field [instance]="fieldInstance|ajfAsFieldInstance" [readonly]="readonly">
<ajf-field [instance]="fieldInstance|ajfAsFieldInstance"
[readonly]="readonly || (!lastSlide && (slideInstance|ajfAsRepeatingSlideInstance).node?.disableRemoval)">
</ajf-field>
</div>
</ng-template>
Expand Down
4 changes: 0 additions & 4 deletions src/material/forms/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ export class AjfFormRenderer extends AjfCoreFormRenderer {
super(rendererService, changeDetectorRef);
}

scrollToSlide(slide: any): void {
this.formSlider.slide({to: slide.position - 1});
}

static ngAcceptInputType_fixedOrientation: BooleanInput;
static ngAcceptInputType_hasEndMessage: BooleanInput;
static ngAcceptInputType_hasStartMessage: BooleanInput;
Expand Down
3 changes: 3 additions & 0 deletions tools/public_api_guard/core/forms.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ export declare abstract class AjfFormRenderer implements AfterViewChecked, After
onSave(_evt: any): void;
orientationChangeHandler(orientation: AjfPageSliderOrientation): void;
removeGroup(nodeGroup: AjfNodeGroupInstance | AjfSlideInstance | AjfRepeatingSlideInstance): void;
scrollToSlide(slide: AjfSlideInstance): void;
trackNodeById(_: number, node: AjfNodeInstance): string;
static ɵdir: i0.ɵɵDirectiveDefWithMeta<AjfFormRenderer, never, never, { "title": "title"; "saveDisabled": "saveDisabled"; "hasStartMessage": "hasStartMessage"; "hasEndMessage": "hasEndMessage"; "hideTopToolbar": "hideTopToolbar"; "hideBottomToolbar": "hideBottomToolbar"; "hideNavigationButtons": "hideNavigationButtons"; "fixedOrientation": "fixedOrientation"; "readonly": "readonly"; "orientation": "orientation"; "form": "form"; }, { "orientationChange": "orientationChange"; "formAction": "formAction"; }, never>;
static ɵfac: i0.ɵɵFactoryDef<AjfFormRenderer, never>;
Expand Down Expand Up @@ -639,6 +640,7 @@ export interface AjfRepeatingContainerNodeInstance extends AjfContainerNodeInsta
}

export interface AjfRepeatingNode extends AjfNode {
disableRemoval?: boolean;
formulaReps?: AjfFormula;
maxReps: number;
minReps: number;
Expand All @@ -647,6 +649,7 @@ export interface AjfRepeatingNode extends AjfNode {
export interface AjfRepeatingNodeInstance extends AjfNodeInstance {
canAdd?: boolean;
canRemove?: boolean;
disableRemoval?: boolean;
formulaReps?: AjfFormula;
node: AjfRepeatingNode;
reps: number;
Expand Down
3 changes: 2 additions & 1 deletion tools/public_api_guard/ionic/forms.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export declare class AjfFormField extends CoreFormField {
export declare class AjfFormRenderer extends AjfCoreFormRenderer implements AfterViewInit, OnDestroy {
get longSlide(): boolean;
popoverController: PopoverController;
topBar: boolean;
constructor(rendererService: AjfFormRendererService, cdr: ChangeDetectorRef, popoverController: PopoverController);
ngAfterViewInit(): void;
ngOnDestroy(): void;
Expand All @@ -54,7 +55,7 @@ export declare class AjfFormRenderer extends AjfCoreFormRenderer implements Afte
static ngAcceptInputType_hideTopToolbar: BooleanInput;
static ngAcceptInputType_readonly: BooleanInput;
static ngAcceptInputType_saveDisabled: BooleanInput;
static ɵcmp: i0.ɵɵComponentDefWithMeta<AjfFormRenderer, "ajf-form", never, {}, {}, never, ["[ajfFormTopToolbarButtons]", "[ajfFormSaveButton]", "[ajfFormStartMessageTitle]", "[ajfFormStartMessage]", "[ajfFormEndMessageTitle]", "[ajfFormEndMessage]"]>;
static ɵcmp: i0.ɵɵComponentDefWithMeta<AjfFormRenderer, "ajf-form", never, { "topBar": "topBar"; }, {}, never, ["[ajfFormTopToolbarButtons]", "[ajfFormSaveButton]", "[ajfFormStartMessageTitle]", "[ajfFormStartMessage]", "[ajfFormEndMessageTitle]", "[ajfFormEndMessage]"]>;
static ɵfac: i0.ɵɵFactoryDef<AjfFormRenderer, never>;
}

Expand Down
1 change: 0 additions & 1 deletion tools/public_api_guard/material/forms.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export declare class AjfFormField extends CoreFormField {
export declare class AjfFormRenderer extends AjfCoreFormRenderer {
topBar: boolean;
constructor(rendererService: AjfFormRendererService, changeDetectorRef: ChangeDetectorRef);
scrollToSlide(slide: any): void;
static ngAcceptInputType_fixedOrientation: BooleanInput;
static ngAcceptInputType_hasEndMessage: BooleanInput;
static ngAcceptInputType_hasStartMessage: BooleanInput;
Expand Down

0 comments on commit 91bfeaa

Please sign in to comment.