asdasdsa's avatar

How to set a cookie with alpine to remove an announcement banner?

Hi! Trying both the new Laravel 8 and Tailwindcss 2.0. And one thing I would like to try is to set a cookie, and at the same time remove a banner. So the next time a users visits the page, the banner isent there anymore.

I have copy and pasted the first example from tailwind components.

How can i do it?

0 likes
6 replies
srasch's avatar

Here is a way to do it:


<div x-data="showBanner()" x-init="checkCookie()">

        <div x-show="show">
            Banner
        </div>

        <button @click="setCookie()">Set cookie</button>

    </div>

    <script>

        function showBanner() {

            return {
                show: true,
                cookieName: 'myCookie',
                setCookie(days = 1) {
                    let d = new Date();
                    d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
                    let expires = "expires="+d.toUTCString();
                    document.cookie = this.cookieName + "=" + !this.show + ";" + expires + ";path=/";

                    this.show = false;
                },
                getCookie() {
                    let matches = document.cookie.match( new RegExp(
                        "(?:^|; )" + this.cookieName.replace( /([\.$?*|{}\(\)\[\]\\/\+^])/g, '\' ) + "=([^;]*)"
                    ) );
                    return matches ? decodeURIComponent( matches[ 1 ] ) : 'true';
                },
                checkCookie() {
                    
                    return this.show = (this.getCookie() === "true");
                }
            }
        }

    </script>

asdasdsa's avatar

Thanks for your reply @srasch !

I dont really understand what im supposed to do with the code you provided.

This seems to be the view

<div x-data="showBanner()" x-init="checkCookie()">

        <div x-show="show">
            Banner
        </div>

        <button @click="setCookie()">Set cookie</button>

    </div>

This

    <script>

        function showBanner() {

            return {
                show: true,
                cookieName: 'myCookie',
                setCookie(days = 1) {
                    let d = new Date();
                    d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
                    let expires = "expires="+d.toUTCString();
                    document.cookie = this.cookieName + "=" + !this.show + ";" + expires + ";path=/";

                    this.show = false;
                },
                getCookie() {
                    let matches = document.cookie.match( new RegExp(
                        "(?:^|; )" + this.cookieName.replace( /([\.$?*|{}\(\)\[\]\/\+^])/g, '\' ) + "=([^;]*)"
                    ) );
                    return matches ? decodeURIComponent( matches[ 1 ] ) : 'true';
                },
                checkCookie() {
                    
                    return this.show = (this.getCookie() === "true");
                }
            }
        }

    </script>

Is wrapped in <script> tags, so supposedly also in the view. I cannot get it to work.

srasch's avatar

What are your error messages in the console?

Did you add Alpine?

asdasdsa's avatar

It seems that i have misunderstood the laravel documentation. I tought that Alpine was included out-of-the box. Let me change my question to How do i set a cookie with Laravel 8 and Livewire to remove an announcement bar?

Sorry for this.

srasch's avatar
srasch
Best Answer
Level 14

Cool. Give this a try and you are good to go.

Here's an example:

Livewire Component

<?php

namespace App\Http\Livewire\MyComponent;


use Illuminate\Support\Facades\Cookie;
use Illuminate\View\View;
use Livewire\Component;


class MyComponent extends Component
{

    public ?bool $bannerClicked = false;

    private string $cookieName = 'banner_clicked';


    public function mount()
    {

        $this->bannerClicked = (bool) request()->cookie($this->cookieName);
    }


    public function bannerClicked()
    {
        $this->bannerClicked = true;
        
        // params are name, value, expire
        Cookie::queue($this->cookieName, 1, 15);

    }


    public function render() : View
    {

        return view('my-component');
    }
}

app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    ...
    
    @livewireStyles	
    <!-- alpine -->
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>
</head>

<body>
   <livewire:my-component>
   @livewireScripts
</body>
</html>

my-component.blade.php

<div>
    <div x-data="{ showBanner: @entangle('bannerClicked') }"
         x-show="!showBanner"
         x-transition:leave="transition ease-in duration-200"
         x-transition:leave-start="opacity-100 transform"
         x-transition:leave-end="opacity-0 transform"
         class="fixed bottom-0 inset-x-0 pb-2 sm:pb-5">
        <div class="max-w-7xl mx-auto px-2 sm:px-6 lg:px-8">
            <div class="p-2 rounded-lg bg-indigo-600 shadow-lg sm:p-3">
                <div class="flex items-center justify-between flex-wrap">
                    <div class="w-0 flex-1 flex items-center">
          <span class="flex p-2 rounded-lg bg-indigo-800">

            <svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                 stroke="currentColor" aria-hidden="true">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                    d="M11 5.882V19.24a1.76 1.76 0 01-3.417.592l-2.147-6.15M18 13a3 3 0 100-6M5.436 13.683A4.001 4.001 0 017 6h1.832c4.1 0 7.625-1.234 9.168-3v14c-1.543-1.766-5.067-3-9.168-3H7a3.988 3.988 0 01-1.564-.317z"/>
            </svg>
          </span>
                        <p class="ml-3 font-medium text-white truncate">
            <span class="md:hidden">
              We announced a new product!
            </span>
                            <span class="hidden md:inline">
              Big news! We're excited to announce a brand new product.
            </span>
                        </p>
                    </div>
                    <div class="order-3 mt-2 flex-shrink-0 w-full sm:order-2 sm:mt-0 sm:w-auto">
                        <a href="#"
                           class="flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-indigo-600 bg-white hover:bg-indigo-50">
                            Learn more
                        </a>
                    </div>
                    <div class="order-2 flex-shrink-0 sm:order-3 sm:ml-2">
                        <button wire:click="bannerClicked"
                                type="button"
                                class="-mr-1 flex p-2 rounded-md hover:bg-indigo-500 focus:outline-none focus:ring-2 focus:ring-white">
                            <span class="sr-only">Dismiss</span>
                            <svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
                                 viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                      d="M6 18L18 6M6 6l12 12"/>
                            </svg>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Here is a working example on LaravelPlayground: https://laravelplayground.com/#/snippets/a56bd702-cc15-49a6-bb9d-62dec917cdd2

5 likes

Please or to participate in this conversation.