Skip to content

Form Component #151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c7e6576
introduction of a forms component
reusr1 Aug 12, 2020
eec8db3
Added success page and failure message dialog options
qial Aug 13, 2020
e3cb545
Added more options to Form's model
qial Aug 17, 2020
f0b255b
Updated form component with test submit code
qial Aug 17, 2020
289a91e
Updated form to use javascript function correctly and fixed dialog is…
qial Aug 19, 2020
d4dc94d
Fixed failure message coming through
qial Aug 19, 2020
cbfe6d7
Updated submitfunction workings
qial Aug 19, 2020
2bb5e16
Updated submitfunction to correctly handle all forms of functions and…
qial Aug 20, 2020
74bb4e7
Fixed functions inside of objects, but doesn't fail well when the obj…
qial Aug 20, 2020
07ce128
Fixed functions inside nested objects in the submitfunction dialog
qial Aug 20, 2020
77057b8
Changed defaultSubmit to onSubmit, changed function not found alert t…
qial Aug 20, 2020
fd9728f
Fixed some styling issues, cleaned up form dialog with hints
qial Aug 20, 2020
5152f32
Updated onSubmit closure to better format so 'this' is carried over
qial Aug 20, 2020
88ca794
Cleaned up useless cases in the submit function loop
qial Aug 20, 2020
75dcf2f
Updated error messages for bad json in the form field model
qial Aug 20, 2020
0196f01
Added _blank target to form model docs link, and removed inline editi…
qial Aug 20, 2020
9c83f7b
poc style implementation of a data list component and a save/load han…
reusr1 Aug 20, 2020
35849d3
Merge branch 'issues/136' of https://github.com/headwirecom/themeclea…
reusr1 Aug 20, 2020
ce28f34
Updated form samples and added sample-all with all supported inputs
qial Aug 21, 2020
99450b8
Updated sample content to fix jcr import error
qial Aug 21, 2020
4184cc1
#136 added styles to error messages and submit btn
smcgrath0 Aug 24, 2020
ba6e404
Fixed Submit button text and other issues with formatting
qial Aug 24, 2020
77c84f1
#136 added transition for error message
smcgrath0 Aug 24, 2020
6ae0a1c
#136 added submit button in all example schemas and removed in markup
smcgrath0 Aug 24, 2020
b44317b
Merge branch 'issues/136' of https://github.com/headwirecom/themeclea…
smcgrath0 Aug 24, 2020
f247851
#136 added styles for all inputs
smcgrath0 Aug 24, 2020
9c24c09
#136 added button alignment and size dialog/styling
smcgrath0 Aug 24, 2020
3862af1
#136 fixed class string/fixed font on textarea/select
smcgrath0 Aug 25, 2020
e7da0a8
updated inline settings for failure messages
qial Aug 25, 2020
5dac11f
Added groups to the input type sample form
qial Aug 25, 2020
3fb9e95
#136 fixed form alignment issue/group styling/checkbox alignment
smcgrath0 Aug 25, 2020
2e29646
#136 dialog button size: sm,lg -> small, large
smcgrath0 Aug 25, 2020
797f0f0
Merge branch 'issues/136' of https://github.com/headwirecom/themeclea…
smcgrath0 Aug 25, 2020
51c8a9c
#136 removed form error transition
smcgrath0 Sep 4, 2020
fe2c405
Merge remote-tracking branch 'upstream/issues/136' into issues/136
qial Sep 4, 2020
056aa96
#136 removing a final setTimeout on the error message
qial Sep 4, 2020
c53e69d
Merge branch 'develop' of https://github.com/headwirecom/themeclean-f…
smcgrath0 Sep 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
545 changes: 545 additions & 0 deletions core/src/main/java/com/themecleanflex/models/DatalistModel.java

Large diffs are not rendered by default.

