diff --git a/build.gradle b/build.gradle
index 4398da6..9bbff5d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,7 +17,6 @@ plugins {
id 'jacoco'
}
-
version "7.2-SNAPSHOT"
group "org.grails.plugins"
diff --git a/grails-app/assets/javascripts/knockout-utils.js b/grails-app/assets/javascripts/knockout-utils.js
index d4f9397..77310f3 100644
--- a/grails-app/assets/javascripts/knockout-utils.js
+++ b/grails-app/assets/javascripts/knockout-utils.js
@@ -13,53 +13,90 @@
*/
ko.bindingHandlers.popover = {
- init: function (element, valueAccessor) {
+ init: function(element, valueAccessor) {
ko.bindingHandlers.popover.initPopover(element, valueAccessor);
},
- update: function (element, valueAccessor) {
+ update: function(element, valueAccessor) {
+ var $element = $(element),
+ instance = $element.data('bs.popover'),
+ popOptions = ko.bindingHandlers.popover.getOptions(valueAccessor),
+ combinedOptions = popOptions.combinedOptions,
+ options = popOptions.options;
+
+ if (!instance) {
+ ko.bindingHandlers.popover.initPopover(element, valueAccessor);
+ instance = $element.data('bs.popover');
+ }
+
+ if (!instance)
+ return;
+
+ // if view model has changed, update the popover
+ instance.config.title = combinedOptions.title || "";
+ instance.config.content = combinedOptions.content || "";
- var $element = $(element);
- $element.popover('dispose');
- var options = ko.bindingHandlers.popover.initPopover(element, valueAccessor);
if (options.autoShow) {
if ($element.data('firstPopover') === false) {
- $element.popover('show');
- $('body').on('click', function (e) {
-
+ instance.show();
+ $('body').on('click', function(e) {
if (e.target != element && $element.find(e.target).length == 0) {
- $element.popover('dispose');
+ instance.hide();
}
});
}
+
$element.data('firstPopover', false);
}
+ // refresh popover content
+ if(ko.bindingHandlers.popover.isPopoverShown(element)) {
+ instance.show();
+ }
},
defaultOptions: {
placement: "right",
animation: true,
html: true,
- trigger: "hover",
- delay: {
- show: 250
- }
+ trigger: "hover"
},
- initPopover: function (element, valueAccessor) {
+ initPopover: function(element, valueAccessor) {
+ var popOptions = ko.bindingHandlers.popover.getOptions(valueAccessor),
+ options = popOptions.options,
+ combinedOptions = popOptions.combinedOptions;
+ $(element).popover(combinedOptions);
+ ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
+ $(element).popover("dispose");
+ });
+
+ return options;
+ },
+ /**
+ * constructs the options object from valueAccessor
+ * @param valueAccessor
+ * @returns {{combinedOptions: any, options: any}}
+ */
+ getOptions: function(valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor());
+ if (typeof(options.content) === "undefined") {
+ options.content = ""
+ }
var combinedOptions = ko.utils.extend({}, ko.bindingHandlers.popover.defaultOptions);
var content = ko.utils.unwrapObservable(options.content);
ko.utils.extend(combinedOptions, options);
combinedOptions.description = content;
-
- $(element).popover(combinedOptions);
-
- ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
- $(element).popover("dispose");
- });
- return options;
+ return {combinedOptions: combinedOptions, options: options};
+ },
+ /**
+ * id of the popover is stored in the element's aria-describedby attribute
+ * @param element
+ * @returns {boolean}
+ */
+ isPopoverShown: function isPopoverShown(element) {
+ const popoverId = $(element).attr("aria-describedby");
+ return $("#" + popoverId).length > 0;
}
};
diff --git a/grails-app/assets/javascripts/speciesModel.js b/grails-app/assets/javascripts/speciesModel.js
index c34ca66..463556d 100644
--- a/grails-app/assets/javascripts/speciesModel.js
+++ b/grails-app/assets/javascripts/speciesModel.js
@@ -222,7 +222,7 @@ var speciesSearchEngines = function() {
* Allows species information to be searched for and displayed.
*/
var SpeciesViewModel = function(data, options, context) {
-
+ var SPECIAL_GUIDS = ['A_GUID'];
var self = this;
ecodata.forms.DataModelItem.apply(self, [options.metadata || {}, context, options]);
@@ -232,6 +232,7 @@ var SpeciesViewModel = function(data, options, context) {
var output = options.output || "";
var dataFieldName = options.dataFieldName || "";
var surveyName = options.surveyName || "";
+ var kvpInfo = "";
self.guid = ko.observable();
self.name = ko.observable();
@@ -252,7 +253,7 @@ var SpeciesViewModel = function(data, options, context) {
self.transients.source = ko.observable(options.speciesSearchUrl +
'&output=' + output+ '&dataFieldName=' + dataFieldName + '&surveyName=' + surveyName);
self.transients.bieUrl = ko.observable();
- self.transients.speciesInformation = ko.observable();
+ self.transients.speciesInformation = ko.observable('');
self.transients.speciesTitle = ko.observable();
self.transients.matched = ko.computed(function() {
return self.guid() && self.guid() != "A_GUID" && self.listId != "unmatched";
@@ -328,7 +329,6 @@ var SpeciesViewModel = function(data, options, context) {
self.transients.textFieldValue(self.name());
// Species Translation
- var kvpInfo = "";
var languages = ["Waramungu", "Warlpiri name"];
var listsId = 'dr8016';
if(self.listId() == listsId || output == 'CLC 2Ha Track Plot') {
@@ -350,38 +350,44 @@ var SpeciesViewModel = function(data, options, context) {
}
});
}
+ };
+ self.fetchSpeciesImage = function() {
if (self.guid() && !options.printable) {
+ if (SPECIAL_GUIDS.indexOf(self.guid()) >= 0) {
+ var profileInfo = "No profile available";
+ self.transients.speciesInformation(profileInfo);
+ }
+ else {
+ var profileUrl = options.bieUrl + '/species/' + encodeURIComponent(self.guid());
+ $.ajax({
+ url: options.speciesProfileUrl + '?id=' + encodeURIComponent(self.guid()),
+ cache: true,
+ dataType: 'json',
+ success: function (data) {
+ var profileInfo = '';
+ var imageUrl = data.thumbnail || (data.taxonConcept && data.taxonConcept.smallImageUrl);
- var profileUrl = options.bieUrl + '/species/' + encodeURIComponent(self.guid());
- $.ajax({
- url: options.speciesProfileUrl+'?id=' + encodeURIComponent(self.guid()),
- dataType: 'json',
- success: function (data) {
- var profileInfo = '';
- var imageUrl = data.thumbnail || (data.taxonConcept && data.taxonConcept.smallImageUrl);
-
- if (imageUrl) {
- profileInfo += "";
- }
- else {
- profileInfo += "No profile image available";
+ if (imageUrl) {
+ profileInfo += "
";
+ } else {
+ profileInfo += "No profile image available";
+ }
+ profileInfo += "";
+ profileInfo += kvpInfo;
+ self.transients.speciesInformation(profileInfo);
+ },
+ error: function (request, status, error) {
+ self.transients.speciesInformation("");
+ console.log(error);
}
- profileInfo += "";
- profileInfo += kvpInfo;
- self.transients.speciesInformation(profileInfo);
- },
- error: function(request, status, error) {
- console.log(error);
- }
- });
-
+ });
+ }
}
else {
self.transients.speciesInformation("No profile information is available.");
}
-
- };
+ }
self.focusLost = function(event) {
self.transients.editing(false);
diff --git a/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp b/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp
index 4a07df4..095e9d8 100644
--- a/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp
+++ b/grails-app/views/output/_imageDataTypeViewModelWithMetadataTemplate.gsp
@@ -5,7 +5,7 @@