filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
15.94k stars 2.54k forks source link

Table Group by Title that contains single quote shows js errors in the console #13153

Closed ismaail closed 4 weeks ago

ismaail commented 4 weeks ago

Package

filament/tables

Package Version

v3.2.86

Laravel Version

v11.10.0

Livewire Version

v3

PHP Version

PHP 8.3.8

Problem description

Table Group by Title that contains single quote shows js errors in the console

Expected behavior

No js errors in the console

Steps to reproduce

  1. Create a Resource Table for Post Model (that have a title attribute)
  2. Show Posts records in the Resource Table
  3. Add Group to the table
    ->groups([
    'title'
    ])->defaultGroup('title')

    Notice: this is just a simplified example, the actual code has a Group by relational Model, this simplified example and the actual production code both throw same error in the console.

2024-06-08_21-52

Reproduction repository

https://github.com/ismaail/filament_issue_13153

Relevant log output

livewire.js?id=07f22875:1123 Alpine Expression Error: missing ) after argument list

Expression: "{
            'hidden': false && isGroupCollapsed('50 Cent's Musical Journey: A Quiz for His Biggest Fans'),
            'bg-gray-50 dark:bg-white/5': isRecordSelected('26'),
            '[&>*:first-child]:relative [&>*:first-child]:before:absolute [&>*:first-child]:before:start-0 [&>*:first-child]:before:inset-y-0 [&>*:first-child]:before:w-0.5 [&>*:first-child]:before:bg-primary-600 [&>*:first-child]:dark:before:bg-primary-500': isRecordSelected('26'),
        }"

 <tr x-bind:class=​"{
            'hidden':​ false && isGroupCollapsed('50 Cent's Musical Journey:​ A Quiz for His Biggest Fans')​,
            'bg-gray-50 dark:​bg-white/​5':​ isRecordSelected('26')​,
            '[&>*:​first-child]​:​relative [&>*:​first-child]​:​before:​absolute [&>*:​first-child]​:​before:​start-0 [&>*:​first-child]​:​before:​inset-y-0 [&>*:​first-child]​:​before:​w-0.5 [&>*:​first-child]​:​before:​bg-primary-600 [&>*:​first-child]​:​dark:​before:​bg-primary-500':​ isRecordSelected('26')​,
        }​" class=​"fi-ta-row [@media(hover:​hover)​]​:​transition [@media(hover:​hover)​]​:​duration-75 hover:​bg-gray-50 dark:​hover:​bg-white/​5" wire:key=​"vWKbomv2GOGbRHbKtDXW.table.records.26">​…​</tr>​
handleError @ livewire.js?id=07f22875:1123
safeAsyncFunction @ livewire.js?id=07f22875:1180
generateFunctionFromString @ livewire.js?id=07f22875:1184
generateEvaluatorFromString @ livewire.js?id=07f22875:1189
normalEvaluator @ livewire.js?id=07f22875:1154
evaluateLater @ livewire.js?id=07f22875:1144
handler2 @ livewire.js?id=07f22875:3513
flushHandlers @ livewire.js?id=07f22875:1281
stopDeferring @ livewire.js?id=07f22875:1286
deferHandlingDirectives @ livewire.js?id=07f22875:1289
initTree @ livewire.js?id=07f22875:1476
_activate @ async-alpine.js?v=3.2.86.0:1
_componentStrategy @ async-alpine.js?v=3.2.86.0:1
await in _componentStrategy (async)
_setupComponent @ async-alpine.js?v=3.2.86.0:1
_setupComponents @ async-alpine.js?v=3.2.86.0:1
start @ async-alpine.js?v=3.2.86.0:1
(anonymous) @ async-alpine.js?v=3.2.86.0:1
dispatch2 @ livewire.js?id=07f22875:1386
start @ livewire.js?id=07f22875:1418
start2 @ livewire.js?id=07f22875:8627
(anonymous) @ livewire.js?id=07f22875:9886
livewire.js?id=07f22875:1174 Uncaught SyntaxError: missing ) after argument list
    at new AsyncFunction (<anonymous>)
    at safeAsyncFunction (livewire.js?id=07f22875:1174:21)
    at generateFunctionFromString (livewire.js?id=07f22875:1184:16)
    at generateEvaluatorFromString (livewire.js?id=07f22875:1189:16)
    at normalEvaluator (livewire.js?id=07f22875:1154:111)
    at evaluateLater (livewire.js?id=07f22875:1144:12)
    at Function.handler2 (livewire.js?id=07f22875:3513:22)
    at flushHandlers (livewire.js?id=07f22875:1281:48)
    at stopDeferring (livewire.js?id=07f22875:1286:7)
    at deferHandlingDirectives (livewire.js?id=07f22875:1289:5)
