diff options
| -rw-r--r-- | ajax.php | 55 | ||||
| -rw-r--r-- | amd/build/display.min.js | 1 | ||||
| -rw-r--r-- | amd/src/display.js | 28 | ||||
| -rw-r--r-- | lang/en/qtype_algebra.php | 5 | ||||
| -rw-r--r-- | renderer.php | 97 | ||||
| -rw-r--r-- | settings.php | 7 | ||||
| -rw-r--r-- | styles.css | 10 | ||||
| -rw-r--r-- | version.php | 2 | 
8 files changed, 176 insertions, 29 deletions
| diff --git a/ajax.php b/ajax.php new file mode 100644 index 0000000..156db22 --- /dev/null +++ b/ajax.php @@ -0,0 +1,55 @@ +<?php +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle.  If not, see <http://www.gnu.org/licenses/>. + +/** + * @package    qtype_algebra + * @copyright  2018 Jean-Michel Vedrine + * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +define('AJAX_SCRIPT', true); + +require_once(__DIR__ . '/../../../config.php'); +require_once(__DIR__ . '/parser.php'); + +$p = new qtype_algebra_parser; + +$vars  = required_param('vars', PARAM_RAW); +$expr  = required_param('expr', PARAM_RAW); +/* +if (!confirm_sesskey()) { +    header('HTTP/1.1 403 Forbidden'); +    die(); +} +*/ +try { +    $vars = explode(',', $vars); +    if (empty($expr)) { +        $texexp = ''; +    } else { +        $exp = $p->parse($expr, $vars); +        $texexp = $exp->tex(); +    } +} catch (Exception $e) { +    $texexp = ''; +} +if ($CFG->qtype_algebra_texdelimiters == 'old') { +    $texexp = '$$' . $texexp . '$$'; +} else { +    $texexp = '\\[' . $texexp . '\\]'; +} +header('Content-Type: application/json; charset: utf-8'); +echo json_encode($texexp); diff --git a/amd/build/display.min.js b/amd/build/display.min.js new file mode 100644 index 0000000..cd5da13 --- /dev/null +++ b/amd/build/display.min.js @@ -0,0 +1 @@ +define(["jquery","core/config","core/notification"],function(a,b,c){return{init:function(){a(".algebra_answer").on("input paste keyup",null,null,function(){var d=a(this).attr("id"),e=d.replace(":","_"),f=a("#"+e+"_vars").html(),g=a(this).val(),h={vars:f,expr:g,sesskey:b.sesskey};a.post(b.wwwroot+"/question/type/algebra/ajax.php",h,null,"json").done(function(b){a("#"+e+"_display").html('<span class="filter_mathjaxloader_equation">'+b+"</span>"),MathJax.Hub.Queue(["Typeset",MathJax.Hub])}).fail(function(a,b,d){c.exception(d)})})}}});
\ No newline at end of file diff --git a/amd/src/display.js b/amd/src/display.js new file mode 100644 index 0000000..e2131b7 --- /dev/null +++ b/amd/src/display.js @@ -0,0 +1,28 @@ +define(['jquery', 'core/config', 'core/notification'], function($, config, notification) { +    return { +        init: function() { +            $(".algebra_answer").on('input paste keyup', null, null, function() { +                // Convert answer id to valid javascript name. +                var id = $(this).attr('id'); +                var display = id.replace(':', '_'); +                var varnames = $('#' + display + '_vars').html(); +                var currentanswer = $(this).val(); +                var params = { +                    vars: varnames, +                    expr: currentanswer, +                    sesskey: config.sesskey, +                }; +                $.post(config.wwwroot + '/question/type/algebra/ajax.php', params, null, 'json') +                    .done(function(data) { +                        // Replace TeX form in page. +                        $('#' + display + '_display').html("<span class=\"filter_mathjaxloader_equation\">" + data +"</span>"); +                        // MathJax update. +                        MathJax.Hub.Queue(["Typeset", MathJax.Hub]); +                    }) +                    .fail(function(jqXHR, status, error) { +                        notification.exception(error); +                    }); +            }); +        } +    }; +});
\ No newline at end of file diff --git a/lang/en/qtype_algebra.php b/lang/en/qtype_algebra.php index 819e14b..4006858 100644 --- a/lang/en/qtype_algebra.php +++ b/lang/en/qtype_algebra.php @@ -145,4 +145,7 @@ $string['brackets'] = '\[...\]';  $string['invalidanswer'] = 'Invalid or unrecongnized answer';  $string['multiplyoperator'] = 'TeX operator for multiplication';  $string['times'] = '\\times'; -$string['cdot'] = '\\cdot';
\ No newline at end of file +$string['cdot'] = '\\cdot'; +$string['iframe'] = 'Using an iframe element'; +$string['dynamic'] = 'Using dynamic AJAX request'; +$string['formuladisplay'] = 'Method to display answer formula';
\ No newline at end of file diff --git a/renderer.php b/renderer.php index 529fb0e..ec3d57e 100644 --- a/renderer.php +++ b/renderer.php @@ -38,6 +38,9 @@ class qtype_algebra_renderer extends qtype_renderer {              question_display_options $options) {              global $CFG; + +        $this->page->requires->js_call_amd('qtype_algebra/display', 'init'); +          $question = $qa->get_question();          $currentanswer = $qa->get_last_qt_var('answer'); @@ -50,6 +53,7 @@ class qtype_algebra_renderer extends qtype_renderer {              'name' => $inputname,              'value' => $currentanswer,              'id' => $inputname, +            'class' => 'algebra_answer',              'size' => 80,          ); @@ -65,13 +69,12 @@ class qtype_algebra_renderer extends qtype_renderer {              } else {                  $fraction = 0;              } -            $inputattributes['class'] = $this->feedback_class($fraction); +            $inputattributes['class'] = $this->feedback_class($fraction). ' algebra_answer';              $feedbackimg = $this->feedback_image($fraction); +        } else { +            $inputattributes['class'] = 'algebra_answer';          } - -        $iframename = $nameprefix.'_if'; -        // Name of the javascript function which causes the entered formula to be rendered. -        $dfname = $nameprefix.'_display'; +                  // Create an array of variable names to use when displaying the function entered.          $varnames = array();          if ($question and isset($question->variables)) { @@ -80,26 +83,14 @@ class qtype_algebra_renderer extends qtype_renderer {                  $varnames[] = $var->name;              }          } -          $varnames = implode(',', $varnames); -        // Javascript function which the button uses to display the rendering -        // This function sents the source of the iframe to the 'displayformula.php' script giving -        // it an argument of the formula entered by the student. -        $displayfunction = 'function '.$dfname."() {\n". -            '    var text="vars='.$varnames.'&expr="+escape(document.getElementsByName("'.$inputname.'")[0].value);'."\n". -            "    if(text.length != 0) {\n". -            '      document.getElementsByName("'.$iframename.'")[0].src="'. -            $CFG->wwwroot.'/question/type/algebra/displayformula.php?"+'. -            'text.replace(/\+/g,"%2b")'."\n". -            "    }\n". -            "  }\n";          $questiontext = $question->format_questiontext($qa);          $input = html_writer::empty_tag('input', $inputattributes) . $feedbackimg;          $result = html_writer::tag('div', $questiontext, array('class' => 'qtext')); -        $result .= html_writer::tag('script', $displayfunction, array('type' => 'text/javascript')); +                  $result .= html_writer::start_tag('div', array('class' => 'ablock'));          $result .= html_writer::start_tag('div', array('class' => 'prompt', 'style' => 'vertical-align: top'));          if (isset($question->answerprefix) and !empty($question->answerprefix)) { @@ -118,15 +109,67 @@ class qtype_algebra_renderer extends qtype_renderer {                      $question->get_validation_error(array('answer' => $currentanswer)),                      array('class' => 'validationerror'));          } -        $result .= html_writer::start_tag('div', array('class' => 'dispresponse')); -        $result .= html_writer::empty_tag('input', array('type' => 'button', -            'value' => get_string('displayresponse', 'qtype_algebra'), 'onclick' => $dfname.'()')); -        $result .= html_writer::start_tag('iframe', -                array('name' => $iframename, 'width' => '60%', 'height' => 60, 'align' => 'middle', 'src' => '')); -        $result .= html_writer::end_tag('iframe'); -        $result .= html_writer::tag('script', $dfname.'();', array('type' => 'text/javascript')); -        $result .= html_writer::end_tag('div'); - +        if (get_config('qtype_algebra', 'formuladisplay') == 'iframe') { +            // Javascript function which the button uses to display the rendering +            // This function sents the source of the iframe to the 'displayformula.php' script giving +            // it an argument of the formula entered by the student. +            $iframename = $nameprefix.'_if'; +            // Name of the javascript function which causes the entered formula to be rendered. +            $dfname = $nameprefix.'_display'; +            $displayfunction = 'function '.$dfname."() {\n". +            '    var text="vars='.$varnames.'&expr="+escape(document.getElementsByName("'.$inputname.'")[0].value);'."\n". +            "    if(text.length != 0) {\n". +            '      document.getElementsByName("'.$iframename.'")[0].src="'. +            $CFG->wwwroot.'/question/type/algebra/displayformula.php?"+'. +            'text.replace(/\+/g,"%2b")'."\n". +            "    }\n". +            "  }\n"; +            $result .= html_writer::tag('script', $displayfunction, array('type' => 'text/javascript')); +            $result .= html_writer::start_tag('div', array('class' => 'dispresponse')); +            $result .= html_writer::empty_tag('input', array('type' => 'button', +                'value' => get_string('displayresponse', 'qtype_algebra'), 'onclick' => $dfname.'()')); +            $result .= html_writer::start_tag('iframe', +                    array('name' => $iframename, 'width' => '60%', 'height' => 60, 'align' => 'middle', 'src' => '')); +            $result .= html_writer::end_tag('iframe'); +            $result .= html_writer::tag('script', $dfname.'();', array('type' => 'text/javascript')); +            $result .= html_writer::end_tag('div'); +        } else { +            $result .= html_writer::tag('div', $varnames ,array( +                'type' => 'text', +                'name' => $nameprefix . '_vars', +                'id' => $nameprefix . '_vars', +                'size' => 80, +                'style' => 'display:none', +                ) +            ); +            $p = new qtype_algebra_parser; +            try { +                $vars = explode(',', $varnames); +                if (empty($currentanswer)) { +                    $texexp = ''; +                } else { +                    $exp = $p->parse($currentanswer, $vars); +                    $texexp = $exp->tex(); +               } +            } catch (Exception $e) { +               $texexp = ''; +            } +            if ($CFG->qtype_algebra_texdelimiters == 'old') { +                $texexp = '$$' . $texexp . '$$'; +            } else { +                $texexp = '\\[' . $texexp . '\\]'; +            } +            $display = $question->format_text("<span class=\"filter_mathjaxloader_equation\">" . $texexp ."</span>", +                                    1 ,$qa, 'question', 'questiontext', $question->id); +            $result .= html_writer::tag('div', $display ,array( +                'type' => 'text', +                'name' => $nameprefix . '_display', +                'id' => $nameprefix. '_display', +                'size' => 80, +                'class' => 'displayformula', +                ) +            ); +        }          return $result;      } diff --git a/settings.php b/settings.php index 525324a..1c6fa30 100644 --- a/settings.php +++ b/settings.php @@ -54,4 +54,11 @@ if ($ADMIN->fulltree) {              array('times' => new lang_string('times', 'qtype_algebra'),                    'cdot' => new lang_string('cdot', 'qtype_algebra')              ))); +    // Method to diplay TeX formatted answer formula. +    $settings->add(new admin_setting_configselect('qtype_algebra/formuladisplay', +            new lang_string('formuladisplay', 'qtype_algebra'), +            '', 'times', +            array('iframe' => new lang_string('iframe', 'qtype_algebra'), +                  'dynamic' => new lang_string('dynamic', 'qtype_algebra') +            )));  } @@ -5,6 +5,16 @@  .que.algebra .answer input {      width: 80%;  } +.que.algebra .displayformula { +    padding: 0.3em; +    display: block; +    width: 300px; +    min-height: 70px ! important; +    background: #fff3bf; +    padding: 0.5em; +    margin-top: 1em; +    box-shadow: 0.5em 0.5em 1em #000; +}  /* Editing form. */  body#page-question-type-algebra div[id^=fgroup_id_][id*=answeroptions_] { diff --git a/version.php b/version.php index 7eb6e41..1db1702 100644 --- a/version.php +++ b/version.php @@ -23,7 +23,7 @@  defined('MOODLE_INTERNAL') || die();  $plugin->component = 'qtype_algebra'; -$plugin->version   = 2018010400; +$plugin->version   = 2018020100;  $plugin->requires  = 2013050100;  $plugin->release   = '1.6 for Moodle 2.8, ... 3.5'; | 
