File: /home/wbwebdes/domains/survey.nailsbyrianne.nl/public_html/assets/packages/limesurvey/survey.js
/**
* @file Javascript core function for public survey
* @description loaded before template javascript : allow template to use own function (if function is called after template.js)
* @copyright LimeSurvey <http://www.limesurvey.org/>
* @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later
*/
/**
* Always set an empty LSvar
*/
var LSvar = LSvar || { };
/**
* Action to do when relevance is set to on or off
*/
function triggerEmRelevance(){
triggerEmRelevanceQuestion();
triggerEmRelevanceGroup();
triggerEmRelevanceSubQuestion();
}
/* On question */
function triggerEmRelevanceQuestion(){
/* Action on this question */
$("[id^='question']").on('relevance:on',function(event,data) {
/* @todo : attach only to this. Use http://stackoverflow.com/a/6411507/2239406 solution for now.
Don't want to stop propagation. */
if(event.target != this) return;
$(this).removeClass("ls-irrelevant ls-hidden");
});
$("[id^='question']").on('relevance:off',function(event,data) {
if(event.target != this) return;
$(this).addClass("ls-irrelevant ls-hidden");
});
/* In all in one mode : need updating group too */
$(".allinone [id^='group-']:not(.ls-irrelevant) [id^='question']").on('relevance:on',function(event,data) {
if(event.target != this) return;
$(this).closest("[id^='group-']").removeClass("ls-hidden");
});
$(".allinone [id^='group-']:not(.ls-irrelevant) [id^='question']").on('relevance:off',function(event,data) {
if(event.target != this) return;
if($(this).closest("[id^='group-']").find("[id^='question']").length==$(this).closest("[id^='group-']").find("[id^='question'].ls-hidden").length){
$(this).closest("[id^='group-']").addClass("ls-hidden");
}
});
}
/* On Group */
function triggerEmRelevanceGroup(){
$("[id^='group-']").on('relevance:on',function(event,data) {
if(event.target != this) return;
$(this).removeClass("ls-irrelevant ls-hidden");
});
$("[id^='group-']").on('relevance:off',function(event,data) {
if(event.target != this) return;
$(this).addClass("ls-irrelevant ls-hidden");
});
}
/* On subquestion and answers-list */
function triggerEmRelevanceSubQuestion(){
$("[id^='question']").on('relevance:on',"[id^='javatbd']",function(event,data) {
if(event.target != this) return; // not needed now, but after (2016-11-07)
data = $.extend({style:'hidden'}, data);
$(this).removeClass("ls-irrelevant ls-"+data.style);
if(data.style=='disabled'){
if($(event.target).hasClass("answer-item")) {
$(event.target).find('input').each(function(itrt, item ){
$(item).prop("disabled", false );
});
} else {
$(event.target).find('.answer-item input').each(function(itrt, item ){
$(item).prop("disabled", false );
});
}
}
if(data.style=='hidden'){
updateLineClass($(this));
updateRepeatHeading($(this).closest(".ls-answers"));
}
});
$("[id^='question']").on('relevance:off',"[id^='javatbd']",function(event,data) {
if(event.target != this) return; // not needed now, but after (2016-11-07)
data = $.extend({style:'hidden'}, data);
$(this).addClass("ls-irrelevant ls-"+data.style);
if(data.style=='disabled'){
$(event.target).find('input')
.each(function(itrt, item ){
if($(item).attr('type') == 'checkbox' && $(item).prop('checked')) {
$(item).prop('checked', false).trigger('change');
}
$(item).prop("disabled", true );
});
}
if(data.style=='hidden'){
updateLineClass($(this));
updateRepeatHeading($(this).closest(".ls-answers"));
}
console.ls.log($(this).find('input[disabled]'));
});
}
/**
* relevance:(on|off) event
*/
/* Update lines class when relevance:(on|off) */
function updateLineClass(line){
if($(line).hasClass("ls-odd") || $(line).hasClass("ls-even")){
$(line).closest(".ls-answers").find(".ls-odd:visible,.ls-even:visible").each(function(index){ // not limited to table
$(this).removeClass('ls-odd ls-even').addClass(((index+1)%2 == 0) ? "ls-odd" : "ls-even");
});
}
}
/* Update repeat heading */
function updateRepeatHeading(answers){
/* Update only (at start) when all hidden line is done : @todo : do it only once */
$(function() {
if($(answers).data("repeatHeading") || $(answers).find("tbody").find(".ls-heading").length){
/* set the data the first time */
if(!$(answers).data("repeatHeading")){
var repeatHeading=$(answers).find("tbody:first tr").length;/* first body don't have heading */
$(answers).data("repeatHeading",repeatHeading)
$(answers).data("repeatHeader",$(answers).find("tbody .ls-heading").filter(":first")[0].outerHTML);
}else{
var repeatHeading=$(answers).data("repeatHeading");
}
/* can remove the heading and clone this one of thead */
var header = $(answers).data("repeatHeader");
$(answers).find("tbody .ls-heading").remove();
var lines=$(answers).find('tr:visible');
var max=$(answers).find('tr:visible').length-1;
$(lines).each(function(index){
if(index != 0 && index % repeatHeading == 0 && index < max)
{
$(header).insertAfter($(this));
}
});
}
});
}
/**
* Manage the index
*/
function manageIndex(){
/* only needed if it's not inside form (form#limesurvey) */
$(".ls-index-buttons").on('click','[name="move"]',function(e){
if(!$(this).closest('form').length && $('form#limesurvey').length==1){
$(this).clone().addClass("d-none").appendTo('form#limesurvey').click();
}
});
}
/**
* Reload page when participant selects a new language.
* Sets input[name=lang] to new language and submits limesurvey form.
*/
function activateLanguageChanger(){
var limesurveyForm = $('form#limesurvey');
if(limesurveyForm.length == 0 && $('form[name="limesurvey"]').length == 1) { /* #form-token for example */
limesurveyForm = $('form[name="limesurvey"]');
}
/**
* @param {string} lang Language to change to.
*/
var applyChangeAndSubmit = function(lang) {
// Remove existing onsubmitbuttoninput, no need to remove lang : last one is the submitted
$("#onsubmitbuttoninput").remove();
// Append new input.
$('<input type="hidden">')
.attr('name', 'lang')
.val(lang)
.appendTo(limesurveyForm);
// Append move type.
/* onsubmitbuttoninput is related to template (and ajax) : MUST move to template with ajax … */
$('<input type="hidden" id="onsubmitbuttoninput" name="move" value="changelang" />').appendTo(limesurveyForm);
limesurveyForm.submit();
};
$('.form-change-lang a.ls-language-link').on('click', function() {
var closestForm = $(this).closest('form');
if (!closestForm.length) {
/* we are not in a forum, can not submit directly */
if (limesurveyForm.length == 1) {
/* The limesurvey form exist in document, move select and button inside and click */
var newLang = $(this).data('limesurvey-lang');
applyChangeAndSubmit(newLang);
// TODO: Check all code below. When does it happen?
} else {
// If there are no form : we can't use it */
if($(this).data('targeturl')){
/* If we have a target url : just move location to this url with lang set */
/* possible usage : in clear all */
var target=$(this).data('targeturl');
/* adding lang in get param manually */
if(target.indexOf("?") >=0){
target+="&lang="+$(this).val();
}else{
target+="?lang="+$(this).val();
}
/* directly move to location */
location.href = target;
return false;
}else{
var lang = $(this).data('limesurvey-lang');
/* No form, not targeturl : just see what happen */
$("<form>", {
"class":'ls-js-hidden',
"html": '<input type="hidden" name="lang" value="' + lang + '" />',
"action": target,
"method": 'get'
}).appendTo(document.body).submit();
}
}
}else{
/* we are inside a form : just submit : but remove other lang input if exist : be sure it's this one send */
$(this).closest('form').find("[name='lang']").not($(this)).remove();
$(this).closest('.ls-language-changer-item').find(":submit").click();
}
});
/* Language changer dropdown */
/* Don't activate change when using key up / key down */
$('.form-change-lang [name="lang"]').on('keypress keydown keyup', function(event) {
var code = event.keyCode || event.which;
/* packaje name : limesurvey */
$(this).data("limesurvey-lastkey",code);
});
$('.form-change-lang [name="lang"]').on('click', function(event) {
/* didn't work with chrome , chrom bug : onclick are an intrinsic event see https://www.w3.org/TR/html401/interact/forms.html#h-17.6 */
/* Happen rarely (keyboard + mouse + still have the button */
$(this).data("limesurvey-lastkey",null);
});
$('.form-change-lang [name="lang"]').on('change', function(event) {
if( $(this).data("limesurvey-lastkey") == 38 || $(this).data("lastkey") == 40) {
/* Last key is up or down : disable auto submit mantis #16024 */
return;
}
var closestForm = $(this).closest('form');
var newLang = $(this).val();
if (!closestForm.length) {
/* we are not in a form, can not submit directly */
// Remind user can put language changer everywhere, not only in home page, but for example in clear all page etc … in form or not etc ...
if (limesurveyForm.length == 1) {
/* The limesurvey form exist in document, move select and button inside and click */
applyChangeAndSubmit(newLang);
} else {
// If there are no form : we can't use it */
if($(this).parent().data('targeturl')){
/* If we have a target url : just move location to this url with lang set */
/* targeturl was used for preview gropup and question in 2.6lts : check if still used/usable */
var target=$(this).parent().data('targeturl');
/* adding lang in get param manually */
if(target.indexOf("?") >=0){
target+="&lang="+$(this).val();
}else{
target+="?lang="+$(this).val();
}
/* directly move to location */
location.href = target;
return false;
}else{
/* No form, not targeturl : just see what happen */
/* This must not happen : issue in theme */
$("<form>", {
"class":'ls-js-hidden',
"html": '<input type="hidden" name="lang" value="' + newLang + '" />',
"action": target,
"method": 'get'
}).appendTo(document.body).submit();
}
}
}else{
/* we are inside a form : just submit : but remove other lang input if exist : be sure it's this one send */
$(this).closest('form').find("[name='lang']").not(this).remove();
$(this).closest('.form-change-lang').find(':submit').click();
}
});
}
/**
* Action link with submit object (json) : add params to form and submit
*/
function activateActionLink(){
/* If no limesurvey form : don't need it */
if(!$('form#limesurvey').length){
$('[data-limesurvey-submit]').remove();
}
/* Submit limesurvey form on click */
else{
$('[data-limesurvey-submit]').on('click',function(event) {
event.preventDefault();
var submit=$(this).data('limesurvey-submit');
var confirmedby=$(this).data('confirmedby');
if(!confirmedby){
$.each(submit, function(name, value) {
$("<input/>",{
'type':"hidden",
'name':name,
'value':value,
}).appendTo('form#limesurvey');
});
$('form#limesurvey').submit();
}else{
var submits=$.extend(submit,confirmedby);
confirmSurveyDialog($(this).data('confirmlabel'),$(this).text(),submits)
}
});
}
}
/**
* function for replacing submit after confirm
* @var string text : the text to be shown
* @var string optional title
* @var object[] submits : name.value to submit
*/
function confirmSurveyDialog(text,title,submits){
if($.bsconfirm !== undefined) {
$.bsconfirm(text, LSvar.lang.confirm, function(){
$.each(submits, function(name, value) {
$("<input/>",{
'type':"hidden",
'name':name,
'value':value,
}).appendTo('form#limesurvey');
});
$('form#limesurvey').submit();
});
} else {
if(confirm(text)){
$.each(submits, function(name, value) {
$("<input/>",{
'type':"hidden",
'name':name,
'value':value,
}).appendTo('form#limesurvey');
});
$('form#limesurvey').submit();
}
}
}
/**
* Ask confirmation on click on .needconfirm
*/
function activateConfirmButton(){
/* With ajax mode : using $(document).on attache X times the same event */
$("button[data-confirmedby]").on('click',function(event){
var btnConfirm=$(this);
var cbConfirm=$(this).parent().find("[name='"+$(this).data('confirmedby')+"']");
if(!$(cbConfirm).is(":checked")) {
event.preventDefault();
var submits = { };
submits[$(btnConfirm).attr('name')]=$(btnConfirm).val();
submits[$(cbConfirm).attr('name')]=$(cbConfirm).val();
confirmSurveyDialog($(cbConfirm).parent("label").text(),$(btnConfirm).text(),submits)
}
});
}
/**
* Trigger tip class when classChangeGood/classChangeError happen
*/
function triggerEmClassChange(){
/* The tips */
$(document).on('classChangeError','.ls-em-tip', function(event){
$(this).removeClass("ls-em-success").addClass("ls-em-error text-danger");
});
$(document).on('classChangeGood','.ls-em-tip', function(event){
$(this).removeClass("ls-em-error text-danger").addClass("ls-em-success");
});
/* The dynamic sum */
$(document).on('classChangeError','.dynamic-total', function(event){
$(this).removeClass("ls-em-success text-success").addClass("ls-em-error text-danger");
});
$(document).on('classChangeGood','.dynamic-total', function(event){
$(this).removeClass("ls-em-error text-danger").addClass("ls-em-success text-success");
});
/* The input */
$(document).on('classChangeError','input,select,textarea', function(event){
$(this).closest(".form-control").addClass("has-warning"); // Use warning, not error : in multiple : if one input have error : it's apply to all input
});
$(document).on('classChangeGood','input,select,textarea', function(event){
$(this).closest(".form-control").removeClass("has-warning");
});
}
/**
* has-error management for ls-error-mandatory
* Only add ls-error-mandatory in PHP currently, not in js : different behaviour after try next and don't try next
* /!\ We can more easily doing without js ( usage of :empty in css with :text & select) but then no boostrap, for before submit : use only css in template
*/
function updateMandatoryErrorClass(){
$(".ls-error-mandatory .has-error,.ls-error-mandatory.has-error").on("blur",":text,textarea",function(event){
if($(this).val()!==""){
$(this).closest(".has-error").removeClass("has-error");
if(!$(this).closest(".ls-error-mandatory").find(".has-error").length){
$(this).closest(".ls-error-mandatory").find(".text-danger").removeClass("text-danger");
}
}
});
$(".ls-error-mandatory .has-error,.ls-error-mandatory.has-error").on("change","select",function(event){
if($(this).val()!==""){
$(this).closest(".has-error").removeClass("has-error");
if(!$(this).closest(".ls-error-mandatory").find(".has-error").length){
$(this).closest(".ls-error-mandatory").find(".text-danger").removeClass("text-danger");
}
}
});
$(".ls-error-mandatory.has-error").on("change",":radio",function(event){
if($(this).closest(".array-flexible-dual-scale").length){
if($(this).closest(".has-error").find("input:radio:checked").length>1){
$(this).closest(".has-error").removeClass("has-error");
}
}else{
$(this).closest(".has-error").removeClass("has-error");
}
});
$(".ls-error-mandatory.has-error").on("change",":checkbox",function(event){
$(this).closest(".has-error").removeClass("has-error");
});
}
/**
* Soft mandatory
*/
function activateSoftMandatory(){
$('#mandatory-soft-alert-box-modal').on('click', function (ev) {
ev.preventDefault();
var $form = $('#limesurvey');
$form.append('<input type="hidden" name="mandSoft" value="' + $(this).data('movenext') + '" />');
$form.find('#ls-button-submit').trigger('click');
$("#bootstrap-alert-box-modal").modal('hide');
});
}
function resetQuestionTimers(sid) {
if(!window.localStorage) {
return;
}
var surveyTimersItemName = 'limesurvey_timers_by_sid_' + sid;
var timers = JSON.parse(window.localStorage.getItem(surveyTimersItemName) || "[]");
timers.forEach(function(timersessionname, idx){
window.localStorage.removeItem('limesurvey_timers_' + timersessionname);
});
window.localStorage.removeItem(surveyTimersItemName);
}
/**
* Disable submit button to prevent multiple submits
* This is done on 'document' instead of the '#limesurvey' form in order to allow
* other scripts (custom themes?) to cancel the submit before we disable the button.
*/
$(document).on('submit', function (e) {
// If the target is not the '#limesurvey' form, don't do anything.
if (e.target.id != 'limesurvey') {
return;
}
// We only care about the final submit, not normal forward/backward navigation.
var submitter = e.originalEvent ? $(e.originalEvent.submitter) : null;
if (!submitter || submitter.attr('value') != 'movesubmit') {
return;
}
// Still, we disable all submit buttons to make sure the "back" button is not
// pressed while submitting.
$('#limesurvey button[type="submit"]').prop('disabled', true);
// We also add a hidden input with the button's value, because it's not included
// in the request when the button is disabled.
$('#limesurvey').append('<input id="onsubmitbuttoninput" name=\'' + submitter.attr('name') + '\' value=\'' + submitter.attr('value') + '\' type=\'hidden\' />');
});