680 changes: 680 additions & 0 deletions core/src/main/java/com/themecleanflex/models/FormModel.java

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions fragments/datalist/hatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
convert: function($, f) {
f.wrap($, 'themecleanflex-components-block')
f.bindAttribute($.parent(),'model','model')
f.mapField($, 'storageData')
}
}
28 changes: 28 additions & 0 deletions fragments/datalist/model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"definitions": {
"Datalist": {
"type": "object",
"x-type": "component",
"properties": {
"endpointurl": {
"type": "string",
"x-source": "inject",
"x-form-label": "Form submit endpoint URL",
"x-form-type": "text",
"x-default": ""
},
"loadFunction": {
"type": "string",
"x-source": "inject",
"x-form-label": "Javascript function to call to load data",
"x-form-hint": "Function must accept (name)",
"x-form-type": "text"
},
"bgref": {
"$ref": "fragments/block/model.json#/definitions/Block",
"x-form-type": "reference"
}
}
}
}
}
7 changes: 7 additions & 0 deletions fragments/datalist/sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"title": "Datalist",
"group": "",
"model": {
"text": "example"
}
}
1 change: 1 addition & 0 deletions fragments/datalist/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div>datalist</div>
23 changes: 23 additions & 0 deletions fragments/datalist/template.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<themecleanflex-components-block v-bind:model="model">
<div data-per-inline="storageData">{{storageData}}</div>
</themecleanflex-components-block>
</template>

