I have a Django form with a multi-select on it. I am using the multi.js library to modify the look & feel of the multi-select. I am also using the Django Bootstrap Modal Forms package to be able to add new options to my select list without leaving/refreshing the page.
Currently, when I add a new item via the modal form, it is added in the back-end, but the multi-select does not get updated from the JsonResponse.
If I remove the code that applies the multi.js functionality to the multi-select, then it is refreshed properly when the modal window closes.
As per this issue in GitHub, I thought I might just have to trigger the change function for the select element, but that doesn't seem to work for me. I've tried adding $select.trigger( 'change' );
to the last line of the createQuestionModalForm
function, but even though that is hit in the debugger after submitting the modal, it doesn't seem to do anything.
Here's the relevant JS:
$('#id_questions').multi();
$(function () {
function createQuestionModalForm() {
$("#addQuestion").modalForm({
formURL: "{% url 'question_create' %}",
asyncUpdate: true,
asyncSettings: {
closeOnSubmit: true,
successMessage: "test",
dataUrl: "/projects/question_update",
dataElementId: "#id_questions",
dataKey: "question_select",
addModalFormFunction: createQuestionModalForm
}
});
}
createQuestionModalForm();
});
Are there any other tricks I can be using to force the multi.js plugin to properly display the updated node when the AJAX update is complete?
If you want to add new Entries to the multi form you basically have to add new options to the select and dispatch a new change Event. I have edited the demo and made a working proof of concept.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo – multi.js</title>
<base href="https://fabianlindfors.se/multijs/" target="_blank">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Include multi.js -->
<link rel="stylesheet" type="text/css" href="multi.min.css">
<script src="multi.min.js"></script>
<style>
/* Basic styling */
body {
font-family: sans-serif;
}
.container {
box-sizing: border-box;;
margin: 0 auto;
max-width: 500px;
padding: 0 20px;
width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>multi.js</h1>
<button class="add_test">Add Test-Element</button>
<p>Demo of select box replacement multi.js. Available on <a href="https://github.com/Fabianlindfors/multi.js">Github</a>.</p>
<select multiple="multiple" name="favorite_fruits" id="fruit_select">
<option>Apple</option>
<option>Banana</option>
<option>Blueberry</option>
<option>Cherry</option>
<option>Coconut</option>
<option>Grapefruit</option>
<option>Kiwi</option>
<option>Lemon</option>
<option>Lime</option>
<option>Mango</option>
<option>Orange</option>
<option>Papaya</option>
</select>
</div>
<script>
var select = document.getElementById( 'fruit_select' );
multi( select, {
search_placeholder: 'Search fruits...',
});
</script>
<script>
var counter = 1;
var button = document.getElementsByTagName("button");
button[0].addEventListener('click',function(e){
var select = document.getElementById( 'fruit_select' );
// Adding new Stuff
var newOption = document.createElement('option');
newOption.innerHTML = 'test'+ counter;
select.appendChild(newOption);
counter++;
// Update Multi
select.dispatchEvent(new Event('change'));
});
</script>
</body>
</html>
EDIT: you also might want to try dispatch the Change-Event in the addModalFormFunction. I've checked the Github-Repo and it seems this is the only place where you can trigger the select after it has been updated.
$('#id_questions').multi();
$(function () {
function createQuestionModalForm() {
$('#id_questions').trigger('change');
$("#addQuestion").modalForm({
formURL: "{% url 'question_create' %}",
asyncUpdate: true,
asyncSettings: {
closeOnSubmit: true,
successMessage: "test",
dataUrl: "/projects/question_update",
dataElementId: "#id_questions",
dataKey: "question_select",
addModalFormFunction: createQuestionModalForm
}
});
}
createQuestionModalForm();
});