Skip to content

Commit 4e1f6d3

Browse files
committedJan 20, 2025
code change to fetch species image only if user trigger popover icon
1 parent b6223a4 commit 4e1f6d3

File tree

4 files changed

+67
-28
lines changed

4 files changed

+67
-28
lines changed
 

‎grails-app/assets/javascripts/knockout-utils.js

+58-21
Original file line numberDiff line numberDiff line change
@@ -13,53 +13,90 @@
1313
*/
1414
ko.bindingHandlers.popover = {
1515

16-
init: function (element, valueAccessor) {
16+
init: function(element, valueAccessor) {
1717
ko.bindingHandlers.popover.initPopover(element, valueAccessor);
1818
},
19-
update: function (element, valueAccessor) {
19+
update: function(element, valueAccessor) {
20+
var $element = $(element),
21+
instance = $element.data('bs.popover'),
22+
popOptions = ko.bindingHandlers.popover.getOptions(valueAccessor),
23+
combinedOptions = popOptions.combinedOptions,
24+
options = popOptions.options;
25+
26+
if (!instance) {
27+
ko.bindingHandlers.popover.initPopover(element, valueAccessor);
28+
instance = $element.data('bs.popover');
29+
}
30+
31+
if (!instance)
32+
return;
33+
34+
// if view model has changed, update the popover
35+
instance.config.title = combinedOptions.title || "";
36+
instance.config.content = combinedOptions.content;
2037

21-
var $element = $(element);
22-
$element.popover('dispose');
23-
var options = ko.bindingHandlers.popover.initPopover(element, valueAccessor);
2438
if (options.autoShow) {
2539
if ($element.data('firstPopover') === false) {
26-
$element.popover('show');
27-
$('body').on('click', function (e) {
28-
40+
instance.show();
41+
$('body').on('click', function(e) {
2942
if (e.target != element && $element.find(e.target).length == 0) {
30-
$element.popover('dispose');
43+
instance.hide();
3144
}
3245
});
3346
}
47+
3448
$element.data('firstPopover', false);
3549
}
3650

51+
// refresh popover content
52+
if(ko.bindingHandlers.popover.isPopoverShown(element)) {
53+
instance.show();
54+
}
3755
},
3856

3957
defaultOptions: {
4058
placement: "right",
4159
animation: true,
4260
html: true,
43-
trigger: "hover",
44-
delay: {
45-
show: 250
46-
}
61+
trigger: "hover"
4762
},
4863

49-
initPopover: function (element, valueAccessor) {
64+
initPopover: function(element, valueAccessor) {
65+
var popOptions = ko.bindingHandlers.popover.getOptions(valueAccessor),
66+
options = popOptions.options,
67+
combinedOptions = popOptions.combinedOptions;
68+
$(element).popover(combinedOptions);
69+
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
70+
$(element).popover("dispose");
71+
});
72+
73+
return options;
74+
},
75+
/**
76+
* constructs the options object from valueAccessor
77+
* @param valueAccessor
78+
* @returns {{combinedOptions: any, options: any}}
79+
*/
80+
getOptions: function(valueAccessor) {
5081
var options = ko.utils.unwrapObservable(valueAccessor());
82+
if (typeof(options.content) === "undefined") {
83+
options.content = ""
84+
}
5185

5286
var combinedOptions = ko.utils.extend({}, ko.bindingHandlers.popover.defaultOptions);
5387
var content = ko.utils.unwrapObservable(options.content);
5488
ko.utils.extend(combinedOptions, options);
5589
combinedOptions.description = content;
56-
57-
$(element).popover(combinedOptions);
58-
59-
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
60-
$(element).popover("dispose");
61-
});
62-
return options;
90+
return {combinedOptions: combinedOptions, options: options};
91+
},
92+
/**
93+
* id of the popover is stored in the element's aria-describedby attribute
94+
* @param element
95+
* @returns {boolean}
96+
*/
97+
isPopoverShown: function isPopoverShown(element) {
98+
const popoverId = $(element).attr("aria-describedby");
99+
return $("#" + popoverId).length > 0;
63100
}
64101
};
65102

‎grails-app/assets/javascripts/speciesModel.js

+7-5
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ var SpeciesViewModel = function(data, options, context) {
232232
var output = options.output || "";
233233
var dataFieldName = options.dataFieldName || "";
234234
var surveyName = options.surveyName || "";
235+
var kvpInfo = "";
235236

236237
self.guid = ko.observable();
237238
self.name = ko.observable();
@@ -252,7 +253,7 @@ var SpeciesViewModel = function(data, options, context) {
252253
self.transients.source = ko.observable(options.speciesSearchUrl +
253254
'&output=' + output+ '&dataFieldName=' + dataFieldName + '&surveyName=' + surveyName);
254255
self.transients.bieUrl = ko.observable();
255-
self.transients.speciesInformation = ko.observable();
256+
self.transients.speciesInformation = ko.observable('<i class="fa fa-spin fa-spinner"></i>');
256257
self.transients.speciesTitle = ko.observable();
257258
self.transients.matched = ko.computed(function() {
258259
return self.guid() && self.guid() != "A_GUID" && self.listId != "unmatched";
@@ -328,7 +329,6 @@ var SpeciesViewModel = function(data, options, context) {
328329
self.transients.textFieldValue(self.name());
329330

330331
// Species Translation
331-
var kvpInfo = "";
332332
var languages = ["Waramungu", "Warlpiri name"];
333333
var listsId = 'dr8016';
334334
if(self.listId() == listsId || output == 'CLC 2Ha Track Plot') {
@@ -350,7 +350,9 @@ var SpeciesViewModel = function(data, options, context) {
350350
}
351351
});
352352
}
353+
};
353354

355+
self.fetchSpeciesImage = function() {
354356
if (self.guid() && !options.printable) {
355357
if (SPECIAL_GUIDS.indexOf(self.guid()) >= 0) {
356358
var profileInfo = "No profile available";
@@ -360,6 +362,7 @@ var SpeciesViewModel = function(data, options, context) {
360362
var profileUrl = options.bieUrl + '/species/' + encodeURIComponent(self.guid());
361363
$.ajax({
362364
url: options.speciesProfileUrl + '?id=' + encodeURIComponent(self.guid()),
365+
cache: true,
363366
dataType: 'json',
364367
success: function (data) {
365368
var profileInfo = '<a href="' + profileUrl + '" target="_blank">';
@@ -375,17 +378,16 @@ var SpeciesViewModel = function(data, options, context) {
375378
self.transients.speciesInformation(profileInfo);
376379
},
377380
error: function (request, status, error) {
381+
self.transients.speciesInformation("");
378382
console.log(error);
379383
}
380384
});
381385
}
382-
383386
}
384387
else {
385388
self.transients.speciesInformation("No profile information is available.");
386389
}
387-
388-
};
390+
}
389391

390392
self.focusLost = function(event) {
391393
self.transients.editing(false);

‎grails-app/views/output/_speciesTemplate.gsp

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<input type="text" class="form-control form-control-sm speciesInputTemplates" data-bind="${databindAttrs}" ${validationAttrs}/>
1212
<div class="input-group-append">
1313
<span class="input-group-text" data-bind="visible: !transients.editing() && name()">
14-
<a data-bind="popover: {title: name, content: transients.speciesInformation}"><i class="fa fa-info-circle"></i></a>
14+
<a data-bind="popover: {title: name, content: transients.speciesInformation}, event: { 'shown.bs.popover': fetchSpeciesImage}"><i class="fa fa-info-circle"></i></a>
1515
</span>
1616
</div>
1717

‎src/main/groovy/au/org/ala/ecodata/forms/EditModelWidgetRenderer.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ public class EditModelWidgetRenderer implements ModelWidgetRenderer {
372372
<div data-bind="with:${context.source}" class="input-group"">
373373
<select class="form-control form-control-sm" data-bind="speciesSelect2:\$data" ${context.validationAttr}></select>
374374
<div class="input-group-append"">
375-
<span class="input-group-text" data-bind="visible:name(), popover: {title: transients.speciesTitle, content: transients.speciesInformation}, css:{'bg-warning':!transients.matched()}"><i class="fa" data-bind="css:{'fa-info-circle':transients.matched(), 'fa-question-circle':!transients.matched()}"></i></span>
375+
<span class="input-group-text" data-bind="visible:name(), popover: {title: transients.speciesTitle, content: transients.speciesInformation}, event: { 'shown.bs.popover': fetchSpeciesImage}, css:{'bg-warning':!transients.matched()}"><i class="fa" data-bind="css:{'fa-info-circle':transients.matched(), 'fa-question-circle':!transients.matched()}"></i></span>
376376
</div>
377377
</div></div>"""
378378
}

0 commit comments

Comments
 (0)
Failed to load comments.