<script>
export default {
props: ['model'],
data() {
return {
storageData: JSON.parse(localStorage.getItem('list'))
}
},
mounted() {
// interesting aspect :-) if another tab on the same computer
// has the same page open it actually updates
window.addEventListener('storage', () => {
this.storageData = JSON.parse(localStorage.getItem('list'))
});
}
}
</script>
45 changes: 45 additions & 0 deletions fragments/form/hatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module.exports = {
convert: function($, f) {
f.wrap($, 'themecleanflex-components-block')
f.bindAttribute($.parent(),'model','model')

const failureP = $.find('p').eq(0)
f.mapField(failureP,'failureText',false)
f.addIf(failureP, "failureText");
const schemaErrorP = $.find('p').eq(1)
f.mapField(schemaErrorP,'schemaError',false)
f.addIf(schemaErrorP, "schemaError");

const messageContainer = $.find('div').eq(0);
f.addIf(messageContainer, "( failureText || schemaError )");

const submit = $.find('input').first()
f.bindAttribute(submit,'value','model.submittext')

const formContainer = $.find('form').eq(0);
let formContainerClasses = `{
'justify-button-start': model.submitalignment === 'start',
'justify-button-center': model.submitalignment === 'center',
'justify-button-end': model.submitalignment === 'end',
'normal-button': model.submitsize === 'normal',
'sm-button': model.submitsize === 'small',
'lg-button': model.submitsize === 'large',
'full-button': model.submitsize === 'full',
}`
f.bindAttribute(formContainer, 'class', formContainerClasses, false);

const div2 = $.find('div').eq(1)
f.replace(div2, '<vue-form-generator></vue-form-generator>')

const formEl = $.find('form')
f.bindEvent(formEl,'submit.prevent.stop','onSubmit')

const form = $.find('vue-form-generator').first()
f.bindAttribute(form,'class','`w-full`', false)
f.bindAttribute(form,'model','formModel')
f.bindAttribute(form,'schema','schema')
f.bindAttribute(form,'options','formOptions')

f.bindPath($)
}
}
104 changes: 104 additions & 0 deletions fragments/form/model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"definitions": {
"Form": {
"type": "object",
"x-type": "component",
"properties": {
"schema": {
"type": "string",
"x-source": "inject",
"x-form-label": "Form Model",
"x-form-type": "textarea",
"x-form-hint": "JSON description passed to vue-form-generator, see <a href='https://vue-generators.gitbook.io/vue-generators/fields' target='_blank'>vue form generator fields documentation</a>",
"x-form-max": "16000"
},
"endpointurl": {
"type": "string",
"x-source": "inject",
"x-form-label": "Form submit endpoint URL",
"x-form-type": "text",
"x-default": ""
},
"submitfunction": {
"type": "string",
"x-source": "inject",
"x-form-label": "Javascript function to call on submit",
"x-form-hint": "Function must accept (model, formdata)",
"x-form-type": "text",
"x-default": ""
},
"submittext": {
"type": "string",
"x-source": "inject",
"x-form-label": "Submit Button Text",
"x-form-type": "text",
"x-default": "Submit"
},
"submitsize": {
"type": "string",
"x-source": "inject",
"x-form-label": "Submit button size",
"x-form-type": "materialselect",
"x-default": "normal",
"properties":{
"section": {
"x-form-name": "normal",
"x-form-value": "normal"
},
"small": {
"x-form-name": "small",
"x-form-value": "small"
},
"large": {
"x-form-name": "large",
"x-form-value": "large"
},
"full": {
"x-form-name": "full width",
"x-form-value": "full"
}
}
},
"submitalignment": {
"type": "string",
"x-source": "inject",
"x-form-label": "Submit button alignment",
"x-form-type": "materialselect",
"x-default": "start",
"properties":{
"start": {
"x-form-name": "start",
"x-form-value": "start"
},
"center": {
"x-form-name": "center",
"x-form-value": "center"
},
"end": {
"x-form-name": "end",
"x-form-value": "end"
}
}
},
"failmessage": {
"type": "string",
"x-source": "inject",
"x-form-label": "Failure Message",
"x-form-type": "text",
"x-default": "Error processing form"
},
"successpage": {
"type": "string",
"x-source": "inject",
"x-form-type": "pathbrowser",
"x-form-label": "Submit Success Page",
"x-form-browserRoot": "/content/themecleanflex/pages"
},
"bgref": {
"$ref": "fragments/block/model.json#/definitions/Block",
"x-form-type": "reference"
}
}
}
}
}
7 changes: 7 additions & 0 deletions fragments/form/sample-all.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"title": "Form - Input Types",
"group": "Features",
"model": {
"schema": "{\n\"groups\":[\n{\n\"legend\":\"Text Inputs\",\n\"fields\": [\n {\n \"type\": \"label\",\n \"label\": \"Label\",\n \"model\": \"label\"\n },{\n \"type\": \"input\",\n \"inputType\": \"text\",\n \"label\": \"Text\",\n \"model\": \"text\",\n \"id\": \"text\",\n \"placeholder\": \"Text\"\n },{\n \"type\": \"textArea\",\n \"label\": \"Text Area\",\n \"model\": \"textarea\",\n \"id\": \"textarea\",\n \"rows\": 4,\n \"placeholder\": \"Enter text here\"\n }\n ]\n},\n{\n\"legend\":\"Other Inputs\",\n\"fields\": [\n {\n \"type\": \"radios\",\n \"label\": \"Radios\",\n \"model\": \"radios\",\n \"values\": [\n \"Option 1\",\n \"Option 2\"\n ]\n },{\n \"type\": \"checkbox\",\n \"label\": \"Checkbox\",\n \"model\": \"checkbox\",\n \"default\": true\n },{\n \"type\": \"checklist\",\n \"label\": \"Checklist\",\n \"model\": \"checklist\",\n \"listBox\": true,\n \"values\": [\n \"Option 1\",\n \"Option 2\"\n ]\n },{\n \"type\": \"select\",\n \"label\": \"Select\",\n \"model\": \"select\",\n \"values\": [\n \"Option 1\",\n \"Option 2\"\n ]\n },{\n \"type\": \"submit\",\n \"buttonText\": \"Submit Button\",\n \"validateBeforeSubmit\": false\n }\n]}]}"
}
}
7 changes: 7 additions & 0 deletions fragments/form/sample-contact.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"title": "Form - Contact",
"group": "Features",
"model": {
"schema": "{\n\"fields\": [\n {\n \"type\": \"input\",\n \"inputType\": \"text\",\n \"label\": \"First Name\",\n \"model\": \"first_name\",\n \"id\": \"first_name\",\n \"placeholder\": \"First Name\"\n },{\n \"type\": \"input\",\n \"inputType\": \"text\",\n \"label\": \"Last Name\",\n \"model\": \"last_name\",\n \"id\": \"last_name\",\n \"placeholder\": \"Last Name\"\n },{\n \"type\": \"input\",\n \"inputType\": \"text\",\n \"label\": \"Email\",\n \"model\": \"email\",\n \"id\": \"email\",\n \"placeholder\": \"Email\",\n \"featured\": true,\n \"required\": true\n },{\n \"type\": \"textArea\",\n \"label\": \"Text\",\n \"model\": \"text\",\n \"id\": \"text\",\n \"rows\": 4,\n \"placeholder\": \"Enter text here\",\n \"featured\": true,\n \"required\": true\n }\n]}"
}
}
7 changes: 7 additions & 0 deletions fragments/form/sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"title": "Form",
"group": "Features",
"model": {
"schema": "{\n\"fields\": [\n {\n \"type\": \"input\",\n \"inputType\": \"text\",\n \"label\": \"Name\",\n \"model\": \"name\",\n \"id\": \"user_name\",\n \"placeholder\": \"Your name\",\n \"featured\": true,\n \"required\": true\n }\n]}"
}
}
10 changes: 10 additions & 0 deletions fragments/form/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="w-full">
<div class="text-black p-2 rounded-r mt-4 border-l-4 shadow-md note-important">
<p class="ml-2"></p>
<p class="ml-2"></p>
</div>
<form class="w-full flex flex-col">
<div></div>
<input class="btn mb-4" type="submit">
</form>
</div>
94 changes: 94 additions & 0 deletions fragments/form/template.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<template>
<themecleanflex-components-block v-bind:model="model">
<div class="w-full" v-bind:data-per-path="model.path">
<div class="text-black p-2 rounded-r mt-4 border-l-4 shadow-md note-important"
v-if="( failureText || schemaError )">
<p class="ml-2" v-if="failureText">{{failureText}}</p>
<p class="ml-2" v-if="schemaError">{{schemaError}}</p>
</div>
<form class="w-full flex flex-col" v-bind:class="{
'justify-button-start': model.submitalignment === 'start',
'justify-button-center': model.submitalignment === 'center',
'justify-button-end': model.submitalignment === 'end',
'normal-button': model.submitsize === 'normal',
'sm-button': model.submitsize === 'small',
'lg-button': model.submitsize === 'large',
'full-button': model.submitsize === 'full',
}" v-on:submit.prevent.stop="onSubmit">
<vue-form-generator v-bind:class="`w-full`" v-bind:model="formModel" v-bind:schema="schema"
v-bind:options="formOptions"></vue-form-generator>
<input class="btn mb-4" type="submit" v-bind:value="model.submittext">
</form>
</div>
</themecleanflex-components-block>
</template>

