What JavaScript function will auto-submit a Qualtrics survey? - javascript

What JavaScript function will auto-submit a Qualtrics survey? I want to create a button in the header or footer of a Qualtrics survey that will automatically submit the survey whenever the user wants to quit. It seems like a pretty standard feature for survey software to have. The question may not seem well researched but that's because there are NO Qualtrics resources out there on this.
I found parts of the Qualtrics JS that might be relevant:
function pressSubmitButtonOnEnter(evt, id) {
if (evt.keyCode == Event.KEY_RETURN) {
Event.stop(evt);
$(id).click();
return false;
}
}
This one as well:
function submitForm(formID) {
var form = $(formID);
if (form) {
Event.fire(form, 'submit');
if (form.onsubmit)
form.onsubmit();
if (form.submit)
form.submit();
return true;
}
}
function submitFormJumpTo(formID, jumpTo) {
$(formID).action = jumpTo;
submitForm(formID);
}
This:
var SEonSubmit = {
add : function (onSubmitFunction) {
Event.observe('Page', 'submit', onSubmitFunction);
}
};
var SEonClick = {
add : function (onClickFunction) {
Event.observe('Page', 'click', onClickFunction);
}
};

According to Qualtrics, there is no way to do this. I submitted a request feature.

This question is still relevant almost seven years later. I just spent a crazy amount of time trying to get this to work, it is exceptionally poorly documented.
The page with the intercept will have the QSI.API object.
QSI.API.load()
QSI.API.run()
Site Intercept JavaScript API
https://s.qualtrics.com/WRAPI/SiteIntercept/JavaScript/classes/API.html

Related

Clicking 'cancel' in confirm() method has the same result as clicking 'ok'

I am a beginner implementing a confirm method in my HTML code - when the user clicks on "x", they will be redirected to the home page. Otherwise, nothing happens.
My problem is that in confirm(), both "ok" and "cancel" options redirect to home page and I cannot figure out why.
I saw that many people have a similar problem, checked many forums and noticed that writing onclick="return confirmCancel() rather than onclick="confirmCancel()" helped in most of the cases but it did not solve the problem for me.
HTML:
<a onclick="return confirmCancel()"><img src="assets/cancel.svg"></a>
JS:
const confirmCancel = () => {
confirm("All your progress will be lost. Are you sure you want to leave?");
if (confirmCancel) {
window.location.assign("index.html");
} else {
return false;
}
}
You need to test the return value of confirm (rather than the truthiness of the confirmCancel function).
const confirmCancel = () => {
if (confirm("All your progress will be lost. Are you sure you want to leave?");) {
window.location.assign("index.html");
} else {
return false;
}
}
Try something like this.
<a onclick="pleaseConfirm"><img src="assets/cancel.svg"></a>
const pleaseConfirm = () => {
if (confirm("All your progress will be lost. Are you sure you want to leave?")) {
window.location.assign("index.html");
}
}
You're mostly there .. You need to check if confirm() is true .. Change:
confirm("All your progress will be lost. Are you sure you want to leave?");
if (confirmCancel)
To
var test_confirm = confirm("All your progress will be lost. Are you sure you want to leave?");
if (test_confirm === true)
Shorthand can be
if (confirm("All ... ... "){
You can do the functionality inside JavaScript instead of calling out JavaScript function in your HTML tag
<a id="btn-exit"><img src="assets/cancel.svg"></a>
var btnExit = document.querySelector('#btn-exit')
btnExit.addEventListener('click', () => {
if (confirm("are you sure?")) {
window.location.assign("index.html");
}
})

Form not submitting data after validation

long time reader first time poster. I am having an issue with a form. It has email validator with JavaScript and once the validation is correct it supposedly has to submit the data but this doesn't happen. If I run the form without the validation the data goes through without a problem but with the validation I have a success message and then no data.
function ValidateEmail(email)
{
var mailformat = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
if(!email.match(mailformat))
{
alert("valid email is required");
return false;
}else{
document.querySelector('form').submit();
setTimeout(function(){
window.parent.location = "https://www.xxxs.com/";
}, 3000);
}
}
window.onload= function(){
document.querySelector('input[type="submit"]').addEventListener("click",
function(e){
e.preventDefault();
var email = document.querySelector('input[name^="Email"]').value;
ValidateEmail(email);
});
}
Thank you for your help
You haven't provided the markup to go along with it, so I can only speculate that there's a problem with the markup.
I also have no idea why you've added this.
setTimeout(function(){
window.parent.location = "https://www.xxxs.com/";
}, 3000);
Apart from this, it works pretty well for my sandbox.
PS: I can't comment yet due to reputation, but #Kayden van Rijn might be interested in
/* Links that start with "https" and end in ".org" */
a[href^="https"][href$=".org"] {
color: green;
}
from MDN Web Docs

Durandal canDeactivate vs window.onbeforeunload possible alternative

Users can edit their profile information. If they attempt to navigate away from the page while changes are present, the desired functionality should be that they are presented with a confirmation box. When I use Durandal's canDeactivate, it is only triggered when I try to navigate to another Durandal page. When I use window.onbeforeunload it is only triggered when I either hard refresh or type in a new URL etc.
Is there any universal solution (unified look and feel) that can catch both of these classes of events in order to prevent users from immediately navigating away from a page?
My two approaches are displayed below:
Durandal canDeactivate
canDeactivate: function () {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
var title = 'Warning';
var msg = 'Do you want to leave this page and lose all of your edits to this form?';
return app.showMessage(msg, title, ['Yes', 'No'])
.then(function (selectedOption) {
return selectedOption === 'Yes';
});
}
return false;
}
window.onbeforeunload
window.onbeforeunload = function() {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
var title = 'Warning';
var msg = 'Do you want to leave this page and lose all of your edits to this form?';
return app.showMessage(msg, title, ['Yes', 'No'])
.then(function (selectedOption) {
return selectedOption === 'Yes';
});
}
return true;
};
I have found in practice that you need both approaches to be sure of the desired behavior. window.onbeforeunload is considered by many to be a bad practice for web applications.
We finally abandoned this approach in our web application in favor of a Work in Progress pattern, where changes are saved (out to a back-end) every 3 seconds. That way, users can freely move from page to page without ever fearing the loss of their work. It does require adjusting one's data model, and the ability to turn off validation for works in progress. A Project document collection--or Projects table, depending on your approach to data--would have a corresponding ProjectDraft document collection or table.
But that's a topic of another discussion. In the meantime, if you have to take the approach you've given, why not encapsulate the logic in another require-able module? In other words:
var onNavigateOrShutdown = function () {
var title = 'Warning';
var msg = 'Do you want to leave this page and lose all of your edits to this form?';
return app.showMessage(msg, title, ['Yes', 'No'])
.then(function (selectedOption) {
return selectedOption === 'Yes';
});
}
and then
canDeactivate: function () {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
onNavigateOrShutdown();
return false;
}
and
window.onbeforeunload = function() {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
onNavigateOrShutdown();
}
return true;
};
Now, let's move this functionality into a new singleton module called, say, navigation.manager. Then, it's simply a matter of requiring the module wherever you need this logic. Of course, you can elaborate on navigation.manager and have it contain an evented hub that's capable of responding to messages and/or publishing them.

