Fix duplicate HTML ID warnings in form components

Resolve browser console warnings about non-unique HTML IDs when multiple
Livewire components with similar form fields appear on the same page.

**Problem:**
Multiple forms using generic IDs like `id="description"` or `id="name"`
caused duplicate ID warnings and potential accessibility/JavaScript issues.

**Solution:**
- Separate `wire:model` binding name from HTML `id` attribute
- Auto-prefix HTML IDs with Livewire component ID for uniqueness
- Preserve existing `wire:model` behavior with property names

**Implementation:**
- Added `$modelBinding` property for wire:model (e.g., "description")
- Added `$htmlId` property for unique HTML ID (e.g., "lw-xyz123-description")
- Updated render() method to generate unique IDs automatically
- Updated all blade templates to use new properties

**Components Updated:**
- Input (text, password, etc.)
- Textarea (including Monaco editor)
- Select
- Checkbox
- Datalist (single & multiple selection)

**Result:**
 All HTML IDs now unique across page
 No console warnings
 wire:model bindings work correctly
 Validation error messages display correctly
 Backward compatible - no changes needed in existing components

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2025-10-14 10:27:41 +02:00
parent 56481b31bc
commit a514c837b6
10 changed files with 118 additions and 31 deletions

View File

@@ -10,6 +10,10 @@ use Visus\Cuid2\Cuid2;
class Input extends Component
{
public ?string $modelBinding = null;
public ?string $htmlId = null;
public function __construct(
public ?string $id = null,
public ?string $name = null,
@@ -43,11 +47,24 @@ class Input extends Component
public function render(): View|Closure|string
{
// Store original ID for wire:model binding (property name)
$this->modelBinding = $this->id;
if (is_null($this->id)) {
$this->id = new Cuid2;
$this->modelBinding = $this->id;
}
// Generate unique HTML ID by prefixing with Livewire component ID
// This prevents duplicate IDs when multiple forms are on the same page
$livewireId = $this->attributes?->wire('id');
if ($livewireId && $this->modelBinding) {
$this->htmlId = $livewireId.'-'.$this->modelBinding;
} else {
$this->htmlId = $this->modelBinding ?: $this->id;
}
if (is_null($this->name)) {
$this->name = $this->id;
$this->name = $this->modelBinding;
}
if ($this->type === 'password') {
$this->defaultClass = $this->defaultClass.' pr-[2.8rem]';