2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
19 * Float type form element
21 * Contains HTML class for a float type element
25 * @copyright 2019 Shamim Rezaie <shamim@moodle.com>
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 defined('MOODLE_INTERNAL') ||
die();
32 require_once($CFG->libdir
. '/form/text.php');
35 * Float type form element.
37 * This is preferred over the text element when working with float numbers, and takes care of the fact that different languages
38 * may use different symbols as the decimal separator.
39 * Using this element, submitted float numbers will be automatically translated from the localised format into the computer format,
40 * and vice versa when they are being displayed.
42 * @copyright 2019 Shamim Rezaie <shamim@moodle.com>
43 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45 class MoodleQuickForm_float
extends MoodleQuickForm_text
{
48 * MoodleQuickForm_float constructor.
50 * @param string $elementName (optional) name of the float field
51 * @param string $elementLabel (optional) float field label
52 * @param string $attributes (optional) Either a typical HTML attribute string or an associative array
54 public function __construct($elementName = null, $elementLabel = null, $attributes = null) {
55 parent
::__construct($elementName, $elementLabel, $attributes);
56 $this->_type
= 'float';
60 * Called by HTML_QuickForm whenever form event is made on this element.
62 * @param string $event Name of event
63 * @param mixed $arg event arguments
64 * @param object $caller calling object
67 public function onQuickFormEvent($event, $arg, &$caller) {
70 if ($value = $this->_findValue($caller->_constantValues
)) {
71 $value = $this->format_float($value);
73 if (null === $value) {
74 $value = $this->_findValue($caller->_submitValues
);
75 if (null === $value) {
76 if ($value = $this->_findValue($caller->_defaultValues
)) {
77 $value = $this->format_float($value);
81 if (null !== $value) {
82 parent
::setValue($value);
86 $caller->setType($arg[0], PARAM_RAW_TRIMMED
);
88 return parent
::onQuickFormEvent($event, $arg, $caller);
93 * Checks that the submitted value is a valid float number.
95 * @param string $value The localised float number that is submitted.
96 * @return string|null Validation error message or null.
98 public function validateSubmitValue($value) {
99 if (false === unformat_float($value, true)) {
100 return get_string('err_numeric', 'core_form');
105 * Sets the value of the form element.
107 * @param string $value Default value of the form element
109 public function setValue($value) {
110 $value = $this->format_float($value);
111 parent
::setValue($value);
115 * Returns the value of the form element.
117 * @return false|float
119 public function getValue() {
120 $value = parent
::getValue();
122 $value = unformat_float($value, true);
128 * Returns a 'safe' element's value.
130 * @param array $submitValues array of submitted values to search
131 * @param bool $assoc whether to return the value as associative array
134 public function exportValue(&$submitValues, $assoc = false) {
135 $value = $this->_findValue($submitValues);
136 if (null === $value) {
137 $value = $this->getValue();
139 $value = unformat_float($value, true);
141 return $this->_prepareValue($value, $assoc);
145 * Used by getFrozenHtml() to pass the element's value if _persistantFreeze is on.
149 public function _getPersistantData() {
150 if (!$this->_persistantFreeze
) {
153 $id = $this->getAttribute('id');
155 // Id of persistant input is different then the actual input.
156 $id = array('id' => $id . '_persistant');
161 return '<input' . $this->_getAttrString(array(
163 'name' => $this->getAttribute('name'),
164 'value' => $this->getAttribute('value')
170 * Given a float, prints it nicely.
171 * This function reserves the number of decimal places.
173 * @param float|null $value The float number to format
174 * @return string Localised float
176 private function format_float($value) {
177 if (is_numeric($value)) {
178 // We want to keep trailing zeros after the decimal point if there is any.
179 // Therefore we cannot just call format_float() and pass -1 as the number of decimal points.
180 $pieces = preg_split('/E/i', $value); // In case it is in the scientific format.
181 $decimalpos = strpos($pieces[0], '.');
182 if ($decimalpos !== false) {
183 $decimalpart = substr($pieces[0], $decimalpos +
1);
184 $decimals = strlen($decimalpart);
188 $pieces[0] = format_float($pieces[0], $decimals);
189 $value = implode('E', $pieces);