Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I know if everything is loaded and ready to be used ? #39

Open
joffreypersia opened this issue Oct 20, 2023 · 4 comments
Open
Labels
needs more info More info is needed in order to help

Comments

@joffreypersia
Copy link

Hi,

I just installed the package according to the instructions (from npm + added the lines in the app.js). I added the attributes to the differents elements like the doc :

<ul wire:sortable="updateTaskOrder" wire:sortable.options="{ animation: 100 }">
    @foreach ($tasks as $task)
        <li wire:sortable.item="{{ $task->id }}" wire:key="task-{{ $task->id }}">
            <h4>{{ $task->title }}</h4>
            <button wire:sortable.handle>drag</button>
        </li>
    @endforeach
</ul>

But the handle doesn't do anything when I am clicking and dragging.

Is there a way to make sure the elements are correctly loaded ?
I am trying to use the inside a tbody (to drag / sort tr)
Should I also import and assign to the window Sortable ?
or is it included in your instructions ?

Thank you

@gdebrauwer
Copy link
Contributor

Can you provide a code snippet so I can reproduce the bug?

@gdebrauwer gdebrauwer added the needs more info More info is needed in order to help label Oct 20, 2023
@joffreypersia
Copy link
Author

joffreypersia commented Oct 20, 2023

Can you provide a code snippet so I can reproduce the bug?

Thank you for your quick answer, it is the first time I am trying to use Sortable.js and your package.

Unfortunately, I can't give you the snippet because my app is quite complex and I am working with a team.

To clarify what I did :
npm install sortablejs --save
Then in my app.js (Laravel/Livewire app)
I added the lines

// app.js
[...]
import '@nextapps-be/livewire-sortablejs';
[...]
Livewire.start()

Then In my Livewire table component is something like :

// table-structure.blade.php
@props([
	'headerType' => 'default', // sticky, default
	'orderable' => false,
])
<table
    {{ $attributes->merge(['class' => 'min-w-full']) }}
    x-data="{
        orderable: @entangle('orderable'),
        init() {
            $nextTick(() => {
                console.log('orderable', this.orderable);
                if (this.orderable) {
                    const elements = document.querySelectorAll('tbody[sortable]');
                    elements.forEach(element => {
                        let sortable = Sortable.create(element);
                        console.log(element);
                    });
                }
            });
        }
    }"
>
    <thead class="">
        <tr>
            {{ $head }}
        </tr>
    </thead>
    <tbody class="divide-shade-200 dark:divide-shade-600 divide-y" @if($orderable) sortable wire:sortable="updateOrder" wire:sortable.options="{ animation: 100 }" @endif>
        {{ $body }}
    </tbody>
</table>

And I passed the cell infos through the parent component table

@props([
    'orderable' => false,
])
<div>
    <div class="bg-white dark:bg-shade-700 border border-shade-200 dark:border-shade-600 rounded">
        <x-table-structure :orderable="$orderable">
            <x-slot name="head"></x-slot>
            <x-slot name="body">
                @forelse ($table['items'] as $item)
                    <tr
                        wire:loading.class="opacity-50"
                        @if($orderable)
                            wire:sortable.item="{{ $item['id'] }}"
                            wire:key="task-{{ $item['id'] }}"
                        @endif
                    >
                        @if($orderable)
                            <x-table.cell class="w-4 cursor-grab" wire:sortable.handle >
                                <x-heroicon-s-bars-2 class="w-4 h-4 text-shade-500 dark:text-shade-400"/>
                            </x-table.cell>
                        @endif
                        @foreach($table['config'] as $col)
                            <x-table.cell class="{{ $col['width'] }}">
                                @switch($col['type'])
                                    {{-- empty --}}
                                    @case('id')
                                        @break
                                    @case('img')
                                        <img src="{{ $item[$col['name']] }}" class="w-full h-12 object-contain"
                                             alt=""/>
                                        @break
                                    @case('url')
                                        <a href="{{ $item[$col['name']] }}" target="_blank">{{ $item[$col['name']] }}</a>
                                        @break
                                     @default
                                        {{ $item[$col['name']] }}
                                @endswitch
                            </x-table.cell>
                        @endforeach
                    </tr>
                @empty
                    <tr>
                        <x-table.cell colspan="{{sizeof($table['config'])}}">
                            <div class="flex justify-center items-center space-x-2">
                                <span
                                    class="font-medium py-8 text-cool-gray-400 text-xl">{{ __('mdall.No items found') }}</span>
                            </div>
                        </x-table.cell>
                    </tr>
                @endforelse
            </x-slot>
        </x-table-structure>
    </div>
</div>

--> Should I add more lines inside my app.js ? Should I import and load Sortable.js ?
--> Should I add something to initialize Sortable ?

EDIT : It is working, my nextTick wasn't correct, I made the change and update the code above

CleanShot 2023-10-20 at 18 57 37@2x
CleanShot 2023-10-20 at 19 02 28@2x

@joffreypersia
Copy link
Author

I have an other trouble with the communication with the class...

I added this function in my class attached to my livewire component

    public function updateOrder() {
        dd('updateOrder');
    }

And as you can see above my tbody line aim this function

<tbody wire:sortable="updateOrder">

But the die and dump doesn't get triggered.

Have you an idea ?

@gdebrauwer
Copy link
Contributor

gdebrauwer commented Oct 26, 2023

Am I correct in saying that you are adding Sortable instances yourself using Javascript?
(code snippet from your comment above)

<table
    {{ $attributes->merge(['class' => 'min-w-full']) }}
    x-data="{
        orderable: @entangle('orderable'),
        init() {
            $nextTick(() => {
                console.log('orderable', this.orderable);
                if (this.orderable) {
                    const elements = document.querySelectorAll('tbody[sortable]');
                    elements.forEach(element => {
                        let sortable = Sortable.create(element);
                        console.log(element);
                    });
                }
            });
        }
    }"
>

Because then it is normal that the Livewire method is not triggered, because you have to configure a lot of stuff when creating the Sortable instance in order to get that working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs more info More info is needed in order to help
Projects
None yet
Development

No branches or pull requests

2 participants