Hi Pablo,
the default attribute
element.visProp.display = 'html'
is set in options.js.
If you start to implement e.g. a checkbox element you may have a look at my htmlSlider implementation in text.js:
https://github.com/jsxgraph/jsxgraph/blob/master/src/base/text.js, starting from line 835.
| JXG.createHTMLSlider = function (board, parents, attributes) { |
| var t, par, |
| attr = Type.copyAttributes(attributes, board.options, 'htmlslider'); |
|
| if (parents.length !== 2 || parents[0].length !== 2 || parents[1].length !== 3) { |
| throw new Error("JSXGraph: Can't create htmlslider with parent types '" + |
| (typeof parents[0]) + "' and '" + (typeof parents[1]) + "'." + |
| "\nPossible parents are: [[x,y], [min, start, max]]"); |
| } |
|
| // backwards compatibility |
| attr.anchor = attr.parent || attr.anchor; |
| attr.fixed = attr.fixed || true; |
|
| par = [parents[0][0], parents[0][1], |
| '<form style="display:inline">' + |
| '<input type="range" /><span></span><input type="text" />' + |
| '</form>']; |
|
| t = JXG.createText(board, par, attr); |
| t.type = Type.OBJECT_TYPE_HTMLSLIDER; |
|
| t.rendNodeForm = t.rendNode.childNodes[0]; |
| t.rendNodeForm.id = t.rendNode.id + '_form'; |
|
| t.rendNodeRange = t.rendNodeForm.childNodes[0]; |
| t.rendNodeRange.id = t.rendNode.id + '_range'; |
| t.rendNodeRange.min = parents[1][0]; |
| t.rendNodeRange.max = parents[1][2]; |
| t.rendNodeRange.step = attr.step; |
| t.rendNodeRange.value = parents[1][1]; |
|
| t.rendNodeLabel = t.rendNodeForm.childNodes[1]; |
| t.rendNodeLabel.id = t.rendNode.id + '_label'; |
|
| if (attr.withlabel) { |
| t.rendNodeLabel.innerHTML = t.name + '='; |
| } |
|
| t.rendNodeOut = t.rendNodeForm.childNodes[2]; |
| t.rendNodeOut.id = t.rendNode.id + '_out'; |
| t.rendNodeOut.value = parents[1][1]; |
|
| t.rendNodeRange.style.width = attr.widthrange + 'px'; |
| t.rendNodeRange.style.verticalAlign = 'middle'; |
| t.rendNodeOut.style.width = attr.widthout + 'px'; |
|
| t._val = parents[1][1]; |
|
| if (JXG.supportsVML()) { |
| /* |
| * OnChange event is used for IE browsers |
| * The range element is supported since IE10 |
| */ |
| Env.addEvent(t.rendNodeForm, 'change', priv.HTMLSliderInputEventHandler, t); |
| } else { |
| /* |
| * OnInput event is used for non-IE browsers |
| */ |
| Env.addEvent(t.rendNodeForm, 'input', priv.HTMLSliderInputEventHandler, t); |
| } |
|
| t.Value = function () { |
| return this._val; |
| }; |
|
| return t; |
};
JXG.registerElement('htmlslider', JXG.createHTMLSlider);
|
|
Important is that you follow the convention in naming the method:
JXG.createCheckbox(board, parents, attribute) { ... ]
and then call
JXG.registerElement('checkbox', JXG.createCheckbox);
If you do this, you can call
attr = Type.copyAttributes(attributes, board.options, 'checkbox');
and therefore get for free the default options which should be (and can be) defined in options.js.
display=='html' means the text is contained in a sperated div-element which is displayed above the JSXGraph canvas.
The only drawback is that if the construction is exported into a png image the text-divs are missing.
For display=='internal' the internal text elements of SVG, canvas and VML are used. Since all these methods are different it is a little bit of a mess to support them all.
You should only allow display==='html'. I'm not aware that SVG text elements and canvas text elements support interactive form elements.
Next, you should provide a method Value() returning true/false in the case of checkboxes.
If you provide the Value method for an element it can be used in every parent or attribute which supports dynamic input:
var check = board.create('checkbox', [3, 5, "Add 5"]) // coordinates and label text are parent elements
var f = board.create('point', [function(){ return 1;}, // X-coordinate
function() {
y = 2;
if (check.Value()) {
y += 5;
}
return y;
}]);
One important point is, you should add an update method for the checkbox element which saves the value in a JavaScript variable.
t.update = function() {
this._value = this.rendNode.value; // rendNode is a pointer to the DOM element, created in JXG.Text
};
Then, in the call of Value() you just refer to this variable:
t.Value = function() {
return this._value;
Otherwise there would way too many DOM accesses which would slow down everything.
Further, I would recommend to keep the new elements in a separate file.
Hoe that helps a little bit...
Best wishes and many thanks,
Alfred