Skip to content

Commit 3a45607

Browse files
lorenloren
authored andcommitted
Integrate FormBuilder with BlnFormular to allow dynamic field rendering via templateResult property. Add Storybook example showcasing the integration.
1 parent eab7186 commit 3a45607

File tree

2 files changed

+103
-1
lines changed

2 files changed

+103
-1
lines changed

src/components/BlnFormular.stories.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import './BlnFormular';
55
import './BlnInput';
66
import './BlnButton';
77
import './BlnCheckBox';
8+
import { FormBuilder } from './FormBuilder';
89

910
interface BlnFormularProps {
1011
ariaLabel: string;
@@ -432,3 +433,100 @@ export const RetroDesign: Story = {
432433
},
433434
},
434435
};
436+
437+
export const WithFormBuilder: Story = {
438+
render: (args) => {
439+
const formularId = `formular-fb-${Math.random().toString(36).slice(2)}`;
440+
441+
// Use setTimeout to ensure the DOM is ready before manipulating it
442+
setTimeout(() => {
443+
const formular = document.getElementById(formularId) as any;
444+
if (!formular) return;
445+
446+
// Create FormBuilder instance with fields
447+
const fb = new FormBuilder()
448+
.addBlnInput({
449+
label: 'Vorname',
450+
name: 'firstname',
451+
placeholder: 'Ihr Vorname',
452+
required: true
453+
})
454+
.addBlnInput({
455+
label: 'E-Mail',
456+
name: 'email',
457+
type: 'email',
458+
placeholder: 'name@example.com',
459+
required: true
460+
})
461+
.addBlnInput({
462+
label: 'Alter',
463+
name: 'age',
464+
type: 'number',
465+
value: '25'
466+
})
467+
.addBlnCheckbox({
468+
name: 'newsletter',
469+
label: 'Newsletter',
470+
checked: true
471+
});
472+
473+
// Pass FormBuilder fields to BlnFormular
474+
formular.templateResult = fb.getFields();
475+
}, 100);
476+
477+
return html`
478+
<bln-formular
479+
id=${formularId}
480+
legend="FormBuilder Integration"
481+
@bln-submit=${(e: any) => console.log('📋 FormBuilder Submit:', e.detail.data)}
482+
@bln-clear=${() => console.log('🧹 FormBuilder Clear')}
483+
@bln-delete=${() => console.log('🗑️ FormBuilder Delete')}>
484+
485+
<div slot="actions" class="flex gap-2">
486+
<bln-button @click=${(e: Event) => (e.currentTarget as HTMLElement).closest('bln-formular')?.submit?.()}>Speichern</bln-button>
487+
<bln-button variant="outline" @click=${(e: any) => (e.currentTarget as any).closest('bln-formular')?.delete?.()}>Löschen</bln-button>
488+
<bln-button variant="ghost" @click=${(e: any) => (e.currentTarget as any).closest('bln-formular')?.clear?.()}>Leeren</bln-button>
489+
</div>
490+
</bln-formular>
491+
<div class="mt-4 p-4 bg-gray-50 rounded">
492+
<h4 class="font-semibold mb-2">FormBuilder Integration Code:</h4>
493+
<pre class="text-sm bg-gray-800 text-green-400 p-3 rounded overflow-x-auto"><code>import { FormBuilder } from './FormBuilder';
494+
495+
// Create FormBuilder with fields
496+
const fb = new FormBuilder()
497+
.addBlnInput({ label: 'Name', name: 'name', required: true })
498+
.addBlnCheckbox({ name: 'newsletter', checked: true })
499+
.addBlnSelect({ name: 'city', options: [...] });
500+
501+
// Get formular element
502+
const formular = document.getElementById('myForm');
503+
504+
// Pass FormBuilder fields to BlnFormular
505+
formular.templateResult = fb.getFields();</code></pre>
506+
</div>
507+
`;
508+
},
509+
parameters: {
510+
docs: {
511+
description: {
512+
story: `
513+
**FormBuilder Integration mit BlnFormular**
514+
515+
Dieses Beispiel zeigt, wie Sie FormBuilder-Felder direkt an ein BlnFormular übergeben können:
516+
517+
**Integration:**
518+
1. **FormBuilder erstellen:** \`new FormBuilder()\` mit gewünschten Feldern
519+
2. **Felder übergeben:** \`formular.templateResult = fb.getFields()\`
520+
3. **Automatische Sammlung:** BlnFormular sammelt alle Daten beim Submit
521+
522+
**Unterstützte FormBuilder-Methoden:**
523+
- \`addBlnInput()\` - Text, Email, Password, Number inputs
524+
- \`addBlnCheckbox()\` - Checkboxen mit boolean values
525+
- \`addBlnSelect()\` - Dropdown-Auswahlen
526+
527+
Die FormBuilder-Felder werden automatisch im BlnFormular gerendert und bei submit() in den Event-Daten erfasst. Öffnen Sie die Browser-Konsole, um die Daten zu sehen.
528+
`.trim(),
529+
},
530+
},
531+
},
532+
};

src/components/BlnFormular.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {customElement, property, queryAssignedElements} from 'lit/decorators.js';
2-
import {html, nothing} from 'lit';
2+
import {html, nothing, TemplateResult} from 'lit';
33
import TailwindElement from '../app/TailwindElement';
44

55
import './BlnInput';
@@ -28,6 +28,9 @@ export class BlnFormular extends TailwindElement {
2828
/** Enable retro design styling. */
2929
@property({type: Boolean, reflect: true, attribute: 'retro-design'}) retroDesign: boolean = false;
3030

31+
/** Template results from FormBuilder - only settable as property, not attribute */
32+
@property({attribute: false}) templateResult: TemplateResult[] = [];
33+
3134
// Grab slotted elements we can read values from
3235
@queryAssignedElements({flatten: true}) private _slotted!: Element[];
3336
@queryAssignedElements({slot: 'actions', flatten: true}) private _actions!: Element[];
@@ -161,6 +164,7 @@ export class BlnFormular extends TailwindElement {
161164
)}">${this.legend}</h2>` : nothing}
162165
<div class="contents">
163166
<slot></slot>
167+
${this.templateResult.length > 0 ? html`${this.templateResult}` : nothing}
164168
</div>
165169
<div class="${this.cn(
166170
['mt-4 pt-4 flex flex-wrap gap-2 justify-end'],

0 commit comments

Comments
 (0)