Browse Source

Allow solve Matching Draggable answer - refs #7611

Angel Fernando Quiroz Campos 10 years ago
parent
commit
09c5864de7

+ 24 - 0
main/css/base.css

@@ -5930,3 +5930,27 @@ ul.exercise-draggable-answer li {
 .question_options .droppable .gallery .exercise-draggable-answer-option {
     margin-bottom: 15px;
 }
+
+/***    Matching Draggable answer ***/
+.drag_question {
+    float: left;
+    min-height: 4em;
+    width: 100%;
+}
+.drag_question .window{
+    box-shadow: 2px 2px 19px #AAA;
+    cursor: pointer;
+    min-height: 65px;
+    padding-top: 25px;
+}
+.window_left_question {
+    padding: 10px 25px 10px 10px;
+    text-align: right;
+}
+.window_right_question {
+    padding: 10px 10px 10px 25px;
+}
+
+._jsPlumb_endpoint {
+    z-index: 50;
+}

+ 16 - 0
main/exercice/answer.class.php

@@ -759,4 +759,20 @@ class Answer
 			}
         }
 	}
+
+    /**
+     * Get the necessary JavaScript for some ansers
+     * @return string
+     */
+    public function getJs() {
+        //if ($this->questionId == 2)
+        return "<script>
+                jsPlumb.ready(function() {
+                    if ($('#drag{$this->questionId}_question').length > 0) {
+                        MatchingDraggable.init('{$this->questionId}');
+                    }
+                });
+            </script>";
+    }
+
 }

+ 1 - 1
main/exercice/exercise_show.php

@@ -343,7 +343,7 @@ foreach ($questionList as $questionId) {
 		$question_result = $objExercise->manage_answer($id, $questionId, $choice,'exercise_show', array(), false, true, $show_results, $objExercise->selectPropagateNeg());
 		$questionScore   = $question_result['score'];
 		$totalScore     += $question_result['score'];
-        } elseif (in_array($answerType, [MATCHING, DRAGGABLE])) {
+        } elseif (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) {
         $question_result = $objExercise->manage_answer($id, $questionId, $choice,'exercise_show', array(), false, true, $show_results, $objExercise->selectPropagateNeg());
         $questionScore   = $question_result['score'];
         $totalScore     += $question_result['score'];

+ 7 - 0
main/exercice/exercise_submit.php

@@ -50,6 +50,13 @@ if ($showGlossary) {
     $htmlHeadXtra[] = api_get_js('jquery.highlight.js');
 }
 
+$htmlHeadXtra[] = '<script src="'
+    . api_get_path(WEB_PATH) . 'web/assets/jsplumb/dist/js/jquery.jsPlumb-1.7.5-min.js'
+    . '"></script>';
+$htmlHeadXtra[] = '<script src="'
+    . api_get_path(WEB_PATH) . 'web/assets/xcolor/jquery.xcolor.min.js'
+    . '"></script>';
+
 //This library is necessary for the time control feature
 $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/stylesheet/jquery.epiclock.css');
 $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epiclock/renderers/minute/epiclock.minute.css');

+ 3 - 3
main/inc/lib/display.lib.php

@@ -954,7 +954,7 @@ class Display
             if ($key == 'id') {
                 $default_id = '';
             }
-            $extra .= $key.'="'.$parameter.'"';
+            $extra .= $key.'="'.$parameter.'" ';
         }
         $html .= '<select name="'.$name.'" '.$default_id.' '.$extra.'>';
 
@@ -976,13 +976,13 @@ class Display
                 if (is_array($default)) {
                     foreach($default as $item) {
                         if ($item == $key) {
-                            $html .= 'selected="selected"';
+                            $html .= ' selected="selected"';
                             break;
                         }
                     }
                 } else {
                     if ($default == $key) {
-                        $html .= 'selected="selected"';
+                        $html .= ' selected="selected"';
                     }
                 }
 

+ 129 - 8
main/inc/lib/exercise.lib.php

@@ -104,13 +104,16 @@ class ExerciseLib
             // on the right side are called answers
             $num_suggestions = 0;
 
