Filament动态隐藏表单输入:未选省份时隐藏城市字段
Filament中实现省份选择后显示城市输入框的正确方式
你之前的代码未生效的核心原因是:省份字段的x-data属于独立作用域,城市字段无法访问到该作用域内的selected变量,导致x-show逻辑失效。以下是两种可行的解决方案,推荐使用第一种Filament原生实现方式:
方法一:利用Filament自带的visible()方法(推荐)
直接通过表单状态控制城市字段的显示,无需手动编写Alpine代码,完全贴合Filament的组件设计逻辑:
Select::make("meta.employment_state") ->label("省份") ->getSearchResultsUsing(fn (string $search): array => State::query()->where('name', 'like', "%{$search}%")->limit(10)->pluck('name', 'id')->toArray()) ->getOptionLabelUsing(fn ($value): ?string => State::find($value)?->name) ->afterStateUpdated(function (Set $set) { $set('meta.employment_city', null); }) ->live() ->searchable() ->dehydrated(false), Select::make("meta.employment_city") ->label("城市") ->getSearchResultsUsing(fn (string $search, Get $get): array => City::query()->whereRelation('state', 'id', '=', $get('meta.employment_state'))->where('name', 'like', "%{$search}%")->limit(10)->pluck('name', 'id')->toArray()) ->getOptionLabelUsing(fn ($value): ?string => City::find($value)?->name) ->placeholder('请选择') ->searchable() // 核心:通过省份字段的状态控制显示 ->visible(fn(Get $get) => filled($get('meta.employment_state'))),
说明
visible()方法接收一个闭包,通过Get $get获取当前省份字段的状态,当省份有值(filled()判断非空)时,城市字段才会显示。配合省份字段的live()特性,选择或清空省份时,城市字段会自动同步显示/隐藏。
方法二:修正Alpine作用域(可选)
如果坚持使用Alpine实现,需要将状态提升到公共作用域(比如整个表单容器),确保城市字段能访问到状态变量:
// 表单层面添加共享状态 Forms\Components\Section::make() ->extraAttributes(['x-data' => '{ stateSelected: false }']) ->schema([ Select::make("meta.employment_state") ->label("省份") ->getSearchResultsUsing(fn (string $search): array => State::query()->where('name', 'like', "%{$search}%")->limit(10)->pluck('name', 'id')->toArray()) ->getOptionLabelUsing(fn ($value): ?string => State::find($value)?->name) ->afterStateUpdated(function (Set $set) { $set('meta.employment_city', null); }) ->live() ->searchable() ->extraAttributes(['x-on:change' => 'stateSelected = $event.target.value !== ""']) ->dehydrated(false), Select::make("meta.employment_city") ->label("城市") ->getSearchResultsUsing(fn (string $search, Get $get): array => City::query()->whereRelation('state', 'id', '=', $get('meta.employment_state'))->where('name', 'like', "%{$search}%")->limit(10)->pluck('name', 'id')->toArray()) ->getOptionLabelUsing(fn ($value): ?string => City::find($value)?->name) ->placeholder('请选择') ->searchable() ->extraAttributes(['x-show' => 'stateSelected', 'x-cloak' => true]), ]),
说明
把Alpine的stateSelected状态定义在父容器(比如Section)上,这样两个子字段都能访问到这个变量。省份字段的x-on:change更新状态,城市字段的x-show基于该状态判断显示。
内容的提问来源于stack exchange,提问作者Pouya
相关产品推荐
相关产品推荐

