Thanks Denis for your tips.
I finally managed to:
1) Add a multi text question
2) Hide this question in javascript
3) Move each input.text of this question in answer part of the array
4) Copy the value from each sub-question row to the the relative input text
5) Hide the input text boxes from my pre-defined sub questions (1-10)
6) Automatically tick option from a hidden multiple-options question according to the given answers
The question at first appears to work, but I have some worries. This question is very crucial as will hold the data for future questions, therefore it is important that the values of text input boxes are captured correctly so that can be used in later questions.
At the moment, next questions show the original sub-question values entered from within Limesurvey Admin and not the modified ones from the text-input boxes. What do you think would be the best solution to properly link the values from the text-input boxes with the array and the hidden multiple-options question?
Below is my code together with some documentation for some commands implemented by me. It needs a lot of optimisation I know, but I'll leave that for after I manage to make it work as expected.
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
// Identify the questions
var QuestionID = 56; // current question number
var hiddenQuestion = 74; // autocomplete hidden question number
var thisQuestion = $('#question{QID}'); // hidden multi-text question ID
var nextQuestion = $(thisQuestion).next('div[id^="question"]'); // current question ID
// Set the minimum and maximum limit of our custom-defined rows
var minSubq = 10;
var MaxSubq = 15;
// Hide the auto-complete question
$('#question'+hiddenQuestion+'').hide();
// Hide the multi-text question
$(nextQuestion).hide();
// The HTML content of the Add/Remove elements - modify as you wish
var addContent = '[+]';
var removeContent = '[-]';
// Create the Add and Remove elements & insert them
var el1 = document.createElement('div');
el1.setAttribute('id','addButton'+QuestionID);
document.body.appendChild(el1);
var el2 = document.createElement('div');
el2.setAttribute('id','removeButton'+QuestionID);
document.body.appendChild(el2);
// Move them to after the array
$( 'div#addButton'+QuestionID ).appendTo($( QuestionID + ' table.question' ).parent());
$( 'div#removeButton'+QuestionID ).appendTo($( QuestionID + ' table.question' ).parent());
// Insert their HTML
$( 'div#addButton'+QuestionID ).html( addContent );
$( 'div#removeButton'+QuestionID ).html( removeContent );
// Style the elements - you can modify here if you wish
$( 'div#addButton'+QuestionID ).css({
'margin':'10px 0 0 10px',
'padding':'1px',
'text-align':'center',
'font-weight':'bold',
'width':'auto',
'cursor':'pointer',
'float':'left'
});
$( 'div#removeButton'+QuestionID ).css({
'margin':'10px 0 0 10px',
'padding':'1px',
'text-align':'center',
'font-weight':'bold',
'width':'auto',
'cursor':'pointer',
'float':'left'
});
// Initially hide the Remove element
$( 'div#removeButton'+QuestionID ).hide();
// Call the functions below when clicked
$( 'div#addButton'+QuestionID ).click(function (event) {
addRow(QuestionID);
});
$( 'div#removeButton'+QuestionID ).click(function (event) {
removeRow(QuestionID);
});
var CurSubq = minSubq; // Initially the current row equals to the last visible one
// Initially hide all rows that are above the lower limit
for (var i=minSubq;i<=MaxSubq;i++) {
$('tr[id*='+QuestionID+'SQ0'+i+']').hide();
}
// Function to add a row, also shows the Remove element and hides the
//Add element if all rows are shown
function addRow(QuestionID) {
CurSubq = CurSubq + 1;
$('tr[id*='+QuestionID+'SQ0'+CurSubq+']').show();
$( 'div#removeButton'+QuestionID ).show();
if ( CurSubq >= MaxSubq ) {
$( 'div#addButton'+QuestionID ).hide();
}
}
// Function to remove a row
function removeRow(QuestionID) {
if (CurSubq>minSubq) {
$('tr[id*='+QuestionID+'SQ0'+CurSubq+']').hide();
CurSubq = CurSubq - 1;
$( 'div#addButton'+QuestionID ).show();
}
if ( CurSubq <= minSubq ) {
$( 'div#removeButton'+QuestionID ).hide();
}
}
// Add extra cells to the array rows
$('.subquestions-list thead tr', thisQuestion).append('<th />');
$('.subquestions-list tbody tr', thisQuestion).append('<td />');
// Move the multi-text question text to the first column header cell of the array
$('.subquestions-list thead tr th:first', thisQuestion).text($('.questiontext', nextQuestion).text());
// Move the text inputs
$('input.text', nextQuestion).each(function(i){
var count = (i+1).toString(); // convert counter to string, but start from 1 instead of 0
var pad = '00'; // define the pad (maximum number of integers)
pad = pad.substring(0, pad.length - count.length) + count; // e.g. convert 5 to 05, but leave 11 intact
var SubqHTML = $('tr[id*='+QuestionID+'SQ0'+pad+'] th').html(); // get the inner html of our th
SubqLabel = SubqHTML.substr(0, SubqHTML.indexOf('<')); // keep only the part before the < characther
SubqLabel = SubqLabel.replace(/^\s*|\s*$/g,""); // remove any spaces left or right
$(this).val(SubqLabel); // Set text input to have the Subquestions label
$(this).css('text-align','right');
$(this).hide(); // Hide the text input boxes
if (i>=minSubq) {
var removeSubqLabel = SubqHTML.substr(0,SubqHTML.indexOf(SubqLabel)); // Remove the label
$('tr[id*='+QuestionID+'SQ0'+pad+'] th').html(removeSubqLabel); // Apply the new html without the label
$(this).show(); // Show text input boxes
}
$('.subquestions-list tbody tr:eq('+i+') th:first', thisQuestion).append(this); // Append all the text-boxes to the TH of our array table
});
// Some cleanup styles (for the default template)
$('col', thisQuestion).css({
'width': 'auto'
});
$('.subquestions-list tbody th, .subquestions-list tbody td', thisQuestion).css({
'padding': '4px 10px'
});
// Call the autoClick function
// Params - Array ID, Hidden question ID, Column of array that auto-checks the hidden question
autoClick(QuestionID, hiddenQuestion, 1);
autoClick(QuestionID, hiddenQuestion, 2);
autoClick(QuestionID, hiddenQuestion, 3);
autoClick(QuestionID, hiddenQuestion, 4);
autoClick(QuestionID, hiddenQuestion, 5);
autoClick(QuestionID, hiddenQuestion, 6);
// Autoclick the hidden questions entries according to the answers on the current question
function autoClick(qArrayID, qHiddenID, column) {
// Hide the hidden question
$('#question'+qHiddenID+'').hide();
// Find the survey and group IDs
if($('input#fieldnames').length != 0) {
var fieldNames = $('input#fieldnames').attr('value');
var tmp = fieldNames.split('X');
var sID = tmp[0];
var gID = tmp[1];
}
// Add some column-specific classes
$('#question'+qArrayID+' table.question tr').each(function(i, el){
$('> *', this).each(function(i, el){
$(el).addClass('col-'+i);
});
});
// Add a class to answers that are to auto-check the hidden question
$('#question'+qArrayID+' .col-'+column).addClass('autoClick');
// A listener on the Q1 radio buttons
$('#question'+qArrayID+' table.question tbody td').click(function () {
//var rowID = $(this).parents('tbody:eq(0)').attr('id');
var rowID = $(this).parents('tr:eq(0)').attr('id');
var tmp2 = rowID.split('X'+qArrayID);
var answerCode = tmp2[1];
// This cell checks the corresponding option it qHidden
if($(this).hasClass('autoClick')) {
$('#answer'+sID+'X'+gID+'X'+qHiddenID+answerCode).attr('checked', true);
}
// This cell unchecks the corresponding option it qHidden
else {
$('#answer'+sID+'X'+gID+'X'+qHiddenID+answerCode).attr('checked', false);
}
});
}
});
</script>
Thanks in advance!