Skip to content

Commit

Permalink
Improve Attach field
Browse files Browse the repository at this point in the history
  • Loading branch information
tabuna committed May 22, 2024
1 parent 19f52ad commit 95e757c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 12 deletions.
29 changes: 23 additions & 6 deletions resources/js/controllers/attach_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ export default class extends ApplicationController {
},
group: {
type: String,
default: null,
},
storage: {
type: String,
default: 'public',
},
path: {
type: String,
default: null,
},
count: {
type: Number,
Expand All @@ -35,6 +33,12 @@ export default class extends ApplicationController {
type: Number,
default: 0,
},
uploadUrl: {
type: String,
},
sortUrl: {
type: String,
},
errorSize: {
type: String,
default: 'File ":name" is too large to upload',
Expand All @@ -45,7 +49,7 @@ export default class extends ApplicationController {
},
};

static targets = ['files', 'preview', 'container', 'template'];
static targets = ['files', 'preview', 'container', 'template', 'nullable'];

connect() {
this.attachmentValue.forEach((id) => this.renderPreview(id));
Expand Down Expand Up @@ -102,7 +106,7 @@ export default class extends ApplicationController {
this.loadingValue = this.loadingValue + 1;
this.element.ariaBusy = 'true';

fetch(this.prefix('/systems/files'), {
fetch(this.uploadUrlValue, {
method: 'POST',
body: data,
headers: {
Expand Down Expand Up @@ -139,9 +143,10 @@ export default class extends ApplicationController {

remove(event) {
const i = event.currentTarget.getAttribute('data-index');

event.currentTarget.closest('.pip').remove();

this.attachmentValue = this.attachmentValue.filter((id) => String(id) !== String(i));
this.attachmentValue = this.attachmentValue.filter((file) => String(file.id) !== String(i));

this.togglePlaceholderShow();
}
Expand All @@ -151,6 +156,16 @@ export default class extends ApplicationController {
*/
togglePlaceholderShow() {
this.containerTarget.classList.toggle('d-none', this.attachmentValue.length >= this.countValue);

// Disable the nullable field if there is at least one valid value and the count equals 1.
// If there are no values or if there are multiple values, the field will remain enabled and be sent to the server as `null`.
if (this.countValue === 1) {
this.nullableTarget.disabled = this.attachmentValue.length > 0;
} else {
// Unfortunately, this does not work with multiple selections because the server receives [0 => null] instead of an empty array.
// Therefore, this logic applies only to single selections.
this.nullableTarget.disabled = true;
}
}

/**
Expand All @@ -164,6 +179,8 @@ export default class extends ApplicationController {
preview.innerHTML = preview.innerHTML
.replace(/{id}/gi, attachment.id)
.replace(/{url}/gi, attachment.url)
.replace(/{original_name}/gi, attachment.original_name)
.replace(/{mime}/gi, attachment.mime)
.replace(/{name}/gi, this.nameValue);
});

Expand All @@ -184,7 +201,7 @@ export default class extends ApplicationController {
items[id] = index;
});

fetch(this.prefix('/systems/files'), {
fetch(this.sortUrlValue, {
method: 'POST',
body: JSON.stringify({
files: items,
Expand Down
7 changes: 5 additions & 2 deletions resources/sass/plugins/plugin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,8 @@
}

&:after {
content: "🔗";
content: attr(title);
white-space: pre;
position: absolute;
top: 0;
left: 0;
Expand All @@ -381,7 +382,9 @@
justify-content: center;
width: 100%;
text-align: center;
@extend .h3;
text-wrap: pretty;
@extend .p-3;
@extend .small;
}
}

Expand Down
24 changes: 20 additions & 4 deletions resources/views/fields/attach.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,25 @@ class="attach"
data-attach-count-value="{{ $maxCount }}"
data-attach-loading-value="0"
data-attach-attachment-value='@json($value ?? [])'

data-attach-upload-url-value="{{ route('platform.systems.files.upload') }}"
data-attach-sort-url-value="{{ route('platform.systems.files.sort') }}"

data-uploader-error-size-value="{{ __('File ":name" is too large to upload') }}"
data-uploader-error-type-value="{{ __('The attached file must be an image') }}"

data-action="
drop->attach#dropFiles:prevent
dragenter->attach#preventDefaults
dragover->attach#preventDefaults
dragleave->attach#preventDefaults
"
>
<div data-target="attach.preview" class="row row-cols-lg-6 gy-3 sortable-dropzone">
<div data-target="attach.preview" class="row row-cols-4 row-cols-lg-6 gy-3 sortable-dropzone">
<div class="col order-last" data-attach-target="container">
<label for="{{$id}}" class="border rounded bg-light attach-image-placeholder pointer-event h-100">
<input class="form-control d-none"
type="file"
multiple
data-attach-target="files"
data-action="change->attach#selectFiles"
{{ $attributes }}
Expand All @@ -35,15 +41,25 @@ class="attach"
</span>
</span>
</label>
<input type="hidden" name="{{ $name }}" data-attach-target="nullable" value="0">
</div>
</div>


<template data-target="attach.template">
<div class="pip col position-relative">
<input type="hidden" name="{name}" value="{id}">
<img class="attach-image rounded border user-select-none" src="{url}"/>
<button class="btn-close rounded-circle bg-white border shadow position-absolute end-0 top-0" type="button" data-action="click->attach#remove" data-index="{id}"></button>


<img class="attach-image rounded border user-select-none" src="{url}" title="{original_name}"/>

{{--
<object class="attach-image rounded border user-select-none" border="0" data="{url}" type="{mime}" title="test" load="lazy" controls allowfullscreen autoplay="false">
</object>
--}}

<button class="btn-close rounded-circle bg-white border shadow position-absolute end-0 top-0"
type="button" data-action="click->attach#remove" data-index="{id}"></button>
</div>
</template>

Expand Down
7 changes: 7 additions & 0 deletions src/Screen/Fields/Attach.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ public function __construct()

$this->set('value', $value);
});

// if is not multiple, then set maxCount to 1
$this->addBeforeRender(function () {
if (! $this->get('multiple')) {
$this->set('maxCount', 1);
}
});
}

/**
Expand Down

0 comments on commit 95e757c

Please sign in to comment.