The code works, though there are a few lines that seem gross to me.
In this line i mount the response to a #id tag, i doubt this is the way to do it in stimulus.
this.element.closest('#notes').innerHTML = response.data;
I think the response needs to target on a parent controller.
<div id="notes">
<form data-controller="createnote">
</form>
</div>
Becomes
<div data-controller="notes">
<form data-controller="createnote">
</form>
</div>
The thing i don’t get working is sending a response to a parent controller. A posibility is getting a controller by a identifier
getControllerByIdentifier(identifier) {
return this.application.controllers.find(controller => {
return controller.context.identifier === identifier;
});
}
The full html
<div id="notes">
<form action="{{ route('notes.store', $customer) }}"
method="POST"
data-controller="create"
data-create-url="{{ route('notes.store', $customer) }}"
data-action="submit->create#submit"
>
<textarea type="text"
name="body"
placeholder="Note Content"
data-target="create.body"
value="{{ old( 'body') }}"
required
></textarea>
<button type="submit">Add Note
</button>
</form>
@foreach($customer->monthYearNotes() as $monthYear => $notes)
<div id="monthYear">
<h2>{{ $monthYear }}</h2>
@foreach($notes as $note)
<div id="note">
<p>{{ dayMonth($note) }}</p>
<div id="edit"
data-controller="toggle"
>
<p data-target="toggle.show"
data-action="click->toggle#toggle"
> {{ $note->body }}</p>
<div class="hidden"
data-target="toggle.hidden"
data-action="click->toggle#toggle"
>
<form action="{{ route('notes.update', $note) }}"
method="POST"
data-controller="edit"
data-edit-url="{{ route('notes.update', $note) }}"
data-action="submit->edit#submit"
>@method('PATCH')
<textarea type="text"
name="body"
placeholder="Note Content"
data-target="edit.body"
required
>{{ old('body') ?: $note->body }}</textarea>
<button type="submit">Voeg Notitie
</button>
</form>
</div>
<small>{{ timeAmPm($note) }}</small>
<button data-action="click->toggle#toggle">
@svg('icon-136-document-edit')
</button>
<form action="{{ route('notes.destroy',$note) }}"
method="POST"
data-controller="delete index"
data-delete-data="{{ $note->id }}"
data-action="submit->delete#submit"
>@method('DELETE')
<button type="submit">
@svg('icon-26-trash-can')
</button>
</form>
</div>
</div>
@endforeach
</div>
@endforeach
</div>
The full Js
// create controller
import { NotesController } from "./notes_controller";
export default class extends NotesController {
static targets = ["body"];
submit(event) {
event.preventDefault();
axios.post(this.data.get('url'), {
body: this.bodyTarget.value
}).then(response => {
this.element.closest('#notes').innerHTML = response.data;
}).catch(error => console.log(error));
}
}
// edit controller
import { NotesController } from "./notes_controller";
export default class extends NotesController {
static targets = ["body"];
submit(event) {
event.preventDefault();
axios.patch(this.data.get('url'), {
body: this.bodyTarget.value
}).then(response => {
this.element.closest('#edit').innerHTML = response.data;
}).catch(error => console.log(error));
}
}
// delete controller
import { NotesController } from "./notes_controller";
export default class extends NotesController {
submit(event) {
this.deleteNote(event, route('notities.destroy', this.data.get("data")), '#monthYear', '#note');
}
}
// attempt at to make the functions reusable this is related to delete
import { Controller } from "stimulus";
export class NotesController extends Controller {
deleteNote(event, route, parent, child) {
event.preventDefault();
axios.delete(route);
if (event.target.closest(parent).querySelectorAll(child).length > 1) {
event.target.closest(child).remove();
} else {
event.target.closest(parent).remove();
}
}
}
// Toggle show to edit
import { Controller } from "stimulus";
export default class extends Controller
{
static targets = [ "show", "hidden" ];
toggle() {
this.showTarget.classList.toggle('hidden');
this.hiddenTarget.classList.toggle('hidden');
}
}