setting the variable of js function from within htm

I am creating a simple function that warns the user when they are about to close out of a web page. I am using the window.onbeforeonload function is javascript. What I am doing is that, I set a variable to false because of the evil window.onbeforeonload function.
function funky() {
var submitFormOkay = false;
window.onbeforeunload = function () {
if (submitFormOkay == false) {
return "You are about to leave this order form. You will lose any information...";
}
}
}
In my html, this is what I am doing
<input type="submit" id="submit_button" onclick="submitFormOkay = true;">
My question however is that I need a way to fire the function funky().
I know I could use an onclick but if I do what is going to set the value of submitFormOkay.
Any help would be appreciated.
Why not make submitFormOkay a parameter of the function funky, and just call it with the given parameter?
<input type="submit" id="submit_button" onclick="funky(true);">
And in the JS file:
function funky(submitFormOkay) {
window.onbeforeunload = function () {
if (submitFormOkay == false) {
return "You are about to leave this order form. You will lose any information...";
}
}
}
Without changing your HTML, I'd do this instead:
window.onbeforeunload = (function(w) {
w.submitFormOkay = false;
return function() {
if (!w.submitFormOkay) {
return "You are about to leave this order form. You will lose any information...";
}
};
})(window);
​A problem with ngmiceli's solution is that window.onbeforeunload's callback never gets defined until the user is okay to leave the page.

Simple client-side framework/pattern to simplify doing async calls?

