Debug School

rakesh kumar
rakesh kumar

Posted on

Multi-component interaction using dispatch Alpine.js

The dispatch method is used to create and dispatch custom events. This is useful for communication between different components or parts of your application. By dispatching an event, you can trigger other parts of your application to respond to it, enabling a decoupled and flexible architecture.

When to Use dispatch:

  1. To communicate between different components or parts of your application.
  2. To trigger custom behavior based on user interactions.
  3. To create a more modular and maintainable code structure
<div @notify="alert('Hello World!')">
    <button @click="$dispatch('notify')">
        Notify
    </button>
</div>
Enter fullscreen mode Exit fullscreen mode

output

Image description

Second Example

<div @notify="alert($event.detail.message)">
    <button @click="$dispatch('notify', { message: 'Hello World!' })">
        Notify
    </button>
</div>
Enter fullscreen mode Exit fullscreen mode

Multi-component interaction in nesting component

when you need to capture events dispatched from nodes that are under the same nesting hierarchy, you'll need to use the .window modifier:

<!-- 🚫 Won't work -->
<div x-data>
    <span @notify="..."></span>
    <button @click="$dispatch('notify')">Notify</button>
</div>

<!-- ✅ Will work (because of .window) -->
<div x-data>
    <span @notify.window="..."></span>
    <button @click="$dispatch('notify')">Notify</button>
</div>
Enter fullscreen mode Exit fullscreen mode
<div
    x-data="{ title: 'Hello' }"
    @set-title.window="title = $event.detail"
>
    <h1 x-text="title"></h1>
</div>

<div x-data>
    <button @click="$dispatch('set-title', 'Hello World!')">Click me</button>
</div>
<!-- When clicked, the content of the h1 will set to "Hello World!". -->
Enter fullscreen mode Exit fullscreen mode

Dispatching to x-model

You can also use $dispatch() to trigger data updates for x-model data bindings. For example:

<div x-data="{ title: 'Hello' }">
    <span x-model="title">
        <button @click="$dispatch('input', 'Hello World!')">Click me</button>
        <!-- After the button is pressed, `x-model` will catch the bubbling "input" event, and update title. -->
    </span>
</div>
Enter fullscreen mode Exit fullscreen mode

Multiselect Component Initialization

inner component or nested component

<div class="msa-wrapper mt-4" x-data="multiselectComponent()" x-init="$watch('selected', value => {
    selectedString = value.map(item => item.value).join(',');
    $wire.updateSelectedTags(selectedString);
    $dispatch('select-string-updated', { selectedString });
})">
Enter fullscreen mode Exit fullscreen mode

Image description

Container Handling Custom Event
outer component

<div x-data="{ selectcountry: null, selectstates: null, selectcities: null, search: null, title: '' }" 
     @select-string-updated.window="console.log('Event received:', $event.detail); title = $event.detail.selectedString" 
     class="container ml-4">
Enter fullscreen mode Exit fullscreen mode

Rendering Posts Dynamically

<template x-for="post in paginatedItems()">
    <div class="col-md-12 mb-3">
        <div class="card">
            <div class="row">
                <div class="col-md-1">
                    <img :src="post.file_pic ? '{{ asset('storage/') }}' + post.file_pic : '{{ asset('assets/images/users/default.webp') }}'" alt="user" style="width: 100px; height: 100px; border-radius: 50%;">
                </div>
                <div class="col-md-3">
                    <div><strong x-text="post.user_name"></strong></div>
                    <h1 x-text="title"></h1>
                </div>
            </div>
        </div>
    </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Image description

full code

<div x-data="{ selectcountry: null, selectstates: null, selectcities: null, search: null, title: '' }" 
     @select-string-updated.window="
         console.log('Event received:', $event.detail);
         title = $event.detail.selectedString
     " 
     class="container ml-4">
        <div class="card" style="width:101%;margin-left:3px;">
            <div class="row py-3 px-3">
                <div x-data='{ "country": {!! json_encode($countries) !!} }' class="col-lg-4 col-md-3 col-sm-3 col-3">
                    <label class="font-weight-bold text-danger">Country</label>
                    <select class="form-control countries" @change="selectcountry = selectedCountry;" x-model="selectedCountry">
                        <option value="">All Country</option>          
                        <template x-for="item in country">
                        <option :value="item.country_id" x-text="item.country_name"></option>           
                        </template>
                    </select>
                </div>


                <div x-data='{ "state": {!! json_encode($states) !!} }' class="col-lg-4 col-md-3 col-sm-3 col-3">
                    <label class="font-weight-bold text-danger">States</label>
                    <select class="form-control states"   @change="selectstates = selectedState;"  x-model="selectedState">
                        <option value="">All State</option>          
                        <template x-for="item in state">
                        <option :value="item.state_id" x-text="item.state_name"></option>           
                        </template>
                    </select>
                </div>

                <div x-data='{ "city": {!! json_encode($cities) !!} }' class="col-lg-4 col-md-3 col-sm-3 col-3">
                    <label class="font-weight-bold text-danger">States</label>
                    <select class="form-control cities"  @change="selectcities = selectedCity;" x-model="selectedCity">
                        <option value="">All City</option>          
                        <template x-for="item in city">
                        <option :value="item.city_id" x-text="item.city_name"></option>           
                        </template>
                    </select>
                </div>

                <div class="col-6 p-3">
                    <label class="font-weight-bold text-danger"> Keyword</label>                  
                    <input type="text" class="form-control"  wire:model.live="q" x-model="q"  @input="search = $event.target.value" placeholder="Search Keyword.." style="font-size:18px; border:1px solid blue;">
                    <input type="hidden" value="{{ Auth::user() ? Auth::user()->id : '' }}" name="admin_id" id="admin_id" />                   
                </div>
                <div   class="col-6 p-3  mt-2">

                <div class="msa-wrapper mt-4" x-data="multiselectComponent()" x-init="$watch('selected', value => {
                    selectedString = value.map(item => item.value).join(',');
                    $wire.updateSelectedTags(selectedString);
                    $dispatch('select-string-updated', { selectedString });
                  })">

  <div class="input-presentation"   @click="listActive = !listActive" @click.away="listActive = false" x-bind:class="{'active': listActive}">
  <span class="placeholder" x-show="selected.length == 0">Select Tags</span>
    <template x-for="(tag, index) in selected">
        <div class="tag-badge">
            <span  x-text="tag.label"></span> <!-- Use tag.label instead of tag -->
            <button x-bind:data-index="index" @click.stop="removeMe($event)">x</button>
        </div>
    </template>
  </div>
  <ul id="tag-list"  x-show.transition="listActive" role="listbox">
    <template x-for="(tag, index, collection) in unselected">
        <li x-show="!selected.map(item => item.value).includes(tag.value)" 
            x-bind:value="tag.value" 
            x-text="tag.label" 
            aria-role="button" 
            @click.stop="addMe($event)" 
            x-bind:data-index="index"
            role="option">
        </li>
    </template>
</ul>
</div>
</div>
 </div>
  </div>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)