2

In my map application, I tried to implement a jQueryUI dialog with a dynamic amount of buttons depending on the number of hits resulting from a search form. The buttons invoke the showResults() method which navigates to the marker that corresponds to the clicked hit.

The problem is that no matter which button you click, it will always navigate to the lowermost of the hit-array. I know that this is due to the click-event, so when it is triggered, the variable hit will always contain the last entry hit[hit.length-1].

The only workaround I have right now is defining separate functions for each possible amount of hits where I define the buttons "regularly" in the div.dialog-object and not in a for-loop but that will cause a lot of redundant code.

Here's my code:

function multiplehits(message, names, sites) {

    var buttons = [];

    for (var i=0; i < hits.length; i++){
        var hit = hits[i];
        var button = {
            text: names[i]+", "+sites[i],
            click: function () {
                div.remove();
                showResults(hit); /*always navigates to the last entry of the hits array*/
                $(this).dialog("close");                    
            }
        }
        buttons.push(button);
    }
    var div = $('<div>');
    div.html(message);
    div.dialog({
        close: function( event, ui ) {
            hits = [];
        },
        closeText: 'close',
        autoOpen: true,
        modal: true,
        draggable: false,
        resizable: false,
        title: OpenLayers.i18n('Title'),            
        buttons: buttons
    });
}

Is there some sort of trick passing the right index to the click-function? Since I am using jQuery-buttons for this, I think I have to stick to the object structure button = {text,click:function(){}).

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
tordah
  • 23
  • 4

1 Answers1

1

Fastest way to go:

Replace:

var hit = hits[i];

with:

let hit = hits[i];

Right way to go:

Learn about JavaScript closures, IIFEs, the .bind method and the new features of ES6.

This other question is a good starting point.


Code snippet

var hits = [1,2,3];
    var names = ['a','b','c'];
    
    var buttons = [];
    
    function showResults(hit){
      console.log(hit);
    }
    
    for (var i=0; i < hits.length; i++){
        let hit = hits[i];
        var button = {
            text: names[i],
            click: function () {
                div.remove();
                showResults(hit); /*always navigates to the last entry of the hits array*/
            }
        }
        buttons.push(button);
    }
    var div = $('<div>');
    div.html("message");
    div.dialog({
        close: function( event, ui ) {
            hits = [];
        },
        closeText: 'close',
        autoOpen: true,
        modal: true,
        draggable: false,
        resizable: false,
        title: 'Title',            
        buttons: buttons
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>
David
  • 6,695
  • 3
  • 29
  • 46
  • Yeah you're right, I guess my code was a perfect example for what makes the let statement so useful! I guess I should've read more into that, thanks alot for the links and examples! – tordah Dec 06 '19 at 19:50