1 /* 2 Copyright 2008-2024 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 Type from "../utils/type.js"; 42 43 var priv = { 44 /** 45 * @class 46 * @ignore 47 */ 48 CheckboxChangeEventHandler: function () { 49 this._value = this.rendNodeCheckbox.checked; 50 this.board.update(); 51 } 52 }; 53 54 /** 55 * @class This element is used to provide a constructor for special texts containing a 56 * form checkbox element. 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 attr = Type.copyAttributes(attributes, board.options, "checkbox"); 176 177 //if (parents.length !== 3) { 178 //throw new Error("JSXGraph: Can't create checkbox with parent types '" + 179 // (typeof parents[0]) + "' and '" + (typeof parents[1]) + "'." + 180 // "\nPossible parents are: [[x,y], label]"); 181 //} 182 183 par = [ 184 parents[0], 185 parents[1], 186 '<span style="display:inline">' + 187 '<input type="checkbox" /><label for=""></label>' + 188 "</span>" 189 ]; 190 191 // 1. Create checkbox element with empty label 192 t = board.create("text", par, attr); 193 t.type = Type.OBJECT_TYPE_CHECKBOX; 194 195 t.rendNodeCheckbox = t.rendNode.childNodes[0].childNodes[0]; 196 t.rendNodeLabel = t.rendNode.childNodes[0].childNodes[1]; 197 198 t.rendNodeTag = t.rendNodeCheckbox; // Needed for unified treatment in setAttribute 199 t.rendNodeTag.disabled = !!attr.disabled; 200 201 // t.rendNodeLabel.innerHTML = parents[2]; 202 t.rendNodeCheckbox.id = t.rendNode.id + "_checkbox"; 203 t.rendNodeLabel.id = t.rendNode.id + "_label"; 204 t.rendNodeLabel.setAttribute("for", t.rendNodeCheckbox.id); 205 206 // 2. Set parents[2] (string|function) as label of the checkbox element. 207 // abstract.js selects the correct DOM element for the update 208 t.setText(parents[2]); 209 210 // This sets the font-size of the checkbox itself 211 t.visPropOld.fontsize = "0px"; 212 board.renderer.updateTextStyle(t, false); 213 214 t.rendNodeCheckbox.checked = attr.checked; 215 216 t._value = attr.checked; 217 218 /** 219 * Returns the value of the checkbox element 220 * @name Value 221 * @memberOf Checkbox.prototype 222 * @function 223 * @returns {String} value of the checkbox. 224 */ 225 t.Value = function () { 226 return this._value; 227 }; 228 229 /** 230 * @class 231 * @ignore 232 */ 233 t.update = function () { 234 if (this.needsUpdate) { 235 JXG.Text.prototype.update.call(this); 236 this._value = this.rendNodeCheckbox.checked; 237 } 238 return this; 239 }; 240 241 Env.addEvent(t.rendNodeCheckbox, "change", priv.CheckboxChangeEventHandler, t); 242 243 return t; 244 }; 245 246 JXG.registerElement("checkbox", JXG.createCheckbox); 247 248 // export default { 249 // createCheckbox: JXG.createCheckbox 250 // }; 251