phayes0289's avatar

I need A Simple Javascript "Seconds" Counter That Resets when Livewire Polling Takes Place

I have the following livewire view in which I need to dsiplay a simple javascript seconds counter that is counting up from 0. It needs to reset to zero when the Livewire polling takes place:

<div class="container" wire:poll.10s>
    {{-- Begin Counter here --}}
  
    {{-- End Counter here --}}

    @if (!$incidents->isEmpty())
        @foreach ($incidents as $incident)
            @php
                if ($incident) {
                    // Convert the 'Time_first_unit_assigned' value to a Carbon instance
                    $assignedTime = \Carbon\Carbon::parse($incident->time_first_unit_assigned);

                    // Get the current time
                    $currentTime = \Carbon\Carbon::now();

                    // Calculate the time difference in seconds
                    $timeDifferenceInSeconds = $assignedTime->diffInSeconds($currentTime);

                    $background = '';

                    if ($timeDifferenceInSeconds <= 60) {
                        $background = 'bg-success-300 ';
                    } else {
                        $background = '';
                    }
                }
            @endphp

            <div class="row alert alert-secondary p-1 mb-2 {{ $background }}"
                onclick="window.location='{{ route('cadincidents.show', [$incident->id]) }}'" style="cursor: pointer;">

                <div class="col-auto pl-0 pr-0 mr-2 ml-2 mt-2 " style="">
                    <div class="block text-center">
                        @if (Str::contains($incident->incident_type, 'EMS'))
                            <img src="/media/images/inci_type_icons/sol_icon.png" width="40" height="40">
                        @elseif (Str::contains($incident->incident_type, 'ALARM'))
                            <img src="/media/images/inci_type_icons/alarm_icon.png" width="40" height="40">
                        @elseif (Str::contains($incident->incident_type, 'FIRE'))
                            <img src="/media/images/inci_type_icons/fire_icon.png" width="40" height="40">
                        @elseif (Str::contains($incident->incident_type, 'MVA'))
                            <img src="/media/images/inci_type_icons/accident_icon.png" width="40" height="40">
                        @elseif (Str::contains($incident->incident_type, 'GAS'))
                            <img src="/media/images/inci_type_icons/gas_icon.png" width="40" height="40">
                        @elseif (Str::contains($incident->incident_type, 'ELEC'))
                            <img src="/media/images/inci_type_icons/electrical_icon.gif" width="40" height="40">
                        @elseif (Str::contains($incident->incident_type, 'ASST'))
                            <img src="/media/images/inci_type_icons/citizen_icon.png" width="40" height="40">
                        @elseif (Str::contains($incident->incident_type, 'ELEV'))
                            <img src="/media/images/inci_type_icons/elevator.png" width="40" height="40">
                        @else
                            --
                        @endif
                    </div>

                    @if (isset($preplanIds[$incident->id]))
                        <div class="block text-center mt-2">
                            <a href="{{ route('preplans.show', $preplanIds[$incident->id]) }}">
                                <button class="btn-danger btn-sm p-1">
                                    {{-- <img src="/media/images/preplan_icon.png" width="20" height="20"> --}}Preplan
                                </button>
                            </a>
                        </div>
                    @else
                        <div class="block text-center mt-2" style="width:55px">


                        </div>
                    @endif
                </div>
                <div class="col border-faded border-top-0 border-bottom-0 border-right-0 pl-2">

                    <div class="position-relative"> {{ $incident->incident_type }}<br>

                        <div>
                            <strong>
                                @if ($incident->location_name)
                                    {{ $incident->location_name }}<br>
                                @endif
                                {{ $incident->location_address }}, Apt {{ $incident->location_apartment }}
                            </strong>, {{ $incident->location_city }}
                        </div>
                        <div>

                            <em>
                                @if ($incident->responsevehicles->count() > 0)
                                    @foreach ($incident->responsevehicles as $vehicle)
                                        @php
                                            if ($vehicle->status == 0) {
                                                $background = 'background-color:#918f8e;color:#ffff;';
                                                $status_name = 'Off Duty';
                                                $border_color = '';
                                            } elseif ($vehicle->status == 1) {
                                                $background = 'background-color:#0a8b5a;color:#ffff;';
                                                $status_name = 'Available';
                                                $border_color = '';
                                            } elseif ($vehicle->status == 2) {
                                                $background = 'background-color:#0a6340;color:#ffff;';
                                                $status_name = 'In Quaters';
                                                $border_color = '';
                                            } elseif ($vehicle->status == 5) {
                                                $background = 'background-color:#918f8e;color:#ffff;';
                                                $status_name = 'O.O.S.';
                                                $border_color = '';
                                            } elseif ($vehicle->status == 6) {
                                                $background = 'background-color:orange;color:#00000;';
                                                $status_name = 'Dispatched';
                                                $border_color = 'border-secondary';
                                            } elseif ($vehicle->status == 7) {
                                                $background = 'background-color:#e1e714;color:#00000;';
                                                $status_name = 'Enroute';
                                                $border_color = 'border-secondary';
                                            } elseif ($vehicle->status == 10) {
                                                $background = 'background-color:#ff5042;color:white;';
                                                $status_name = 'On Scene';
                                                $border_color = '';
                                            } elseif ($vehicle->status == 20) {
                                                $background = 'background-color:#9f2bca;color:yellow;';
                                                $status_name = 'Enroute to Secondary';
                                                $border_color = '';
                                            } elseif ($vehicle->status == 21) {
                                                $background = 'background-color:#9f2bca;color:white;height';
                                                $status_name = 'At Seconday';
                                                $border_color = '';
                                            } else {
                                                $background = 'background-color:black;color:#ffff;';
                                                $status_name = '';
                                                $border_color = '';
                                            }

                                        @endphp

                                        <button class="btn btn-sm p-0 pl-2 pr-2" style="{{ $background }}"
                                            title="{{ $status_name }}" name="{{ $status_name }}">
                                            {{ $vehicle->vehicle_name }} </button>
                                    @endforeach
                                    <div><small>
                                            {{ Carbon\Carbon::parse($incident->time_first_unit_assigned)->diffForHumans() }}</small>
                                    </div>
                                @else
                                    No Unit Assigned
                                @endif
                            </em>

                        </div>
                    </div>
                </div>
            </div>
        @endforeach
    @else
        <div class="text-center">
            <h3>There are no active Incidents</h3>
        </div>
    @endif


