mod form
This commit is contained in:
parent
810ced2efb
commit
ea5a64e732
|
@ -0,0 +1,91 @@
|
||||||
|
import scrollToElement from './scrollToElement.js';
|
||||||
|
|
||||||
|
var toastedOptions = {
|
||||||
|
position: 'top-right',
|
||||||
|
duration: 3000,
|
||||||
|
fitToScreen: true,
|
||||||
|
fullWidth: true,
|
||||||
|
theme: 'material',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (toasted) {
|
||||||
|
var toasted = new toasted(toastedOptions);
|
||||||
|
|
||||||
|
return {
|
||||||
|
finished: false,
|
||||||
|
submitRequest: null,
|
||||||
|
errorFields: [],
|
||||||
|
active: 0,
|
||||||
|
slideTo(e, index) {
|
||||||
|
if (e !== null) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
if (index < 0 || index > this.slides.length-1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.scrollForm(this.$refs.form);
|
||||||
|
this.active = index;
|
||||||
|
this.$refs.slider.scrollLeft = this.$refs.slider.scrollWidth / this.slides.length * index;
|
||||||
|
this.$refs.mobileSlider.scrollLeft = this.$refs.mobileSlider.scrollWidth / this.slides.length * index;
|
||||||
|
},
|
||||||
|
scrollForm(el) {
|
||||||
|
var margin = window.getComputedStyle(el).marginTop.replace('px', '');
|
||||||
|
scrollToElement(el, 300, (margin?margin:0) * -1);
|
||||||
|
},
|
||||||
|
submit() {
|
||||||
|
var _self = this;
|
||||||
|
var promise = fetch(window.location.href, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'X-WINTER-REQUEST-HANDLER': this.submitRequest,
|
||||||
|
'X-WINTER-REQUEST-PARTIALS': [],
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(this.data),
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.then(function(response) {
|
||||||
|
if (response.status === 422) {
|
||||||
|
response.json().then((errors) => {
|
||||||
|
_self.scrollToFirstError(errors);
|
||||||
|
Object.keys(errors).forEach((field) => {
|
||||||
|
toasted.error(errors[field].join('<br>'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (response.status === 201) {
|
||||||
|
_self.finished = true;
|
||||||
|
_self.scrollForm(_self.$refs.form);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
scrollToFirstError(errors) {
|
||||||
|
if (Object.keys(errors).length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstField = Object.keys(errors)[0];
|
||||||
|
var field = this.$refs.form.querySelector('[name="'+firstField+'"]');
|
||||||
|
|
||||||
|
if (field === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slideElement = field.closest('.slider-element');
|
||||||
|
this.slideTo(null, Array.from(slideElement.parentNode.children).indexOf(slideElement));
|
||||||
|
},
|
||||||
|
prevButton: {
|
||||||
|
[':class']() {
|
||||||
|
return this.active == 0 ? 'opacity-40' : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nextButton: {
|
||||||
|
[':class']() {
|
||||||
|
return this.active == this.core.slides.length - 1 ? 'opacity-40' : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ export default function (toasted) {
|
||||||
address: '',
|
address: '',
|
||||||
zip: '',
|
zip: '',
|
||||||
location: '',
|
location: '',
|
||||||
|
courses: [],
|
||||||
|
fcourses: [],
|
||||||
food_preferences: [],
|
food_preferences: [],
|
||||||
activity: 'Teilnehmer*in',
|
activity: 'Teilnehmer*in',
|
||||||
gender: '',
|
gender: '',
|
||||||
|
@ -34,7 +36,6 @@ export default function (toasted) {
|
||||||
parent: false,
|
parent: false,
|
||||||
vorteam: null,
|
vorteam: null,
|
||||||
},
|
},
|
||||||
meta: {
|
|
||||||
finished: false,
|
finished: false,
|
||||||
submitRequest: null,
|
submitRequest: null,
|
||||||
errorFields: [],
|
errorFields: [],
|
||||||
|
@ -53,6 +54,10 @@ export default function (toasted) {
|
||||||
{"id": "Weiblich", "name": "Weiblich"},
|
{"id": "Weiblich", "name": "Weiblich"},
|
||||||
{"id": "Divers", "name": "Divers"},
|
{"id": "Divers", "name": "Divers"},
|
||||||
],
|
],
|
||||||
|
fcourses: [
|
||||||
|
{"id": "Ich bin Samstags beim Abendprogramm dabei", "name": "Ich bin Samstags beim Abendprogramm dabei"},
|
||||||
|
{"id": "Ich esse sonntag Mittag mit", "name": "Ich esse sonntag Mittag mit"},
|
||||||
|
],
|
||||||
groups: [
|
groups: [
|
||||||
{"id": "Gallier", "name": "Gallier (Wuppertal)"},
|
{"id": "Gallier", "name": "Gallier (Wuppertal)"},
|
||||||
{"id": "Gandalf", "name": "Gandalf (SG-Mangenberg)"},
|
{"id": "Gandalf", "name": "Gandalf (SG-Mangenberg)"},
|
||||||
|
@ -71,6 +76,10 @@ export default function (toasted) {
|
||||||
{"id": "Rover", "name": "Rover"},
|
{"id": "Rover", "name": "Rover"},
|
||||||
{"id": "Leiter*in", "name": "Leiter*in"},
|
{"id": "Leiter*in", "name": "Leiter*in"},
|
||||||
],
|
],
|
||||||
|
agegroupsroverleiter: [
|
||||||
|
{"id": "Rover", "name": "Rover"},
|
||||||
|
{"id": "Leiter*in", "name": "Leiter*in"},
|
||||||
|
],
|
||||||
agegroups_leaders: [
|
agegroups_leaders: [
|
||||||
{"id": "Biber", "name": "Biber"},
|
{"id": "Biber", "name": "Biber"},
|
||||||
{"id": "Wölfling", "name": "Wölfling"},
|
{"id": "Wölfling", "name": "Wölfling"},
|
||||||
|
@ -87,26 +96,33 @@ export default function (toasted) {
|
||||||
{"id": "Vegan", "name": "Ich ernähre mich vegan"},
|
{"id": "Vegan", "name": "Ich ernähre mich vegan"},
|
||||||
{"id": "Glutenfrei", "name": "Ich vertrage kein Gluten"},
|
{"id": "Glutenfrei", "name": "Ich vertrage kein Gluten"},
|
||||||
{"id": "Laktosefrei", "name": "Ich vertrage keine Laktose"},
|
{"id": "Laktosefrei", "name": "Ich vertrage keine Laktose"},
|
||||||
]
|
],
|
||||||
},
|
foodPreferencesVeg: [
|
||||||
methods: {
|
{"id": "Vegan", "name": "Ich ernähre mich vegan"},
|
||||||
uuu(event) {
|
{"id": "Glutenfrei", "name": "Ich vertrage kein Gluten"},
|
||||||
console.log(event);
|
{"id": "Laktosefrei", "name": "Ich vertrage keine Laktose"},
|
||||||
},
|
],
|
||||||
hasAddress() {
|
get courses() {
|
||||||
return this.data.location && this.data.address && this.data.zip;
|
return this.data.agegroup === 'Rover' ? [
|
||||||
|
{id: 'Schritt 2', name: 'Schritt 2', hint: 'Sonntag, 10 - 18 Uhr'},
|
||||||
|
] : [
|
||||||
|
{id: 'Baustein 2c', name: 'Baustein 2c', hint: 'Pfadfinderische Methodik - Samstag 10 - 18 Uhr'},
|
||||||
|
{id: 'Baustein 2e', name: 'Baustein 2e', hint: 'Präventionsschulung - Sonntag 10 - 13 Uhr'},
|
||||||
|
{id: 'Baustein 3c', name: 'Baustein 3c', hint: 'Finanzen, Haftung, Versicherung - Sonntag 14 - 17 Uhr'},
|
||||||
|
{id: 'Schritt 2', name: 'Schritt 2', hint: 'Sonntag, 10 - 18 Uhr'},
|
||||||
|
];
|
||||||
},
|
},
|
||||||
slideTo(e, index) {
|
slideTo(e, index) {
|
||||||
if (e !== null) {
|
if (e !== null) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
if (index < 0 || index > this.meta.slides.length-1) {
|
if (index < 0 || index > this.slides.length-1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.scrollForm(this.$refs.form);
|
this.scrollForm(this.$refs.form);
|
||||||
this.meta.active = index;
|
this.active = index;
|
||||||
this.$refs.slider.scrollLeft = this.$refs.slider.scrollWidth / this.meta.slides.length * index;
|
this.$refs.slider.scrollLeft = this.$refs.slider.scrollWidth / this.slides.length * index;
|
||||||
this.$refs.mobileSlider.scrollLeft = this.$refs.mobileSlider.scrollWidth / this.meta.slides.length * index;
|
this.$refs.mobileSlider.scrollLeft = this.$refs.mobileSlider.scrollWidth / this.slides.length * index;
|
||||||
},
|
},
|
||||||
scrollForm(el) {
|
scrollForm(el) {
|
||||||
var margin = window.getComputedStyle(el).marginTop.replace('px', '');
|
var margin = window.getComputedStyle(el).marginTop.replace('px', '');
|
||||||
|
@ -119,7 +135,7 @@ export default function (toasted) {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'X-WINTER-REQUEST-HANDLER': this.meta.submitRequest,
|
'X-WINTER-REQUEST-HANDLER': this.submitRequest,
|
||||||
'X-WINTER-REQUEST-PARTIALS': [],
|
'X-WINTER-REQUEST-PARTIALS': [],
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
},
|
},
|
||||||
|
@ -136,7 +152,7 @@ export default function (toasted) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (response.status === 201) {
|
if (response.status === 201) {
|
||||||
_self.meta.finished = true;
|
_self.finished = true;
|
||||||
_self.scrollForm(_self.$refs.form);
|
_self.scrollForm(_self.$refs.form);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -156,8 +172,6 @@ export default function (toasted) {
|
||||||
var slideElement = field.closest('.slider-element');
|
var slideElement = field.closest('.slider-element');
|
||||||
this.slideTo(null, Array.from(slideElement.parentNode.children).indexOf(slideElement));
|
this.slideTo(null, Array.from(slideElement.parentNode.children).indexOf(slideElement));
|
||||||
},
|
},
|
||||||
},
|
|
||||||
spreads: {
|
|
||||||
prevButton: {
|
prevButton: {
|
||||||
[':class']() {
|
[':class']() {
|
||||||
return this.active == 0 ? 'opacity-40' : '';
|
return this.active == 0 ? 'opacity-40' : '';
|
||||||
|
@ -165,12 +179,9 @@ export default function (toasted) {
|
||||||
},
|
},
|
||||||
nextButton: {
|
nextButton: {
|
||||||
[':class']() {
|
[':class']() {
|
||||||
return this.active == this.meta.slides.length - 1 ? 'opacity-40' : '';
|
return this.active == this.slides.length - 1 ? 'opacity-40' : '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
|
||||||
init() {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
import scrollToElement from './scrollToElement.js';
|
||||||
|
|
||||||
|
var toastedOptions = {
|
||||||
|
position: 'top-right',
|
||||||
|
duration: 3000,
|
||||||
|
fitToScreen: true,
|
||||||
|
fullWidth: true,
|
||||||
|
theme: 'material',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function (toasted) {
|
||||||
|
var toasted = new toasted(toastedOptions);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
event_id: null,
|
||||||
|
firstname: '',
|
||||||
|
lastname: '',
|
||||||
|
address: '',
|
||||||
|
zip: '',
|
||||||
|
location: '',
|
||||||
|
courses: [],
|
||||||
|
fcourses: [],
|
||||||
|
food_preferences: [],
|
||||||
|
activity: 'Teilnehmer*in',
|
||||||
|
gender: '',
|
||||||
|
email: '',
|
||||||
|
birthday: '',
|
||||||
|
agegroup: '',
|
||||||
|
group: '',
|
||||||
|
agegroup_leader: '',
|
||||||
|
emergency_phone: '',
|
||||||
|
phone: '',
|
||||||
|
misc: '',
|
||||||
|
foto: false,
|
||||||
|
parent: false,
|
||||||
|
vorteam: null,
|
||||||
|
},
|
||||||
|
finished: false,
|
||||||
|
submitRequest: null,
|
||||||
|
errorFields: [],
|
||||||
|
active: 0,
|
||||||
|
slides: [
|
||||||
|
'Persönliches',
|
||||||
|
'Veranstaltung',
|
||||||
|
'Sonstiges'
|
||||||
|
],
|
||||||
|
activities: [
|
||||||
|
{"id": "Orga", "name": "Orga"},
|
||||||
|
{"id": "Teilnehmer*in", "name": "Teilnehmer*in"},
|
||||||
|
],
|
||||||
|
genders: [
|
||||||
|
{"id": "Männlich", "name": "Männlich"},
|
||||||
|
{"id": "Weiblich", "name": "Weiblich"},
|
||||||
|
{"id": "Divers", "name": "Divers"},
|
||||||
|
],
|
||||||
|
fcourses: [
|
||||||
|
{"id": "Ich bin Samstags beim Abendprogramm dabei", "name": "Ich bin Samstags beim Abendprogramm dabei"},
|
||||||
|
{"id": "Ich esse sonntag Mittag mit", "name": "Ich esse sonntag Mittag mit"},
|
||||||
|
],
|
||||||
|
groups: [
|
||||||
|
{"id": "Gallier", "name": "Gallier (Wuppertal)"},
|
||||||
|
{"id": "Gandalf", "name": "Gandalf (SG-Mangenberg)"},
|
||||||
|
{"id": "Gravenrode", "name": "Gravenrode (SG-Gräfrath)"},
|
||||||
|
{"id": "Lennep", "name": "Lennep (RS-Lennep)"},
|
||||||
|
{"id": "Silva", "name": "Silva (SG-Wald)"},
|
||||||
|
{"id": "Sugambrer", "name": "Sugambrer (SG-Höhscheid)"},
|
||||||
|
{"id": "Tenkterer", "name": "Tenkterer (SG-Löhdorf)"},
|
||||||
|
{"id": "von Berg", "name": "von Berg (SG-Ohligs)"},
|
||||||
|
],
|
||||||
|
agegroups: [
|
||||||
|
{"id": "Biber", "name": "Biber"},
|
||||||
|
{"id": "Wölfling", "name": "Wölfling"},
|
||||||
|
{"id": "Jungpfadfinder", "name": "Jungpfadfinder"},
|
||||||
|
{"id": "Pfadfinder", "name": "Pfadfinder"},
|
||||||
|
{"id": "Rover", "name": "Rover"},
|
||||||
|
{"id": "Leiter*in", "name": "Leiter*in"},
|
||||||
|
],
|
||||||
|
agegroupsroverleiter: [
|
||||||
|
{"id": "Rover", "name": "Rover"},
|
||||||
|
{"id": "Leiter*in", "name": "Leiter*in"},
|
||||||
|
],
|
||||||
|
agegroups_leaders: [
|
||||||
|
{"id": "Biber", "name": "Biber"},
|
||||||
|
{"id": "Wölfling", "name": "Wölfling"},
|
||||||
|
{"id": "Jungpfadfinder", "name": "Jungpfadfinder"},
|
||||||
|
{"id": "Pfadfinder", "name": "Pfadfinder"},
|
||||||
|
{"id": "Rover", "name": "Rover"},
|
||||||
|
],
|
||||||
|
boolean: [
|
||||||
|
{"id": "Ja", "name": "Ja"},
|
||||||
|
{"id": "Nein", "name": "Nein"},
|
||||||
|
],
|
||||||
|
foodPreferences: [
|
||||||
|
{"id": "Fleisch", "name": "Ich esse Fleisch"},
|
||||||
|
{"id": "Vegan", "name": "Ich ernähre mich vegan"},
|
||||||
|
{"id": "Glutenfrei", "name": "Ich vertrage kein Gluten"},
|
||||||
|
{"id": "Laktosefrei", "name": "Ich vertrage keine Laktose"},
|
||||||
|
],
|
||||||
|
foodPreferencesVeg: [
|
||||||
|
{"id": "Vegan", "name": "Ich ernähre mich vegan"},
|
||||||
|
{"id": "Glutenfrei", "name": "Ich vertrage kein Gluten"},
|
||||||
|
{"id": "Laktosefrei", "name": "Ich vertrage keine Laktose"},
|
||||||
|
],
|
||||||
|
get courses() {
|
||||||
|
return this.data.agegroup === 'Rover' ? [
|
||||||
|
{"id": "Schritt 2", "name": "Schritt 2"},
|
||||||
|
] : [
|
||||||
|
{"id": "Baustein 2a", "name": "Baustein 2a"},
|
||||||
|
{"id": "Baustein 2c", "name": "Baustein 2c"},
|
||||||
|
{"id": "Baustein 3c", "name": "Baustein 3c"},
|
||||||
|
{"id": "Schritt 2", "name": "Schritt 2"},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
slideTo(e, index) {
|
||||||
|
if (e !== null) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
if (index < 0 || index > this.slides.length-1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.scrollForm(this.$refs.form);
|
||||||
|
this.active = index;
|
||||||
|
this.$refs.slider.scrollLeft = this.$refs.slider.scrollWidth / this.slides.length * index;
|
||||||
|
this.$refs.mobileSlider.scrollLeft = this.$refs.mobileSlider.scrollWidth / this.slides.length * index;
|
||||||
|
},
|
||||||
|
scrollForm(el) {
|
||||||
|
var margin = window.getComputedStyle(el).marginTop.replace('px', '');
|
||||||
|
scrollToElement(el, 300, (margin?margin:0) * -1);
|
||||||
|
},
|
||||||
|
submit() {
|
||||||
|
var _self = this;
|
||||||
|
var promise = fetch(window.location.href, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'X-WINTER-REQUEST-HANDLER': this.submitRequest,
|
||||||
|
'X-WINTER-REQUEST-PARTIALS': [],
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(this.data),
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.then(function(response) {
|
||||||
|
if (response.status === 422) {
|
||||||
|
response.json().then((errors) => {
|
||||||
|
_self.scrollToFirstError(errors);
|
||||||
|
Object.keys(errors).forEach((field) => {
|
||||||
|
toasted.error(errors[field].join('<br>'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (response.status === 201) {
|
||||||
|
_self.finished = true;
|
||||||
|
_self.scrollForm(_self.$refs.form);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
scrollToFirstError(errors) {
|
||||||
|
if (Object.keys(errors).length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstField = Object.keys(errors)[0];
|
||||||
|
var field = this.$refs.form.querySelector('[name="'+firstField+'"]');
|
||||||
|
|
||||||
|
if (field === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slideElement = field.closest('.slider-element');
|
||||||
|
this.slideTo(null, Array.from(slideElement.parentNode.children).indexOf(slideElement));
|
||||||
|
},
|
||||||
|
prevButton: {
|
||||||
|
[':class']() {
|
||||||
|
return this.active == 0 ? 'opacity-40' : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nextButton: {
|
||||||
|
[':class']() {
|
||||||
|
return this.active == this.slides.length - 1 ? 'opacity-40' : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Zoomyboy\Event\Classes;
|
||||||
|
|
||||||
|
use Cms\Classes\CmsCompoundObject;
|
||||||
|
use File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CMS content file class.
|
||||||
|
*
|
||||||
|
* @author Alexey Bobkov, Samuel Georges
|
||||||
|
*/
|
||||||
|
class Jsonfile extends CmsCompoundObject
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string the container name associated with the model, eg: pages
|
||||||
|
*/
|
||||||
|
protected $dirName = 'json';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array allowable file extensions
|
||||||
|
*/
|
||||||
|
protected $allowedExtensions = ['json'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array list of attribute names which are not considered "settings"
|
||||||
|
*/
|
||||||
|
protected $purgeable = [];
|
||||||
|
|
||||||
|
public function markup(): array
|
||||||
|
{
|
||||||
|
return json_decode($this->content, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVar(string $var)
|
||||||
|
{
|
||||||
|
return array_get($this->markup(), $var);
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,32 +40,15 @@ class EventForm extends ComponentBase
|
||||||
public function onRender()
|
public function onRender()
|
||||||
{
|
{
|
||||||
$this->customInit($this->property('event_id'));
|
$this->customInit($this->property('event_id'));
|
||||||
|
|
||||||
|
return $this->renderPartial('@'.$this->event->slug.'.htm');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onSubmit(): JsonResponse
|
public function onSubmit(): JsonResponse
|
||||||
{
|
{
|
||||||
$this->customInit(Input::get('event_id'));
|
$this->customInit(Input::get('event_id'));
|
||||||
|
|
||||||
$rules = [
|
$rules = $this->event->loadConfig('validator');
|
||||||
'activity' => 'required|max:255',
|
|
||||||
'gender' => 'required|max:255',
|
|
||||||
'firstname' => 'required|max:255',
|
|
||||||
'lastname' => 'required|max:255',
|
|
||||||
'birthday' => 'required|date|before_or_equal:'.now()->format('Y-m-d'),
|
|
||||||
'address' => 'required|max:255',
|
|
||||||
'zip' => 'required|numeric',
|
|
||||||
'location' => 'required|max:255',
|
|
||||||
'phone' => 'required|max:255',
|
|
||||||
'email' => 'required|max:255|email',
|
|
||||||
'agegroup' => 'required|max:255',
|
|
||||||
'group' => 'nullable|max:255',
|
|
||||||
'agegroup_leader' => 'nullable|max:255',
|
|
||||||
'emergency_phone' => 'required|max:255',
|
|
||||||
'food_preferences' => 'array',
|
|
||||||
'misc' => '',
|
|
||||||
'foto' => '',
|
|
||||||
'parent' => 'boolean|accepted',
|
|
||||||
];
|
|
||||||
|
|
||||||
if ('Orga' === Input::get('activity')) {
|
if ('Orga' === Input::get('activity')) {
|
||||||
$rules['vorteam'] = 'in:Ja,Nein';
|
$rules['vorteam'] = 'in:Ja,Nein';
|
||||||
|
@ -80,13 +63,15 @@ class EventForm extends ComponentBase
|
||||||
return response()->json($validator->errors(), 422);
|
return response()->json($validator->errors(), 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
$participant = Participant::create(array_merge($validator->validated(), [
|
$participant = Participant::create([
|
||||||
'vorteam' => 'Ja' === Input::get('vorteam'),
|
'firstname' => Input::get('firstname'),
|
||||||
|
'lastname' => Input::get('lastname'),
|
||||||
|
'email' => Input::get('email'),
|
||||||
'event_id' => $this->event->id,
|
'event_id' => $this->event->id,
|
||||||
]));
|
'payload' => Input::all(),
|
||||||
Mail::send('zoomyboy.event::mail.confirm', ['data' => $participant, 'until' => '1.9.2023', 'iban' => 'XXX', 'birthday' => $participant->birthday->format('d.m.Y')], function ($message) use ($participant) {
|
]);
|
||||||
|
Mail::send('confirm_'.$this->event->slug, ['data' => Input::all()], function ($message) use ($participant) {
|
||||||
$message->to($participant->email, $participant->firstname.' '.$participant->lastname);
|
$message->to($participant->email, $participant->firstname.' '.$participant->lastname);
|
||||||
$message->subject('Deine Anmeldung fürs Bezirkslager');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return response()->json([], 201);
|
return response()->json([], 201);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<div class="flex flex-col items-center space-y-4 md:space-y-0 md:flex-row mt-10 justify-start md:justify-evenly">
|
<div class="flex flex-col items-center space-y-4 md:space-y-0 md:flex-row mt-10 justify-start md:justify-evenly">
|
||||||
{% if not first %}
|
{% if not first %}
|
||||||
<div class="bg-primary hover:bg-emerald-600 px-4 py-2 shadow text-teal-200 leading-none cursor-pointer rounded-lg" @click.prevent="slideTo($event, meta.active - 1)">
|
<div class="bg-primary hover:bg-emerald-600 px-4 py-2 shadow text-teal-200 leading-none cursor-pointer rounded-lg" @click.prevent="slideTo($event, active - 1)">
|
||||||
Zurück
|
Zurück
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not last %}
|
{% if not last %}
|
||||||
<div class="bg-primary hover:bg-emerald-600 px-4 py-2 shadow text-teal-200 leading-none cursor-pointer rounded-lg" @click.prevent="slideTo($event, meta.active + 1)">
|
<div class="bg-primary hover:bg-emerald-600 px-4 py-2 shadow text-teal-200 leading-none cursor-pointer rounded-lg" @click.prevent="slideTo($event, active + 1)">
|
||||||
Weiter
|
Weiter
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
namespace Zoomyboy\Event\Models;
|
namespace Zoomyboy\Event\Models;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use Model;
|
use Model;
|
||||||
|
use Zoomyboy\Event\Classes\Jsonfile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event Model.
|
* Event Model.
|
||||||
|
@ -77,8 +79,16 @@ class Event extends Model
|
||||||
public $attachOne = [];
|
public $attachOne = [];
|
||||||
public $attachMany = [];
|
public $attachMany = [];
|
||||||
|
|
||||||
public static function getOptions(): array
|
public static function getOptions()
|
||||||
{
|
{
|
||||||
return static::pluck('name', 'id')->toArray();
|
return static::pluck('name', 'id')->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function loadConfig($v)
|
||||||
|
{
|
||||||
|
$file = $this->slug.'.json';
|
||||||
|
throw_unless(Jsonfile::find($file), Exception::class, 'Datei '.$file.' nicht gefunden.');
|
||||||
|
|
||||||
|
return Jsonfile::find($file)->getVar($v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Participant extends Model
|
||||||
/**
|
/**
|
||||||
* @var array Attributes to be cast to JSON
|
* @var array Attributes to be cast to JSON
|
||||||
*/
|
*/
|
||||||
protected $jsonable = ['food_preferences'];
|
protected $jsonable = ['payload'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array Attributes to be appended to the API representation of the model (ex. toArray())
|
* @var array Attributes to be appended to the API representation of the model (ex. toArray())
|
||||||
|
|
|
@ -6,3 +6,6 @@ columns:
|
||||||
name:
|
name:
|
||||||
label: Name
|
label: Name
|
||||||
searchable: true
|
searchable: true
|
||||||
|
slug:
|
||||||
|
label: Slug
|
||||||
|
searchable: true
|
||||||
|
|
|
@ -24,10 +24,13 @@ class CreateEventsTable extends Migration
|
||||||
|
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('zoomyboy_event_events');
|
if (Schema::hasTable('zoomyboy_event_participants')) {
|
||||||
|
Schema::table('zoomyboy_event_participants', function (Blueprint $table) {
|
||||||
Schema::create('zoomyboy_event_participants', function (Blueprint $table) {
|
$table->dropForeign(['event_id']);
|
||||||
$table->dropColumn('event_id');
|
$table->dropColumn('event_id');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Schema::dropIfExists('zoomyboy_event_events');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,26 +12,10 @@ class CreateParticipantsTable extends Migration
|
||||||
{
|
{
|
||||||
Schema::create('zoomyboy_event_participants', function (Blueprint $table) {
|
Schema::create('zoomyboy_event_participants', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->string('gender');
|
|
||||||
$table->string('firstname');
|
$table->string('firstname');
|
||||||
$table->string('lastname');
|
$table->string('lastname');
|
||||||
$table->date('birthday');
|
|
||||||
$table->string('email');
|
$table->string('email');
|
||||||
$table->string('group')->nullable();
|
$table->json('payload');
|
||||||
$table->string('agegroup');
|
|
||||||
$table->string('agegroup_leader');
|
|
||||||
$table->boolean('vorteam')->default(false);
|
|
||||||
$table->boolean('foto');
|
|
||||||
$table->boolean('parent');
|
|
||||||
$table->string('emergency_phone');
|
|
||||||
$table->string('address');
|
|
||||||
$table->string('zip');
|
|
||||||
$table->string('location');
|
|
||||||
$table->string('phone');
|
|
||||||
$table->string('activity');
|
|
||||||
$table->json('food_preferences');
|
|
||||||
$table->string('further_food_preferences')->nullable();
|
|
||||||
$table->text('misc')->nullable();
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
{% macro field(context, name, label, required, type) %}
|
||||||
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
||||||
|
<input name="{{name}}" type="{{type|default('text')}}" id="{{name}}" placeholder=" " class="bg-white rounded-lg focus:outline-none text-gray-600 text-left placeholder-white peer py-1 px-2 sm:py-2 text-sm sm:text-base sm:px-3 w-full" x-model="data.{{name}}" />
|
||||||
|
<span
|
||||||
|
class="transition-all duration-200 absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 peer-placeholder-shown:bottom-0 peer-placeholder-shown:-top-0
|
||||||
|
text-xs xs:text-sm peer-placeholder-shown:text-sm xs:peer-placeholder-shown:text-base peer-focus:text-xs xs:peer-focus:text-sm
|
||||||
|
peer-focus:-top-3 peer-focus:bottom-auto "
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro textarea(context, name, label, required, type) %}
|
||||||
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex">
|
||||||
|
<textarea name="{{name}}" rows="6" id="{{name}}" class="bg-white rounded-lg focus:outline-none text-gray-600 text-left placeholder-white peer py-1 px-2 sm:py-2 text-sm sm:text-base sm:px-3 w-full" x-model="data.{{name}}">
|
||||||
|
</textarea>
|
||||||
|
<span
|
||||||
|
class="transition-all duration-200 absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-xs xs:text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro select(context, name, label, required, options) %}
|
||||||
|
<label class="w-full border border-solid border-gray-500 focus-within:border-primary rounded-lg relative flex" for="{{name}}">
|
||||||
|
<select name="{{name}}" id="{{name}}" class="bg-white rounded-lg focus:outline-none text-gray-600 text-left peer py-1 px-2 sm:py-2 text-sm sm:text-base sm:px-3 w-full" x-model="data.{{name}}">
|
||||||
|
<option :selected="data.{{name}} === ''" value="">-- kein --</option>
|
||||||
|
<template x-for="model in {{options}}">
|
||||||
|
<option :selected="data.{{name}} === model.id" :value="model.id" x-text="model.name"></option>
|
||||||
|
</template>
|
||||||
|
</select>
|
||||||
|
<span
|
||||||
|
class="absolute text-gray-600 left-2 flex bg-white items-center -top-3 px-1 text-xs xs:text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro radio(context, name, label, required, options) %}
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text-gray-600 text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
<div class="grid grid-cols-2 sm:grid-cols-1 gap-2">
|
||||||
|
<template x-for="option, index in {{options}}">
|
||||||
|
<label :for="`{{name}}-${index}`" class="block relative flex items-center">
|
||||||
|
<input type="radio" name="{{name}}" :value="option.name" x-model="data.{{name}}" class="peer absolute invisible" :id="`{{name}}-${index}`" />
|
||||||
|
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded-full block"></span>
|
||||||
|
<span class="peer-checked:bg-primary left-2 w-2 h-2 absolute rounded-full block"></span>
|
||||||
|
<span class="pl-8" x-text="option.name"></span>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro yesno(context, name, label, required) %}
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-col space-y-1">
|
||||||
|
<label for="{{name}}" class="block relative flex items-center">
|
||||||
|
<input type="checkbox" name="{{name}}" x-model="data.{{name}}" class="peer absolute invisible" id="{{name}}" />
|
||||||
|
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block"></span>
|
||||||
|
<span class="peer-checked:bg-primary left-2 w-2 h-2 absolute rounded-sm block"></span>
|
||||||
|
<span class="pl-8 text-sm">{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
{% macro checkboxes(context, name, label, required, options) %}
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text-gray-600 flex text-sm"
|
||||||
|
>{{label}} {% if required %} <span class="text-red-800 ml-1">*</span> {% endif %}</span
|
||||||
|
>
|
||||||
|
<div class="mt-2 grid gap-2">
|
||||||
|
<template x-for="option, index in {{options}}">
|
||||||
|
<label :for="`{{name}}-${index}`" class="block relative flex items-center">
|
||||||
|
<input type="checkbox" name="{{name}}[]" :value="option.name" x-model="data.{{name}}" class="peer absolute invisible" :id="`{{name}}-${index}`" />
|
||||||
|
<span class="border-neutral-400 border-4 border-solid peer-checked:border-primary absolute left-0 w-6 h-6 rounded block"></span>
|
||||||
|
<span class="peer-checked:bg-primary left-2 w-2 h-2 absolute rounded-sm block"></span>
|
||||||
|
<span class="pl-8 text-sm sm:text-base flex flex-col">
|
||||||
|
<span x-text="option.name" class="block" class="leading-none"></span>
|
||||||
|
<template x-if="option.hint">
|
||||||
|
<span class="text-xs leading-none text-gray-500" x-text="option.hint"></span>
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
Loading…
Reference in New Issue