fanpero87
fanpero87

Reputation: 63

Modify Alpine flash notification

I have a question. I have this component that displays a flash notification. By default is set to show a green checkmark, but I wanted to also include code so I can send a "type" and a "message" variables to the component and be able to either show the green success message or a red failed message.

How can I do this?

From my livewire component I saying this:

if($validatedData->fails()){
         $this->notify('Failed creation of extensions');
}else{
        $this->notify('Successfully Imported '.$importCount.' Extensions');
}

Here is kind of how I want to send the info:

if($validatedData->fails()){
         $this->notify('error', 'Failed creation of extensions');
}else{
        $this->notify('success', 'Successfully Imported '.$importCount.' Extensions');
}

On my view, I have a blade component that has the following code:

<div x-data="{
        messages: [],
        remove(message) {
            this.messages.splice(this.messages.indexOf(message), 1)
        },
    }"
    @notify.window="let message = $event.detail; messages.push(message); setTimeout(() => { remove(message) }, 2500)"
    class="fixed inset-0 flex flex-col items-end justify-center px-4 py-6 space-y-4 pointer-events-none sm:p-6 sm:justify-start">
    <template x-for="(message, messageIndex) in messages" :key="messageIndex" hidden>
        <div x-transition:enter="transform ease-out duration-300 transition"
            x-transition:enter-start="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
            x-transition:enter-end="translate-y-0 opacity-100 sm:translate-x-0"
            x-transition:leave="transition ease-in duration-100" x-transition:leave-start="opacity-100"
            x-transition:leave-end="opacity-0"
            class="w-full max-w-sm bg-white rounded-lg shadow-lg pointer-events-auto">
            <div class="overflow-hidden rounded-lg shadow-xs">
                <div class="p-4">
                    <div class="flex items-start">
                        <div class="flex-shrink-0">
                            <svg class="w-6 h-6 text-green-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                    d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
                            </svg>
                        </div>
                        <div class="ml-3 w-0 flex-1 pt-0.5">
                            <p x-text="message" class="text-sm font-medium leading-5 text-gray-900"></p>
                        </div>
                        <div class="flex flex-shrink-0 ml-4">
                            <button @click="remove(message)"
                                class="inline-flex text-gray-400 transition duration-150 ease-in-out focus:outline-none focus:text-gray-500">
                                <svg class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
                                    <path fill-rule="evenodd"
                                        d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
                                        clip-rule="evenodd"></path>
                                </svg>
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </template>
</div>

Upvotes: 3

Views: 429

Answers (2)

Yinci
Yinci

Reputation: 2480

You haven't shown us how you dispatch the notify event, but I assume you're using dispatchBrowserEvent. If you take a look at the docs, you can pass named arguments.

$this->dispatchBrowserEvent('name-updated', ['newName' => $value]);

If you were to do this with yours:

public function notify(string $type, string $message) 
{
    $this->dispatchBrowserEvent('notify', compact('type', 'message'));
}

$this->notify('success', "Successfully Imported {$importCount} Extensions");

Then you can grab it in Alpine using the named detail:

<div x-data="{ // }" @notify.window="let message = $event.detail.message">

Upvotes: 1

fanpero87
fanpero87

Reputation: 63

I was able to workaround my problem. Here is what I did:

On my livewire component I do something like this:

$this->notify(['error','Oops something went wrong!']);
$this->notify(['success','Operation completed Successfully']);

Sending one message or the other.

Then, on my notification component I made something like this:

<div x-show="message[0] == 'error' ">
            <p x-text="message[1]" class="text-sm font-medium leading-5 text-gray-900"></p>
</div>
<div x-show="message[0] == 'success' ">
            <p x-text="message[1]" class="text-sm font-medium leading-5 text-gray-900"></p>
</div>
                           

So, depending on the first element inside notify, it will show one div or the other.

Upvotes: 0

Related Questions