Добавление действия клика Stimulus к ссылке Turbo?
Я выполняю функцию встроенного редактирования на странице шоу с помощью кнопки «Редактировать» над фреймом, который загружается с турбо. Попытка добавить переключатель на кнопку редактирования, который переключается на кнопку отмены в режиме редактирования.
Прикинул, что простой контроллер стимулов поможет, если только вы не добавите
data-action="click->edit-button#toggle"
это отменяет действие турбо на кнопке. Мысли? Идеи?
<div turbo-controller="edit-button">
<a class="btn btn-sm btn-primary btn-outline" data-turbo-frame="project" data-edit-button-target="button" data-value="show" href="/foobar/234/edit">Edit</a>
<turbo-frame id="project">
content
</turbo-frame>
</div>
2 ответа
добавить действие в целевой кадр? — Дэн Таппин
Позвольте мне просто украсть эту идею:
<div data-controller="edit-button">
<a
href="/project/1/edit"
data-turbo-frame="project_1"
data-edit-button-target="toggle"
>
Edit
</a>
<turbo-frame
id="project_1"
data-action="turbo:frame-load->edit-button#toggle"
>
content
</turbo-frame>
</div>
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["toggle"];
toggle({ target: frame, params: { toggleUrl, toggleText } }) {
frame.dataset.editButtonToggleTextParam = this.toggleTarget.textContent;
this.toggleTarget.textContent = toggleText || "Cancel";
frame.dataset.editButtonToggleUrlParam = this.toggleTarget.href;
this.toggleTarget.href = toggleUrl || window.location.href;
}
}
https://stimulus.hotwired.dev/reference/actions#action-parameters
Изначально единственная проблема, которая у меня была, была при смене ссылкиhref
перед фактической навигацией по кадру. Просто имеяdata-action
не мешал фрейму перемещаться. Но если это все еще проблема, вот еще один способ сделать это, он также упрощает html-часть:
<a
href="/project/1/edit"
data-turbo-frame="project_1"
data-controller="edit-button"
data-action="edit-button#toggle:prevent"
>
Edit
</a>
<turbo-frame id="project_1">
content
</turbo-frame>
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
// `target` is the link so no need for explicit Target definition
toggle({ target, params: { toggleUrl, toggleText } }) {
// but the frame, we need to get manually
const frame = document.getElementById(target.dataset.turboFrame);
// navigate the frame before changing link's href
frame.src = target.href;
target.dataset.editButtonToggleTextParam = target.textContent;
target.textContent = toggleText || "Cancel";
target.dataset.editButtonToggleUrlParam = target.href;
target.href = toggleUrl || window.location.href;
}
}
Это работает, но я не знаю, поддерживается ли этот вариант использования, который я нашел здесь: https://github.com/hotwired/turbo/blob/v7.2.5/src/core/frames/frame_controller.ts#L374 .
а затем в документах дляloading
атрибут:
https://turbo.hotwired.dev/reference/frames#html-attributes
изменения в атрибуте будут немедленно перемещаться по элементу
Я могу только предположить, что это нормально изменитьsrc
.
Самым простым решением было бы иметь партиал с фреймом, который отображает либо ссылку редактирования и содержимое, либо ссылку отмены и форму редактирования, в зависимости от локальной настройки var. Например:
<turbo-frame id="project">
<% if local_assigns[:editing] == true %>
<a href="/foobar/123/cancel">Cancel</a>
editing form....
<% else %>
<a href="/foobar/234/edit">Edit</a>
content
<% end %>
</turbo-frame>
Это по умолчанию отобразит содержимое и отредактирует ссылку. В запросе на редактирование вам просто нужно отобразить частичное с помощью
def edit
foobar = Foobar.find(params[:id])
render partial: 'foobar_editor', locals: { foobar: foobar, editing: true }
end
def cancel
foobar = Foobar.find(params[:id])
render partial: 'foobar_editor', locals: { foobar: foobar, editing: false }
end