Linus
Linus
FFilament
Created by Linus on 7/18/2024 in #❓┊help
Update Content of Key-Value Field
Hi! I'm new to Filament and need some help with conditional fields: Problem: I have a Select field and a KeyValue field. When the user selects a different option in the select, the data in the kv-field should be updated. But as you can see in this recording, it doesn't really work, only sometimes the field is updated: 🎥 https://krausskomm-my.sharepoint.com/:v:/g/personal/lb_krausskommunikation_de/Ef_yx_bOS9xEqcdP51xW-ugBJmJlNkkxEZv_N0mOp3tnjg?e=pCzNnz&nav=eyJyZWZlcnJhbEluZm8iOnsicmVmZXJyYWxBcHAiOiJTdHJlYW1XZWJBcHAiLCJyZWZlcnJhbFZpZXciOiJTaGFyZURpYWxvZy1MaW5rIiwicmVmZXJyYWxBcHBQbGF0Zm9ybSI6IldlYiIsInJlZmVycmFsTW9kZSI6InZpZXcifX0%3D Fields: - the Select has reactive(), some options() and an afterStateUpdated hook which uses $set('config', []) to update the kv-field - the KeyValue is configured to not allow any modifications (no new rows, no deletions, no key changes) Code:
Forms\Components\Select::make( 'type' )
->reactive()
->options( [
'mysql' => 'MySQL',
'mysql_ssh' => 'MySQL (SSH)',
'sftp' => 'SFTP',
] )
->afterStateUpdated( function ( Forms\Get $get, Forms\Set $set ) {
// create a new key-value array depending on the selection...
$config = match ( $get( 'type' ) ) {
"mysql" => [
'hostname' => '',
// ...
],
"mysql_ssh" => [
'hostname' => '',
// ...
],
"sftp" => [
'hostname' => '',
// ...
],
default => [],
};

// ...if a key was already filled, keep it...
foreach ( $get( 'config' ) as $k => $v ) {
if ( isset( $current[ $k ] ) ) {
$config[ $k ] = $current[ $k ];
}
}

// ...and finally update the key-value field
$set( 'config', $config );
} )
->required(),

Forms\Components\KeyValue::make( 'config' )
->addable( false )
->deletable( false )
->editableKeys( false )
->columnSpanFull(),
Forms\Components\Select::make( 'type' )
->reactive()
->options( [
'mysql' => 'MySQL',
'mysql_ssh' => 'MySQL (SSH)',
'sftp' => 'SFTP',
] )
->afterStateUpdated( function ( Forms\Get $get, Forms\Set $set ) {
// create a new key-value array depending on the selection...
$config = match ( $get( 'type' ) ) {
"mysql" => [
'hostname' => '',
// ...
],
"mysql_ssh" => [
'hostname' => '',
// ...
],
"sftp" => [
'hostname' => '',
// ...
],
default => [],
};

// ...if a key was already filled, keep it...
foreach ( $get( 'config' ) as $k => $v ) {
if ( isset( $current[ $k ] ) ) {
$config[ $k ] = $current[ $k ];
}
}

// ...and finally update the key-value field
$set( 'config', $config );
} )
->required(),

Forms\Components\KeyValue::make( 'config' )
->addable( false )
->deletable( false )
->editableKeys( false )
->columnSpanFull(),
I don't see anything related to this on the Key-Value field documentation (https://filamentphp.com/docs/3.x/forms/fields/key-value), same for the Field updates documentation (https://filamentphp.com/docs/3.x/forms/advanced#field-updates). Context: I have a model that has two columns: - type (VARCHAR(100)) - config (TEXT) The config column stores key-value info formatted as JSON, with different keys depending on the type column. Example: | type | config | |--------|-----------------------------------------------| | mysql |{"database":"db1","port":3306} | | sftp |{"hostname":"hello.world","port":22}|
2 replies