We're currently not using any serious client side framework besides jQuery (and jQuery.ui + validation + form wizard plugins).
A problem that surfaces a few times in our code is this:
We have a button that initiates an Ajax call to the server.
While the call is taking place, we display a "loading" icon with some text
If the server returns a result too quickly (e.g. < 200 ms), we "sleep" for 200 millis (using setTimeout()), to prevent flickering of the waiting icon & text.
After max(the call returns, a minimal timeout), we clear the loading icon & text.
We then either display an error text, if there was some problem in the ajax call (the server doesn't return 500, but a custom json that has an "error message" property. In fact, sometimes we have such a property in the response per form field ... and we then match errors to form fields ... but I digress).
In case of success, we do ... something (depends on the situation).
I'm trying to minimize code reuse, and either write or reuse a pattern / piece of code / framework that does this. While I probably won't start using an entire new heavy-duty framework just for this use case, I would still like to know what my options are ... perhaps such a client-side framework would be good for other things as well. If there's a lightweight framework that doesn't require me to turn all my code upside down, and I could use just on specific cases, then we might actually use it instead of reinventing the wheel.
I just recently heard about Ember.js - is it a good fit for solving this problem? How would you solve it?
$(function(){
var buttonSelector = "#button";
$('body').on({'click': function(evt){
var $button = $(this);
$button.toggleClass('loading');
var time = new Date();
$.get('some/ajax').then(function(data,text,jqXhr){
// typical guess at load work
$button.empty();
$(data).wrap($button);
}).fail(function(data,text,jqXhr){
alert("failed");
}).done(function(data,text,jqXhr){
var elapsed = new Date();
if((elapsed - time) < 200){
alert("to short, wait");
}
$button.toggleClass('loading');
});
}},buttonSelector,null);
});
Just wrap the $.ajax in your own function. that way you can implement your own queing etc. I would suggest to do a jquery component for this. It can get pretty powerful, for example you can also pass http headers etc.
Regarding frameworks it depends on your requirements.
For example, you may consider Kendo UI, it has good framework for creating data sources:
http://demos.kendoui.com/web/datasource/index.html.
Working Sample Code (well, almost)
I was going for something along the lines of #DefyGravity's answer anyway - his idea is good, but is still pseudo-code/not fully complete. Here is my working code (almost working demo, up to the Ajax URL itself, and UI tweaks)
The code & usage example:
jQuery.fn.disable = function() {
$(this).attr("disabled", "disabled");
$(this).removeClass("enabled");
// Special handling of jquery-ui buttons: http://stackoverflow.com/questions/3646408/how-can-i-disable-a-button-on-a-jquery-ui-dialog
$(this).filter("button").button({disabled: true});
};
jQuery.fn.enable = function() {
$(this).removeAttr("disabled");
$(this).addClass("enabled");
// Special handling of jquery-ui buttons: http://stackoverflow.com/questions/3646408/how-can-i-disable-a-button-on-a-jquery-ui-dialog
$(this).filter("button").button({disabled: false});
};
function AjaxCallbackWaiter(ajaxUrl, button, notificationArea, loadingMessage, errorMessage, inSuccessHandler, inFailureHandler) {
// Every request that takes less than this, will be intentionally delayed to prevent a flickering effect
// http://ripper234.com/p/sometimes-a-little-sleep-is-ok/
var minimalRequestTime = 800;
var loadingIconUrl = 'http://loadinfo.net/images/preview/11_cyrcle_one_24.gif?1200916238';
var loadingImageContent = $("<img class='loading-image small' src='" + loadingIconUrl + "'/><span class='loading-text'>" + loadingMessage + "</span>");
var errorContentTemplate = $("<span class='error ajax-errors'></span>");
var requestSentTime = null;
button.click(clickHandler);
function displayLoadingMessage() {
clearNotificationArea();
notificationArea.html(loadingImageContent);
}
function clearNotificationArea() {
notificationArea.html("");
}
function displayError(message) {
var errorContent = errorContentTemplate.clone(errorContentTemplate).html(message);
notificationArea.html(errorContent);
}
function ajaxHandler(result) {
var requestReceivedTime = new Date().getTime();
var timeElapsed = requestReceivedTime - requestSentTime;
// Reset requestSentTime, preparing it for the next request
requestSentTime = null;
var sleepTime = Math.max(0, minimalRequestTime - timeElapsed);
function action() {
clearNotificationArea();
button.enable();
if (result) {
inSuccessHandler();
} else {
displayError(errorMessage);
inFailureHandler();
}
}
if (sleepTime <= 0) {
action();
} else {
setTimeout(action, sleepTime);
}
}
function failureHandler() {
}
function clickHandler(){
if (requestSentTime !== null) {
logError("Bad state, expected null");
}
requestSentTime = new Date().getTime();
displayLoadingMessage();
button.disable();
$.get(ajaxUrl, 'json').then(ajaxHandler, failureHandler);
}
}
// Usage:
var ajaxUrl = 'FILL IN YOUR OWN URL HERE';
var button = $("#clickme");
var notificationArea = $(".ajax-notification-area");
var waitingMessage = "Doing Stuff";
var errorMessage = "Not Good<br/> Please try again";
$(document).ready(function(){
new AjaxCallbackWaiter(
ajaxUrl,
button,
notificationArea,
waitingMessage,
errorMessage,
function(){
alert("All is well with the world");
},
function(){
alert("Not good - winter is coming");
});
});

Categories