[GIS] Leaflet popups – preserving user input on close/reopen

leafletleaflet-drawpopup

I am working on a Leaflet map that allows a user to open a popup by clicking on a geometry and then generate dynamic content within the popup. However, I find that on closing and then reopening the popup, the dynamic content is lost – I can think of a very lengthy workaround to preserve the content, but I'd like to see if anyone has a suggestion about a more direct way to do this, perhaps using Leaflet's methods… is there any way to preserve a popup's dynamic content when it has been closed and reopened?

Here is a slightly edited version of my code…

map.on('draw:created', function(e){

    //SETS THE BASIC FORMAT, INCLUDING BUTTONS FOR ADDING C
    popUpFields = "<button class='add_content'>Add content</button><div class='content_container'></div><button class='popup_save'>Save</button>";

    $(document).on("click", ".add_content", function(){
        $(this).next(".content_container").append("Hello popup!");
    });

    //ADDS THE LAYER TO THE MAP
    featureGroup.addLayer(e.layer);
    //AUTOMATICALLY OPENS THE POPUP
    e.layer.bindPopup(popUpFields).openPopup();

    e.layer.on('click', function(){
        //IF THE POPUP'S CONTENT HAS BEEN 'SAVED' AS AN ATTRIBUTE OF THE GEOMETRY - IN OTHER WORDS, THE USER HAS EDITED THE POPUP CONTENT
        if(e.layer.hello){
            //THIS IS WHERE A REOPENED POPUP NEEDS TO APPEAR WITH ALL OF THE CONTENT THAT HAD BEEN 'SAVED' - CODE BELOW DOES NOT WORK (OPENS WITH ONLY popUpFields CONTENT, NO ADDED CONTENT, BUT IS ILLUSTRATIVE OF WHAT I'M LOOKING FOR
            e.layer.openPopup();
        }
        else{
            e.layer.bindPopup(popUpFields).openPopup();
        };
    });

    $('.popup_save').click(function(){
        //THE USER SAVES THEIR POPUP CONTENT, WRITING THE ADDED CONTENT TO AN ATTRIBUTE OF THE LAYER     
        e.layer.hello = $(this).prev().html();
    });

});

So in summary, what happens here is that a user adds a geometry, a popup opens, the user clicks the 'Add content' button a few times, appending a few strings to a div in the popup… the user saves those strings as an attribute of the geometry and then closes the popup to do other stuff. Later, they wish to reopen the popup to add more strings, but all of the original added strings have been lost from the view. I would like it so that the added content is not lost when the popup closes. I actually have implemented a bit of a 'hack' solution that rebuilds the popup with the dynamic content every time it is reopened, but I feel that there must be a more elegant solution, where the state of the popup is preserved between closings and reopenings rather than freshly rebuilding it every time. Is there?

Best Answer

If you want to save the data only for that session, then this can achieved by the following code. I've basically re-arranged the code that you have written, along with the code to show the data in the Popup.

map.on('draw:created', function (e) {

        //ADDS THE LAYER TO THE MAP
        featureGroup.addLayer(e.layer);


        e.layer.on('click', function(){
            //IF THE POPUP'S CONTENT HAS BEEN 'SAVED' AS AN ATTRIBUTE OF THE GEOMETRY - IN OTHER WORDS, THE USER HAS EDITED THE POPUP CONTENT
            if(e.layer.hello){
                //If we have the data, then we will show only the content of the hello variable
                e.layer.bindPopup(e.layer.hello).openPopup();               
            }
            else{
                //we do not have the data; Hence we will show the editing functionality
                //SETS THE BASIC FORMAT, INCLUDING BUTTONS FOR ADDING C
                popUpFields = "<button class='add_content'>Add content</button><div class='content_container'></div><button class='popup_save'>Save</button>";

                //Open the Popup
                e.layer.bindPopup(popUpFields).openPopup();

                //Bind the click event on the Add content Button
                $(document).on("click", ".add_content", function(){
                    $(this).next(".content_container").append("Hello popup!");
                });

                //bind the click event on the save button
                $('.popup_save').click(function(){
                    //THE USER SAVES THEIR POPUP CONTENT, WRITING THE ADDED CONTENT TO AN ATTRIBUTE OF THE LAYER     
                    e.layer.hello = $(this).prev().html();
                });
            };
        });
});