safeAsyncFunction @ livewire.js?id=07f22875:1174
generateFunctionFromString @ livewire.js?id=07f22875:1184
generateEvaluatorFromString @ livewire.js?id=07f22875:1189
normalEvaluator @ livewire.js?id=07f22875:1154
evaluateLater @ livewire.js?id=07f22875:1144
handler2 @ livewire.js?id=07f22875:3513
flushHandlers @ livewire.js?id=07f22875:1281
stopDeferring @ livewire.js?id=07f22875:1286
deferHandlingDirectives @ livewire.js?id=07f22875:1289
initTree @ livewire.js?id=07f22875:1476
_activate @ async-alpine.js?v=3.2.86.0:1
_componentStrategy @ async-alpine.js?v=3.2.86.0:1
setTimeout (async)
handleError @ livewire.js?id=07f22875:1126
safeAsyncFunction @ livewire.js?id=07f22875:1180
generateFunctionFromString @ livewire.js?id=07f22875:1184
generateEvaluatorFromString @ livewire.js?id=07f22875:1189
normalEvaluator @ livewire.js?id=07f22875:1154
evaluateLater @ livewire.js?id=07f22875:1144
handler2 @ livewire.js?id=07f22875:3513
flushHandlers @ livewire.js?id=07f22875:1281
stopDeferring @ livewire.js?id=07f22875:1286
deferHandlingDirectives @ livewire.js?id=07f22875:1289
initTree @ livewire.js?id=07f22875:1476
_activate @ async-alpine.js?v=3.2.86.0:1
_componentStrategy @ async-alpine.js?v=3.2.86.0:1
await in _componentStrategy (async)
_setupComponent @ async-alpine.js?v=3.2.86.0:1
_setupComponents @ async-alpine.js?v=3.2.86.0:1
start @ async-alpine.js?v=3.2.86.0:1
(anonymous) @ async-alpine.js?v=3.2.86.0:1
dispatch2 @ livewire.js?id=07f22875:1386
start @ livewire.js?id=07f22875:1418
start2 @ livewire.js?id=07f22875:8627
(anonymous) @ livewire.js?id=07f22875:9886

Donate 💰 to fund this issue

Fund with Polar

zepfietje commented 4 weeks ago

Please provide an actual reproduction repository that we can access. Let us know once you've added that and we can reopen this issue.

ismaail commented 4 weeks ago

@zepfietje https://github.com/ismaail/filament_issue_13153

rossbearman commented 4 weeks ago

Can also confirm that we've run into this bug in production. Looking into a fix.

rossbearman commented 4 weeks ago

@zepfietje Is there any reason not to use backticks to surround the record title when used in a Alpine attribute?

For example here and here.

Switching to the following: :alpine-hidden="($group?->isCollapsible() ? 'true' : 'false') . ' && isGroupCollapsed(`' . $recordGroupTitle . '`)'"

isGroupCollapsed(`{{ $recordGroupTitle }}`),

Resolves this issue.

zepfietje commented 4 weeks ago

No particular reason I can think of, @rossbearman. Thanks for creating a PR. 👍