Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: text column placeholder #7439

Merged
merged 13 commits into from
Sep 9, 2023

Conversation

ashleyhood
Copy link
Contributor

This solves #7401

  • Changes have been thoroughly tested to not break existing functionality.

@what-the-diff
Copy link
Contributor

what-the-diff bot commented Aug 3, 2023

PR Summary

  • Array Update in text-entry.blade.php and text-column.blade.php
    The variable $arrayState was updated in text-entry.blade.php and text-column.blade.php files. The purpose is to always ensure this variable is an array. This provides more stability to the program so you won't face issues or errors when it isn't in an expected format.

  • Method Update in CanFormatState.php
    The formatState() method in the CanFormatState.php file has been revised. Instead of using evaluate($this->placeholder), it now uses getPlaceholder(). This change enhances the reliability of the program as it allows us to better control the state format, potentially reducing error scenarios.

@danharrin
Copy link
Member

Hey, where does $placeholder come from here? Have you tested this?

@ashleyhood
Copy link
Contributor Author

I have tested this on my local dev machine.

The $placeholder comes from:

protected string | Closure | null $placeholder = null;

This is why it is wrapped in filled() to make sure it only does this if a placeholder is set and the state is null.

@sumardi
Copy link
Contributor

sumardi commented Aug 4, 2023

The issue is about TextEntry. You should add this in text-entry.blade.php as well. And can we prepend null instead of empty string "". It is better if we want to format state, for example

->formatStateUsing(fn ($state) => $state?->format('d F Y'))

@danharrin
Copy link
Member

@ashleyhood I'm sorry I don't understand, a protected property should not be accessible in the view like that. Are you on the latest version?

@zepfietje zepfietje marked this pull request as draft August 4, 2023 09:56
@zepfietje zepfietje added the bug Something isn't working label Aug 4, 2023
@zepfietje zepfietje added this to the v3 milestone Aug 4, 2023
@ashleyhood
Copy link
Contributor Author

I'm on Filament v3.0.7 and Livewire v3.0.0-beta.7.

That is really weird, because it does read the $placeholder and only changes the $arrayStates if it is filled!?!

How would I track down where this is being set if it is not in the CanFormatState trait?

Would be helpful to have livewire/wiretap 😜

@ashleyhood
Copy link
Contributor Author

On second thoughts, isn't this okay to access the $placeholder property because it is being set in the blade @php directive and therefore being rendered before sending the request?

@ashleyhood
Copy link
Contributor Author

My bad 😕

This is not working as it is returning:

Filament\Tables\Columns\TextColumn::placeholder(Closure|string|null $placeholder): static

Which will always be true.

We could only check for blank($arrayState) or we make the $placeholder accessible from a getter

public function getPlaceholder(): string | Closure | null
{
    return $this->placeholder;
}

and then check if it is `filled`.

@ashleyhood
Copy link
Contributor Author

This will also need to be add to the InfoLists text-entry.blade.php as mentioned by @sumardi above.

Should that be in a separate PR or could it be added to this PR?

@danharrin
Copy link
Member

Yeah we can make a getPlaceholder(). And please make the changes to infolists here instead of a new PR.

@ashleyhood ashleyhood marked this pull request as ready for review August 6, 2023 22:57
@@ -37,6 +37,10 @@
}

$arrayState = \Illuminate\Support\Arr::wrap($arrayState);

