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

Fixed a couple bugs in CustomFieldSetDefaultValuesForModel component #15486

Merged
merged 27 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f6c1642
Use computed fields in CustomFieldSetDefaultValuesForModel component
marcusmoore Aug 14, 2024
038e869
Improve property name
marcusmoore Aug 14, 2024
ab63a19
Initialize concept of cached values
marcusmoore Aug 14, 2024
6ab976f
Use cached values for text input
marcusmoore Aug 15, 2024
e7c9c79
Add wire:keys
marcusmoore Aug 15, 2024
75c1e76
Improve method name
marcusmoore Aug 15, 2024
43b109f
Use cached values for textarea and radio input
marcusmoore Aug 15, 2024
5d1f98b
Simplify by directly wire:modeling
marcusmoore Aug 20, 2024
6c5ec6a
Get datepicker working
marcusmoore Aug 20, 2024
680cce3
Align indents
marcusmoore Aug 20, 2024
5983212
Improve comment
marcusmoore Aug 20, 2024
833bcb2
Add failing test
marcusmoore Aug 21, 2024
21d2217
Point test to correct endpoint
marcusmoore Aug 21, 2024
206f8fe
Add test case
marcusmoore Aug 21, 2024
1d89759
Implement fix
marcusmoore Aug 21, 2024
a2246b9
Simplify assertions
marcusmoore Aug 22, 2024
0abb563
WIP: handle old input
marcusmoore Aug 22, 2024
68749e7
Simplify logic
marcusmoore Aug 22, 2024
d0a351a
Add comment
marcusmoore Aug 22, 2024
c316571
Handle old input
marcusmoore Aug 22, 2024
10b4581
Improve id for checkboxes and radio buttons
marcusmoore Aug 22, 2024
7f3c861
Conditionally disable Add default values checkbox
marcusmoore Aug 22, 2024
aec781e
Be a little more explicit
marcusmoore Aug 22, 2024
9a73311
Fix nested checkboxes being updated as a group
marcusmoore Aug 23, 2024
51d63d5
Hide the "Add default values" checkbox if no fieldset selected
marcusmoore Sep 3, 2024
6423df2
Merge branch 'develop' into fixes/custom-field-values
marcusmoore Sep 9, 2024
ca01261
Merge branch 'develop' into fixes/custom-field-values
marcusmoore Sep 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 78 additions & 18 deletions app/Livewire/CustomFieldSetDefaultValuesForModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace App\Livewire;

use App\Models\CustomField;
use Livewire\Attributes\Computed;
use Livewire\Component;

use App\Models\CustomFieldset;
Expand All @@ -12,37 +14,95 @@ class CustomFieldSetDefaultValuesForModel extends Component
public $add_default_values;

public $fieldset_id;
public $fields;
public $model_id;

