Skip to content

Commit

Permalink
pkp/pkp-lib#3594 Initial implementation of Form component
Browse files Browse the repository at this point in the history
  • Loading branch information
NateWr committed May 24, 2018
1 parent d1bd2a1 commit 0bf891d
Show file tree
Hide file tree
Showing 9 changed files with 618 additions and 0 deletions.
116 changes: 116 additions & 0 deletions src/components/Form/Form.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<template>
<form
method="POST"
class="pkpForm -pkpClearfix"
:action="action"
>
<form-page v-for="page in pages"
:key="page.id"
:id="page.id"
:submitOnNext="page.submitOnNext"
:groups="groups"
:fields="fields"
:formId="id"
:activeLocales="activeLocales"
:availableLocales="availableLocales"
@toggleLocale="toggleLocale"
@change="fieldChanged"
/>
<div v-if="submitButton" class="pkpForm__buttons">
<pkp-button
:label="submitButton.label"
:isPrimary="submitButton.isPrimary"
:isWarnable="submitButton.isWarnable"
:isLink="submitButton.isLink"
:isActive="submitButton.isActive"
:withicon="submitButton.withicon"
@click.prevent.stop="submit"
/>
</div>
</form>
</template>

<script>
import FormPage from './FormPage.vue';
import PkpButton from '@/components/Button/Button.vue';
export default {
name: 'Form',
components: {
FormPage,
PkpButton,
},
data: function () {
return {
id: '',
action: '',
errors: [],
object: null,
fields: [],
groups: [],
pages: [],
submitButton: null,
activeLocales: [],
};
},
computed: {
/**
* Available form locales
*
* @return array
*/
availableLocales: function () {
return $.pkp.app.formLocales;
},
},
methods: {
/**
* Submit the form
*/
submit: function () {
console.log('submit');
},
/**
* Change the locale
*
* @param string localeKey (eg - "en_US")
*/
toggleLocale: function (localeKey) {
if (this.activeLocales.includes(localeKey)) {
this.activeLocales.splice(this.activeLocales.indexOf(localeKey), 1);
} else {
this.activeLocales.push(localeKey);
}
},
/**
* Update values when a field has changed
*
* @param object data {{
* @option string name Field name
* @option string value New value
* @option string localeKey Locale key for this value. Empty it not multilingual
* }}
*/
fieldChanged: function (data) {
console.log('field changed', data);
},
},
mounted: function () {
// Set the current locale
if (!this.activeLocales.length) {
this.activeLocales = [this.availableLocales[0].key];
}
},
};
</script>

<style lang="less">
@import '../../styles/_import';
.pkpForm__buttons {
padding: @base;
}
</style>
122 changes: 122 additions & 0 deletions src/components/Form/FormGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<template>
<fieldset class="pkpFormGroup -pkpClearfix">
<div v-if="label" class="pkpFormGroup__heading">
<legend class="pkpFormGroup__legend">{{ label }}</legend>
<div v-if="description" class="pkpFormGroup__description" v-html="description"></div>
</div>
<div class="pkpFormGroup__fields">
<template v-for="field in fieldsInGroup">
<template v-if="field.isMultilingual">
<div v-for="locale in availableLocales" class="pkpFormGroup__locale" :class="{'-isActive': activeLocales.includes(locale)}">
<component
:is="field.component"
v-bind="field"
:localeKey="locale.key"
:formId="formId"
@change="fieldChanged"
></component>
</div>
</template>
<template v-else>
<component
:is="field.component"
v-bind="field"
:formId="formId"
@change="fieldChanged"
></component>
</template>
</template>
</div>
</fieldset>
</template>

<script>
import FieldText from '@/components/Form/fields/FieldText.vue';
export default {
name: 'FormGroup',
components: {
FieldText,
},
props: {
id: String,
label: [String, Object],
description: [String, Object],
pageId: String,
fields: Array,
formId: String,
activeLocales: Array,
availableLocales: Array,
},
computed: {
/**
* All fields assigned to this group
*
* @return array
*/
fieldsInGroup: function () {
return this.fields.filter(field => field.groupId === this.id);
},
/**
* Are there any multilingual fields in this group?
*
* @return boolean
*/
isMultilingual: function () {
return this.availableLocales.length > 1 &&
this.fieldsInGroup.find((field) => field.isMultilingual === true);
},
},
methods: {
/**
* Emit an event when a field's value has changed
*
* @param object data {{
* @option string name Field name
* @option string value New value
* @option string localeKey Locale key for this value. Empty it not multilingual
* }}
*/
fieldChanged: function (data) {
this.$emit('change', data);
},
},
};
</script>

<style lang="less">
@import '../../styles/_import';
.pkpFormGroup {
position: relative;
padding: @base;
border: none;
}
.pkpFormGroup__heading {
float: left;
width: 30%;
padding-right: 1.5rem;
line-height: @line-sml;
+ .pkpFormGroup__fields {
float: right;
width: 70%;
padding-left: 1.5rem;
}
}
.pkpFormGroup__legend {
display: inline-block;
font-weight: @bold;
}
.pkpFormGroup__description {
font-size: @font-sml;
}
.pkpFormGroup .pkpFormField + .pkpFormField {
margin-top: @base + @half;
}
</style>
86 changes: 86 additions & 0 deletions src/components/Form/FormPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<template>
<div class="pkpFormPage">
<div v-if="isMultilingual" class="pkpFormPage__locales">
<pkp-button v-for="locale in availableLocales"
:key="locale.key"
:label="locale.label"
@click.prevent.stop="toggleLocale(locale.key)"
/>
</div>
<form-group v-for="group in groupsInPage"
:key="group.id"
v-bind="group"
:fields="fields"
:activeLocales="activeLocales"
:availableLocales="availableLocales"
@change="fieldChanged"
/>
</div>
</template>

<script>
import FormGroup from '@/components/Form/FormGroup.vue';
import PkpButton from '@/components/Button/Button.vue';
export default {
name: 'FormPage',
components: {
FormGroup,
PkpButton,
},
props: {
id: String,
submitOnNext: {
type: Boolean,
default: false,
},
groups: Array,
fields: Array,
activeLocales: Array,
availableLocales: Array,
},
computed: {
/**
* All groups assigned to this page
*
* @return array
*/
groupsInPage: function () {
return this.groups.filter(group => group.pageId === this.id);
},
/**
* All assigned to groups on this page
*
* @return array
*/
fieldsInPage: function () {
return this.fields.filter(field => this.groupsInPage.includes(this.fields.groupId));
},
/**
* Are there any multilingual fields on this page?
*
* @return boolean
*/
isMultilingual: function () {
return this.availableLocales.length > 1 &&
this.fieldsInPage.find((field) => field.isMultilingual === true);
},
},
methods: {
/**
* Emit an event when a field's value has changed
*
* @param object data {{
* @option string name Field name
* @option string value New value
* @option string localeKey Locale key for this value. Empty it not multilingual
* }}
*/
fieldChanged: function (data) {
this.$emit('change', data);
},
},
};
</script>
Loading

0 comments on commit 0bf891d

Please sign in to comment.