Changeset 33099 for main

Show
Ignore:
Timestamp:
21.05.2019 18:33:09 (5 months ago)
Author:
wy59
Message:

In previous commits, the autocompletelist was a member variable of the mapeditor: one autocomplete labels list per map. Now we want one list per whole document/page, i.e. one autocomplete list covering all the maps on one page. This means making the autocomplete list 'global' to the file instead of a member var of mapeditor. It had as further consequence that there needed to be a global hashmap to maintain unique labels, from which the autocomplete labels list would get constituted. Another consequence was that the jquery handler, which would setup the autocomplete to source from our autocomplete labels array, would need to be global to the file and no longer called from within a map editor method. So this jquery method likewise needs to be called only once per document and not for each map in a doc. The mapeditor LOAD function now still keeps a local labels hashmap to work out unique labels per loaded mapeditor, then adds these to our global labels hashmap (by calling jquery extend), to ensure uniqueness of the sum of all labels on the page. And finally, the LOAD function converts that recalculated global hashmap into an array to reset our autocomplete labels list/array.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js

    r33098 r33099  
     1var global_autocompleteLabelsList = []; 
     2var global_labels_hashmap = {}; 
    13 
    24function MapEditor(id) { 
     
    3638    this.resizable = false; 
    3739    this.dontResize = false; 
    38     this.autocompleteLabelsList = []; 
     40     
    3941 
    4042    this.shapeOptions = { 
     
    132134    descriptionInput.onblur = function () { 
    133135        var description = this.value; 
    134         that.addToAutocompleteLabelsList(description) 
     136        that.addToAutocompleteLabelsList(description); 
    135137    } 
    136138     
     
    178180        } 
    179181    } 
    180  
    181     // Having got our unique (set) of descriptions/labels, we're ready to set it up as the source for our autocomplete list 
    182     $(function setupAutocompleteLabelsList() { 
    183         // Overrides the default autocomplete filter function to 
    184         // search only from the beginning of the string 
    185         //resource: https://miroslavpopovic.com/posts/2012/06/jqueryui-autocomplete-filter-words-starting-with-term 
    186         $.ui.autocomplete.filter = function (array, term) { 
    187             var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i"); 
    188             return $.grep(array, function (value) { 
    189                 return matcher.test(value.label || value.value || value); 
    190             }); 
    191         }; 
    192  
    193         $(".description").autocomplete({ 
    194             source: that.autocompleteLabelsList 
    195         }); 
    196     }); 
    197182} 
    198183 
     
    201186MapEditor.prototype.addToAutocompleteLabelsList = function (newLabel) { 
    202187     
    203     if (newLabel !== "" && !this.autocompleteLabelsList.includes(newLabel)) { 
     188    if (newLabel !== "" && !global_autocompleteLabelsList.includes(newLabel)) { 
    204189        // add to autocomplete list and sort alphabetically 
    205         this.autocompleteLabelsList.push(newLabel); 
    206         this.autocompleteLabelsList.sort(); 
     190        global_autocompleteLabelsList.push(newLabel); 
     191        global_autocompleteLabelsList.sort();         
    207192    } 
     193 
     194    console.log("the added new label to global autocomplete array:"); console.log(global_autocompleteLabelsList); 
    208195} 
    209196 
     
    819806    map_editor.overlays = new_overlays; 
    820807 
    821     var labels_hashmap = {}; 
     808    var local_labels_hashmap = {}; 
    822809    for (var i=0; i<map_editor.overlays.length; i++) { 
    823810        var shape = map_editor.overlays[i]; 
     
    826813        //map_editor.addToAutocompleteLabelsList(shape.description); // inefficient in ensuring uniqueness of values, use (hash)map 
    827814        if (shape.description !== "") { 
    828             labels_hashmap[shape.description] = 1;  // we just want the shape.description added to the map as key, don't care about value 
     815            local_labels_hashmap[shape.description] = 1;  // we just want the shape.description added to the map as key, don't care about value 
    829816                                                    // so that we can maintain a list of unique descriptions 
    830817        } 
     
    841828    this.mapEditorHistory.presentOverlayPush(); 
    842829     
    843     var keys = Object.keys(labels_hashmap); 
    844     // DO NOT assign "this.autocompleteLabelsList = keys(labels_hashmap);" 
     830     
     831    // DO NOT assign "this.autocompleteLabelsList = keys(local_labels_hashmap);" 
    845832    // Because Javascript is like Java and (in this) like C, not like C++. JavaScript uses Call-By-Sharing for objects: 
    846833    // when reference addresses that are overwritten inside functions, 
     
    849836    // Instead, push.apply=addAll elements of keys to our autocomplete list, see  
    850837    // https://stackoverflow.com/questions/35658464/what-is-the-equivalent-of-java-collection-addall-for-javascript-arrays/35658514 
    851     this.autocompleteLabelsList.push.apply(this.autocompleteLabelsList, keys); // addAll keys to our autocompleteLabelsList 
    852     this.autocompleteLabelsList.sort(); 
     838 
     839    // Combining contents of one JavaScript Object/hashmap (or associative 'array') into another is also described as merging our JavaScript Objects, so see 
     840    // https://stackoverflow.com/questions/929776/merging-objects-associative-arrays 
     841    // We've decided to use the jQuery based suggested solution for merging hashmaps: 
     842    // $.extend(obj1, obj2); means obj1 = obj1 + obj2. Overwriting any existing properties in obj1 with new values in obj2. 
     843 
     844    console.log("@@@@ Adding local contents to global: "); console.log(local_labels_hashmap); 
     845    console.log("@@@@ global map before: "); console.log(global_labels_hashmap); 
     846     
     847 
     848    $.extend(global_labels_hashmap, local_labels_hashmap); 
     849 
     850    console.log("@@@@ global map after: "); console.log(global_labels_hashmap); 
     851 
     852    // important to empty our global autocomplete labels list array 
     853    //See https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript 
     854    // and https://www.jstips.co/en/javascript/two-ways-to-empty-an-array/ 
     855    global_autocompleteLabelsList.length = 0; 
     856     
     857    var keys = Object.keys(global_labels_hashmap); 
     858    global_autocompleteLabelsList.push.apply(global_autocompleteLabelsList, keys); // addAll keys to our global_autocompleteLabelsList (turns map's keys into array) 
     859 
     860    console.log("@@@@ global ARRAY after setting to global map: "); console.log(global_autocompleteLabelsList); 
     861    global_autocompleteLabelsList.sort();    
    853862} 
    854863 
     
    893902    } 
    894903} 
     904 
     905 
     906// Having got our unique (set) of descriptions/labels, we're ready to set it up as the source for our autocomplete list 
     907$(function setupAutocompleteLabelsList() { 
     908    // Overrides the default autocomplete filter function to 
     909    // search only from the beginning of the string 
     910    //resource: https://miroslavpopovic.com/posts/2012/06/jqueryui-autocomplete-filter-words-starting-with-term 
     911    $.ui.autocomplete.filter = function (array, term) { 
     912        var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i"); 
     913        return $.grep(array, function (value) { 
     914            return matcher.test(value.label || value.value || value); 
     915        }); 
     916    }; 
     917 
     918    $(".description").autocomplete({ 
     919        source: global_autocompleteLabelsList 
     920    }); 
     921});