use `configureUsing` to avoid repetition

I have many password fields in my application so i'd like to use
class AdminPanelProvider extends PanelProvider
{
public function boot()
TextInput::configureUsing(function (TextInput $component) {
$component->isPassword() && $component->revealable(config('panel.password.revealable'));
}, isImportant: true);
}
class AdminPanelProvider extends PanelProvider
{
public function boot()
TextInput::configureUsing(function (TextInput $component) {
$component->isPassword() && $component->revealable(config('panel.password.revealable'));
}, isImportant: true);
}
Problem is this is the boot function runs BEFORE the component is created i want it to execute after so i don't have to manually add ->revealable(config('panel.password.revealable')) to every TextInput of the password kind.
I tried using
dump($component->isPassword());
dump($component->isPassword());
and it will always return false same goes for
dump($component->getType());
dump($component->getType());
it will always return text even though its a password, email or alphanumeric field. I don't want to make my own component just for passwords cause i want to apply similar edit to other components as well Thanks for your help 🙂
15 Replies
phydeaux
phydeaux4d ago
I had a similar issue a while back. Try putting it in the register() function instead.
Martin Oscar
Martin Oscar4d ago
Not sure im doing this quite right where should i put the register() method ?
phydeaux
phydeaux4d ago
The PanelProvider that gets made using the artisan commands don't put it there by default but any ServiceProvider can have a register() method since they all ultimately should be extending Illuminate\Support\ServiceProvider. If it's not there, just add it. And those things can be in any ServiceProvider. For maintenance simplicity, I created a generic ConfigurationServiceProvider (basic Laravel - nothing Filament specific) and put all my global configureUsing items in there. Sometimes boot() works fine but sometimes that gets hit too soon and register() works better.
Martin Oscar
Martin Oscar4d ago
I tried putting it under AppServiceProvider::register() seems like it still is too early Do you need to import the ConfigurationServiceProvider somewhere else for it to get called later or bootstrap/providers.php should do the job ? cause mine is still too early just like if i made that under boot no change at all
phydeaux
phydeaux4d ago
Yeah, it needs to be in bootstrap/providers.php.
I haven't seen it where one of those wouldn't do the trick. If it's still not working, my next try would be to throw some debug lines (log, dd, ray, whatev) into the main method and also into the configureUsing closure to verify if it's actually getting called or not. (Note: I'm not a Filament pro by any stretch.)
Martin Oscar
Martin Oscar4d ago
It gets called out i see the dump on the page but it still gets called before the component is actually made
dump($component->isPassword(), $component->getLabel());

produces :
false // app/Providers/ConfigurationServiceProvider.php:17

"Username" // app/Providers/ConfigurationServiceProvider.php:17

false // app/Providers/ConfigurationServiceProvider.php:17

"Email" // app/Providers/ConfigurationServiceProvider.php:17

false // app/Providers/ConfigurationServiceProvider.php:17

"Password" // app/Providers/ConfigurationServiceProvider.php:17

false // app/Providers/ConfigurationServiceProvider.php:17

"Password confirmation" // app/Providers/ConfigurationServiceProvider.php:17
dump($component->isPassword(), $component->getLabel());

produces :
false // app/Providers/ConfigurationServiceProvider.php:17

"Username" // app/Providers/ConfigurationServiceProvider.php:17

false // app/Providers/ConfigurationServiceProvider.php:17

"Email" // app/Providers/ConfigurationServiceProvider.php:17

false // app/Providers/ConfigurationServiceProvider.php:17

"Password" // app/Providers/ConfigurationServiceProvider.php:17

false // app/Providers/ConfigurationServiceProvider.php:17

"Password confirmation" // app/Providers/ConfigurationServiceProvider.php:17
it goes on and on but i cut it so i don't flood Thanks for trying to help me still
phydeaux
phydeaux4d ago
According to the docs, you can also put global configureUsing() in a middleware. I've never tried that but it's worth a shot
Martin Oscar
Martin Oscar4d ago
Ok so i made a middleware with a configureUsing() method and added it to $panel->middleware([]) inside AdminPanelProvider but the debug no longer appears on the page so it doesn't seem like it cares one bit
Moved it to handle(), debug is back but it still always returns false
Did you ever overcome the issue yourself with either of those methods ?
Im afraid i'll have to use something like
TextInput::macro('password', function () {
return $this->password()->revealable(config('panel.password.revealable'));
});
TextInput::macro('password', function () {
return $this->password()->revealable(config('panel.password.revealable'));
});
Edit macros doesn't work for that either
phydeaux
phydeaux4d ago
All I needed to do was move from boot() to register() and magic happened
Martin Oscar
Martin Oscar4d ago
Is your code opensource so i can take a look at it ?
phydeaux
phydeaux4d ago
It's not open source or posted anywhere but I can share the config stuff. It's pretty basic, though. I'll pop it up here in just a sec. bootstrap/providers.php
return [
App\Providers\AppServiceProvider::class,
App\Providers\ConfigurationServiceProvider::class,
App\Providers\Filament\AdminPanelProvider::class,
];
return [
App\Providers\AppServiceProvider::class,
App\Providers\ConfigurationServiceProvider::class,
App\Providers\Filament\AdminPanelProvider::class,
];
app/Providers/ConfigurationServiceProvider.php
namespace App\Providers;

use Filament\Forms\Components\RichEditor;
use Filament\Panel;
use Illuminate\Support\ServiceProvider;

class ConfigurationServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
// Define the logos here rather than in every panel
Panel::configureUsing(function (Panel $panel) {
return $panel
->brandLogo(asset('img/hrlink-logo.svg'))
->darkModeBrandLogo(asset('img/hrlink-logo-light.svg'));
});
}

