1 /* 2 Copyright 2008-2021 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 <http://www.gnu.org/licenses/> 29 and <http://opensource.org/licenses/MIT/>. 30 */ 31 32 33 /*global JXG: true, define: true, window: true*/ 34 /*jslint nomen: true, plusplus: true*/ 35 36 /* depends: 37 jxg 38 utils/env 39 utils/type 40 */ 41 42 /** 43 * @fileoverview In this file the Text element is defined. 44 */ 45 46 define([ 47 'jxg', 'utils/env', 'utils/type' 48 ], function (JXG, Env, Type) { 49 50 "use strict"; 51 52 var priv = { 53 CheckboxChangeEventHandler: function () { 54 this._value = this.rendNodeCheckbox.checked; 55 this.board.update(); 56 } 57 }; 58 59 /** 60 * @class This element is used to provide a constructor for special texts containing a 61 * form checkbox element. 62 * <p> 63 * For this element, the attribute "display" has to have the value 'html' (which is the default). 64 * 65 * @pseudo 66 * @description 67 * @name Checkbox 68 * @augments Text 69 * @constructor 70 * @type JXG.Text 71 * 72 * @param {number,function_number,function_String_String} x,y,label Parent elements for checkbox elements. 73 * <p> 74 * x and y are the coordinates of the lower left corner of the text box. 75 * The position of the text is fixed, 76 * x and y are numbers. The position is variable if x or y are functions. 77 * <p> 78 * The label of the input element may be given as string. 79 * <p> 80 * The value of the checkbox can be controlled with the attribute <tt>checked</tt> 81 * <p>The HTML node can be accessed with <tt>element.rendNodeCheckbox</tt> 82 * 83 * @example 84 * // Create a checkbox element at position [0,3]. 85 * var checkbox = board.create('checkbox', [0, 3, 'Change Y'], {}); 86 * var p = board.create('point', [ 87 * function(){ return 0.5;}, // X-coordinate 88 * function() { 89 * y = 0.5; 90 * if (checkbox.Value()) { 91 * y += 0.5; 92 * } 93 * return y; 94 * }]); 95 * </pre><div class="jxgbox" id="JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c" style="width: 300px; height: 300px;"></div> 96 * <script type="text/javascript"> 97 * (function() { 98 * var t1_board = JXG.JSXGraph.initBoard('JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false}); 99 * var checkbox = t1_board.create('checkbox', [0, 3, 'Change Y'], {}); 100 * var p = t1_board.create('point', [ 101 * function(){ return 0.5;}, // X-coordinate 102 * function() { 103 * y = 0.5; 104 * if (checkbox.Value()) { 105 * y += 0.5; 106 * } 107 * return y; 108 * }]); 109 * })(); 110 * </script><pre> 111 * 112 * The checkbox can be supplied with custom-made events by using the property rendNodeCheckbox. 113 * @example 114 * var checkbox = board.create('checkbox', [0, 4, 'Click me']), 115 * p = board.create('point', [1, 1]); 116 * 117 * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() { 118 * if (this.Value()) { 119 * p.moveTo([4, 1]); 120 * } else { 121 * p.moveTo([1, 1]); 122 * } 123 * }, checkbox); 124 * </pre><div class="jxgbox" id="JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810" style="width: 300px; height: 300px;"></div> 125 * <script type="text/javascript"> 126 * (function() { 127 * var board = JXG.JSXGraph.initBoard('JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false}); 128 * var checkbox = board.create('checkbox', [0, 4, 'Click me']), 129 * p = board.create('point', [1, 1]); 130 * 131 * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() { 132 * if (this.Value()) { 133 * p.moveTo([4, 1]); 134 * } else { 135 * p.moveTo([1, 1]); 136 * } 137 * }, checkbox); 138 * })(); 139 * </script><pre> 140 * 141 * @example 142 * var i1 = board.create('input', [-3, 4, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2}); 143 * var c1 = board.create('checkbox', [-3, 2, 'label 1'], {}); 144 * var b1 = board.create('button', [-3, -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:400px'}); 151 * 152 * </pre><div id="JXG11cac8gg-2354-47e7-9da4-eb298e53de05" class="jxgbox" style="width: 300px; height: 300px;"></div> 153 * <script type="text/javascript"> 154 * (function() { 155 * var board = JXG.JSXGraph.initBoard('JXG11cac8gg-2354-47e7-9da4-eb298e53de05', 156 * {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false}); 157 * var i1 = board.create('input', [-3, 4, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2}); 158 * var c1 = board.create('checkbox', [-3, 2, 'label 1'], {}); 159 * var b1 = board.create('button', [-3, -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:400px'}); 166 * 167 * })(); 168 * 169 * </script><pre> 170 */ 171 JXG.createCheckbox = function (board, parents, attributes) { 172 var t, par, 173 attr = Type.copyAttributes(attributes, board.options, 'checkbox'); 174 175 //if (parents.length !== 3) { 176 //throw new Error("JSXGraph: Can't create checkbox with parent types '" + 177 // (typeof parents[0]) + "' and '" + (typeof parents[1]) + "'." + 178 // "\nPossible parents are: [[x,y], label]"); 179 //} 180 181 par = [parents[0], parents[1], 182 '<span style="display:inline">' + 183 '<input type="checkbox" /><label for=""></label>' + 184 '</span>' 185 ]; 186 187 //t = JXG.createText(board, par, attr); 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 // This sets the font-size of the checkbox itself 203 t.visPropOld.fontsize = "0px"; 204 board.renderer.updateTextStyle(t, false); 205 206 t.rendNodeCheckbox.checked = attr.checked; 207 208 t._value = attr.checked; 209 210 /** 211 * Returns the value of the checkbox element 212 * @name Value 213 * @memberOf Checkbox.prototype 214 * @function 215 * @returns {String} value of the checkbox. 216 */ 217 t.Value = function () { 218 return this._value; 219 }; 220 221 t.update = function () { 222 if (this.needsUpdate) { 223 JXG.Text.prototype.update.call(this); 224 this._value = this.rendNodeCheckbox.checked; 225 } 226 return this; 227 }; 228 229 Env.addEvent(t.rendNodeCheckbox, 'change', priv.CheckboxChangeEventHandler, t); 230 231 return t; 232 }; 233 234 JXG.registerElement('checkbox', JXG.createCheckbox); 235 236 return { 237 createCheckbox: JXG.createCheckbox 238 }; 239 }); 240