BulkActions - Copy multiple rows to clipboard

I've got a custom Action that extends BulkAction, and I'm using $this->dispatch to send the data for the clipboard to the client: (this is in the ->action())
foreach ($records as $record) {
//copy to clipboard logic
$showName = $record->show->name;
$tourName = $record->production->name;
$date = $record->clipboardDate;
$this->clipboard .= "$showName - $tourName - $date\n";
}
$this->dispatch('copy-to-clipboard', [$this->clipboard]);
foreach ($records as $record) {
//copy to clipboard logic
$showName = $record->show->name;
$tourName = $record->production->name;
$date = $record->clipboardDate;
$this->clipboard .= "$showName - $tourName - $date\n";
}
$this->dispatch('copy-to-clipboard', [$this->clipboard]);
This works fine - ish. It only uses the data from the previous time you ran bulk action, rather than waiting for the foreach to finish it seems the dispatch is running first, even though it should be synchronous? The js in my blade file is:
<div x-data="{
copyToClipboard(event) {
console.log(event.detail);
navigator.clipboard.writeText(event.detail);
}
}"
x-on:copy-to-clipboard.window="copyToClipboard">
</div>
<div x-data="{
copyToClipboard(event) {
console.log(event.detail);
navigator.clipboard.writeText(event.detail);
}
}"
x-on:copy-to-clipboard.window="copyToClipboard">
</div>
Any ideas why this dispatch is running before the foreach loop ends, or how I can achieve this another way?
26 Replies
Pekempy
PekempyOP7mo ago
Bumping 🙂
awcodes
awcodes7mo ago
Maybe try it in ->after() instead of ->action(). That will give the bulk action time to do everything it needs to do.
Pekempy
PekempyOP7mo ago
still seems to only copy the first times item when its ran a second time I've got this atm:
protected function setUp(): void
{
parent::setUp();

$this->label('Copy information')
->icon('heroicon-o-clipboard')
->action(function (Collection $records, array $data) {
$this->buildClipboard($records, $data);
})
->after(function () {
$this->sendDataToClipboard();
})
->deselectRecordsAfterCompletion();
}
protected function setUp(): void
{
parent::setUp();

$this->label('Copy information')
->icon('heroicon-o-clipboard')
->action(function (Collection $records, array $data) {
$this->buildClipboard($records, $data);
})
->after(function () {
$this->sendDataToClipboard();
})
->deselectRecordsAfterCompletion();
}
which is calling the function above as buildClipboard(); sendDataToClipboard is just
public function sendDataToClipboard() {
$this->dispatch('copy-to-clipboard', [$this->clipboard]);
}
public function sendDataToClipboard() {
$this->dispatch('copy-to-clipboard', [$this->clipboard]);
}
awcodes
awcodes7mo ago
Can you dd in action() to see if it’s giving you all the records? I think you might be overriding the base action.
Pekempy
PekempyOP7mo ago
it's definitely pulling all 3 items i selected in. If I add a Log::info($this->clipboard), that seems to appear after the data is "copied" by the js
No description
Pekempy
PekempyOP7mo ago
in case im not explaining the behaviour well 😄
Pekempy
PekempyOP7mo ago
so when I copy Americano, nothing goes to clipboard. When I copy Ay, Carmela, the previous Americano goes to clipboard When i copy something else, the Ay Carmela I selected then goes to clipboard, it's like it's a step behind due to the foreach taking a while? https://pastebin.com/raw/1cJzUAXm that's the full ClipboardBulkAction I've created
awcodes
awcodes7mo ago
Ok. try moving the buildClipboard() into after()
Pekempy
PekempyOP7mo ago
so removing the actions() block ?
awcodes
awcodes7mo ago
Yea. You should still be able to get the records in after the same way.
Pekempy
PekempyOP7mo ago
Unfortunately same behaviour
awcodes
awcodes7mo ago
Well that doesn’t make any sense. Lol. Give me a minute.
Pekempy
PekempyOP7mo ago
Thanks 😄 I think for some reason the ->dispatch is running asynchronously, whereas the buildClipboard foreach loop is being synchronous? Though I did try using react/promise to do the buildclipboard()->then(sendDataToClipboard), so maybe it's just the JS firing too early?
awcodes
awcodes7mo ago
I’m wondering if it’s the $clipboard property getting cached with the action.
Pekempy
PekempyOP7mo ago
Even when I had the sendDataToClipboard() function call inside the buildClipboard() function (just outside the foreach), it still ran before the foreach completed
awcodes
awcodes7mo ago
Well, after doesn’t get called until the end of the action. So it can’t be run before action finishes. So the issue is somewhere else in the code.
Pekempy
PekempyOP7mo ago
Hm, weird then on the first run how it doesn't fire anything to the clipboard, but on subsequent runs the clipboard is set before the foreach ends
awcodes
awcodes7mo ago
Just have to dd() and step through it to figure out what is happening. Sorry.
Pekempy
PekempyOP7mo ago
yeah. I just added a dd($record) at the very start of the foreach and its fired a clipboard action already by that point 😂
Pekempy
PekempyOP7mo ago
in fact, it seems to be firing before it's even called.. what the f
No description
No description
awcodes
awcodes7mo ago
Not seeing anything unusual in your code other than methods and stuff not being used. So a little difficult to grok it all. 😆 I’m not sure how that’s possible unless alpine is triggering it. But that looked ok to me.
Pekempy
PekempyOP7mo ago
yeah its definitely firing before its called, somehow.. 🤔
Pekempy
PekempyOP7mo ago
double checked and that event isn't being emitted anywhere else, and the function isn't being called either
awcodes
awcodes7mo ago
Not totally sure. Sorry.
Pekempy
PekempyOP7mo ago
no worries, at least it's not just me 😂
CT
CT3mo ago
hey, did you ever get this working? I am about to implement exactly the same thing
Want results from more Discord servers?
Add your server