-            if (in_array($answerType, [MATCHING, DRAGGABLE])) {
+            if (in_array($answerType, [MATCHING, DRAGGABLE, MATCHING_DRAGGABLE])) {
                 if ($answerType == DRAGGABLE) {
                     $s .= '<div class="ui-widget ui-helper-clearfix">
                         <div class="clearfix">
                         <ul class="exercise-draggable-answer ui-helper-reset ui-helper-clearfix">';
                 } else {
-                    $s .= '<table class="table table-hover table-striped">';
+                    $s .= <<<HTML
+                        <div id="drag{$questionId}_question" class="drag_question">
+                            <table class="data_table">
+HTML;
                 }
                 // Iterate through answers
                 $x = 1;
@@ -1002,17 +1005,129 @@ JAVASCRIPT;
 
                         $s .= '</li>';
                     }
+                } elseif ($answerType == MATCHING_DRAGGABLE) {
+                    if ($answerId == 1) {
+                        echo $objAnswerTmp->getJs();
+                    }
+
+                    if ($answerCorrect != 0) {
+                        $parsed_answer = $answer;
+                        $windowId = "{$questionId}_{$lines_count}";
+
+                        $s .= <<<HTML
+                            <tr>
+                                <td widht="45%">
+                                    <div id="window_{$windowId}" class="window window_left_question window{$questionId}_question">
+                                        <strong>$lines_count.</strong> $parsed_answer
+                                    </div>
+                                </td>
+                                <td width="10%">
+HTML;
+                        $selectedValue = 0;
+                        $questionOptions = [];
+
+                        foreach ($select_items as $key => $val) {
+                            if ($debug_mark_answer) {
+                                if ($val['id'] == $answerCorrect) {
+                                    $selectedValue = $val['id'];
+                                }
+                            }
+
+                            if (
+                                isset($user_choice[$matching_correct_answer]) &&
+                                $val['id'] == $user_choice[$matching_correct_answer]['answer']
+                            ) {
+                                $selectedValue = $val['id'];
+                            }
+
+                            $questionOptions[$val['id']] = $val['letter'];
+                        }
+
+                        $s .= Display::select(
+                            "choice[$questionId][$numAnswer]",
+                            $questionOptions,
+                            $selectedValue,
+                            [
+                                'id' => "window_{$windowId}_select",
+                                'class' => 'hidden'
+                            ],
+                            false
+                        );
+
+                        if (!empty($answerCorrect) && !empty($selectedValue)) {
+                            $s .= <<<JAVASCRIPT
+                                <script>
+                                    jsPlumb.ready(function() {
+                                        jsPlumb.connect({
+                                            source: 'window_$windowId',
+                                            target: 'window_{$questionId}_{$selectedValue}_answer',
+                                            endpoint: ['Blank', {radius: 15}],
+                                            anchors: ['RightMiddle', 'LeftMiddle'],
+                                            paintStyle: {strokeStyle: '#8A8888', lineWidth: 8},
+                                            connector: [
+                                                MatchingDraggable.connectorType,
+                                                {curvines: MatchingDraggable.curviness}
+                                            ]
+                                        });
+                                    });
+                                </script>
+JAVASCRIPT;
+                        }
+
+                        $s .= <<<HTML
+                            </td>
+                            <td width="45%">
+HTML;
+
+                        if (isset($select_items[$lines_count])) {
+                            $s .= <<<HTML
+                                <div id="window_{$windowId}_answer" class="window window_right_question">
+                                    <strong>{$select_items[$lines_count]['letter']}.</strong> {$select_items[$lines_count]['answer']}
+                                </div>
+HTML;
+                        } else {
+                            $s .= '&nbsp;';
+                        }
+
+                        $s .= '</td></tr>';
+
+                        $lines_count++;
+
+                        if (($lines_count - 1) == $num_suggestions) {
+                            while (isset($select_items[$lines_count])) {
+                                $s .= <<<HTML
+                                    <tr>
+                                        <td colspan="2"></td>
+                                        <td>
+                                            <strong>{$select_items[$lines_count]['letter']}</strong>
+                                            $select_items[$lines_count]['answer']
+                                        </td>
+                                    </tr>
+HTML;
+                                $lines_count++;
+                            }
+                        }
+
+                        $matching_correct_answer++;
+                    }
                 }
             }    // end for()
 
             if ($show_comment) {
                 $s .= '</table>';
-            } else {
-                if ($answerType == MATCHING || $answerType == UNIQUE_ANSWER_NO_OPTION || $answerType == MULTIPLE_ANSWER_TRUE_FALSE ||
-                    $answerType == MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE
-                ) {
+            } elseif(
+                in_array(
+                    $answerType,
+                    [
+                        MATCHING,
+                        MATCHING_DRAGGABLE,
+                        UNIQUE_ANSWER_NO_OPTION,
+                        MULTIPLE_ANSWER_TRUE_FALSE,
+                        MULTIPLE_ANSWER_COMBINATION_TRUE_FALSE
+                    ]
+                )
+            ) {
                     $s .= '</table>';
-                }
             }
 
             if ($answerType == DRAGGABLE) {
@@ -1042,7 +1157,7 @@ JAVASCRIPT;
                 $s .= '</div></div>';
             }
 
-            if ($answerType == MATCHING) {
+            if (in_array($answerType, [MATCHING, MATCHING_DRAGGABLE])) {
                 $s .= '</div>';
             }
 
@@ -3106,6 +3221,9 @@ JAVASCRIPT;
                 $select_condition = " e.exe_id, answer ";
                 break;
             case MATCHING:
+                //no break
+            case MATCHING_DRAGGABLE:
+                //no break
             default:
                 $answer_condition = " answer = $answer_id AND ";
                 $select_condition = " DISTINCT exe_user_id ";
@@ -3161,6 +3279,9 @@ JAVASCRIPT;
                     return $good_answers;
                     break;
                 case MATCHING:
+                    //no break
+                case MATCHING_DRAGGABLE:
+                    //no break
                 default:
                     $return = Database::num_rows($result);
             }

