Ich brauche den JavaScript Code, den ich bei SoSci Survey nicht sehe, der für die richtige Umsetzung der Summe und der Antwortprüfung verantwortlich ist.
Auf Basis Ihrer Frage kann ich die Hintergründe dieses Anliegens zwar nicht nachvollziehen (und deshalb auch keine weiterführenden Empfehlungen geben) ... aber den Code kann ich gerne bereitstellen.
Innerhalb des Fragebogens sind es zwei Aufrufe:
S2QstText.textSumInstance.attach(outputID, summe, [inputIDs], dezimalstellen, fehlermeldung);
2QstText.textSumInstance.setDecimalSeparator(",");
Die Klasse S2QstText
, dich dann im Hintergrund um die Überprüfung und Anzeige der Summe kümmert, ist dann ein wenig umfangreicher.
function S2QstText(qstID) {
"use strict";
// Inherit
var node = document.getElementById(qstID + "_qst");
SoSciTools.QuestionWithItems.call(this, qstID, "text", node);
this.responseComplete = function() {
var items = this.items;
for (var key in items) {
if (items[key].input && (items[key].input.value.trim() === "")) {
return false;
}
}
return true;
};
}
/**
* @constructur
*/
S2QstText.TextSum = function() {
"use strict";
var collections = {};
var checks = [];
var decimalSeparator = ".";
/**
* Constructor
* @param {type} sumID
* @param {type} sum
* @param {type} inputIDs
* @param {type} decimals
* @param {type} msg
* @returns {oFbTextSum.Collection}
*/
function Collection(sumID, sum, inputIDs, decimals, msg) {
var collection = this;
var inputs = [];
var sumDisplay = document.getElementById(sumID);
if (sumDisplay) {
// The sum display need not look like an input
// Legacy
if (!sumDisplay.classList) {
sumDisplay.classList = SoSciTools.classList(sumDisplay);
}
sumDisplay.classList.add("s2iInputOut");
} else {
console.warn("There is no element for the S2QstText.TextSum with ID", sumID);
}
function getSum() {
var sum = 0;
for (var i = 0; i < inputs.length; i++) {
var valueS = inputs[i].value;
var value;
if (decimals > 0) {
valueS = valueS.replace(/,/, ".");
value = parseFloat(valueS);
} else {
value = parseInt(valueS);
}
if (!isNaN(value)) {
sum += value;
}
}
// Round to decimals
if (decimals > 0) {
var factor = Math.pow(10, decimals);
sum = Math.round(sum * factor) / factor;
} else {
sum = Math.round(sum);
}
return sum;
}
this.updateSum = function() {
if (!sumDisplay) {
return;
}
var sumV = getSum();
// Show decimals
var sumS;
if (decimals > 0) {
sumS = sumV.toFixed(decimals);
// Format
if (decimalSeparator !== ".") {
sumS = sumS.replace(".", decimalSeparator);
}
} else {
sumS = sumV.toString();
}
// Display new sum
sumDisplay.value = sumS;
// Does it fit?
if (sumV === 0) {
sumDisplay.classList.remove("s2iFine");
sumDisplay.classList.remove("s2iFail");
} else if (sumV == sum) {
sumDisplay.classList.add("s2iFine");
sumDisplay.classList.remove("s2iFail");
} else {
sumDisplay.classList.add("s2iFail");
sumDisplay.classList.remove("s2iFine");
}
};
for (var i = 0; i < inputIDs.length; i++) {
var input = document.getElementById(inputIDs[i]);
if (!input) {
console.warn("There is no input " + inputIDs[i]);
continue;
} else if (input.addEventListener) {
// Mozilla style
input.addEventListener("keyup", this.updateSum, false);
input.addEventListener("change", this.updateSum, false);
} else if (input.attachEvent) {
// IE style
input.attachEvent("onkeyup", this.updateSum);
}
inputs.push(input);
}
this.updateSum();
this.checkExpectation = function () {
return (sum == getSum());
};
this.getExpectation = function () {
return sum;
};
this.getErrorMessage = function() {
return msg;
};
}
function checkSums(evt) {
for (var i = 0; i < checks.length; i++) {
var collection = collections[checks[i]];
if (!collection.checkExpectation()) {
alert(collection.getErrorMessage());
return false;
}
}
return true;
}
/*
* Register a text collection for sum display
*/
this.attach = function (sumID, sum, inputIDs, decimals, msg) {
collections[sumID] = new Collection(sumID, sum, inputIDs, decimals, msg);
};
/*
* Tell the form to check the given sum before submit.
*/
this.check = function (sumID) {
checks.push(sumID);
var page = SoSciTools.getPage();
page.attachCheck(checkSums);
};
/**
* Set the character to separate a number's decimals.
* @param {String} s
* @returns {undefined}
*/
this.setDecimalSeparator = function (s) {
decimalSeparator = s;
// Refresh all collections
for (var id in collections) {
collections[id].updateSum();
}
};
};
// Global instance to be used
S2QstText.textSumInstance = new S2QstText.TextSum();
window["oFbTextSumInstance"] = S2QstText.textSumInstance;
S2QstText.Item = function(itemID, input) {
"use strict";
// Inherit
var gi = parseInt(itemID.substr(5).replace(/^0/, ""));
var inputs = [input];
var node = document.getElementById(itemID + "_input");
// May have a DK input
var dkInput = document.getElementById(itemID + "a");
if (dkInput) {
inputs.push(dkInput);
}
SoSciTools.QuestionItem.call(this, gi, inputs, node);
};
// Initialize
S2QstText.instances = {};
S2QstText.getInstance = function(qstID) {
if (!(qstID in S2QstText.instances)) {
S2QstText.instances[qstID] = new S2QstText(qstID);
}
return S2QstText.instances[qstID];
};
// Automatically load all cardrate questions on the page
S2QstText.init = function() {
var elements = document.getElementsByClassName("s2jsText");
for (var i=0; i<elements.length; i++) {
var input = elements[i];
var itemID = input.getAttribute("id");
var qstID = itemID.substr(0, 4);
var appendix = itemID.substr(4);
if (appendix === "_sum") {
continue;
}
var question = S2QstText.getInstance(qstID);
var item = new S2QstText.Item(itemID, input);
question.registerItem(item);
}
};
S2Autorun.onload(S2QstText.init);
Bitte beachten Sie, dass dieses Script auf einige Schnittstellen von SoSciTools zurückgreift, die sich durchaus auch mal ändern können. Zum Beispiel das S2Autorun
oder SoSciTools.QuestionWithItems
.