diff --git a/.gitignore b/.gitignore
index a69372a..511ab9e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
Scratch/*
*/wip*
-.history/*
\ No newline at end of file
+.history/*
+wip/
\ No newline at end of file
diff --git a/functions/Fast Select Button.js b/JavaScript Files/Fast Select Button.js
similarity index 100%
rename from functions/Fast Select Button.js
rename to JavaScript Files/Fast Select Button.js
diff --git a/functions/Fast Select KB.js b/JavaScript Files/Fast Select KB.js
similarity index 100%
rename from functions/Fast Select KB.js
rename to JavaScript Files/Fast Select KB.js
diff --git a/functions/List of answered and unanswered questions.js b/JavaScript Files/List of answered and unanswered questions.js
similarity index 100%
rename from functions/List of answered and unanswered questions.js
rename to JavaScript Files/List of answered and unanswered questions.js
diff --git a/JavaScript Files/Other box validation.js b/JavaScript Files/Other box validation.js
new file mode 100644
index 0000000..4dfac0b
--- /dev/null
+++ b/JavaScript Files/Other box validation.js
@@ -0,0 +1,43 @@
+//Other Box Validation -->
+Qualtrics.SurveyEngine.addOnReady(function () {
+ function check_box_and_text() {
+ setTimeout(() => {
+ ip_choices.forEach((box) => {
+ let sel = box.querySelector(".q-checked"),
+ val = box.querySelector(".InputText").value.trim();
+ if (sel !== null && val !== "") {
+ box.querySelector(".InputText").placeholder = "Please enter a value";
+ nb.disabled = false;
+ } else if (sel !== null && val === "") {
+ box.querySelector(".InputText").placeholder = "Please enter a value";
+ nb.disabled = true;
+ } else if (sel === null && val !== "") {
+ box.querySelector(".InputText").placeholder = "";
+ nb.disabled = true;
+ box.querySelector(".InputText").value = "";
+ } else if (sel === null && val === "") {
+ box.querySelector(".InputText").placeholder = "";
+ nb.disabled = false;
+ }
+ });
+ }, 200);
+ }
+ let ip_box = document.querySelectorAll(".InputText"),
+ ip_choices = [],
+ nb = document.querySelector("#NextButton");
+
+ if (ip_box.length > 0) {
+ ip_box.forEach((box) => {
+ let is_valid = box.parentElement.parentElement.querySelector(".q-checkbox, .q-radio");
+ if (is_valid) ip_choices.push(is_valid.parentElement);
+ });
+
+ let all_options = document.querySelectorAll(".q-checkbox, .q-radio");
+
+ all_options.forEach((opt) => {
+ opt.parentElement.onclick = check_box_and_text;
+ });
+
+ ip_box.forEach((box) => (box.oninput = check_box_and_text));
+ }
+});
diff --git a/functions/Randomize by blocks.js b/JavaScript Files/Randomize by blocks.js
similarity index 100%
rename from functions/Randomize by blocks.js
rename to JavaScript Files/Randomize by blocks.js
diff --git a/functions/Timing Calculation.js b/JavaScript Files/Timing Calculation.js
similarity index 100%
rename from functions/Timing Calculation.js
rename to JavaScript Files/Timing Calculation.js
diff --git a/functions/Allow only integers.md b/functions/Allow only integers.md
new file mode 100644
index 0000000..3cddfff
--- /dev/null
+++ b/functions/Allow only integers.md
@@ -0,0 +1,31 @@
+# Allow only integers
+
+Qualtrics' validation have a problem that the checks are only triggered when the repsondent clicks the next button. This function allows you enforce entering **only integers** while the respondent enters the answers, allows for faster feedback and a much better user experience.
+
+
+```js
+Qualtrics.SurveyEngine.addOnReady(function () {
+ //Get the Question Id
+ const qid = this.questionId;
+ // Get the number of choices
+ const n_choices = Qualtrics.SurveyEngine.registry[qid].getChoices();
+
+ const base_msg = jQuery("#" + qid + " .QuestionText").html();
+ const padding_pre = ' ';
+ const padding_post = "";
+ let err_msg = base_msg + padding_pre + "Please enter only valid integer numbers." + padding_post;
+
+ // Detect a change in any of the choices
+ n_choices.forEach((item) => {
+ document.querySelector("#QR\\~" + qid + "\\~" + item).oninput = function () {
+ if (document.querySelector("#QR\\~" + qid + "\\~" + item).value.search(/\D/) != -1) {
+ jQuery("#" + qid + " .QuestionText").html(err_msg);
+ } else {
+ jQuery("#" + qid + " .QuestionText").html(base_msg);
+ }
+ };
+ });
+});
+
+```
+
diff --git a/functions/Change Question Text.md b/functions/Change Question Text.md
new file mode 100644
index 0000000..c1077b9
--- /dev/null
+++ b/functions/Change Question Text.md
@@ -0,0 +1,27 @@
+# Change Question Text Based on Respondent Input
+
+This script allows you to change the Question Text based on the choice made.
+
+There were three choices in the question, and I wanted to change the text of the question, based on what they clicked.
+
+```js
+Qualtrics.SurveyEngine.addOnload(function () {
+ this.questionclick = function (event, element) {
+ //for a single answer multiple choice question, the element type will be radio
+ if (element.type == "radio") {
+ var choiceNum = element.id.split("~")[2];
+ if (choiceNum == 1) {
+ jQuery("#" + this.questionId + " .QuestionText").html(
+ "Please continue and click next when you are done."
+ ); // Changes the question text
+ } else if (choiceNum == 2) {
+ jQuery("#" + this.questionId + " .QuestionText").html(
+ "Please click next to exit or select the other choice if you would like to"
+ );
+ } else if (choiceNum == 3) {
+ jQuery("#" + this.questionId + " .QuestionText").html("Looking for alternate methods....");
+ }
+ }
+ };
+});
+```
diff --git a/functions/Character Limit Reminder.md b/functions/Character Limit Reminder.md
new file mode 100644
index 0000000..bdcb327
--- /dev/null
+++ b/functions/Character Limit Reminder.md
@@ -0,0 +1,40 @@
+# Character-Limit-Reminder
+
+The following code allows you add a character limit reminder to your text boxes.
+
+```js
+Qualtrics.SurveyEngine.addOnload(function () {
+ //Create a placeholder to display the reminder message
+ let char_rem = document.createElement("p");
+ char_rem.setAttribute("id", "char_reminder");
+ char_rem.setAttribute("style", "color:LightGray;");
+ this.getChoiceContainer().parentNode.appendChild(char_rem);
+});
+
+Qualtrics.SurveyEngine.addOnReady(function () {
+ const qid = this.questionId;
+
+ // Get the text box and check the characters on each input
+ document.querySelector("#QR~" + qid).oninput = function () {
+ limited();
+ };
+
+ function limited() {
+ let curr_len = document.querySelector("#QR~" + qid).value.length;
+
+ //Set the max_len as an embedded data field equal to maximum length in validation options
+ let max_len = "${e://Field/max_len}";
+
+ //Nothing will be displayed if the characters are less than 10
+ //If you want to always have the reminder, then delete the statement below and remove the if condition
+ let reminder = "";
+
+ if (curr_len > 10) {
+ rem_len = max_len - curr_len;
+ reminder = rem_len + "/20 characters remaining";
+ }
+
+ document.querySelector("#char_reminder").innerText = reminder;
+ }
+});
+```
diff --git a/functions/Check Sum on Page.md b/functions/Check Sum on Page.md
new file mode 100644
index 0000000..d5e4bb0
--- /dev/null
+++ b/functions/Check Sum on Page.md
@@ -0,0 +1,68 @@
+# Check sum on the page
+
+A variation of the constant sum question that allows you to check the sum on the page itself and hence not wait for the user to click the next button for validation.
+
+```js
+Qualtrics.SurveyEngine.addOnload(function () {
+ //Disable the next button
+ // You can delete this if you are fine with the sum as being zero
+ this.disableNextButton();
+});
+
+Qualtrics.SurveyEngine.addOnReady(function () {
+ //Get the Question Id
+ const qid = this.questionId;
+ // Get the number of choices
+ let n_choices = Qualtrics.SurveyEngine.registry[qid].getChoices();
+
+ const base_msg = jQuery("#" + qid + " .QuestionText").html();
+
+ // Detect a change in any of the choices
+ n_choices.forEach((item) => {
+ // console.log("input detected");
+ document.querySelector("#QR\\~" + qid + "\\~" + item).oninput = function () {
+ chk_sum();
+ };
+ });
+
+ let that = this;
+ function chk_sum() {
+ let max_sum = parseInt("${e://Field/max_sum}");
+ let current_sum = 0;
+
+ let padding_pre = ' ';
+ let padding_post = "";
+ let err_msg = "The total should be more than zero and less than " + max_sum + " to proceed";
+
+ //Iterate over each of choices
+ n_choices.forEach((item) => {
+ curr_val = parseInt(document.querySelector("#QR\\~" + qid + "\\~" + item).value);
+ // Check for empty blocks
+ if (isNaN(curr_val)) {
+ if (document.querySelector("#QR\\~" + qid + "\\~" + item).value == "") {
+ curr_val = 0;
+ } else {
+ err_msg = "Please enter only valid integer numbers.";
+ }
+ }
+ //Check for invalid characters
+ if (document.querySelector("#QR\\~" + qid + "\\~" + item).value.search(/\D/) != -1) {
+ err_msg = "Please enter only valid integer numbers.";
+ curr_val = max_sum + 1;
+ }
+ current_sum += curr_val;
+ });
+ err_msg = base_msg + padding_pre + err_msg + padding_post;
+
+ //Checks for zero and the value being more than zero and less than the max_sum
+ // If you are fine with zero then delete "current_sum >0 &&"
+ if (current_sum > 0 && current_sum <= max_sum) {
+ that.enableNextButton();
+ jQuery("#" + qid + " .QuestionText").html(base_msg);
+ } else {
+ that.disableNextButton();
+ jQuery("#" + qid + " .QuestionText").html(err_msg);
+ }
+ }
+});
+```
diff --git a/functions/Clear Text Entry Box.md b/functions/Clear Text Entry Box.md
new file mode 100644
index 0000000..83fbfcc
--- /dev/null
+++ b/functions/Clear Text Entry Box.md
@@ -0,0 +1,20 @@
+# Clear Text Entry Box
+
+This function allows you clear the text entry box if it is empty. This is to overcome a quirk of Qualtrics, where if you have a text entry box in a matrix/MC question and the option is unselected, proceeding to the next page throws an error.
+
+```js
+Qualtrics.SurveyEngine.addOnReady(function () {
+ const qid = this.questionId;
+ let n_choices = Qualtrics.SurveyEngine.registry[qid].getChoices().length;
+ // Set this according to where you are placing your text entry box
+ //This refers to the last choice, -1 to the second last choice etc.
+ let text_choice = n_choices;
+
+ this.questionclick = function (event, element) {
+ let selected_choice = element.id.split("~")[2];
+ if (selected_choice != text_choice) {
+ document.querySelector("#QR~" + qid + "~" + text_choice + "~TEXT").value = "";
+ }
+ };
+});
+```
diff --git a/functions/Complex Display Logic.md b/functions/Complex Display Logic.md
new file mode 100644
index 0000000..3dbf813
--- /dev/null
+++ b/functions/Complex Display Logic.md
@@ -0,0 +1,40 @@
+# Complex Diplay Logic
+
+Qualtrics' inbuilt display logic, while powerfull is quite tedious to work with for complicated logic. The following function demonstrates an implementation of a complicated display logic.
+
+```js
+Qualtrics.SurveyEngine.addOnload(function () {
+ // Hide the question as soon as the page loads
+ this.getQuestionContainer().hide();
+
+ //Variable to decide whether to show the question or not. Initially false
+ let show_answer = false;
+
+ //Create an embedded variable with all the valid choices using a seperator
+ // In this a comma "," is used
+ let valid_choices = "${e://Field/valid_choices}";
+ valid_choices = valid_choices.split(",");
+
+ //Get your entered choice. This is showning an embedded variable
+ // Which you can set based on your question type.
+ const entered_choice = "${e://Field/entered_choice}";
+
+ // Check if the entered choice is equal to any of the valid choices
+ valid_choices.forEach((item) => {
+ if (item.trim() == entered_choice) {
+ show_answer = true;
+ }
+ });
+
+ //Show the question, if the condition is met
+ if (show_answer == true) {
+ this.getQuestionContainer().show();
+ }
+
+ //Optionally you can add a condition to click the next button
+ // If you only have that one question on the page
+ if (show_answer == false) {
+ this.clickNextButton();
+ }
+});
+```
diff --git a/functions/Custom Request Response.md b/functions/Custom Request Response.md
new file mode 100644
index 0000000..ca92148
--- /dev/null
+++ b/functions/Custom Request Response.md
@@ -0,0 +1,31 @@
+# Custom Request Response Message
+
+This function doesn't change the request response message, but instead throws a custom message. The use of this with request/force response in not recommended.
+
+```js
+Qualtrics.SurveyEngine.addOnReady(function () {
+ const qid = this.questionId;
+ tot_choices = Qualtrics.SurveyEngine.registry[qid].getChoices().length;
+ var sel_choices = 0;
+
+ that = this;
+ this.questionclick = function () {
+ sel_choices = that.getSelectedChoices().length;
+ };
+
+ document.querySelector("#NextButton").onmousedown = function () {
+ check_answers();
+ };
+
+ function check_answers() {
+ if (sel_choices == tot_choices) {
+ that.clickNextButton();
+ } else {
+ //Selecting Okay will result in continuing
+ if (confirm("Custom message here") == true) {
+ that.clickNextButton();
+ }
+ }
+ }
+});
+```
diff --git a/functions/Dynamic Sum on Page.js b/functions/Custom Sum on Page.md
similarity index 73%
rename from functions/Dynamic Sum on Page.js
rename to functions/Custom Sum on Page.md
index 7c7f318..97d7aa1 100644
--- a/functions/Dynamic Sum on Page.js
+++ b/functions/Custom Sum on Page.md
@@ -1,3 +1,10 @@
+# Custom sum on Page
+
+This function demonstrates calculating a weighted or any customized sum on the page. The weights are assigned at the top for each of the three questions and based on the selection of the respondents the final value is calculated.
+
+This was developed for someone who wanted to calculate the total calories based on the toppings selected in the desert.
+
+```js
Qualtrics.SurveyEngine.addOnReady(function () {
var q_weights = {
1: [100, 150, 125, 0],
@@ -38,3 +45,4 @@ Qualtrics.SurveyEngine.addOnReady(function () {
option_watcher.disconnect();
};
});
+```
diff --git a/functions/Deselect Choices.md b/functions/Deselect Choices.md
new file mode 100644
index 0000000..ad529dd
--- /dev/null
+++ b/functions/Deselect Choices.md
@@ -0,0 +1,60 @@
+# Deselect Choices
+
+This function allows participants to deselect their choices on the single answer (radio) type questions
+
+Courtesy mattyb513 Ref: [https://www.qualtrics.com/community/discussion/1387/deselecting-a-radio-button](https://www.qualtrics.com/community/discussion/1387/deselecting-a-radio-button)
+
+Working Demo: [https://iima.au1.qualtrics.com/jfe/form/SV_3mJczLmUFE9c7L7](https://iima.au1.qualtrics.com/jfe/form/SV_3mJczLmUFE9c7L7)
+
+You'll need to first create a Deselect Button.
+
+## Deselect Button HTML
+
+```html
+
+
+```
+
+## For single answer type questions.
+
+```js
+Qualtrics.SurveyEngine.addOnReady(function () {
+ //Get the Question Id
+ let qid = this.questionId;
+
+ // Get the choices. This is needed as sometimes Qualtrics just goes crazy with choice numbers
+ let all_choices = Qualtrics.SurveyEngine.registry[qid].getChoices();
+
+ jQuery("#Deselect").click(function () {
+ all_choices.forEach((choice) => {
+ Qualtrics.SurveyEngine.registry[qid].setChoiceValue(choice, false);
+ });
+ });
+});
+```
+
+## For Matrices
+
+```js
+// Add the button above as one of the statements
+
+Qualtrics.SurveyEngine.addOnReady(function () {
+ let qid = this.questionId;
+ let scale_points = Object.keys(Qualtrics.SurveyEngine.QuestionInfo[qid].Answers).length;
+
+ // Get the location of the Deselect Button
+ choices = Qualtrics.SurveyEngine.QuestionInfo[qid].Choices;
+ deselect_position = [];
+ Object.keys(choices).forEach((item) => {
+ if (choices[item].Text.includes("Deselect")) deselect_position.push(item);
+ });
+ deselect_position = parseInt(deselect_position);
+
+ // Clear the choices
+ jQuery("#Deselect").click(function () {
+ for (i = 1; i <= scale_points; i++) {
+ Qualtrics.SurveyEngine.registry[qid].setChoiceValue(deselect_position, i, false);
+ }
+ });
+});
+```
diff --git a/functions/giving-three-attemps.md b/functions/Limit Attempts.md
similarity index 55%
rename from functions/giving-three-attemps.md
rename to functions/Limit Attempts.md
index 553e622..fb0a08e 100644
--- a/functions/giving-three-attemps.md
+++ b/functions/Limit Attempts.md
@@ -1,22 +1,21 @@
# Maximum Number of Attempts
-This function allows you to specify a limit to the number of attempts a respondent has for getting the answer correct, before moving forward. This is especially useful for tests.
+This function allows you to specify a limit to the number of attempts a respondent has for getting the answer correct, before moving forward. This is especially useful for tests.
-The variable ```desired_answer``` corresponds to the correct answer and ```max_attempts``` corresponds to maximum number of attempts allowed. These can be changed in the code as required.
+The variable `desired_answer` corresponds to the correct answer and `max_attempts` corresponds to maximum number of attempts allowed. These can be changed in the code as required.
-If you do not want to show the number of attempts set the ```show_attempt``` variable to ```0``` (*zero*).
+If you do not want to show the number of attempts set the `show_attempt` variable to `0` (_zero_).
-
- [_Link to Working Demo_](https://iima.au1.qualtrics.com/jfe/preview/SV_bd8Lv6cH7a3pJVb/BL_1Nug9eocGALKm8J?Q_SurveyVersionID=current)
-Hold down Ctrl or ⌘ Cmd to open the link in a new tab
-
- _Screenshot_:
+[_Link to Working Demo_](https://iima.au1.qualtrics.com/jfe/preview/SV_bd8Lv6cH7a3pJVb/BL_1Nug9eocGALKm8J?Q_SurveyVersionID=current)
+Hold down Ctrl or ⌘ Cmd to open the link in a new tab
+
+_Screenshot_:

_Question Javascript:_
-```
+```js
Qualtrics.SurveyEngine.addOnReady(function () {
desired_answer = 25;
max_attempts = 3;
@@ -35,44 +34,46 @@ Qualtrics.SurveyEngine.addOnReady(function () {
btn.onclick = check_answer;
if (show_attempt) {
- this.getQuestionContainer().insertAdjacentHTML("beforeend", '');
+ this.getQuestionContainer().insertAdjacentHTML(
+ "beforeend",
+ ''
+ );
atmpt = this.getQuestionContainer().querySelector("#atmpt");
}
that = this;
function check_answer() {
given_answer = 0;
- for(i=0;i item.disable());
+ el.forEach((item) => item.disable());
} else wrong_times += 1;
if (wrong_times == max_attempts) {
that.clickNextButton();
btn.disable();
- el.forEach(item => item.disable());
+ el.forEach((item) => item.disable());
}
if (show_attempt) update_attempt();
}
function update_attempt() {
- atmpt.innerHTML =
- "Attempts used: " + wrong_times + " out of " + max_attempts;
+ atmpt.innerHTML = "Attempts used: " + wrong_times + " out of " + max_attempts;
if (given_answer == desired_answer) {
- atmpt.innerHTML =
- "Correct Answer. Moving to Next Question";
+ atmpt.innerHTML = "Correct Answer. Moving to Next Question";
}
if (wrong_times == max_attempts) {
@@ -81,4 +82,4 @@ Qualtrics.SurveyEngine.addOnReady(function () {
}
}
});
-```
\ No newline at end of file
+```
diff --git a/functions/Limit Choices.md b/functions/Limit Choices.md
new file mode 100644
index 0000000..2187892
--- /dev/null
+++ b/functions/Limit Choices.md
@@ -0,0 +1,51 @@
+# Limit Choices
+
+These functions allow you to limit the number of choices a respondent can select, either at the question or page level.
+
+## Limit Choices: Question Level
+
+ Link to Working Demo
+
+```js
+Qualtrics.SurveyEngine.addOnReady(function () {
+ const quest = this,
+ qid = quest.questionId;
+ let okay_choices1 = [];
+
+ this.questionclick = function () {
+ let sel_choices = quest.getSelectedChoices();
+ // Set the maximum number of choices you want here
+ if (sel_choices.length <= 3) {
+ okay_choices1 = sel_choices;
+ } else {
+ alert("You can not select more than 3 choices.\nPlease deselect to select another.");
+ sel_choices.forEach((item) => {
+ Qualtrics.SurveyEngine.registry[qid].setChoiceValue(item, false);
+ });
+ okay_choices1.forEach((item) => {
+ Qualtrics.SurveyEngine.registry[qid].setChoiceValue(item, true);
+ });
+ }
+ };
+});
+```
+
+## Limit Choices: Page Level
+
+ Link to Working Demo
+
+```js
+Qualtrics.SurveyEngine.addOnReady(function () {
+ let all_checkboxes = document.querySelectorAll(".q-checkbox");
+ all_checkboxes.forEach((cb) => (cb.parentElement.onmousedown = selected_choices));
+
+ function selected_choices() {
+ let num_chosen = document.querySelectorAll(".q-checkbox.q-checked").length;
+
+ if (num_chosen >= 4 && !this.querySelector(".q-checked")) {
+ this.click();
+ alert("You can not select more than 4 choices. Please unselect one to select another");
+ }
+ }
+});
+```
diff --git a/functions/add-social-media-link.md b/functions/Social Media Links.md
similarity index 61%
rename from functions/add-social-media-link.md
rename to functions/Social Media Links.md
index 1ca0c71..ecafc3c 100644
--- a/functions/add-social-media-link.md
+++ b/functions/Social Media Links.md
@@ -24,46 +24,48 @@ Create a Descriptive Text Question with just some guiding text like:
_Question Javascript:_
-```text
+```js
Qualtrics.SurveyEngine.addOnReady(function () {
- qid = "#" + this.questionId;
- survey_link = encodeURI("${e://Field/Q_URL}");
+ let qid = "#" + this.questionId;
+ let survey_link = encodeURI("${e://Field/Q_URL}");
- wa_link = "https://api.whatsapp.com/send?text=survey_link";
- rd_link = "https://www.reddit.com/submit?title=Awesome&newwindow=1&selftext=true&text=My awesome survey %0A Survey Link: survey_link";
+ let wa_link = "https://api.whatsapp.com/send?text=survey_link";
+ let rd_link = "https://www.reddit.com/submit?title=Awesome&newwindow=1&selftext=true&text=My awesome survey %0A Survey Link: survey_link";
wa_link = wa_link.replace("survey_link",survey_link);
rd_link = rd_link.replace("survey_link",survey_link);
- rd_image = "https://raw.githubusercontent.com/tafakkur/use-files/main/reddit.png";
- wa_image = "https://raw.githubusercontent.com/tafakkur/use-files/main/whatsapp.png";
+ let rd_image = "https://raw.githubusercontent.com/tafakkur/use-files/main/reddit.png";
+ let wa_image = "https://raw.githubusercontent.com/tafakkur/use-files/main/whatsapp.png";
- wa = "
";
- rd = "
";
+ let wa = "
";
+ let rd = "
";
document.querySelector(qid).insertAdjacentHTML('beforeend',wa);
document.querySelector(qid).insertAdjacentHTML('beforeend',rd);
});
```
+
+
**For End of Survey:**
-```text
+```html