1
votes

In laravel 7 /livewire 1.3 / turbolinks:5.2 / alpine@v2 app I have crud editor as component with $form defined

class AppNews extends Component
{
    use WithPagination;
    use WithFileUploads;

    public $form = [
        'title'           => '1',
        'slug'            => '',
        'content'         => '2',
        'content_shortly' => '3',

and editor with inpoyt defined:

<form class="form-editor" @if($updateMode=='edit')  wire:submit.prevent="update" @else  wire:submit.prevent="store" @endif >
            <div class="card">
                <div class="card-body card-block">                                    
                    
                    <dl class="block_2columns_md m-3"> <!-- title FIELD DEFINITION -->
                        <dt class="key_values_rows_label_13">
                            <label class="col-form-label" for="title">Title:</label>
                        </dt>
                        <dd class="key_values_rows_value_13">
                            <input
                                wire:model.lazy="form.title"
                                id="title"
                                class="form-control editable_field"
                                placeholder="Enter descriptive title"
                                autocomplete=off
                            >
                            @error('form.title')
                            <div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
                        </dd>
                    </dl> <!-- <dt class="block_2columns_md m-0"> title FIELD DEFINITION -->

                    

and it works for me except, in the console I see a lot of additive requests, like

http://127.0.0.1:8084/livewire/message/admin.app-news

when I modify some fields of the form I try to get rid of it with alpineJS and in the docs I see dispatch method and I try to define it :

<dl class="block_2columns_md m-3"> 
    <dt class="key_values_rows_label_13">
        <label class="col-form-label" for="title">Title:</label>
    </dt>
    <dd class="key_values_rows_value_13" wire:model="form.title" x-data="{ title: ''}">
        <input
            x-model="search"
            id="title"
            class="form-control editable_field"
            placeholder="Enter descriptive title"
            autocomplete=off
        >
        @error('form.title')
        <div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
    </dd>
</dl> 

But how can I on event when field is edited(focus changed) to set value from defined (in x-data block) title var into form.title ?

Modified block :

  1. I try :

     $form['title']::{{ print_r($form['title'],true) }}
    
    <dd class="key_values_rows_value_13" wire:model="form.title.lazy" x-data="{ title: ''}" >
    <input
         x-model="title"
         x-on:blur="$dispatch('title', title)"
         id="title"
         class="form-control editable_field"
         placeholder="Enter descriptive title"
         autocomplete=off
     >
    

it works but on any keydown I see request. Looks like lazy mode does not work here. How to set it ?

  1. When form is opened with existing data I need to set default data in x-init:

    $form['title']::{{ print_r($form['title'],true) }}
    <dd class="key_values_rows_value_13" wire:model="form.title.lazy" x-data="{ title: ''}" x-init="title = '{{$form['title']}}'" >
    <input
        x-model="title"
        x-on:blur="$dispatch('title', title)"
        id="title"
        class="form-control editable_field"
        placeholder="Enter descriptive title"
        autocomplete=off
     >
    

as result input has valid data on form opened, byt trying to edit input I got error :

htmlspecialchars() expects parameter 1 to be string, array given (View: .../form.blade.php) 

Which way is valid ?

Modified block # 2 Thanks, but there is something unclear for me . I made it as :

<dd class="key_values_rows_value_13" wire:model.lazy="form.title" x-data="{ title: '{{$form['title']}}'}">

    <input
        x-model="title"
        x-on:blur="$dispatch('input', title)"
        id="title"
        class="form-control editable_field"
        placeholder="Enter descriptive title"
        autocomplete=off
    >
    @error('form.title')
    <div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
</dd>
  1. It works, But in the console I still see requests, like

    http://127.0.0.1:8084/livewire/message/admin.app-news

when the input lose focus. I can not get rid of this request? Is it triggered when for $form data from alpine var is assigned?

  1. in line

    x-on:blur="$dispatch('input', title)"

is 'input' predefined event in alpine? Is it referenced to current input control ?

  1. Why wire:model.lazy is defined in wrapping dd element? I supposed it must be assigned to input control ?

Thanks!

1
The reason you need to use input is that Livewire/Alpine model directives listen for input events. The reason wire:model is higher up the tree is that otherwise it will get updated as you type in the input, the way it's structured now the "input" event which triggers the livewire update is the one dispatched from Alpine on blur.Hugo

1 Answers

2
votes

Per the Livewire docs, in Alpine.js you can trigger an input event when the input is blurred using x-on:blur="$dispatch('input', title)" relevant code from your example:

<dd class="key_values_rows_value_13" wire:model="form.title" x-data="{ title: ''}">
  <input
    x-model="search"
    x-on:blur="$dispatch('input', title)"
    id="title"
    class="form-control editable_field"
    placeholder="Enter descriptive title"
    autocomplete=off
  >