I'm currently working on a Qualtrics survey in which respondents have to solve a long list of anagrams, and then answer some demographic questions.
To make the anagram part easier, I've used a Loop and Merge block: the first field is the anagram to be solved, the second field is the solution of the anagram, and the survey can therefore check the answer of the respondent against the solution for each anagram.
As it is, the survey is working perfectly: however, I'd like to allow respondents to prematurely exit the loop by typing "EXIT" in the response field, and to redirect them to the next question block (the demographic questions).
This is typically something that is achieved using "Skip" logic: however, skipping to the end of the block does not do the trick (the loop restarts). I managed to redirect them to the end of the survey, but not to the demographic question block.
Is there a way to use javascript to jump to the demographic block or exit the loop and merge block prematurely? Am I missing a Qualtrics option that would do the trick?
If this is still relevant to you: I needed the same functionality and this is how I solved it: First, I define a helper variable, call it EndLoop, which I initialize to 0. Then I set up a function to change the value of EndLoop to 1 after people hit a button, additionally I add a display logic to the question in the loop showing them only if EndLoop is still 0 and hiding the questions as soon as EndLoop is 1.
This is a step-by-step instruction and the javascript and html code.
The bold stuff is what you need to do, the bulletpoints a more detailed instruction how to do it.
1. Before your loop-and-merge define an embedded data field called EndLoop and initialize it as 0.
Go to the Survey Flow Panel
Add a new element > select embedded data field
Name the field 'EndLoop'
Set its value t0 the number 0 by click on the link "set value now"
Make sure you move it before the merge-and-loop block
2. For each item in the loop set a display logic to show them conditional on 'EndLoop' = 0
Go to the options menu of each question in the loop
Select "add display logic"
Select "Embedded Data" from the first dropdown menu
A new type field opens > as name type EndLoop + select "is equal to" + type 0 as value
3. Insert a customized button into the page where people should be able to opt-out. The button runs a user-defined function called setEndLoop() onclick.
Click on the question where the button should appear
On the top-right of the question text select "html view"
The code I used is:
<input id="css-class-mybutton" onclick="setEndLoop()" value=" done " type="button">
If you want to change the button text, change the " done " in value = " done "
4. Define the function setEndLoop() using custom javascript to change the value of EndLoop to 1 and emulate a next button click
Go to the options menu of each question in the loop
Select "add JavaScript"
The code I used is:
/* Get the EndLoop variable */
var EndLoop = "${e://Field/EndLoop}";
Qualtrics.SurveyEngine.addOnload(function(){
/* hide previous and next button */
$('NextButton') && $('NextButton').hide();
$('PreviousButton') && $('PreviousButton').hide();
/* Function: on click on user-defined button -> change the field EndLoop */
var that = this;
setEndLoop = function(){
Qualtrics.SurveyEngine.setEmbeddedData('EndLoop', 1);
that.clickNextButton();
};
});
The button will not have the default style, thus, define a custom css to style your button to look like the buttons of your theme. The class name for the button I used here is id="css-class-mybutton", use .css-class-mybutton{ ... } in the css.
Hope that helps.
I know this is a bit late, but I had a similar issue and wanted to post an alternative solution. I used the loop and merge function, but I didn't want to have participants click on a button to exit the loop, instead I wanted to use a multiple choice question to exit the loop. This question was, "would you like to ask more questions?", with responses yes and no. If the participant selected "Yes" they would keep going through the loop and if they selected "No" they would exit the loop and go on to the next block of questions.
My first two steps are the same as those above.
1.Set up an Embedded data field named EndLoop and set the value to 1.
- in the survey flow panel select add an element. Then type in the name EndLoop.
- Then select set value now and set the value to 1.
- make sure that this is before your loop and merge block in the survey flow.
For each question in the loop and merge block use display logic to ensure that they only display when the embedded data element EndLoop is 1.
Now for the question "would you like to ask more questions?" add the following code in the add javascript area.
the javascript area can be found by clicking the advanced options button under the question number on the lefthand side of the screen. Select 'Add javascript...'
There will be some code already present...it should look like this:
Qualtrics.SurveyEngine.addOnload(function()
{
/Place Your Javascript Below This Line/
});
Basically I used event tracking to update the embedded data field EndLoop to the numerical value associated with the answer choice when the answer choice was selected. In this case the answer "Yes" had a value of 1 because it was the first option and "No" had a value of 2 because it was the second option. When "No" was selected, the embedded data field EndLoop was set to a value of 2. This then meant that none of the questions would display since they have display logic to ensure they only display when the EndLoop field is 1.
My entire code looks like this:
Qualtrics.SurveyEngine.addOnload(function ()
{
this.questionclick = function(event,element)
{
console.log(event, element);
if (element.type == 'radio')
{
var choiceNum = element.id;
if (choiceNum == 2)
{
Qualtrics.SurveyEngine.setEmbeddedData("EndLoop", choiceNum);
}
}
}
});
I used the second solution. Here's a minor correction for the script:
I wrote element.id.split('~')[2] instead of element.id, and it worked!
Qualtrics.SurveyEngine.addOnload(function ()
{
this.questionclick = function(event,element)
{
console.log(event,element);
if (element.type == 'radio')
{
var choiceNum = element.id.split('~')[2];
if (choiceNum == 2)
{
Qualtrics.SurveyEngine.setEmbeddedData("EndLoop", choiceNum);
}
}
}
});
Related
In my web app, when a user selects an item in a dropdown box, the next dropdown box is updated with conditional options. I have created a script to allow for templates of the fields, but the second dropdown box does not update to allow me to assign a value to it.
Example: www.mywebsite.com?template=newcust
In the header I have:
if (isset($_GET['template'])) {
$templ = $_GET['template'];
if ($templ == "newcust") {
$autoname = "New Customer";
$c1f = "city"; //"join_date"
$c1w = 1; //1=is equal to, 2=is not equal to, 3=is great than, 4=is less than
}
So in this example, 1 would load with "city", while 2 would need to display just the valid fields (is equal to, is not equal 2) and select "is equal to" by default. But if "join date" is put into $c1f, then all 4 options would need to be available.
When doing this manually it works fine, I'm trying to get this to auto-update the fields when the user selects to start off with a template.
I hope this gives enough background info. Let me know if I need to share anything else.
Thanks
I wanna to try to researching around on how to achieve this but I am not sure about how to make the solution for this.
Basically I have a form that contains some select list, radio buttons, and checkboxes. Each option on the form has a corresponding numeric value that will be accumulated and displayed to the user when the form gets submitted.
What I am not sure about is how to be able to add or deduct a value if the user chooses to change the a choice on the form.
For example, when a user is on the first dropdown element, and they choose option 2 which has a value of 5 then the current accummulated value us 5. Then on question 2, they choose option 1 which has a value of 2 which makes the accummulated value 7. Then the user changes the answer for question one from option 2 to option one which means 5 will be deducted from the accumulated value and 2 will be added since it is the value for option 1 which changes the accumulated value to 4.
I know the description I mentioned might be all over the place but I hope it makes sense.
I am trying to use jQuery and so far, my approach would be to check if any of the form element's value has changed:
(function($) {
var score = 0;
$(".the-form #step-5 :input").change(function() {
console.log($(this).val());
});
})(jQuery);
But I can't seem to figure out how to get the previous value of the option that was selected if the user changes their answer.
Any suggestion would be appreciated.
Can you recalculate across the whole form each time the user changes any of the elements?
$(".the-form :input").change(calculateChanges);
function calculateChanges() {
// Retrieve the current values of all elements and add them together
}
When a user submits, then start doing the calculations or when a select is changed, i.e. attach it to the event. Score is now a local variable
function calcValue() {
var score = 0;
//select all the elements using example below
$(".the-form :input").each(function( index ) {
//i forgot jQuery exact syntax but $(this).val or //$(this).val()
score += $( this ).val();
});
console.log(score);
}
In this case you can attach it to the submit
function submit() {
var score = calcValue();
}
Or you can put it in a change event of a select
function selectChanged() {
var score = calcValue();
}
Given I have a model Post which can have up to n Comments (the number is controlled by the Backend) and I have a view which allows to add a Comment via a AJAX request. What is the best way to tell the view upon the nth request to disable the Add-Comment-Form?
The nth request is successfull so status code should still be 200/201 but the backend already "knows" that the nth + 1 call will invalidate the Post, so i want to somehow tell this to the view so it can take action before the user experiences the (catched) error upon nth + 1 submit.
By now the backend renders html which is then simply attached to a div in the DOM, with JSON I might add an additional field but then would move the templating to the view again.
If someone has an idea for an elegant solution?
Try having your server render javascript value for comment count and max comments. Then you can increment the count value in your success function as well as perhaps render the html comment.
Something like
var commentCount = *value from server*;
var maxComments =*value from server*;
$('#mybutton').click(function(){
$.ajax({
// your code here
})
. success(function (response) {
// process response
commentCount ++;
if( commentCount >= maxComments)
$('#mybutton). prop('disabled', true);
});
Just hide the "Add comment" button by JavaScript, when it will be "nth + 1". Or remove eventListener from button and change caption to smth like "You reached max comments".
Keep a track of the number of clicks. After the n th click, you can change the disabled attribute of your button to true.
$(".myButton").attr("disabled",true);
I wrote an autocomplete type thingy that goes through divs and adds them to a list if their name/id is found. I am using an event handler that I found online that is called on any sort of input change. The issue that I am having is: When a valid div is found and added to the autocomplete list, and then the user continues to type, but is typing an invalid div name, the div name is removed from the list; HOWEVER, if no divs are found, the list persists but is blank.
A better way to explain is to try it out.
http://jsfiddle.net/ypz0zrzv/21/
Type "Test Unit" in the box, and then continue to type random letters. I am trying to get the now empty list to remove. The issue is that, when I implement such a feature, it is only going to happen after a second character is entered. This is because the handler checks the list on input change.
So if I type "Test Unit" it adds the div. If I type "Test Unita" it shows a blank autocomplete div. If I type "test Unitaa" now the autocomplete div will be gone. I am puzzled how to get the autocomplete to be blank immediately after it has found no divs.
Code problem in question
if ($('#autocomplete_list li').length === 0){
hide_remove($('#autocomplete'))
}
Your check for the auto complete was in the wrong location. It was being triggered by the wrong event.
I moved the check into its own function, in case you want to call this check at a later time:
function checkArray(){
console.log($('#autocomplete_list li').length);
if ($('#autocomplete_list li').length <= 0){
hide_remove($('#autocomplete'))
}
}
Then I added that checkArray() function into the hide_remove() function.
function hide_remove($div){
if ($div.length > 0){
$div.slideUp(250, function(){
$div.remove();
checkArray();
});
}
}
Here is a DEMO. Hope this helps!
I have a select element in a form with id of "qlt".
And if I change the value of that selection, other SELECT(#names) element changes its option(s).
However, it seems the change function takes effect at the moment I tick the dropdown, not after the value has changed.
So my jquery code condition below has an opposite effect. If the value of qlt is 14-1, then the selection will have "Hello (90x55mm)" as its option insted of Business Card (90x55mm.
var qlt = (jQuery("#qlt").val()).split(":")[0];
jQuery('#qlt').change(function(){
if(qlt=="14-1"){
ChangeOptions(["Business Card (90x55mm)"],"#names",[1]);
}
else if(qlt=="14-2"){
ChangeOptions(["Hello (90x55mm)"],"#names",[2]);
}
});
jQuery('#names').change(function(){
quantities=[50,100,250,500,1000,2000,5000];
ChangeOptions(quantities,"#qlnt",quantities);
});
If my question is not clear, you can visit the actual site here:
http://210.48.94.218/~printabl/products/labels-stickers/
The two select elements I am referring to are the Quality and Size dropdowns. The form is in the middle.
The actual problem looks like the order of callback execution
The qlt variable is set using the method calculate which is registered using jQuery("select").change(calculate); at line 701.
But the change options callback is registered at line 528 which will get executed before the calculate method is called that is why the value of qlt is not updated until next select.
One solution is to move jQuery("select").change(calculate); before line 528 another one is below
It might be a problem of some script execution, I assume qlt is supposed to be the current selected value in the #qlt input then you can declare a local variable and assign the current value using $(this).val()
jQuery('#qlt').change(function(){
var qlt = $(this).val().split(":")[0];
if(qlt=="14-1"){
ChangeOptions(["Business Card (90x55mm)"],"#names",[1]);
}
else if(qlt=="14-2"){
ChangeOptions(["Hello (90x55mm)"],"#names",[2]);
}
});