Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions lang/en/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
'entry_origin_instructions' => 'The new localization will inherit values from the entry in the selected site.',
'expect_root_instructions' => 'Consider the first page in the tree a "root" or "home" page.',
'field_conditions_always_save_instructions' => 'Always save field value, even if the field is hidden.',
'field_conditions_reserve_space_when_hidden_instructions' => 'When hidden, reserve the field\'s space in the layout.',
'field_conditions_field_instructions' => 'You may enter any field handle. You are not limited to the options in the dropdown.',
'field_conditions_instructions' => 'When to show or hide this field.',
'field_desynced_from_origin' => 'Desynced from origin. Click to sync and revert to the origin\'s value.',
Expand Down
33 changes: 27 additions & 6 deletions resources/js/components/field-conditions/Builder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,23 @@
</div>
</div>

<Field
:label="__('Always Save')"
:instructions="__('messages.field_conditions_always_save_instructions')"
>
<Switch v-model="alwaysSave" />
</Field>
<div class="w-full publish-fields">
<Field
class="form-group field-w-33"
:label="__('Always Save')"
:instructions="__('messages.field_conditions_always_save_instructions')"
>
<Switch v-model="alwaysSave" />
</Field>

<Field
class="form-group field-w-33"
:label="__('Reserve Space When Hidden')"
:instructions="__('messages.field_conditions_reserve_space_when_hidden_instructions')"
>
<Switch v-model="reserveSpaceWhenHidden" />
</Field>
</div>
</div>
</template>

Expand Down Expand Up @@ -77,6 +88,7 @@ export default {
customMethod: null,
conditions: [],
alwaysSave: false,
reserveSpaceWhenHidden: false,
};
},

Expand Down Expand Up @@ -135,12 +147,17 @@ export default {
alwaysSave(alwaysSave) {
this.$emit('updated-always-save', alwaysSave);
},

reserveSpaceWhenHidden(reserveSpaceWhenHidden) {
this.$emit('updated-reserve-space-when-hidden', reserveSpaceWhenHidden);
},
},

created() {
this.add();
this.getInitialConditions();
this.getInitialAlwaysSaveState();
this.getInitialReserveSpaceWhenHiddenState();
},

methods: {
Expand Down Expand Up @@ -187,6 +204,10 @@ export default {
this.alwaysSave = data_get(this.config, 'always_save', false);
},

getInitialReserveSpaceWhenHiddenState() {
this.reserveSpaceWhenHidden = data_get(this.config, 'reserve_space_when_hidden', false);
},

prepareEditableConditions(conditions) {
return new Converter().fromBlueprint(conditions).map((condition) => {
condition._id = uniqid();
Expand Down
7 changes: 7 additions & 0 deletions resources/js/components/fields/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
:suggestable-fields="suggestableConditionFields"
@updated="updateFieldConditions"
@updated-always-save="updateAlwaysSave"
@updated-reserve-space-when-hidden="updateReserveSpaceWhenHidden"
/>
</CardPanel>
</TabContent>
Expand Down Expand Up @@ -263,6 +264,12 @@ export default {
this.markFieldEdited('always_save');
},

updateReserveSpaceWhenHidden(reserveSpaceWhenHidden) {
this.values.reserve_space_when_hidden = reserveSpaceWhenHidden;

this.markFieldEdited('reserve_space_when_hidden');
},

markFieldEdited(handle) {
if (this.editedFields.indexOf(handle) === -1) {
this.editedFields.push(handle);
Expand Down
14 changes: 12 additions & 2 deletions resources/js/components/ui/Publish/Field.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ const shouldShowField = computed(() => {
).showField(props.config, fullPath.value);
});

// Only applies when hidden by conditions; blueprint "hidden" visibility still removes the field from layout.
const reserveSpaceWhenHiddenEnabled = computed(
() => props.config.reserve_space_when_hidden === true && props.config.visibility !== 'hidden',
);

const shouldHideFieldVisually = computed(
() => reserveSpaceWhenHiddenEnabled.value && !shouldShowField.value,
);

const shouldShowLabelText = computed(() => !props.config.hide_display);

const shouldShowLabel = computed(
Expand Down Expand Up @@ -229,8 +238,9 @@ const fieldtypeComponentEvents = computed(() => ({
:shouldShowField="shouldShowField"
>
<Field
v-show="shouldShowField"
:class="`${config.type}-fieldtype`"
v-show="shouldShowField || reserveSpaceWhenHiddenEnabled"
:class="[`${config.type}-fieldtype`, { 'opacity-0 pointer-events-none': shouldHideFieldVisually }]"
:inert="shouldHideFieldVisually"
:id="fieldId"
:instructions="config.instructions"
:instructions-below="config.instructions_position === 'below'"
Expand Down
6 changes: 6 additions & 0 deletions src/Fields/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ public function alwaysSave()
return Arr::get($this->config, 'always_save', false);
}

public function reserveSpaceWhenHidden()
{
return Arr::get($this->config, 'reserve_space_when_hidden', false);
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand Down Expand Up @@ -277,6 +282,7 @@ public function toPublishArray()
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
'always_save' => $this->alwaysSave(),
'reserve_space_when_hidden' => $this->reserveSpaceWhenHidden(),
]);

unset($array['validate']);
Expand Down
23 changes: 23 additions & 0 deletions tests/Fields/FieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,32 @@ public function preProcess($data)
'required' => true,
'read_only' => false, // deprecated
'always_save' => false,
'reserve_space_when_hidden' => false,
], $field->toPublishArray());
}

#[Test]
public function to_publish_array_passes_through_reserve_space_when_hidden()
{
FieldtypeRepository::partialMock();

FieldtypeRepository::shouldReceive('find')
->with('example')
->andReturn(new class extends Fieldtype
{
protected $component = 'example';

protected $configFields = [];
});

$field = new Field('test', [
'type' => 'example',
'reserve_space_when_hidden' => true,
]);

$this->assertTrue($field->toPublishArray()['reserve_space_when_hidden']);
}

#[Test]
public function it_gets_the_value()
{
Expand Down
Loading