parent
a8f8c0ebf1
commit
3fd6a54622
@ -0,0 +1,100 @@
|
||||
<ion-item
|
||||
*ngIf="this.node
|
||||
&& (
|
||||
this.node.type === 'form_input_text'
|
||||
|| this.node.type === 'form_input_number'
|
||||
|| this.node.type === 'form_input_password'
|
||||
|| this.node.type === 'form_input_email'
|
||||
|| this.node.type === 'form_input_select'
|
||||
|| this.node.type === 'form_input_multiselect'
|
||||
|| this.node.type === 'form_input_textarea'
|
||||
)"
|
||||
>
|
||||
<ion-label [position]="'floating'" *ngIf="this.node.AdditionalData.label">
|
||||
{{ this.node.AdditionalData.label }}
|
||||
</ion-label>
|
||||
<ion-input
|
||||
*ngIf="this.node.type === 'form_input_text'"
|
||||
[(ngModel)]="value"
|
||||
[placeholder]="this.node.AdditionalData.placeholder"
|
||||
[required]="this.node.AdditionalData.required"
|
||||
[readonly]="this.isReadonly"
|
||||
(ionChange)="triggerChangeCheck()"
|
||||
></ion-input>
|
||||
<ion-input
|
||||
*ngIf="this.node.type === 'form_input_number'"
|
||||
[(ngModel)]="value"
|
||||
[type]="'number'"
|
||||
[placeholder]="this.node.AdditionalData.placeholder"
|
||||
[required]="this.node.AdditionalData.required"
|
||||
[readonly]="this.isReadonly"
|
||||
(ionChange)="triggerChangeCheck()"
|
||||
></ion-input>
|
||||
<ion-input
|
||||
*ngIf="this.node.type === 'form_input_password'"
|
||||
[(ngModel)]="value"
|
||||
[type]="'password'"
|
||||
[placeholder]="this.node.AdditionalData.placeholder"
|
||||
[required]="this.node.AdditionalData.required"
|
||||
[readonly]="this.isReadonly"
|
||||
(ionChange)="triggerChangeCheck()"
|
||||
></ion-input>
|
||||
<ion-input
|
||||
*ngIf="this.node.type === 'form_input_email'"
|
||||
[(ngModel)]="value"
|
||||
[type]="'email'"
|
||||
[placeholder]="this.node.AdditionalData.placeholder"
|
||||
[required]="this.node.AdditionalData.required"
|
||||
[readonly]="this.isReadonly"
|
||||
(ionChange)="triggerChangeCheck()"
|
||||
></ion-input>
|
||||
|
||||
<!-- TODO readonly handling -->
|
||||
<ion-select
|
||||
*ngIf="this.node.type === 'form_input_select'"
|
||||
[(ngModel)]="value"
|
||||
[placeholder]="this.node.AdditionalData.placeholder"
|
||||
[required]="this.node.AdditionalData.required"
|
||||
(ionChange)="triggerChangeCheck()"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<ion-select-option
|
||||
*ngFor="let choice of selectChoices"
|
||||
[value]="choice.value"
|
||||
>{{ choice.display }}</ion-select-option>
|
||||
</ion-select>
|
||||
|
||||
<!-- TODO readonly handling -->
|
||||
<ion-select
|
||||
*ngIf="this.node.type === 'form_input_multiselect'"
|
||||
[(ngModel)]="value"
|
||||
[placeholder]="this.node.AdditionalData.placeholder"
|
||||
[required]="this.node.AdditionalData.required"
|
||||
(ionChange)="triggerChangeCheck()"
|
||||
[multiple]="true"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<ion-select-option
|
||||
*ngFor="let choice of selectChoices"
|
||||
[value]="choice.value"
|
||||
>{{ choice.display }}</ion-select-option>
|
||||
</ion-select>
|
||||
|
||||
<ion-textarea
|
||||
*ngIf="this.node.type === 'form_input_textarea'"
|
||||
[(ngModel)]="value"
|
||||
[placeholder]="this.node.AdditionalData.placeholder"
|
||||
[required]="this.node.AdditionalData.required"
|
||||
(ionChange)="triggerChangeCheck()"
|
||||
[autoGrow]="true"
|
||||
style="width: 100%;"
|
||||
[readonly]="this.isReadonly"
|
||||
></ion-textarea>
|
||||
|
||||
<ion-button
|
||||
slot="end"
|
||||
style="margin-top: 5px;"
|
||||
*ngIf="!this.isReadonly && !this.isFilloutMode"
|
||||
(click)="onEditClick()"
|
||||
>Edit</ion-button>
|
||||
</ion-item>
|
@ -0,0 +1,130 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {EditorNodeContract} from '../EditorNode.contract';
|
||||
import {EditorService} from '../../../service/editor.service';
|
||||
import {ModalController} from '@ionic/angular';
|
||||
import {FormInputOptionsComponent} from './options/form-input-options.component';
|
||||
import {DbApiService} from '../../../service/db-api.service';
|
||||
|
||||
export interface FormSelectChoiceObject {
|
||||
display: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'editor-node-form-input',
|
||||
templateUrl: './form-input.component.html',
|
||||
styleUrls: ['./form-input.component.scss'],
|
||||
})
|
||||
export class FormInputComponent extends EditorNodeContract implements OnInit {
|
||||
@Input() nodeId: string;
|
||||
@Input() editorUUID?: string;
|
||||
@Input() isFilloutMode = false;
|
||||
|
||||
public initialValue: any;
|
||||
public value: any;
|
||||
public forceDirty = false;
|
||||
|
||||
// TODO load this from somewhere
|
||||
public selectChoices: FormSelectChoiceObject[] = [];
|
||||
|
||||
constructor(
|
||||
public editorService: EditorService,
|
||||
public readonly modals: ModalController,
|
||||
public readonly dbApi: DbApiService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public isDark() {
|
||||
return document.body.classList.contains('dark');
|
||||
}
|
||||
|
||||
public get isReadonly(): boolean {
|
||||
return !this.editorService.canEdit();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.editorService = this.editorService.getEditor(this.editorUUID);
|
||||
this.editorService.registerNodeEditor(this.nodeId, this).then(() => {
|
||||
console.log('form input node', this.node);
|
||||
if ( !this.node.AdditionalData ) {
|
||||
this.node.AdditionalData = {};
|
||||
}
|
||||
|
||||
this.initialValue = this.value = this.isFilloutMode ? undefined : this.node.Value.Value;
|
||||
|
||||
if ( this.node.type === 'form_input_select' || this.node.type === 'form_input_multiselect' ) {
|
||||
if ( this.node.AdditionalData.selectSource === 'local' ) {
|
||||
this.selectChoices = [...this.node.AdditionalData.selectStaticOptions];
|
||||
} else if ( this.node.AdditionalData.selectSource === 'database' ) {
|
||||
this.loadSelectOptionsFromDatabase();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadSelectOptionsFromDatabase() {
|
||||
try {
|
||||
const db = await this.dbApi.getDatabase(this.node.AdditionalData.selectSourceDatabaseId);
|
||||
if ( db ) {
|
||||
const data = await db.data();
|
||||
console.log('loaded db data', data, this.node.AdditionalData);
|
||||
this.selectChoices = data.map(x => {
|
||||
return {
|
||||
display: x.data[this.node.AdditionalData.selectDatabaseDisplayColumnId],
|
||||
value: x.data[this.node.AdditionalData.selectDatabaseValueColumnId],
|
||||
};
|
||||
});
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
this.selectChoices = [];
|
||||
}
|
||||
}
|
||||
|
||||
triggerChangeCheck() {
|
||||
this.editorService.triggerSave();
|
||||
}
|
||||
|
||||
public isDirty(): boolean | Promise<boolean> {
|
||||
return this.value !== this.initialValue || this.forceDirty;
|
||||
}
|
||||
|
||||
// FIXME this isn't saving properly, write Mode = 'form'
|
||||
public writeChangesToNode(): void | Promise<void> {
|
||||
this.node.Value.Value = this.value;
|
||||
this.initialValue = this.value;
|
||||
}
|
||||
|
||||
public async onEditClick() {
|
||||
if ( this.isFilloutMode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const modal = await this.modals.create({
|
||||
component: FormInputOptionsComponent,
|
||||
componentProps: {
|
||||
node: this.nodeRec,
|
||||
editorUUID: this.editorUUID,
|
||||
},
|
||||
});
|
||||
|
||||
modal.onDidDismiss().then(result => {
|
||||
if ( result.data ) {
|
||||
this.forceDirty = true;
|
||||
this.editorService.triggerSave();
|
||||
|
||||
if (
|
||||
(
|
||||
this.node.type === 'form_input_select'
|
||||
|| this.node.type === 'form_input_multiselect'
|
||||
)
|
||||
&& this.node.AdditionalData.selectSource === 'database'
|
||||
) {
|
||||
this.loadSelectOptionsFromDatabase();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await modal.present();
|
||||
}
|
||||
}
|
@ -0,0 +1,313 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {EditorService} from '../../../../service/editor.service';
|
||||
import {ModalController} from '@ionic/angular';
|
||||
import HostRecord from '../../../../structures/HostRecord';
|
||||
import {debug} from '../../../../utility';
|
||||
import {DbApiService} from '../../../../service/db-api.service';
|
||||
import {Database, DatabaseColumn} from '../../../../structures/db-api';
|
||||
import {NodeTypeIcons} from '../../../../structures/node-types';
|
||||
|
||||
@Component({
|
||||
selector: 'noded-node-form-input-options',
|
||||
template: `
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Edit Form Input</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="dismissModal(true)">
|
||||
<ion-icon name="save"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-button (click)="dismissModal(false)">
|
||||
<ion-icon name="close"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col size="12">
|
||||
<ion-item>
|
||||
<ion-label [position]="'floating'">Label Text</ion-label>
|
||||
<ion-input [(ngModel)]="label"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col size="12">
|
||||
<ion-item>
|
||||
<ion-label [position]="'floating'">Placeholder Text</ion-label>
|
||||
<ion-input [(ngModel)]="placeholder"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col size="12">
|
||||
<ion-item>
|
||||
<ion-checkbox slot="start" [(ngModel)]="required">
|
||||
</ion-checkbox>
|
||||
Required
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row *ngIf="node.type === 'form_input_select' || node.type === 'form_input_multiselect'">
|
||||
<ion-col size="12" [title]="'Defines where the options for the select field should come from'">
|
||||
<ion-item>
|
||||
<ion-label [position]="'floating'">Select Options Source</ion-label>
|
||||
<ion-select
|
||||
[(ngModel)]="selectSource"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<ion-select-option value="local">Static Options</ion-select-option>
|
||||
<ion-select-option value="database">Database Values</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row
|
||||
*ngIf="
|
||||
(node.type === 'form_input_select' || node.type === 'form_input_multiselect')
|
||||
&& this.selectSource === 'database'"
|
||||
>
|
||||
<ion-col size="12">
|
||||
<ion-item>
|
||||
<ion-label position="floating">Source Database</ion-label>
|
||||
<ionic-selectable
|
||||
[items]="databases"
|
||||
itemTextField="name"
|
||||
itemValueField="uuid"
|
||||
[canSearch]="true"
|
||||
[title]="'Select a source database'"
|
||||
[(ngModel)]="selectedDatabase"
|
||||
(onChange)="onSelectDatabaseChange()"
|
||||
>
|
||||
<ng-template ionicSelectableItemTemplate let-port="item" let-isPortSelected="itemIsSelected">
|
||||
<div><i [ngClass]="typeIcons.db" style="margin-right: 15px;"></i>{{ port.name }}</div>
|
||||
</ng-template>
|
||||
</ionic-selectable>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row
|
||||
*ngIf="
|
||||
(node.type === 'form_input_select' || node.type === 'form_input_multiselect')
|
||||
&& this.selectSource === 'database' && this.selectedDatabase"
|
||||
>
|
||||
<ion-col size="6">
|
||||
<ion-item>
|
||||
<ion-label position="floating">Display Column</ion-label>
|
||||
<ionic-selectable
|
||||
[items]="selectedDatabaseColumns"
|
||||
itemTextField="name"
|
||||
itemValueField="uuid"
|
||||
[canSearch]="true"
|
||||
[title]="'Select the column to be used as the display value'"
|
||||
[(ngModel)]="selectDatabaseDisplayColumn"
|
||||
></ionic-selectable>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<ion-item>
|
||||
<ion-label position="floating">Value Column</ion-label>
|
||||
<ionic-selectable
|
||||
[items]="selectedDatabaseColumns"
|
||||
itemTextField="name"
|
||||
itemValueField="uuid"
|
||||
[canSearch]="true"
|
||||
[title]="'Select the column to be used as the record value'"
|
||||
[(ngModel)]="selectDatabaseValueColumn"
|
||||
></ionic-selectable>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row
|
||||
*ngIf="
|
||||
(node.type === 'form_input_select' || node.type === 'form_input_multiselect')
|
||||
&& this.selectSource === 'local'"
|
||||
>
|
||||
<ion-header style="display: flex; padding-top: 20px;">
|
||||
<h5 style="flex: 1;">Options</h5>
|
||||
<button [title]="'Add new option'" (click)="onAddSelectOption()">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</ion-header>
|
||||
<ion-grid>
|
||||
<ion-row *ngFor="let option of selectStaticOptions">
|
||||
<ion-col size="5">
|
||||
<ion-item>
|
||||
<ion-label position="floating">Display</ion-label>
|
||||
<ion-input [(ngModel)]="option.display"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col size="5">
|
||||
<ion-item>
|
||||
<ion-label position="floating">Value</ion-label>
|
||||
<ion-input [(ngModel)]="option.value"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col size="2">
|
||||
<button [title]="'Remove this option'" style="height: 100px; padding: 10px; color: red;" (click)="onRemoveSelectOption(option)">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-row>
|
||||
<ion-row *ngIf="node.type === 'form_input_password' || node.type === 'form_input_text'">
|
||||
<ion-col size="6">
|
||||
<ion-item>
|
||||
<ion-label [position]="'floating'">Min Length</ion-label>
|
||||
<ion-input type="'number'" [(ngModel)]="minLength"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<ion-item>
|
||||
<ion-label [position]="'floating'">Max Length</ion-label>
|
||||
<ion-input type="'number'" [(ngModel)]="maxLength"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row *ngIf="node.type === 'form_input_number'">
|
||||
<ion-col size="6">
|
||||
<ion-item>
|
||||
<ion-label [position]="'floating'">Min</ion-label>
|
||||
<ion-input type="'number'" [(ngModel)]="min"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<ion-item>
|
||||
<ion-label [position]="'floating'">Max</ion-label>
|
||||
<ion-input type="'number'" [(ngModel)]="max"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
`,
|
||||
})
|
||||
export class FormInputOptionsComponent implements OnInit {
|
||||
@Input() node: HostRecord;
|
||||
@Input() editorUUID: string;
|
||||
|
||||
public typeIcons = NodeTypeIcons;
|
||||
|
||||
public label = '';
|
||||
public placeholder = '';
|
||||
public required = false;
|
||||
|
||||
public minLength?: number;
|
||||
public maxLength?: number;
|
||||
|
||||
public min?: number;
|
||||
public max?: number;
|
||||
|
||||
public selectSource?: 'local'|'database';
|
||||
public selectDatabaseDisplayColumn?: DatabaseColumn;
|
||||
public selectDatabaseValueColumn?: DatabaseColumn;
|
||||
public selectStaticOptions: { display: string, value: string }[] = [];
|
||||
|
||||
public databases: Database[] = [];
|
||||
public selectedDatabase?: Database;
|
||||
public selectedDatabaseColumns: DatabaseColumn[] = [];
|
||||
|
||||
constructor(
|
||||
public editorService: EditorService,
|
||||
public readonly dbApi: DbApiService,
|
||||
public readonly modal: ModalController,
|
||||
) { }
|
||||
|
||||
async ngOnInit() {
|
||||
debug('Form input options', this);
|
||||
this.editorService = this.editorService.getEditor(this.editorUUID);
|
||||
|
||||
this.label = this.node.AdditionalData.label;
|
||||
this.placeholder = this.node.AdditionalData.placeholder;
|
||||
this.required = this.node.AdditionalData.required;
|
||||
|
||||
if ( this.node.type === 'form_input_password' || this.node.type === 'form_input_text' ) {
|
||||
this.minLength = this.node.AdditionalData.minLength;
|
||||
this.maxLength = this.node.AdditionalData.maxLength;
|
||||
}
|
||||
|
||||
if ( this.node.type === 'form_input_number' ) {
|
||||
this.min = this.node.AdditionalData.min;
|
||||
this.max = this.node.AdditionalData.max;
|
||||
}
|
||||
|
||||
if ( this.node.type === 'form_input_select' || this.node.type === 'form_input_multiselect' ) {
|
||||
this.selectSource = this.node.AdditionalData.selectSource;
|
||||
|
||||
this.databases = await this.dbApi.getDatabases();
|
||||
|
||||
if ( this.selectSource === 'database' ) {
|
||||
this.selectedDatabase = this.databases.find(x => x.uuid === this.node.AdditionalData.selectSourceDatabaseId);
|
||||
await this.onSelectDatabaseChange();
|
||||
|
||||
this.selectDatabaseValueColumn = this.selectedDatabaseColumns.find(x => {
|
||||
return x.field === this.node.AdditionalData.selectDatabaseValueColumnId;
|
||||
});
|
||||
|
||||
this.selectDatabaseDisplayColumn = this.selectedDatabaseColumns.find(x => {
|
||||
return x.field === this.node.AdditionalData.selectDatabaseDisplayColumnId;
|
||||
});
|
||||
} else if ( this.selectSource === 'local' ) {
|
||||
this.selectStaticOptions = this.node.AdditionalData.selectStaticOptions || [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dismissModal(success = true) {
|
||||
if ( success ) {
|
||||
this.node.AdditionalData.label = this.label;
|
||||
this.node.AdditionalData.placeholder = this.placeholder;
|
||||
this.node.AdditionalData.required = !!this.required;
|
||||
}
|
||||
|
||||
if ( this.node.type === 'form_input_password' || this.node.type === 'form_input_text' ) {
|
||||
this.node.AdditionalData.minLength = this.minLength;
|
||||
this.node.AdditionalData.maxLength = this.maxLength;
|
||||
}
|
||||
|
||||
if ( this.node.type === 'form_input_number' ) {
|
||||
this.node.AdditionalData.min = this.min;
|
||||
this.node.AdditionalData.max = this.max;
|
||||
}
|
||||
|
||||
if ( this.node.type === 'form_input_select' || this.node.type === 'form_input_multiselect' ) {
|
||||
this.node.AdditionalData.selectSource = this.selectSource;
|
||||
|
||||
if ( this.selectSource === 'database' ) {
|
||||
this.node.AdditionalData.selectSourceDatabaseId = this.selectedDatabase?.uuid;
|
||||
this.node.AdditionalData.selectDatabaseValueColumnId = this.selectDatabaseValueColumn?.field;
|
||||
this.node.AdditionalData.selectDatabaseDisplayColumnId = this.selectDatabaseDisplayColumn?.field;
|
||||
} else if ( this.selectSource === 'local' ) {
|
||||
this.node.AdditionalData.selectStaticOptions = this.selectStaticOptions;
|
||||
}
|
||||
}
|
||||
|
||||
this.modal.dismiss(success);
|
||||
}
|
||||
|
||||
async onSelectDatabaseChange() {
|
||||
if ( this.selectedDatabase ) {
|
||||
this.selectedDatabaseColumns = await this.selectedDatabase.columns();
|
||||
} else {
|
||||
this.selectedDatabaseColumns = [];
|
||||
}
|
||||
|
||||
this.selectDatabaseDisplayColumn = undefined;
|
||||
this.selectDatabaseValueColumn = undefined;
|
||||
}
|
||||
|
||||
onAddSelectOption() {
|
||||
this.selectStaticOptions.push({
|
||||
display: '',
|
||||
value: '',
|
||||
});
|
||||
}
|
||||
|
||||
onRemoveSelectOption(option: any) {
|
||||
this.selectStaticOptions = this.selectStaticOptions.filter(x => x !== option);
|
||||
}
|
||||
}
|
@ -1,13 +1,22 @@
|
||||
export const NodeTypeIcons = {
|
||||
branch: 'fa fa-folder',
|
||||
node: 'fa fa-quote-left',
|
||||
norm: 'fa fa-quote-left',
|
||||
page: 'fa fa-sticky-note',
|
||||
db: 'fa fa-database',
|
||||
database_ref: 'fa fa-database',
|
||||
code: 'fa fa-code',
|
||||
code_ref: 'fa fa-code',
|
||||
file_ref: 'fa fa-archive',
|
||||
files: 'fa fa-archive',
|
||||
markdown: 'fab fa-markdown',
|
||||
node: 'fa fa-quote-left noded-node',
|
||||
norm: 'fa fa-quote-left noded-node',
|
||||
form: 'fa fa-clipboard-list noded-form',
|
||||
page: 'fa fa-sticky-note noded-note',
|
||||
db: 'fa fa-database noded-db',
|
||||
database_ref: 'fa fa-database noded-db',
|
||||
code: 'fa fa-code noded-code',
|
||||
code_ref: 'fa fa-code noded-code',
|
||||
file_ref: 'fa fa-archive noded-files',
|
||||
files: 'fa fa-archive noded-files',
|
||||
markdown: 'fab fa-markdown noded-markdown',
|
||||
form_input_text: 'fa fa-font noded-form',
|
||||
form_input_number: 'fa fa-hashtag noded-form',
|
||||
form_input_password: 'fa fa-key noded-form',
|
||||
form_input_email: 'fa fa-envelope noded-form',
|
||||
form_input_select: 'fa fa-check noded-form',
|
||||
form_input_multiselect: 'fa fa-check-double noded-form',
|
||||
form_input_textarea: 'fa fa-paragraph noded-form',
|
||||
form_input_wysiwyg: 'fa fa-quote-right noded-form',
|
||||
};
|
||||
|
Loading…
Reference in new issue