Changeset 33099 for main


Ignore:
Timestamp:
2019-05-21T18:33:09+12:00 (2 years 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.

File:
1 edited

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});
Note: See TracChangeset for help on using the changeset viewer.