+ 148 - 0
main/template/default/exercise/submit.js.tpl

@@ -86,6 +86,154 @@
         }
     };
 
+    var MatchingDraggable = {
+        colorDestination: '#316B31',
+        curviness: 0,
+        connectorType: 'Straight',
+        initialized: false,
+        init: function (questionId) {
+            var windowQuestionSelector = '.window' + questionId + '_question',
+                countConnections = $(windowQuestionSelector).length,
+                colorArray = [],
+                colorArrayDestination = [];
+
+            if (countConnections > 0) {
+                colorArray = $.xcolor.analogous("#da0", countConnections);
+                colorArrayDestination = $.xcolor.analogous("#51a351", countConnections);
+            } else {
+                colorArray = $.xcolor.analogous("#da0", 10);
+                colorArrayDestination = $.xcolor.analogous("#51a351", 10);
+            }
+
+            jsPlumb.importDefaults({
+                DragOptions: {cursor: 'pointer', zIndex: 2000},
+                PaintStyle: {strokeStyle: '#000'},
+                EndpointStyle: {strokeStyle: '#316b31'},
+                Endpoint: 'Rectangle',
+                Anchors: ['TopCenter', 'TopCenter']
+            });
+
+            var exampleDropOptions = {
+                tolerance: 'touch',
+                hoverClass: 'dropHover',
+                activeClass: 'dragActive'
+            };
+
+            var destinationEndPoint = {
+                endpoint: ["Dot", {radius: 15}],
+                paintStyle: {fillStyle: MatchingDraggable.colorDestination},
+                isSource: false,
+                connectorStyle: {strokeStyle: MatchingDraggable.colorDestination, lineWidth: 8},
+                connector: [
+                    MatchingDraggable.connectorType,
+                    {curviness: MatchingDraggable.curviness}
+                ],
+                maxConnections: 1000,
+                isTarget: true,
+                dropOptions: exampleDropOptions,
+                beforeDrop: function (params) {
+                    jsPlumb.select({source: params.sourceId}).each(function (connection) {
+                        jsPlumb.detach(connection);
+                    });
+
+                    var selectId = params.sourceId + "_select";
+                    var value = params.targetId.split("_")[2];
+
+                    $("#" + selectId + " option")
+                        .removeAttr('selected')
+                        .filter(function (index) {
+                            return index === parseInt(value);
+                        })
+                        .attr("selected", true);
+
+                    return true;
+                }
+            };
+
+            var count = 0;
+            var sourceDestinationArray = [];
+
+            $(windowQuestionSelector).each(function (index) {
+                var windowId = $(this).attr("id");
+                var scope = windowId + "scope";
+                var destinationColor = colorArray[count].getHex();
+
+                var sourceEndPoint = {
+                    endpoint: [
+                        "Dot",
+                        {radius: 15}
+                    ],
+                    paintStyle: {
+                        fillStyle: destinationColor
+                    },
+                    isSource: true,
+                    connectorStyle: {
+                        strokeStyle: "#8a8888",
+                        lineWidth: 8
+                    },
+                    connector: [
+                        MatchingDraggable.connectorType,
+                        {curviness: MatchingDraggable.curviness}
+                    ],
+                    maxConnections: 1,
+                    isTarget: false,
+                    dropOptions: exampleDropOptions,
+                    scope: scope
+                };
+
+                sourceDestinationArray[count + 1] = sourceEndPoint;
+
+                count++;
+
+                jsPlumb.addEndpoint(
+                    windowId,
+                    {
+                        anchor: ['RightMiddle', 'RightMiddle', 'RightMiddle', 'RightMiddle']
+                    },
+                    sourceEndPoint
+                );
+
+                var destinationCount = 0;
+
+                $(windowQuestionSelector).each(function (index) {
+                    var windowDestinationId = $(this).attr("id");
+                    destinationEndPoint.scope = scope;
+                    destinationEndPoint.paintStyle.fillStyle = colorArrayDestination[destinationCount].getHex();
+                    destinationCount++;
+
+                    jsPlumb.addEndpoint(
+                        windowDestinationId + "_answer",
+                        {
+                            anchors: ['LeftMiddle', 'LeftMiddle', 'LeftMiddle', 'LeftMiddle']
+                        },
+                        destinationEndPoint
+                    );
+                });
+            });
+
+            MatchingDraggable.attachBehaviour();
+        },
+        attachBehaviour: function () {
+            if (!MatchingDraggable.initialized) {
+                MatchingDraggable.initialized = true;
+            }
+        }
+    };
+    
+    jsPlumb.ready(function () {
+        if ($(".drag_question").length > 0) {
+            MatchingDraggable.init();
+
+            $(document).scroll(function () {
+                jsPlumb.repaintEverything();
+            });
+
+            $(window).resize(function () {
+                jsPlumb.repaintEverything();
+            });
+        }
+    });
+
     $(document).on('ready', function () {
         DraggableAnswer.init(
             $(".exercise-draggable-answer"),