<script>
export default {
props: ['model'],
data() {
return {
formModel: {},
formOptions: {
validateAfterChange: true
},
failureText: ''
}
},
methods: {
onSubmit(e) {
if(this.model.submitfunction != 'onSubmit' && this.model.submitfunction != '') {
const objs = this.model.submitfunction.split('.')
let parent = window
let i = 0
while(i < objs.length && parent[objs[i]]) {
if(i == objs.length-1) {
try {
const result = parent[objs[i]](this.model,this.formModel)
if(result === false) {
Vue.set(this, 'failureText', this.model.failmessage);
}
} catch(err) {
console.error(err)
Vue.set(this, 'failureText', this.model.failmessage);
}
return
}
parent = parent[objs[i]]
i++
}
console.log('window.' + this.model.submitfunction + ' not found')
Vue.set(this, 'failureText', this.model.failmessage);
return
}
axios.post(this.model.endpointurl, {
form: this.formModel
})
.then( (response) => {
$peregrineApp.loadContent(this.model.successpage)
})
.catch( (error) => {
Vue.set(this, 'failureText', this.model.failmessage);
})
}
},
computed: {
schema() {
try {
return JSON.parse(this.model.schema)
} catch( error ) {
return { fields: [] }
}
},
schemaError() {
try {
JSON.parse(this.model.schema)
} catch( error ) {
return 'Error parsing form model: ' + error
}
return ''
}
}
}
</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="per:Component" jcr:title="Datalist" group="">
<jcr:content jcr:primaryType="nt:unstructured" text="example"/>
</jcr:root>
Loading