From aa74293f23e579f72b8a94a1c5506a049801c529 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 19 Oct 2017 18:22:08 +0200
Subject: [PATCH] OO-2926: choose cardinality of hotspot interaction in editor

---
 .../model/xml/AssessmentItemFactory.java      |   7 +-
 .../HotspotAssessmentItemBuilder.java         |  21 +-
 ...sessmentObjectVelocityRenderDecorator.java |   8 +
 .../_content/hotspotInteraction.html          |   2 +
 .../editor/_i18n/LocalStrings_de.properties   |   4 +
 .../editor/_i18n/LocalStrings_en.properties   |   4 +
 .../editor/_i18n/LocalStrings_fr.properties   |   1 +
 .../interactions/HotspotEditorController.java |  23 ++
 .../static/js/jquery/qti/jquery.hotspot.js    | 232 +++++++++---------
 9 files changed, 186 insertions(+), 116 deletions(-)

diff --git a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java
index 081db4707a3..1bc4d1cb81a 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java
@@ -317,10 +317,13 @@ public class AssessmentItemFactory {
 		return responseDeclaration;
 	}
 	
-	public static ResponseDeclaration createHotspotCorrectResponseDeclaration(AssessmentItem assessmentItem, Identifier declarationId, List<Identifier> correctResponseIds) {
+	public static ResponseDeclaration createHotspotCorrectResponseDeclaration(AssessmentItem assessmentItem, Identifier declarationId,
+			List<Identifier> correctResponseIds, Cardinality cardinality) {
 		ResponseDeclaration responseDeclaration = new ResponseDeclaration(assessmentItem);
 		responseDeclaration.setIdentifier(declarationId);
-		if(correctResponseIds == null || correctResponseIds.size() == 0 || correctResponseIds.size() > 1) {
+		if(cardinality != null && (cardinality == Cardinality.SINGLE || cardinality == Cardinality.MULTIPLE)) {
+			responseDeclaration.setCardinality(cardinality);
+		} else if(correctResponseIds == null || correctResponseIds.size() == 0 || correctResponseIds.size() > 1) {
 			responseDeclaration.setCardinality(Cardinality.MULTIPLE);
 		} else {
 			responseDeclaration.setCardinality(Cardinality.SINGLE);
diff --git a/src/main/java/org/olat/ims/qti21/model/xml/interactions/HotspotAssessmentItemBuilder.java b/src/main/java/org/olat/ims/qti21/model/xml/interactions/HotspotAssessmentItemBuilder.java
index dda243ded4c..876836b1f80 100644
--- a/src/main/java/org/olat/ims/qti21/model/xml/interactions/HotspotAssessmentItemBuilder.java
+++ b/src/main/java/org/olat/ims/qti21/model/xml/interactions/HotspotAssessmentItemBuilder.java
@@ -73,6 +73,7 @@ import uk.ac.ed.ph.jqtiplus.serialization.QtiSerializer;
 import uk.ac.ed.ph.jqtiplus.types.ComplexReferenceIdentifier;
 import uk.ac.ed.ph.jqtiplus.types.Identifier;
 import uk.ac.ed.ph.jqtiplus.value.BaseType;
+import uk.ac.ed.ph.jqtiplus.value.Cardinality;
 import uk.ac.ed.ph.jqtiplus.value.IdentifierValue;
 import uk.ac.ed.ph.jqtiplus.value.SingleValue;
 
@@ -85,6 +86,7 @@ import uk.ac.ed.ph.jqtiplus.value.SingleValue;
 public class HotspotAssessmentItemBuilder extends AssessmentItemBuilder {
 	
 	private String question;
+	private Cardinality cardinality;
 	private Identifier responseIdentifier;
 	private List<Identifier> correctAnswers;
 	protected ScoreEvaluation scoreEvaluation;
@@ -151,9 +153,12 @@ public class HotspotAssessmentItemBuilder extends AssessmentItemBuilder {
 		if(hotspotInteraction != null) {
 			ResponseDeclaration responseDeclaration = assessmentItem
 					.getResponseDeclaration(hotspotInteraction.getResponseIdentifier());
-			if(responseDeclaration != null && responseDeclaration.getCorrectResponse() != null) {
-				CorrectResponse correctResponse = responseDeclaration.getCorrectResponse();
-				extractIdentifiersFromCorrectResponse(correctResponse, correctAnswers);
+			if(responseDeclaration != null) {
+				if(responseDeclaration.getCorrectResponse() != null) {
+					CorrectResponse correctResponse = responseDeclaration.getCorrectResponse();
+					extractIdentifiersFromCorrectResponse(correctResponse, correctAnswers);
+				}
+				cardinality = responseDeclaration.getCardinality();
 			}
 		}
 	}
@@ -182,6 +187,14 @@ public class HotspotAssessmentItemBuilder extends AssessmentItemBuilder {
 		scoreEvaluation = hasMapping ? ScoreEvaluation.perAnswer : ScoreEvaluation.allCorrectAnswers;
 	}
 	
+	public boolean isSingleChoice() {
+		return cardinality == Cardinality.SINGLE;
+	}
+	
+	public void setCardinality(Cardinality cardinality) {
+		this.cardinality = cardinality;
+	}
+	
 	public String getBackground() {
 		Object graphichObject = hotspotInteraction.getObject();
 		if(graphichObject != null) {
@@ -307,7 +320,7 @@ public class HotspotAssessmentItemBuilder extends AssessmentItemBuilder {
 	@Override
 	protected void buildResponseAndOutcomeDeclarations() {
 		ResponseDeclaration responseDeclaration = AssessmentItemFactory
-				.createHotspotCorrectResponseDeclaration(assessmentItem, responseIdentifier, correctAnswers);
+				.createHotspotCorrectResponseDeclaration(assessmentItem, responseIdentifier, correctAnswers, cardinality);
 		if(scoreEvaluation == ScoreEvaluation.perAnswer) {
 			AssessmentItemFactory.appendMapping(responseDeclaration, scoreMapping);
 		}
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java
index 05fdaed97ee..1d643309ecf 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java
@@ -55,6 +55,7 @@ import uk.ac.ed.ph.jqtiplus.node.item.interaction.GapMatchInteraction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.GraphicAssociateInteraction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.GraphicGapMatchInteraction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.GraphicOrderInteraction;
+import uk.ac.ed.ph.jqtiplus.node.item.interaction.HotspotInteraction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.InlineChoiceInteraction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.Interaction;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.MatchInteraction;
@@ -240,6 +241,13 @@ public class AssessmentObjectVelocityRenderDecorator extends VelocityRenderDecor
 				return false;
 			}
 			return sc;
+		} else if(interaction instanceof HotspotInteraction) {
+			HotspotInteraction hotspotInteraction = (HotspotInteraction)interaction;
+			ResponseDeclaration responseDeclaration = assessmentItem.getResponseDeclaration(hotspotInteraction.getResponseIdentifier());
+			if(responseDeclaration != null && responseDeclaration.hasCardinality(Cardinality.SINGLE)) {
+				return true;
+			}
+			return false;
 		}
 		return false;
 	}
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html b/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html
index f9b50d33366..2de67d60f4e 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html
+++ b/src/main/java/org/olat/ims/qti21/ui/components/_content/hotspotInteraction.html
@@ -1,6 +1,7 @@
 #set($responseIdentifier = $r.responseUniqueId($interaction))
 #set($qtiContainerId = "oc_" + $responseIdentifier)
 #set($responseValue = $r.getResponseValue($interaction.responseIdentifier))
+#set($singleChoice = $r.isSingleChoice($interaction))
 
 <input name="qtiworks_presented_${responseIdentifier}" type="hidden" value="1"/>
 <div class="$localName">
@@ -37,6 +38,7 @@
 			responseIdentifier: '$responseIdentifier',
 			formDispatchFieldId: '$r.formDispatchFieldId',
 			maxChoices: $interaction.maxChoices,
+			singleChoice: $singleChoice,
 			responseValue: '$r.toString($responseValue,",")',
 			opened: $isItemSessionOpen
 		});
diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties
index 1c94b4775c6..de9b3239486 100644
--- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties
@@ -12,6 +12,7 @@ editor.sc.title=Single choice
 editor.unkown.title=Unbekanntes interaction
 error.cannot.create.section=Sie k\u00F6nnen hier keine Sektion erstellen.
 error.cannot.delete=Sie d\u00FCrfen diese Ressource nicht l\u00F6schen.
+error.cardinality.answer=Single choice erlaubt nur eine korrekte Antwort.
 error.double=$org.olat.ims.qti21.ui\:error.double
 error.import.question=Die Frage konnte wegen eine unerwartete Fehler nicht importiert werden
 error.lock=Dieser Test/Fragebogen wird momentan vom Benutzer {0} editiert und ist deshalb gesperrt.
@@ -64,6 +65,7 @@ form.imd.answer=Antwort
 form.imd.answered.text=Feedback bei Antwort
 form.imd.answered.title=Titel
 form.imd.background=Hintergrund
+form.imd.cardinality=Typ
 form.imd.correct.kprim=Richtig
 form.imd.correct.spots=Korrekte Spots
 form.imd.correct.solution.title=Titel
@@ -137,6 +139,7 @@ item.session.control.show.solution=L\u00F6sung anzeigen
 item.session.control.show.solution.hint=Beim R\u00FCckblick werden auch L\u00F6sungen angezeigt.
 hour.short=h
 minute.short=m
+MULTIPLE=Multiple choice
 max.score=Maximal erreichbare Punktzahl
 min.score=Minimal erreichbare Punktzahl
 new.answer=Neue Antwort
@@ -162,6 +165,7 @@ new.testpart=Test-Part
 new.upload=Datei hochladen
 preview=Vorschau
 preview.solution=Vorschau L\u00F6sung
+SINGLE=Single choice
 time.limit.max=Zeitbeschr\u00E4nkung
 title.add=$org.olat.ims.qti.editor\:title.add
 tools.change.copy=$org.olat.ims.qti.editor\:tools.change.copy
diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties
index 2a7a2060639..7818af20a25 100644
--- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties
@@ -11,6 +11,7 @@ delete.testPart=Do you really want to delete the test part along with all its qu
 editor.sc.title=Single choice
 editor.unkown.title=Unkown interaction
 error.cannot.create.section=A section cannot be created everywhere\!
+error.cardinality.answer=Single choice allow only one correct answer.
 error.cannot.delete=You cannot delete this object.
 error.double=$org.olat.ims.qti21.ui\:error.double
 error.positive.double=Only positive number are allowed. Example\: 15.0, 5.5, 10
@@ -64,6 +65,7 @@ form.imd.answer=Answer
 form.imd.answered.text=Feedback by answer
 form.imd.answered.title=Title
 form.imd.background=Background
+form.imd.cardinality=Type
 form.imd.correct.kprim=True
 form.imd.correct.spots=Correct spots
 form.imd.correct.solution.title=Title
@@ -139,6 +141,7 @@ item.session.control.show.solution=Show solution
 item.session.control.show.solution.hint=Solution is shown in review as well.
 max.score=Max. score
 min.score=Min. score
+MULTIPLE=Multiple choice
 new.answer=New answer
 new.circle=Circle
 new.drawing=Drawing
@@ -164,6 +167,7 @@ preview=Preview
 preview.solution=Preview solution
 time.limit.max=Time limit
 title.add=$org.olat.ims.qti.editor\:title.add
+SINGLE=Single choice
 tools.change.copy=$org.olat.ims.qti.editor\:tools.change.copy
 tools.change.delete=$org.olat.ims.qti.editor\:tools.change.delete
 tools.export.docx=$org.olat.ims.qti.editor\:tools.export.docx
diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties
index 8b10c5c87c4..52c3b36f892 100644
--- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties
@@ -63,6 +63,7 @@ form.imd.answer=R\u00E9ponse
 form.imd.answered.text=Retour d'information par question
 form.imd.answered.title=Titre
 form.imd.background=Image de fond
+form.imd.cardinality=Type
 form.imd.correct.kprim=Vrai
 form.imd.correct.solution.text=Solution correcte
 form.imd.correct.solution.text.word=$\:form.imd.correct.solution.text (seulement pour export Word)
diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/HotspotEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/HotspotEditorController.java
index b62bb8a66b1..f3d9a0b2779 100644
--- a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/HotspotEditorController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/HotspotEditorController.java
@@ -41,6 +41,7 @@ import org.olat.core.gui.components.form.flexible.elements.FileElement;
 import org.olat.core.gui.components.form.flexible.elements.FormLink;
 import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
 import org.olat.core.gui.components.form.flexible.elements.RichTextElement;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
 import org.olat.core.gui.components.form.flexible.elements.TextElement;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
 import org.olat.core.gui.components.form.flexible.impl.FormEvent;
@@ -67,6 +68,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import uk.ac.ed.ph.jqtiplus.node.expression.operator.Shape;
 import uk.ac.ed.ph.jqtiplus.node.item.interaction.graphic.HotspotChoice;
 import uk.ac.ed.ph.jqtiplus.types.Identifier;
+import uk.ac.ed.ph.jqtiplus.value.Cardinality;
 
 /**
  * 
@@ -87,6 +89,7 @@ public class HotspotEditorController extends FormBasicController {
 	private TextElement titleEl;
 	private RichTextElement textEl;
 	private FileElement backgroundEl;
+	private SingleSelection cardinalityEl;
 	private FormLayoutContainer hotspotsCont;
 	private FormLink newCircleButton, newRectButton;
 	private MultipleSelectionElement correctHotspotsEl;
@@ -137,6 +140,15 @@ public class HotspotEditorController extends FormBasicController {
 				formLayout, ureq.getUserSession(), getWindowControl());
 		textEl.addActionListener(FormEvent.ONCLICK);
 		
+		String[] cardinalityKeys = new String[] { Cardinality.SINGLE.name(), Cardinality.MULTIPLE.name() };
+		String[] cardinalityValues = new String[] { translate(Cardinality.SINGLE.name()), translate(Cardinality.MULTIPLE.name()) };
+		cardinalityEl = uifactory.addRadiosHorizontal("form.imd.cardinality", formLayout, cardinalityKeys, cardinalityValues);
+		if(itemBuilder.isSingleChoice()) {
+			cardinalityEl.select(cardinalityKeys[0], true);
+		} else {
+			cardinalityEl.select(cardinalityKeys[1], true);
+		}
+		
 		initialBackgroundImage = getCurrentBackground();
 		backgroundEl = uifactory.addFileElement(getWindowControl(), "form.imd.background", "form.imd.background", formLayout);
 		backgroundEl.setEnabled(!restrictedEdit);
@@ -219,6 +231,12 @@ public class HotspotEditorController extends FormBasicController {
 			}
 		}
 		
+		cardinalityEl.clearError();
+		if(cardinalityEl.isSelected(0) && correctHotspotsEl.getSelectedKeys().size() > 1) {
+			cardinalityEl.setErrorKey("error.cardinality.answer", null);
+			allOk &= false;
+		}
+		
 		return allOk & super.validateFormLogic(ureq);
 	}
 
@@ -387,6 +405,11 @@ public class HotspotEditorController extends FormBasicController {
 			objectImg = initialBackgroundImage;
 		}
 		
+		if(cardinalityEl.isOneSelected()) {
+			String selectedCardinality = cardinalityEl.getSelectedKey();
+			itemBuilder.setCardinality(Cardinality.valueOf(selectedCardinality));
+		}
+		
 		if(objectImg != null) {
 			String filename = objectImg.getName();
 			String mimeType = WebappHelper.getMimeType(filename);
diff --git a/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js b/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js
index 2d35266e6ce..d7737fc0fb9 100644
--- a/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js
+++ b/src/main/webapp/static/js/jquery/qti/jquery.hotspot.js
@@ -1,117 +1,129 @@
 (function ($) {
-    $.fn.hotspotInteraction = function(options) {
-    	var settings = $.extend({
-    		responseIdentifier: null,
-    		formDispatchFieldId: null,
-    		maxChoices: 1,
-    		responseValue: null,
-    		opened: false
-        }, options );
-    	
-    	try {
-    		if(!(typeof settings.responseValue === "undefined") && settings.responseValue.length > 0) {
-    			drawHotspotAreas(this, settings);
-    		} 
-    		if(settings.opened) {
-    			hotspots(this, settings);
-    		}
-    	} catch(e) {
-    		if(window.console) console.log(e);
-    	}
-        return this;
-    };
-    
-    function drawHotspotAreas($obj, settings) {
-    	var containerId = $obj.attr('id');
-    	var divContainer = jQuery('#' + containerId);
-    	
-    	var areaIds = settings.responseValue.split(',');
-    	for(i=areaIds.length; i-->0; ) {
-    		var areaEl = jQuery('#ac_' + settings.responseIdentifier + '_' + areaIds[i]);
-    		var data = areaEl.data('maphilight') || {};
-    		data.selectedOn = true;
-    		colorData(data);
-    		areaEl.data('maphilight', data).trigger('alwaysOn.maphilight');
-    		
-    		var inputElement = jQuery('<input type="hidden"/>')
+	$.fn.hotspotInteraction = function(options) {
+		var settings = $.extend({
+			responseIdentifier: null,
+			formDispatchFieldId: null,
+			maxChoices: 1,
+			singleChoice: false,
+			responseValue: null,
+			opened: false
+		}, options );
+		
+		try {
+			if(!(typeof settings.responseValue === "undefined") && settings.responseValue.length > 0) {
+				drawHotspotAreas(this, settings);
+			} 
+			if(settings.opened) {
+				hotspots(this, settings);
+			}
+		} catch(e) {
+			if(window.console) console.log(e);
+		}
+		return this;
+	};
+	
+	function drawHotspotAreas($obj, settings) {
+		var containerId = $obj.attr('id');
+		var divContainer = jQuery('#' + containerId);
+		
+		var areaIds = settings.responseValue.split(',');
+		for(i=areaIds.length; i-->0; ) {
+			var areaEl = jQuery('#ac_' + settings.responseIdentifier + '_' + areaIds[i]);
+			var data = areaEl.data('maphilight') || {};
+			data.selectedOn = true;
+			colorData(data);
+			areaEl.data('maphilight', data).trigger('alwaysOn.maphilight');
+			
+			var inputElement = jQuery('<input type="hidden"/>')
 				.attr('name', 'qtiworks_response_' + settings.responseIdentifier)
 				.attr('value', areaEl.data('qti-id'));
-    		divContainer.append(inputElement);
-    	}
-    }
-    
-    function hotspots($obj, settings) {
-    	var containerId = $obj.attr('id');
-    	jQuery('#' + containerId + " map area").each(function(index, el) {
-    		jQuery(el).on('click', function() {
-    			clickHotspotArea(this, containerId, settings.responseIdentifier, settings.maxChoices);
-    		});
-    	})
-    };
+			divContainer.append(inputElement);
+		}
+	}
+	
+	function hotspots($obj, settings) {
+		var containerId = $obj.attr('id');
+		jQuery('#' + containerId + " map area").each(function(index, el) {
+			jQuery(el).on('click', function() {
+				clickHotspotArea(this, containerId, settings.responseIdentifier, settings.maxChoices, settings.singleChoice);
+			});
+		})
+	};
 
-    function clickHotspotArea(spot, containerId, responseIdentifier, maxChoices) {
-    	var areaEl = jQuery(spot);
-    	var data = areaEl.data('maphilight') || {};
-    	if((typeof data.selectedOn === "undefined") || !data.selectedOn) {
-    		var numOfChoices = maxChoices;
-    		if(numOfChoices > 0) {
-    			var countChoices = 0;
-    			jQuery("area", "map[name='" + containerId + "_map']").each(function(index, el) {
-    				var cData = jQuery(el).data('maphilight') || {};
-    				if(cData.selectedOn) {
-    					countChoices++;
-    				}
-    			});
-    			if(countChoices >= numOfChoices) {
-    				return false;
-    			}
-    		}
-    	}
-    	
-    	if(typeof data.selectedOn === "undefined") {
-    		data.selectedOn = true;
-    	} else {
-    		data.selectedOn = !data.selectedOn;
-    	}
-    	colorData(data);
-    	areaEl.data('maphilight', data).trigger('alwaysOn.maphilight');
+	function clickHotspotArea(spot, containerId, responseIdentifier, maxChoices, singleChoice) {
+		var areaEl = jQuery(spot);
+		var data = areaEl.data('maphilight') || {};
+		if((typeof data.selectedOn === "undefined") || !data.selectedOn) {
+			if(singleChoice) {
+				jQuery("area", "map[name='" + containerId + "_map']").each(function(index, el) {
+					var cData = jQuery(el).data('maphilight') || {};
+					if(cData.selectedOn) {
+						cData.selectedOn = false;
+						colorData(cData);
+						jQuery(el).data('maphilight', cData).trigger('alwaysOn.maphilight');
+					}
+				});
+			}
+			
+			var numOfChoices = maxChoices;
+			if(numOfChoices > 0) {
+				var countChoices = 0;
+				jQuery("area", "map[name='" + containerId + "_map']").each(function(index, el) {
+					var cData = jQuery(el).data('maphilight') || {};
+					if(cData.selectedOn) {
+						countChoices++;
+					}
+				});
+				if(countChoices >= numOfChoices) {
+					return false;
+				}
+			}
+		}
+		
+		if(typeof data.selectedOn === "undefined") {
+			data.selectedOn = true;
+		} else {
+			data.selectedOn = !data.selectedOn;
+		}
+		colorData(data);
+		areaEl.data('maphilight', data).trigger('alwaysOn.maphilight');
 
-    	var divContainer = jQuery('#' + containerId);
-    	divContainer.find("input[type='hidden']").remove();
-    	jQuery("area", "map[name='" + containerId + "_map']").each(function(index, el) {
-    		var cAreaEl = jQuery(el);
-    		var cData = cAreaEl.data('maphilight') || {};
-    		if(cData.selectedOn) {
-    			var inputElement = jQuery('<input type="hidden"/>')
-    				.attr('name', 'qtiworks_response_' + responseIdentifier)
-    				.attr('value', cAreaEl.data('qti-id'));
-    			divContainer.append(inputElement);
-    		}
-    	});
-    };
-    
-    /*
-     * Color the data based on the selectedOn flag
-     */
-    function colorData(data) {
-    	if(data.selectedOn) {
-        	data.fillColor = '0000ff';
-        	data.fillOpacity = 0.5;
-    		data.strokeColor = '0000ff';
-    		data.strokeOpacity = 1;
-    		data.shadow = true;
-    		data.shadowX = 0;
-    		data.shadowY = 0;
-    		data.shadowRadius = 7;
-    		data.shadowColor = '000000';
-    		data.shadowOpacity = 0.8;
-    		data.shadowPosition = 'outside';
-    	} else {
+		var divContainer = jQuery('#' + containerId);
+		divContainer.find("input[type='hidden']").remove();
+		jQuery("area", "map[name='" + containerId + "_map']").each(function(index, el) {
+			var cAreaEl = jQuery(el);
+			var cData = cAreaEl.data('maphilight') || {};
+			if(cData.selectedOn) {
+				var inputElement = jQuery('<input type="hidden"/>')
+					.attr('name', 'qtiworks_response_' + responseIdentifier)
+					.attr('value', cAreaEl.data('qti-id'));
+				divContainer.append(inputElement);
+			}
+		});
+	};
+	
+	/*
+	 * Color the data based on the selectedOn flag
+	 */
+	function colorData(data) {
+		if(data.selectedOn) {
+			data.fillColor = '0000ff';
+			data.fillOpacity = 0.5;
+			data.strokeColor = '0000ff';
+			data.strokeOpacity = 1;
+			data.shadow = true;
+			data.shadowX = 0;
+			data.shadowY = 0;
+			data.shadowRadius = 7;
+			data.shadowColor = '000000';
+			data.shadowOpacity = 0.8;
+			data.shadowPosition = 'outside';
+		} else {
 			data.fillColor = 'bbbbbb';
-        	data.fillOpacity = 0.5;
-    		data.strokeColor = '666666';
-    		data.strokeOpacity = 0.8;
-    		data.shadow = false;
-    	}
-    }
+			data.fillOpacity = 0.5;
+			data.strokeColor = '666666';
+			data.strokeOpacity = 0.8;
+			data.shadow = false;
+		}
+	}
 }( jQuery ));
-- 
GitLab