LimeSurvey 2.0 question structure

LimeSurvey 2.0 Proposed Question Structure
To be able to analyze the results, we need a list of possible answers for each questions, ability to record answer with start-time, ipaddress, end-time. Currently, we can record list of possible answers for qtsingleselect question types, however, the current implementation requires us to have several tables, each can only support a specific set of question types. Therefore, we need a different implementation.

After studying the question types structure, I propose an implementation which need only one table to record possible answers for question types

Overview Structure
QuestionTypes

--hasMany --

Questions

--hasMany -- ModelAnswers

--hasMany -- Result

--hasMany -- Statistics

images will be added later

Structure of ModelAnswer
example: 2-dimensional Matrix-type question

can be translated into

example: Multiple-choice question with alternative answer

can be translated into
 * 1950
 * 1960
 * Alternative

With ModelAnswers table, we can record all possible type of answers for a question hence allow the statistics and result model gather information about the questions' answers. This approach is similar to LS1 (lime_answer) table, however with the appearance of category and attribute fields instead of simple answer field, we would be able to create more sophisticated question types and it also provide better resources for statistics model.

Update about Model Answer implementation

Currently we are able to create/edit/delete model answer related to questions. Test implementation is being done with qtsingleselect question types, however the UI has not been completed yet ( please see builder implementation changes section ).

Data return from modelanswer when we perform search will be in the form:

array(

'category1'=>array('answerid'=>'attribute'),

'category2'=>array('answerid'=>'attribute'),

'category3'=>array('answerid'=>'attribute')

)

This data will be fetched into the views to display as question's model answer.

Update about Builder implementation
- Currently builder implementation is doing save/edit/delete inputs all by itself. Furthermore, the current approach involve saving data that need to be edit/delete into a JSON object and post in one time instead of right when it is edited/deleted. So the database operations doesnt really happen ( except when we add ) even when the UI has been changed. It is only run when we save the whole survey. This would save us some speed however the data preparation to be able to create a JSON object is very complicated and take a lot of time for question types developer. Therefore, I proposed a change that data will be saved into the database right after it is added/edited/deleted on the UI.

With this implementation, we can also offload some operations to respective controllers such as
 * modelAnswer
 * Question
 * Section

instead of grouping everything into builder controller.

- Current Builder.js is doing all the data preparation by itself. This is not good for question types development as it would require builder.js developer to know the structure of questions beforehand. Therefore, I would propose a rewriting of Builder.js with an OO implementation and offload the data processing to respectively question types:

Issues regarding CSS of Builder pages
- Currently when added new questions, I noticed that the question container's are not using unique id. They are actually reusing the same id and CSS are applied to those id directly which could cause some problems in the future. The duplicated ids were fixed in qtsingleselect question but they arent being render correctly because of the CSS problems as described above.

For example:

-Current implementation:
//qtsingleselect_design.js

function qtsingleselect_addinput(questionid, inputid, optiontext)

{

$("#qtsingleselect_edDefaultValueID"+questionid).addOption(inputid,optiontext);

}

function addinput

{

//Data preparation here

//........

//end Data preparation

jQuery.post(basepath+"modelAnswers/add/",

{question_id: questionid, category: category, type:type, lastOrder: lastOrder,attribute: optiontext},

function(data){

console.log(data);

});

}

-New implementation
//qtsingleselect_design.js

function qtsingleselect_addinput(questionid, inputid, optiontext)

{

$("#qtsingleselect_edDefaultValueID"+questionid).addOption(inputid,optiontext);

//call function addinput in builder js

//TODO: define parameters here

Builder.addinput(questionid,optiontext,category,sortorder);

}

//Builder.js

Builder = {

.......

removechars: function(string){

},

//more utilities function here

//.........

// - -  -  -  - ---

addinput : function(questionid,optiontext,category,sortorder,type)

{

jQuery.post(basepath+"modelAnswers/add/",

{question_id: questionid, category: category, type:type, lastOrder: lastOrder,attribute: optiontext},

function(data){

console.log(data);

});

}

.......

}