/**
* Bootstrap services.
*/
public function boot(): void
{
RichEditor::configureUsing(function (RichEditor $richEditor) {
return $richEditor
->columnSpanFull()

/* Available toolbar buttons:
'bold', 'italic', 'underline', 'link', 'h2', 'h3', 'undo', 'redo',
'attachFiles', 'blockquote', 'bulletList', 'codeBlock', 'orderedList', 'strike'
*/
->toolbarButtons([
'bold',
'italic',
'underline',
'link',
'undo',
'redo',
]);
});
}
}
namespace App\Providers;

use Filament\Forms\Components\RichEditor;
use Filament\Panel;
use Illuminate\Support\ServiceProvider;

class ConfigurationServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
// Define the logos here rather than in every panel
Panel::configureUsing(function (Panel $panel) {
return $panel
->brandLogo(asset('img/hrlink-logo.svg'))
->darkModeBrandLogo(asset('img/hrlink-logo-light.svg'));
});
}

/**
* Bootstrap services.
*/
public function boot(): void
{
RichEditor::configureUsing(function (RichEditor $richEditor) {
return $richEditor
->columnSpanFull()

/* Available toolbar buttons:
'bold', 'italic', 'underline', 'link', 'h2', 'h3', 'undo', 'redo',
'attachFiles', 'blockquote', 'bulletList', 'codeBlock', 'orderedList', 'strike'
*/
->toolbarButtons([
'bold',
'italic',
'underline',
'link',
'undo',
'redo',
]);
});
}
}
In this app, the RichEditor config works great. But the logo change wasn't happening when it was in boot(). Moved it to register(0 and it worked fine.
Martin Oscar
Martin Oscar4d ago
I see, that's what i'v done without success, it works for you cause its setting "hardcoded" stuff whereas i need to check if the $component has the bool isPassword = true Also you should put
->brandLogo(asset('img/hrlink-logo.svg'))
->darkModeBrandLogo(asset('img/hrlink-logo-light.svg'));
->brandLogo(asset('img/hrlink-logo.svg'))
->darkModeBrandLogo(asset('img/hrlink-logo-light.svg'));
under your PanelProvider
public function panel(Panel $panel): Panel
return $panel
public function panel(Panel $panel): Panel
return $panel
instead of a register method @see Assuming you are using Filament 3.x
phydeaux
phydeaux4d ago
D'oh! I mentally glossed over the part where you were trying to use the component object. Sorry for that irrelevant wild goose chase. (facepalm) I may make that change when I pick that project back up. It's not my active one at the moment. But it's working for now.
Martin Oscar
Martin Oscar4d ago
Don't worry we've tried stuff and even though it didn't work we both learned move Filament so i guess kinda win ? Yeah if it ain't broke don't fix it 🤪 Well lets forget the whole override thing imagine i want to use
$panel->revealablePasswords(config('panel.password.revealable'))
$panel->revealablePasswords(config('panel.password.revealable'))
instead the fields still aren't revealable() even though that var is true @see
Also i don't know why but they are not revealable() by default unless i tell the component to be even if (bool) $panel->arePasswordsRevealable = true
Zen Nitiruj
Zen Nitiruj4d ago
I had similar use case, I tried to reveal input text by using type as password, but the problem then causing google chrome asking to save password all the time. Then I decided to reveal in different way. I set macro in AppServiceProvider register function `
class AppServiceProvider extends ServiceProvider
{

public function register(): void
{
TextInput::macro('revealOnMouseOver', function () {
/** @var TextInput $this */
return $this->autocomplete('false')
->extraInputAttributes([
'class' => 'key',
'x-on:focus' => "\$el.classList.remove('key')",
'x-on:mouseover' => "\$el.classList.remove('key')",
'x-on:blur' => "\$el.classList.add('key')",
'x-on:mouseout' => "\$el.classList.add('key')",

]);
});
}
class AppServiceProvider extends ServiceProvider
{

public function register(): void
{
TextInput::macro('revealOnMouseOver', function () {
/** @var TextInput $this */
return $this->autocomplete('false')
->extraInputAttributes([
'class' => 'key',
'x-on:focus' => "\$el.classList.remove('key')",
'x-on:mouseover' => "\$el.classList.remove('key')",
'x-on:blur' => "\$el.classList.add('key')",
'x-on:mouseout' => "\$el.classList.add('key')",

]);
});
}
No description
Want results from more Discord servers?
Add your server