if (blank($arrayState) && filled($getPlaceholder())) {
$arrayState = \Illuminate\Support\Arr::prepend($arrayState, '');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this need to prepend the actual placeholder as state instead of an empty string? Also, can't it just reassign $arrayState completely into a new array since its already blank, instead of prepending

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be an empty string because when we call formatState () on line 69 it expects a blank() state:

You are right about just assigning a new array and that makes sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets use null instead of an empty string please

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially, we don't want the placeholder to run through formatState() though 🤔 It might need different styling, for example. Maybe we should use an if statement in the view to decide whether or not to render a placeholder. And then remove the placeholder application from the formatState() method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that looking at how the placeholder is formatted might be for another PR?

This PR was about trying to address how a placeholder works as intended only if the state is an empty string but not if the state is null.

@ashleyhood
Copy link
Contributor Author

I have removed the Arr::wrap that was evaluating null values as an empty array. This keeps the same results for an empty string and allows a null value to give same results as an empty string.

@ashleyhood
Copy link
Contributor Author

This also brings up the fundamental difference between $defaultState and $placeholder as there seems to be an overlap. For instance, if the state is null and both $defaultState and $placeholder are set then $defaultState will be used but if the state is an empty string then $placeholder is used.
Why would an empty string be replaced by the $placeholder? Wouldn't the expectation be the same as the $defaultState?

@danharrin
Copy link
Member

$placeholder should probably have different styling and is not simply a "formatting" thing, whereas $defaultState acts as if it came from the database

@ashleyhood
Copy link
Contributor Author

$placeholder should probably have different styling and is not simply a "formatting" thing, whereas $defaultState acts as if it came from the database

I see your point. Would you be happy to merge this fix and then another PR could address the issue of having a placeholder that accepted it's own styling.

@DanielSpravtsev
Copy link
Contributor

Any news about state of this PR? Maybe help needed? @danharrin

@danharrin
Copy link
Member

Work needs to be done on it, but by the time I have time to write instructions I might as well do it myself

@danharrin
Copy link
Member

Alright this should be fixed up now for all columns and entries, they have a differently-styled placeholder

@danharrin danharrin merged commit ae2edc8 into filamentphp:3.x Sep 9, 2023
4 checks passed
@faizananwerali
Copy link

faizananwerali commented Sep 12, 2023

Not working now for me in Infotlist with relationship. It was working before. The last working version was v3.0.42, after that, it has not been fixed. tried every single version to find the last working version.

TextEntry::make('profile.father_name')
    ->label('Father Name')
    ->placeholder('N/A'),
TextEntry::make('profile.father_occupation')
    ->label('Father Occupation/Profession')
    ->placeholder('N/A'),
TextEntry::make('profile.grand_father_name')
    ->label('Grand Father Name')
    ->placeholder('N/A'),
TextEntry::make('profile.mother_name')
    ->label("Mother's Name")
    ->placeholder('N/A'),
TextEntry::make('profile.mother_from')
    ->label("Mother's Home Town")
    ->placeholder('N/A'),
TextEntry::make('profile.mother_occupation')
    ->label("Mother's Occupation/Profession")
    ->placeholder('N/A'),
TextEntry::make('profile.guardian_phone_number')
    ->label('Guardian Phone Number')
    ->placeholder('N/A'),
TextEntry::make('profile.brothers')
    ->label('No. of Brothers')
    ->placeholder('N/A'),
TextEntry::make('profile.sisters')
    ->label('No. of Sisters')
    ->placeholder('N/A'),
TextEntry::make('profile.brothers_married')
    ->label('No. of Brothers Married')
    ->placeholder('N/A'),
TextEntry::make('profile.sisters_married')
    ->label('No. of Sisters Married')
    ->placeholder('N/A'),

This is how it looks.

Screenshot 2023-09-12 at 6 12 54 PM

Right now I using formatStateUsing to resolve this temporarily.

TextEntry::make('profile.father_name')
    ->label('Father Name')
    ->formatStateUsing(fn (User $record): string => $record->profile->father_name ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.father_occupation')
    ->label('Father Occupation/Profession')
    ->formatStateUsing(fn (User $record): string => $record->profile->father_occupation ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.grand_father_name')
    ->label('Grand Father Name')
    ->formatStateUsing(fn (User $record): string => $record->profile->grand_father_name ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.mother_name')
    ->label("Mother's Name")
    ->formatStateUsing(fn (User $record): string => $record->profile->mother_name ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.mother_from')
    ->label("Mother's Home Town")
    ->formatStateUsing(fn (User $record): string => $record->profile->mother_from ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.mother_occupation')
    ->label("Mother's Occupation/Profession")
    ->formatStateUsing(fn (User $record): string => $record->profile->mother_occupation ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.guardian_phone_number')
    ->label('Guardian Phone Number')
    ->formatStateUsing(fn (User $record): string => $record->profile->guardian_phone_number ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.brothers')
    ->label('No. of Brothers')
    ->formatStateUsing(fn (User $record): string => $record->profile->brothers ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.sisters')
    ->label('No. of Sisters')
    ->formatStateUsing(fn (User $record): string => $record->profile->sisters ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.brothers_married')
    ->label('No. of Brothers Married')
    ->formatStateUsing(fn (User $record): string => $record->profile->brothers_married ?? 'N/A')
    ->placeholder('N/A'),
TextEntry::make('profile.sisters_married')
    ->label('No. of Sisters Married')
    ->formatStateUsing(fn (User $record): string => $record->profile->sisters_married ?? 'N/A')
    ->placeholder('N/A'),

This is how now it looks.

Screenshot 2023-09-12 at 6 14 04 PM

$this->record is the User Model. I've set the record this way.

   public function infolist(Infolist $infolist): Infolist
   {
       return $infolist
           ->record($this->record)
           ->schema([
               Section::make(__('Family Info'))
                   ->heading('')
                   ->schema([
                       Grid::make(3)
                           ->schema([
                               // ....
                           ])
                   ])
       ]);
   }

@danharrin
Copy link
Member

Please open an issue as I cannot reproduce it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

placeholder() not working on Relationship / TextColumn::make('relationship.name')
6 participants