</div>

This is my Livewire Component:

<?php

namespace App\Http\Livewire;

use App\Models\Preplan;
use App\Models\CadIncident;
use Livewire\Component;

class Incident extends Component
{


    public function render()
    {
        $incidents = CadIncident::whereNull('time_call_closed')
            ->orderByRaw('ISNULL(time_first_unit_assigned) DESC, time_first_unit_assigned DESC')
            ->with('responsevehicles') // Eager load the responsevehicles relationship
            ->get();

        // Create an array to store the preplan IDs
        $preplanIds = [];

        // Loop through the incidents and check for matching preplans
        foreach ($incidents as $incident) {
            $incident->load('responsevehicles');

            $streetLocation = $incident->location_address;
            // Query the preplan database to check for matching preplans
            $matchingPreplan = Preplan::whereRaw("CONCAT(geo_streetnumber, ' ', geo_street) = ?", [$streetLocation])
                ->first();

            // dd($matchingPreplan);

            // Add the preplan ID to the array if it exists
            if ($matchingPreplan) {
                $preplanIds[$incident->id] = $matchingPreplan->id;
            }
        }
        return view('livewire.incident', compact('incidents', 'preplanIds'));
    }
}

How can I make that happen? I can get the counter on there, but I cannot get it reset when the polling occurs.

0 likes
5 replies
LaryAI's avatar
Level 58

To create a simple JavaScript seconds counter that resets when Livewire polling takes place, you can use the following approach. You'll need to define a JavaScript function that starts the counter and resets it whenever a Livewire polling event occurs.

Here's a solution that you can place within your Livewire component's view:

<div class="container" wire:poll.10s="resetCounter">
    {{-- Begin Counter here --}}
    <span id="seconds-counter">0</span> seconds
    {{-- End Counter here --}}

    <!-- ... rest of your Livewire component ... -->
</div>

<script>
    document.addEventListener('livewire:load', function () {
        // Initialize the counter
        let counter = 0;
        const counterElement = document.getElementById('seconds-counter');

        // Function to update the counter display
        function updateCounter() {
            counterElement.textContent = counter++;
        }

        // Start the counter
        let intervalId = setInterval(updateCounter, 1000);

        // Listen for the Livewire 'poll' event to reset the counter
        window.livewire.on('resetCounter', () => {
            counter = 0; // Reset the counter
            updateCounter(); // Update the counter display immediately
        });
    });
</script>

In the Livewire component's PHP class, you should define the resetCounter method that will be called when the polling event occurs. This method will emit an event that the JavaScript will listen for to reset the counter.

Here's the method you should add to your Livewire component's PHP class:

class Incident extends Component
{
    // ...

    public function resetCounter()
    {
        // Emit an event to the frontend to reset the counter
        $this->emit('resetCounter');
    }

    // ...
}

This solution uses Livewire's wire:poll.10s="resetCounter" directive to call the resetCounter method every 10 seconds. The JavaScript listens for the resetCounter event and resets the counter accordingly. The counter is displayed in a <span> element with the ID seconds-counter, and it's updated every second using setInterval. When the resetCounter event is received, the counter is reset to 0 and the display is updated immediately.

phayes0289's avatar

@laryai That code id not work.. It flash back to zero, but then continues counting up from where it left off.

Snapey's avatar
Snapey
Best Answer
Level 122

This should be all you need

    <div><span id="seconds">0</span> Seconds</div>

    <script>
        setInterval(function() {
            seconds = document.getElementById("seconds");

            seconds.innerHTML = parseInt(seconds.innerHTML) + 1;

        },1000);
    </script>
phayes0289's avatar

@snapey That is a much simpler approach. I had a pure javascript counter working, but it kept counting past the the poll reset. I don't remember the code I was using, but THANK YOU. Just FYI.. Larry's code did work. I forgot to modify the poll code to reset it. But I like the simpler approach MUCH BETTER.

Snapey's avatar

@phayes0289 thats good. The main trick is that the count is in the html and gets reset to 0 on every re-render of the page

Please or to participate in this conversation.