1 /* 2 Copyright 2008-2023 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"; 40 import Env from "../utils/env"; 41 import Type from "../utils/type"; 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 * <p> 58 * For this element, the attribute "display" has to have the value 'html' (which is the default). 59 * <p> 60 * The underlying HTML checkbox element can be accessed through the sub-object 'rendNodeCheck', e.g. to 61 * add event listeners. 62 * 63 * @pseudo 64 * @name Checkbox 65 * @augments Text 66 * @constructor 67 * @type JXG.Text 68 * 69 * @param {number,function_number,function_String,function} x,y,label Parent elements for checkbox elements. 70 * <p> 71 * x and y are the coordinates of the lower left corner of the text box. 72 * The position of the text is fixed, 73 * x and y are numbers. The position is variable if x or y are functions. 74 * <p> 75 * The label of the input element may be given as string or function. 76 * <p> 77 * The value of the checkbox can be controlled with the attribute <tt>checked</tt> 78 * <p>The HTML node can be accessed with <tt>element.rendNodeCheckbox</tt> 79 * 80 * @example 81 * // Create a checkbox element at position [0,3]. 82 * var checkbox = board.create('checkbox', [0, 3, 'Change Y'], {}); 83 * var p = board.create('point', [ 84 * function(){ return 0.5;}, // X-coordinate 85 * function() { 86 * y = 0.5; 87 * if (checkbox.Value()) { 88 * y += 0.5; 89 * } 90 * return y; 91 * }]); 92 * </pre><div class="jxgbox" id="JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c" style="width: 300px; height: 300px;"></div> 93 * <script type="text/javascript"> 94 * (function() { 95 * var t1_board = JXG.JSXGraph.initBoard('JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false}); 96 * var checkbox = t1_board.create('checkbox', [0, 3, 'Change Y'], {}); 97 * var p = t1_board.create('point', [ 98 * function(){ return 0.5;}, // X-coordinate 99 * function() { 100 * y = 0.5; 101 * if (checkbox.Value()) { 102 * y += 0.5; 103 * } 104 * return y; 105 * }]); 106 * })(); 107 * </script><pre> 108 * 109 * The checkbox can be supplied with custom-made events by using the property rendNodeCheckbox. 110 * @example 111 * var checkbox = board.create('checkbox', [0, 4, 'Click me']), 112 * p = board.create('point', [1, 1]); 113 * 114 * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() { 115 * if (this.Value()) { 116 * p.moveTo([4, 1]); 117 * } else { 118 * p.moveTo([1, 1]); 119 * } 120 * }, checkbox); 121 * </pre><div class="jxgbox" id="JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810" style="width: 300px; height: 300px;"></div> 122 * <script type="text/javascript"> 123 * (function() { 124 * var board = JXG.JSXGraph.initBoard('JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false}); 125 * var checkbox = board.create('checkbox', [0, 4, 'Click me']), 126 * p = board.create('point', [1, 1]); 127 * 128 * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() { 129 * if (this.Value()) { 130 * p.moveTo([4, 1]); 131 * } else { 132 * p.moveTo([1, 1]); 133 * } 134 * }, checkbox); 135 * })(); 136 * </script><pre> 137 * @example 138 * var i1 = board.create('input', [1, 5, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2}); 139 * var c1 = board.create('checkbox', [1, 3, 'label 1'], {}); 140 * var b1 = board.create('button', [1, 1, 'Change texts', function () { 141 * i1.setText('g(x)='); 142 * i1.set('cos(x)'); 143 * c1.setText('label 2'); 144 * b1.setText('Texts are changed'); 145 * }], 146 * {cssStyle: 'width:200px'}); 147 * 148 * </pre><div id="JXG31c6d070-354b-4f09-aab9-9aaa796f730c" class="jxgbox" style="width: 300px; height: 300px;"></div> 149 * <script type="text/javascript"> 150 * (function() { 151 * var board = JXG.JSXGraph.initBoard('JXG31c6d070-354b-4f09-aab9-9aaa796f730c', 152 * {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}); 153 * var i1 = board.create('input', [1, 5, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2}); 154 * var c1 = board.create('checkbox', [1, 3, 'label 1'], {}); 155 * var b1 = board.create('button', [1, 1, 'Change texts', function () { 156 * i1.setText('g(x)='); 157 * i1.set('cos(x)'); 158 * c1.setText('label 2'); 159 * b1.setText('Texts are changed'); 160 * }], 161 * {cssStyle: 'width:200px'}); 162 * 163 * })(); 164 * 165 * </script><pre> 166 * 167 */ 168 JXG.createCheckbox = function (board, parents, attributes) { 169 var t, 170 par, 171 attr = Type.copyAttributes(attributes, board.options, "checkbox"); 172 173 //if (parents.length !== 3) { 174 //throw new Error("JSXGraph: Can't create checkbox with parent types '" + 175 // (typeof parents[0]) + "' and '" + (typeof parents[1]) + "'." + 176 // "\nPossible parents are: [[x,y], label]"); 177 //} 178 179 par = [ 180 parents[0], 181 parents[1], 182 '<span style="display:inline">' + 183 '<input type="checkbox" /><label for=""></label>' + 184 "</span>" 185 ]; 186 187 // 1. Create checkbox element with empty label 188 t = board.create("text", par, attr); 189 t.type = Type.OBJECT_TYPE_CHECKBOX; 190 191 t.rendNodeCheckbox = t.rendNode.childNodes[0].childNodes[0]; 192 t.rendNodeLabel = t.rendNode.childNodes[0].childNodes[1]; 193 194 t.rendNodeTag = t.rendNodeCheckbox; // Needed for unified treatment in setAttribute 195 t.rendNodeTag.disabled = !!attr.disabled; 196 197 // t.rendNodeLabel.innerHTML = parents[2]; 198 t.rendNodeCheckbox.id = t.rendNode.id + "_checkbox"; 199 t.rendNodeLabel.id = t.rendNode.id + "_label"; 200 t.rendNodeLabel.setAttribute("for", t.rendNodeCheckbox.id); 201 202 // 2. Set parents[2] (string|function) as label of the checkbox element. 203 // abstract.js selects the correct DOM element for the update 204 t.setText(parents[2]); 205 206 // This sets the font-size of the checkbox itself 207 t.visPropOld.fontsize = "0px"; 208 board.renderer.updateTextStyle(t, false); 209 210 t.rendNodeCheckbox.checked = attr.checked; 211 212 t._value = attr.checked; 213 214 /** 215 * Returns the value of the checkbox element 216 * @name Value 217 * @memberOf Checkbox.prototype 218 * @function 219 * @returns {String} value of the checkbox. 220 */ 221 t.Value = function () { 222 return this._value; 223 }; 224 225 /** 226 * @class 227 * @ignore 228 */ 229 t.update = function () { 230 if (this.needsUpdate) { 231 JXG.Text.prototype.update.call(this); 232 this._value = this.rendNodeCheckbox.checked; 233 } 234 return this; 235 }; 236 237 Env.addEvent(t.rendNodeCheckbox, "change", priv.CheckboxChangeEventHandler, t); 238 239 return t; 240 }; 241 242 JXG.registerElement("checkbox", JXG.createCheckbox); 243 244 // export default { 245 // createCheckbox: JXG.createCheckbox 246 // }; 247