the idea is to make a livebuilder with livewire
Last active
December 11, 2022 15:57
-
-
Save Zakarialabib/ef0caaf91aa5ca8860523dd171e52eb7 to your computer and use it in GitHub Desktop.
LiveBuilder with Livewire Laravel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div x-data="{ edit: {{ $edit ? 'true' : 'false' }} }"> | |
| <div> | |
| <button | |
| x-show="!edit" | |
| @click="edit = true" | |
| class="btn btn-primary" | |
| > | |
| Edit Sections | |
| </button> | |
| </div> | |
| {{-- Use the `x-show` directive to toggle the visibility of the form based on the value of the `edit` variable. --}} | |
| <form | |
| x-show="edit" | |
| wire:submit.prevent="updateSections" | |
| x-cloak | |
| > | |
| {{-- Use the `x-model` directive to bind the form input values to the reactive properties in the component. --}} | |
| @foreach ($sections as $index => $section) | |
| <div class="form-group"> | |
| <label for="title-{{ $index }}">Title:</label> | |
| <input | |
| type="text" | |
| id="title-{{ $index }}" | |
| class="form-control" | |
| wire:model="sections.{{ $index }}.title" | |
| x-model="sections.{{ $index }}.title" | |
| > | |
| </div> | |
| <div class="form-group"> | |
| <label for="description-{{ $index }}">Description:</label> | |
| <textarea | |
| id="description-{{ $index }}" | |
| class="form-control" | |
| wire:model="sections.{{ $index }}.description" | |
| x-model="sections.{{ $index }}.description" | |
| ></textarea> | |
| </div> | |
| <div class="form-group"> | |
| <label for="image-{{ $index }}">Image:</label> | |
| <input | |
| type="file" | |
| id="image-{{ $index }}" | |
| class="form-control" | |
| wire:model="sections.{{ $index }}.image" | |
| x-model="sections.{{ $index }}.image" | |
| > | |
| </div> | |
| @livewire('live-builder-styler', ['styles' => $section]) | |
| <button type="submit" class="btn btn-primary">Update Section</button> | |
| @endforeach | |
| <button type="button" @click="edit = false" class="btn btn-secondary">Cancel</button> | |
| <button type="submit" class="btn btn-primary">Update Sections</button> | |
| </form> | |
| {{-- Use the `x-inner-html` directive to render the `LiveBuilder` component HTML in the view. --}} | |
| <div x-data="{}" x-inner-html="{{ $liveBuilderHtml }}"></div> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div> | |
| <h2 class="text-xl font-bold mb-2">Styles</h2> | |
| {{-- Use the `x-data` directive to define the `edit` variable, which is used to toggle the visibility of the form. --}} | |
| <div x-data="{ edit: {{ $edit ? 'true' : 'false' }} }"> | |
| {{-- Use the `x-show` directive to toggle the visibility of the form based on the value of the `edit` variable. --}} | |
| <form | |
| x-show="edit" | |
| wire:submit.prevent="updateStyles" | |
| x-cloak | |
| > | |
| {{-- Use the `x-model` directive to bind the form input values to the reactive properties in the component. --}} | |
| <div class="mb-4"> | |
| <label | |
| for="title-size" | |
| class="block text-gray-700 text-sm font-bold mb-2" | |
| > | |
| Title Size: | |
| </label> | |
| <input | |
| type="number" | |
| id="title-size" | |
| class="form-control" | |
| wire:model="styles.titleSize" | |
| x-model="styles.titleSize" | |
| > | |
| </div> | |
| <div class="mb-4"> | |
| <label | |
| for="title-color" | |
| class="block text-gray-700 text-sm font-bold mb-2" | |
| > | |
| Title Color: | |
| </label> | |
| <input | |
| type="color" | |
| id="title-color" | |
| class="form-control" | |
| wire:model="styles.titleColor" | |
| x-model="styles.titleColor" | |
| > | |
| </div> | |
| <div class="mb-4"> | |
| <label | |
| for="title-align" | |
| class="block text-gray-700 text-sm font-bold mb-2" | |
| > | |
| Title Alignment: | |
| </label> | |
| <select | |
| id="title-align" | |
| class="form-control" | |
| wire:model="styles.titleAlign" | |
| x-model="styles.titleAlign" | |
| > | |
| <option value="left">Left</option> | |
| <option value="center">Center</option> | |
| <option value="right">Right</option> | |
| </select> | |
| </div> | |
| {{-- Other style options... --}} | |
| <button type="submit" class="btn btn-primary">Update Styles</button> | |
| </form> | |
| {{-- Use the `x-show` directive to toggle the visibility of the style preview based on the value of the `edit` variable. --}} | |
| <div x-show="!edit"> | |
| <h3 | |
| class="font-bold" x-bind:style="{ | |
| fontSize: styles.titleSize + 'px', | |
| color: styles.titleColor, | |
| textAlign: styles.titleAlign, | |
| // Other styles... | |
| }" | |
| > | |
| Preview Title | |
| </h3> | |
| {{-- Other style previews... --}} | |
| <button | |
| type="button" | |
| @click="edit = true" | |
| class="btn btn-primary" | |
| > | |
| Edit Styles | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div> | |
| <h2 class="text-xl font-bold mb-2">Sections</h2> | |
| @foreach ($sections as $index => $section) | |
| {{-- Use the `x-data` directive to define the `edit` variable, which is used to toggle the visibility of the form. --}} | |
| <div | |
| class="section" | |
| wire:key="{{ $index }}" | |
| x-data="{ edit: {{ $edit ? 'true' : 'false' }} }" | |
| > | |
| {{-- Use the `x-show` directive to toggle the visibility of the form based on the value of the `edit` variable. --}} | |
| <form | |
| x-show="edit" | |
| wire:submit.prevent="updateSection({{ $index }})" | |
| x-cloak | |
| > | |
| {{-- Use the `x-model` directive to bind the form input values to the reactive properties in the component. --}} | |
| <div class="mb-4"> | |
| <label | |
| for="title-{{ $index }}" | |
| class="block text-gray-700 text-sm font-bold mb-2" | |
| > | |
| Title: | |
| </label> | |
| <input | |
| type="text" | |
| id="title-{{ $index }}" | |
| class="form-control" | |
| wire:model="sections.{{ $index }}.title" | |
| x-model="sections.{{ $index }}.title" | |
| > | |
| </div> | |
| <div class="mb-4"> | |
| <label | |
| for="description-{{ $index }}" | |
| class="block text-gray-700 text-sm font-bold mb-2" | |
| > | |
| Description: | |
| </label> | |
| <textarea | |
| id="description-{{ $index }}" | |
| class="form-control" | |
| wire:model="sections.{{ $index }}.description" | |
| x-model="sections.{{ $index }}.description" | |
| ></textarea> | |
| </div> | |
| <div class="mb-4"> | |
| <label | |
| for="image-{{ $index }}" | |
| class="block text-gray-700 text-sm font-bold mb-2" | |
| > | |
| Image: | |
| </label> | |
| <input | |
| type="file" | |
| id="image-{{ $index }}" | |
| class="form-control" | |
| wire:model="sections.{{ $index }}.image" | |
| x-model="sections.{{ $index }}.image" | |
| > | |
| </div> | |
| @livewire('live-builder-styler', ['styles' => $section]) | |
| <button type="submit" class="btn btn-primary">Update Section</button> | |
| </form> | |
| {{-- Use the `x-show` directive to toggle the visibility of the section content based on the value of the `edit` variable. --}} | |
| <div x-show="!edit"> | |
| <h3 | |
| class="text-2xl font-bold mb-2" | |
| x-text="sections.{{ $index }}.title" | |
| ></h3> | |
| <p | |
| class="text-gray-700 text-base" | |
| x-text="sections.{{ $index }}.description" | |
| ></p> | |
| <img | |
| x-bind:src="sections.{{ $index }}.image" | |
| class="w-full" | |
| x-show="sections.{{ $index }}.image" | |
| > | |
| <button | |
| type="button" | |
| @click="edit = true" | |
| class="btn btn-primary" | |
| > | |
| Edit Section | |
| </button> | |
| </div> | |
| </div> | |
| @endforeach | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Http\Livewire; | |
| use Livewire\Component; | |
| class LiveBuilder extends Component | |
| { | |
| // Reactive properties to store the page title, description, and image. | |
| public $title; | |
| public $description; | |
| public $image; | |
| // Reactive property to store the sections for the page. | |
| public $sections = []; | |
| // Reactive property to track whether the user is currently editing a section. | |
| public $edit = false; | |
| // Use the `mount` lifecycle hook to initialize the reactive properties with any existing page data. | |
| public function mount($page) | |
| { | |
| $this->title = $page->title; | |
| $this->description = $page->description; | |
| $this->image = $page->image; | |
| $this->sections = $page->sections; | |
| } | |
| // Use the `save` method to handle the form submission and save the page to the database. | |
| public function save() | |
| { | |
| // Validate the form input. | |
| $this->validate([ | |
| 'title' => 'required', | |
| 'description' => 'required', | |
| 'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048', | |
| ]); | |
| // Save the page to the database. | |
| Page::create([ | |
| 'title' => $this->title, | |
| 'description' => $this->description, | |
| 'image' => $this->image, | |
| 'sections' => $this->sections, | |
| ]); | |
| // Redirect the user to the page they just created. | |
| return redirect()->to(route('page', ['id' => $page->id])); | |
| } | |
| // Use the `addSection` method to add a new section to the page. | |
| public function addSection() | |
| { | |
| $this->sections[] = [ | |
| 'title' => '', | |
| 'description' => '', | |
| 'image' => '', | |
| ]; | |
| } | |
| // Use the `updateSection` method to update an existing section on the page. | |
| public function updateSection($index) | |
| { | |
| // Validate the form input. | |
| $this->validate([ | |
| "sections.{$index}.title" => 'required', | |
| "sections.{$index}.description" => 'required', | |
| "sections.{$index}.image" => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048', | |
| ]); | |
| // Set the edit property to false to exit edit mode. | |
| $this->edit = false; | |
| } | |
| // Use the `removeSection` method to remove a section from the page. | |
| public function removeSection($index) | |
| { | |
| unset($this->sections[$index]); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Http\Livewire; | |
| use Livewire\Component; | |
| class LiveBuilderGenerator extends Component | |
| { | |
| // Reactive properties to store the sections and styles. | |
| public $sections = [ | |
| [ | |
| 'title' => 'Section 1', | |
| 'description' => 'This is the first section.', | |
| 'image' => '', | |
| 'titleSize' => '1.5rem', | |
| 'titleColor' => '#333', | |
| 'titleAlign' => 'left', | |
| 'descriptionSize' => '1rem', | |
| 'descriptionColor' => '#666', | |
| 'descriptionAlign' => 'left', | |
| 'position' => 'left' | |
| ] | |
| ]; | |
| public $edit; | |
| // Use the `updated` lifecycle hook to generate the LiveBuilder component HTML when the sections or styles change. | |
| public function updated($field) | |
| { | |
| if ($field === 'sections' || $field === 'styles') { | |
| $this->generateLiveBuilder(); | |
| } | |
| } | |
| // Generate the LiveBuilder component HTML and store it in a reactive property. | |
| public function generateLiveBuilder() | |
| { | |
| $this->liveBuilderHtml = view('livewire.livebuilder') | |
| ->with('sections', $this->sections) | |
| ->with('edit', $this->edit) | |
| ->render(); | |
| } | |
| public function render() | |
| { | |
| return view('livewire.livebuilder-generator'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Http\Livewire; | |
| use Livewire\Component; | |
| class LiveBuilderStyler extends Component | |
| { | |
| // Reactive properties to store the title and description styles. | |
| public $titleSize; | |
| public $titleColor; | |
| public $titleAlign; | |
| public $descriptionSize; | |
| public $descriptionColor; | |
| public $descriptionAlign; | |
| public $position; | |
| // Use the `mount` lifecycle hook to initialize the reactive properties with any existing style data. | |
| public function mount($styles) | |
| { | |
| $this->titleSize = $styles['titleSize']; | |
| $this->titleColor = $styles['titleColor']; | |
| $this->titleAlign = $styles['titleAlign']; | |
| $this->descriptionSize = $styles['descriptionSize']; | |
| $this->descriptionColor = $styles['descriptionColor']; | |
| $this->descriptionAlign = $styles['descriptionAlign']; | |
| $this->position = $styles['position']; | |
| } | |
| public function render() | |
| { | |
| return view('livewire.livebuilder-styler'); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment