Drag and drop answer option values
Challenge
In order to be more flexible in displaying questions
As a questionnaire creator
I want to drag and drop elements in a pre-defined lists to use as question's answers
Example
I want to drag products in left list to textboxes in right list, and have the ability of changing my choices by clicking a Remove link
Solution
- Create a text grid question
- Add a column containing the products to the left of the sub question text column, make the text draggable
- Make an extra space column between product column and sub question text column
- Add a column containing Remove links to the right of the sub question text column
- Make textboxes droppable
- Hide the product in the left grid when it is dropped in the text box, the previous product in the textbox will be shown again in the left list
- Clicking Remove will clear the textbox in the same row and show the corresponding product in the left list
Code
1 quest.onInit = function()
2 {
3 this.initializeLeftList();
4
5 //add Remove link after text boxes
6 $("input:text").each(
7 function(i)
8 {
9 $(this).parent().after(
10 $("<td>")
11 .append($("<a href=\"javascript:quest.clearAnswer("+i+");\">Remove</a>"))
12 .addClass("grid_subquestion_text grid_subquestion_odd")
13 );
14 }
15 );
16
17 //configure the drag move
18 $(".draggable_text").draggable
19 (
20 {
21 mouse: "pointer",
22 helper: 'clone'
23 }
24 );
25
26 //make the textboxes droppable and not editable
27 $("input:text").each(
28 function(i)
29 {
30 $(this).addClass("droppable_cell");
31 $(this)[0].contentEditable = false;
32 $(this).width("300px");
33 }
34 );
35
36 //drop function
37 $(".droppable_cell").droppable
38 (
39 {
40 accept: ".draggable_text",
41 activeClass: 'droppable-active',
42 hoverClass: 'droppable-hover',
43 drop: function(ev, ui)
44 {
45 var currentValue = $(this).val();
46 var newValue = ui.draggable.text();
47 if (currentValue != "" && currentValue != newValue)
48 {
49 quest.showProduct(currentValue);
50 }
51 $(this).val(ui.draggable.text());
52 ui.draggable._hide("fast");
53 }
54 }
55 );
56 }
57
58 quest.initializeLeftList = function()
59 {
60 var n = this.questions.length;
61 var answers = this.getAnswers();
62
63 var products = new Array();
64 products[0] = "{{Brands[0]}}";
65 products[1] = "{{Brands[1]}}";
66 products[2] = "{{Brands[2]}}";
67 products[3] = "{{Brands[3]}}";
68 products[4] = "{{Brands[4]}}";
69
70 //add a product cell before the sub question text cell
71
72 for(var i=0; i<n; i++)
73 {
74 var v = products[i];
75 $("#grid_subquestion_text_" + (i+1))
76 .before(
77 $("<td>").append(
78 $("<div>")
79 .append(
80 $("<p>").text(v)
81 .addClass("draggable_text")
82 .css("mouse", "pointer")
83 )
84 )
85 .width("200px")
86 )
87 .width("10px");
88 }
89
90 $("#grid_subquestion_text_1")
91 .before(
92 $("<td rowspan=\""+(n + 1)+"\"> </td>")
93 .addClass("grid_space_cell")
94 .width("200px")
95 );
96
97 $(".draggable_text").each(
98 function(i)
99 {
100 if (answers.exists($(this).text()))
101 $(this)._hide("fast");
102 }
103 );
104 }
105
106 //get list of answered value
107 quest.getAnswers = function()
108 {
109 var a = new Array();
110 a[0] = "{{Q7[0]}}";
111 a[1] = "{{Q7[1]}}";
112 a[2] = "{{Q7[2]}}";
113 a[3] = "{{Q7[3]}}";
114 a[4] = "{{Q7[4]}}";
115 return a;
116 }
117
118 //check if a value exists in an array
119 Array.prototype.exists = function(value)
120 {
121 for(var i=0; i<this.length; i++)
122 {
123 if (this[i] == value)
124 return true;
125 }
126 return false;
127 }
128
129 //show a product in the left list
130 quest.showProduct = function(value)
131 {
132 $(".draggable_text").each(
133 function(i)
134 {
135 if ($(this).text() == value)
136 $(this).show();
137 }
138 );
139 }
140
141 //remove a product from the right list and put back in the left list
142 quest.clearAnswer = function(index)
143 {
144 var input = $("input:text")[index];
145 var value = input.value;
146 if (value != "")
147 {
148 this.showProduct(value);
149 input.value = "";
150 }
151 }