public function mount()
{
if(is_null($this->model_id)){
return;
}

$this->model = AssetModel::find($this->model_id); // It's possible to do some clever route-model binding here, but let's keep it simple, shall we?
$this->fieldset_id = $this->model->fieldset_id;
public array $selectedValues = [];

$this->fields = null;
public function mount($model_id = null)
{
$this->model_id = $model_id;
$this->fieldset_id = $this->model?->fieldset_id;
$this->add_default_values = ($this->model?->defaultValues->count() > 0);

if ($fieldset = CustomFieldset::find($this->fieldset_id)) {
$this->fields = CustomFieldset::find($this->fieldset_id)->fields;
}
$this->initializeSelectedValuesArray();
$this->populatedSelectedValuesArray();
}

$this->add_default_values = ($this->model->defaultValues->count() > 0);
#[Computed]
public function model()
{
return AssetModel::find($this->model_id);
}

public function updatedFieldsetId()
#[Computed]
public function fields()
{
if (CustomFieldset::find($this->fieldset_id)) {
$this->fields = CustomFieldset::find($this->fieldset_id)->fields;
$customFieldset = CustomFieldset::find($this->fieldset_id);

if ($customFieldset) {
return $customFieldset?->fields;
}


return collect();
}

public function render()
{
return view('livewire.custom-field-set-default-values-for-model');
}

/**
* Livewire property binding plays nicer with arrays when it knows
* which keys will be present instead of them being
* dynamically added (this is especially true for checkboxes).
*
* Let's go ahead and initialize selectedValues with all the potential keys (custom field db_columns).
*
* @return void
*/
private function initializeSelectedValuesArray(): void
{
CustomField::all()->each(function ($field) {
$this->selectedValues[$field->db_column] = null;

if ($field->element === 'checkbox') {
$this->selectedValues[$field->db_column] = [];
}
});
}

/**
* Populate the selectedValues array with the
* default values or old input for each field.
*
* @return void
*/
private function populatedSelectedValuesArray(): void
{
$this->fields->each(function ($field) {
$this->selectedValues[$field->db_column] = $this->getSelectedValueForField($field);
});
}

private function getSelectedValueForField(CustomField $field)
{
$defaultValue = $field->defaultValue($this->model_id);

// if old() contains a value for default_values that means
// the user has submitted the form and we were redirected
// back with the old input.
// Let's use what they had previously set.
if (old('default_values')) {
$defaultValue = old('default_values.' . $field->id);
}

// on first load the default value for checkboxes will be
// a comma-separated string but if we're loading the page
// with old input then it was already parsed into an array.
if ($field->element === 'checkbox' && is_string($defaultValue)) {
$defaultValue = explode(', ', $defaultValue);
}

return $defaultValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@
{!! $errors->first('custom_fieldset', '<span class="alert-msg" aria-hidden="true"><br><i class="fas fa-times"></i> :message</span>') !!}
</div>
<div class="col-md-3">
@if ($fieldset_id)
<label class="form-control">
{{ Form::checkbox('add_default_values', 1, old('add_default_values', $add_default_values), ['data-livewire-component' => $this->getId(), 'id' => 'add_default_values', 'wire:model.live' => 'add_default_values']) }}
{{ trans('admin/models/general.add_default_values') }}
</label>
{{ Form::checkbox('add_default_values', 1, old('add_default_values', $add_default_values), ['data-livewire-component' => $this->getId(), 'id' => 'add_default_values', 'wire:model.live' => 'add_default_values', 'disabled' => $this->fields->isEmpty()]) }}
{{ trans('admin/models/general.add_default_values') }}
</label>
@endif
</div>
</div>

@if ($this->add_default_values ) {{-- 'if the checkbox is enabled *AND* there are more than 0 fields in the fieldsset' --}}
@if ($fields)
@if ($add_default_values)
@if ($this->fields)

@foreach ($fields as $field)
<div class="form-group">
@foreach ($this->fields as $field)
<div class="form-group" wire:key="field-{{ $field->id }}">

<label class="col-md-3 control-label{{ $errors->has($field->name) ? ' has-error' : '' }}">{{ $field->name }}</label>

Expand All @@ -30,47 +32,88 @@

<div class="input-group col-md-4" style="padding-left: 0px;">
<div class="input-group date" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-autoclose="true">
<input type="text" class="form-control" placeholder="{{ trans('general.select_date') }}" name="default_values[{{ $field->id }}]" id="default-value{{ $field->id }}" value="{{ $field->defaultValue($model_id) }}">
<input
type="text"
class="form-control"
placeholder="{{ trans('general.select_date') }}"
name="default_values[{{ $field->id }}]"
id="default-value{{ $field->id }}"
wire:model="selectedValues.{{ $field->db_column }}"
{{-- catch the onchange event and dispatch an InputEvent ourselves so Livewire can react to it... --}}
{{-- https://laracasts.com/discuss/channels/livewire/livewire-and-bootstrap-datepicker?page=1&replyId=623122--}}
onchange="this.dispatchEvent(new InputEvent('input'))"
>
<span class="input-group-addon"><x-icon type="calendar" /></span>
</div>
</div>

@elseif ($field->element == "text")


<input class="form-control" type="text" value="{{ $field->defaultValue($model_id) }}" id="default-value{{ $field->id }}" name="default_values[{{ $field->id }}]">
<input
class="form-control"
type="text"
id="default-value{{ $field->id }}"
name="default_values[{{ $field->id }}]"
wire:model="selectedValues.{{ $field->db_column }}"
/>


@elseif($field->element == "textarea")


<textarea class="form-control" style="width: 100%;" id="default-value{{ $field->id }}" name="default_values[{{ $field->id }}]">{{ $field->defaultValue($model_id) }}</textarea>
<textarea
class="form-control"
style="width: 100%;"
id="default-value{{ $field->id }}"
name="default_values[{{ $field->id }}]"
wire:model="selectedValues.{{ $field->db_column }}"
></textarea>


@elseif($field->element == "listbox")


<select class="form-control" name="default_values[{{ $field->id }}]">
<select class="form-control" name="default_values[{{ $field->id }}]" wire:model="selectedValues.{{ $field->db_column }}">
<option value=""></option>
@foreach(explode("\r\n", $field->field_values) as $field_value)
<option value="{{$field_value}}" {{ $field->defaultValue($model_id) == $field_value ? 'selected="selected"': '' }}>{{ $field_value }}</option>
<option
value="{{$field_value}}"
wire:key="listbox-{{ $field_value }}"
>
{{ $field_value }}
</option>
@endforeach
</select>


@elseif($field->element == "radio")

@foreach(explode("\r\n", $field->field_values) as $field_value)
<label class="col-md-3 form-control" for="{{ str_slug($field_value) }}">
<input id="{{ str_slug($field_value) }}" aria-label="{{ str_slug($field->name) }}" type='radio' name="default_values[{{ $field->id }}]" value="{{$field_value}}" {{ $field->defaultValue($model_id) == $field_value ? 'checked="checked"': '' }} />{{ $field_value }}
</label>
<label class="col-md-3 form-control" for="{{ $field->db_column }}_{{ str_slug($field_value) }}" wire:key="radio-{{ $field_value }}">
<input
id="{{ $field->db_column }}_{{ str_slug($field_value) }}"
aria-label="{{ str_slug($field->name) }}"
type="radio"
name="default_values[{{ $field->id }}]"
value="{{$field_value}}"
wire:model="selectedValues.{{ $field->db_column }}"
/>{{ $field_value }}
</label>
@endforeach

@elseif($field->element == "checkbox")

@foreach(explode("\r\n", $field->field_values) as $field_value)
<label class="col-md-3 form-control" for="{{ str_slug($field_value) }}">
<input id="{{ str_slug($field_value) }}" type="checkbox" aria-label="{{ str_slug($field->name) }}" name="default_values[{{ $field->id }}][]" value="{{ $field_value }}"{{ in_array($field_value, explode(', ',$field->defaultValue($model_id))) ? ' checked="checked"': '' }}> {{ $field_value }}
<label class="col-md-3 form-control" for="{{ $field->db_column }}_{{ str_slug($field_value) }}" wire:key="checkbox-{{ $field_value }}">
<input
id="{{ $field->db_column }}_{{ str_slug($field_value) }}"
type="checkbox"
aria-label="{{ str_slug($field->name) }}"
name="default_values[{{ $field->id }}][]"
value="{{ $field_value }}"
wire:model="selectedValues.{{ $field->db_column }}"
> {{ $field_value }}
</label>
@endforeach

Expand All @@ -80,12 +123,12 @@
Unknown field element: {{ $field->element }}
</span>
@endif
</div>
</div>
</div>

@endforeach
</div>
@endif

@endif

@endif
</span>
Loading