1 /* 2 Copyright 2008-2026 3 Matthias Ehmann, 4 Michael Gerhaeuser, 5 Carsten Miller, 6 Bianca Valentin, 7 Alfred Wassermann, 8 Peter Wilfahrt 9 10 This file is part of JSXGraph. 11 12 JSXGraph is free software dual licensed under the GNU LGPL or MIT License. 13 14 You can redistribute it and/or modify it under the terms of the 15 16 * GNU Lesser General Public License as published by 17 the Free Software Foundation, either version 3 of the License, or 18 (at your option) any later version 19 OR 20 * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT 21 22 JSXGraph is distributed in the hope that it will be useful, 23 but WITHOUT ANY WARRANTY; without even the implied warranty of 24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 GNU Lesser General Public License for more details. 26 27 You should have received a copy of the GNU Lesser General Public License and 28 the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/> 29 and <https://opensource.org/licenses/MIT/>. 30 */ 31 32 /*global JXG: true, define: true, window: true*/ 33 /*jslint nomen: true, plusplus: true*/ 34 35 /** 36 * @fileoverview In this file the Text element is defined. 37 */ 38 39 import JXG from "../jxg.js"; 40 import Env from "../utils/env.js"; 41 import Text from "../base/text.js"; 42 import Type from "../utils/type.js"; 43 44 var priv = { 45 /** 46 * @class 47 * @ignore 48 */ 49 CheckboxChangeEventHandler: function () { 50 this._value = this.rendNodeCheckbox.checked; 51 this.board.update(); 52 } 53 }; 54 55 /** 56 * @class A text element that contains an HTML checkbox tag. 57 * For this element, the attribute "display" has to have the value 'html' (which is the default). 58 * 59 * <p><b>Setting a CSS class:</b> The attribute <tt>cssClass</tt> affects the HTML div element that contains the checkbox element. To change the CSS properties of the HTML checkbox element a selector of the form 60 * <tt>.mycheck > checkbox { ... }</tt> has to be used. See the analog example for buttons: 61 * {@link Button}. 62 * 63 * <p><b>Access the checkbox element with JavaScript:</b> 64 * The underlying HTML checkbox element can be accessed through the sub-object 'rendNodeCheck', e.g. to 65 * add event listeners. 66 * 67 * @pseudo 68 * @name Checkbox 69 * @augments Text 70 * @constructor 71 * @type JXG.Text 72 * 73 * @param {number,function_number,function_String,function} x,y,label Parent elements for checkbox elements. 74 * <p> 75 * x and y are the coordinates of the lower left corner of the text box. 76 * The position of the text is fixed, 77 * x and y are numbers. The position is variable if x or y are functions. 78 * <p> 79 * The label of the input element may be given as string or function. 80 * <p> 81 * The value of the checkbox can be controlled with the attribute <tt>checked</tt> 82 * <p>The HTML node can be accessed with <tt>element.rendNodeCheckbox</tt> 83 * 84 * @example 85 * // Create a checkbox element at position [0,3]. 86 * var checkbox = board.create('checkbox', [0, 3, 'Change Y'], {}); 87 * var p = board.create('point', [ 88 * function(){ return 0.5;}, // X-coordinate 89 * function() { 90 * y = 0.5; 91 * if (checkbox.Value()) { 92 * y += 0.5; 93 * } 94 * return y; 95 * }]); 96 * </pre><div class="jxgbox" id="JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c" style="width: 300px; height: 300px;"></div> 97 * <script type="text/javascript"> 98 * (function() { 99 * var t1_board = JXG.JSXGraph.initBoard('JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false}); 100 * var checkbox = t1_board.create('checkbox', [0, 3, 'Change Y'], {}); 101 * var p = t1_board.create('point', [ 102 * function(){ return 0.5;}, // X-coordinate 103 * function() { 104 * y = 0.5; 105 * if (checkbox.Value()) { 106 * y += 0.5; 107 * } 108 * return y; 109 * }]); 110 * })(); 111 * </script><pre> 112 * 113 * The checkbox can be supplied with custom-made events by using the property rendNodeCheckbox. 114 * @example 115 * var checkbox = board.create('checkbox', [0, 4, 'Click me']), 116 * p = board.create('point', [1, 1]); 117 * 118 * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() { 119 * if (this.Value()) { 120 * p.moveTo([4, 1]); 121 * } else { 122 * p.moveTo([1, 1]); 123 * } 124 * }, checkbox); 125 * </pre><div class="jxgbox" id="JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810" style="width: 300px; height: 300px;"></div> 126 * <script type="text/javascript"> 127 * (function() { 128 * var board = JXG.JSXGraph.initBoard('JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false}); 129 * var checkbox = board.create('checkbox', [0, 4, 'Click me']), 130 * p = board.create('point', [1, 1]); 131 * 132 * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() { 133 * if (this.Value()) { 134 * p.moveTo([4, 1]); 135 * } else { 136 * p.moveTo([1, 1]); 137 * } 138 * }, checkbox); 139 * })(); 140 * </script><pre> 141 * @example 142 * var i1 = board.create('input', [1, 5, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2}); 143 * var c1 = board.create('checkbox', [1, 3, 'label 1'], {}); 144 * var b1 = board.create('button', [1, 1, 'Change texts', function () { 145 * i1.setText('g(x)='); 146 * i1.set('cos(x)'); 147 * c1.setText('label 2'); 148 * b1.setText('Texts are changed'); 149 * }], 150 * {cssStyle: 'width:200px'}); 151 * 152 * </pre><div id="JXG31c6d070-354b-4f09-aab9-9aaa796f730c" class="jxgbox" style="width: 300px; height: 300px;"></div> 153 * <script type="text/javascript"> 154 * (function() { 155 * var board = JXG.JSXGraph.initBoard('JXG31c6d070-354b-4f09-aab9-9aaa796f730c', 156 * {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}); 157 * var i1 = board.create('input', [1, 5, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2}); 158 * var c1 = board.create('checkbox', [1, 3, 'label 1'], {}); 159 * var b1 = board.create('button', [1, 1, 'Change texts', function () { 160 * i1.setText('g(x)='); 161 * i1.set('cos(x)'); 162 * c1.setText('label 2'); 163 * b1.setText('Texts are changed'); 164 * }], 165 * {cssStyle: 'width:200px'}); 166 * 167 * })(); 168 * 169 * </script><pre> 170 * 171 */ 172 JXG.createCheckbox = function (board, parents, attributes) { 173 var t, 174 par, 175 setTextBackup, 176 attr = Type.copyAttributes(attributes, board.options, 'checkbox'); 177 178 //if (parents.length !== 3) { 179 //throw new Error("JSXGraph: Can't create checkbox with parent types '" + 180 // (typeof parents[0]) + "' and '" + (typeof parents[1]) + "'." + 181 // "\nPossible parents are: [[x,y], label]"); 182 //} 183 184 par = [ 185 parents[0], 186 parents[1], 187 '<span style="display:inline">' + 188 '<input type="checkbox" /><label for=""></label>' + 189 "</span>" 190 ]; 191 192 // Make sure the setText method is the original one. The JessieCode parser changes it during parsing. 193 setTextBackup = Text.prototype.setText; 194 Text.prototype.setText = Text.prototype._setText; 195 196 // 1. Create checkbox element with empty label 197 t = board.create("text", par, attr); 198 t.type = Type.OBJECT_TYPE_CHECKBOX; 199 200 // Restore whichever setText method was set before this contructor was called. 201 Text.prototype.setText = setTextBackup; 202 203 204 t.rendNodeCheckbox = t.rendNode.childNodes[0].childNodes[0]; 205 t.rendNodeLabel = t.rendNode.childNodes[0].childNodes[1]; 206 207 t.rendNodeTag = t.rendNodeCheckbox; // Needed for unified treatment in setAttribute 208 t.rendNodeTag.disabled = !!attr.disabled; 209 210 t.rendNodeCheckbox.id = t.rendNode.id + "_checkbox"; 211 t.rendNodeLabel.id = t.rendNode.id + "_label"; 212 t.rendNodeLabel.setAttribute("for", t.rendNodeCheckbox.id); 213 214 // 2. Set parents[2] (string|function) as label of the checkbox element. 215 // abstract.js selects the correct DOM element for the update 216 t.setText(parents[2]); 217 218 // This sets the font-size of the checkbox itself 219 t.visPropOld.fontsize = '0px'; 220 board.renderer.updateTextStyle(t, false); 221 222 t.rendNodeCheckbox.checked = attr.checked; 223 224 t._value = attr.checked; 225 226 /** 227 * Returns the value of the checkbox element 228 * @name Value 229 * @memberOf Checkbox.prototype 230 * @function 231 * @returns {String} value of the checkbox. 232 */ 233 t.Value = function () { 234 return this._value; 235 }; 236 237 /** 238 * @class 239 * @ignore 240 */ 241 t.update = function () { 242 if (this.needsUpdate) { 243 JXG.Text.prototype.update.call(this); 244 this._value = this.rendNodeCheckbox.checked; 245 } 246 return this; 247 }; 248 249 Env.addEvent(t.rendNodeCheckbox, "change", priv.CheckboxChangeEventHandler, t); 250 251 return t; 252 }; 253 254 JXG.registerElement("checkbox", JXG.createCheckbox); 255 256 // export default { 257 // createCheckbox: JXG.createCheckbox 258 // }; 259