2

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?

Uri
  • 2,992
  • 8
  • 43
  • 86
Raggedtoad
  • 511
  • 2
  • 8
  • 24
  • Did you tried setting `addModalFormFunction` to [something other than `createQuestionModalForm`](https://github.com/trco/django-bootstrap-modal-forms/issues/117#issuecomment-651284762)? – vrintle Aug 27 '20 at 02:26
  • 1
    First check if the select is loaded properly and if so, you should call the `multi` plugin after your new select data are loaded. If your select data is not loaded, then the problem is with `modalForm` itself. – MMDM Aug 28 '20 at 04:31
  • Did you try to call `$('#id_questions').multi();` after the ajax call returns with results? – Uri Aug 28 '20 at 08:15
  • @MMDM - I tried calling the `multi` plugin again after the call to `.modalForm` but that didn't change anything. The data in `question_select` is correct, which is the full HTML representing the new state of the ``. Any other ideas? – Raggedtoad Sep 01 '20 at 14:03

1 Answers1

1

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();
});
Marko Jozic
  • 146
  • 4
  • I don't have time to test this right now, but it looks like it will definitely point me in the right direction. Thank you for the help! – Raggedtoad Sep 02 '20 at 00:58