source: Dev/branches/rest-dojo-ui/client/dojox/calc/Standard.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 11.9 KB
Line 
1define([
2        "dojo/_base/declare",
3        "dojo/_base/lang",
4        "dojo/_base/sniff",
5        "dojo/_base/window",
6        "dojo/_base/event",
7        "dojo/dom-style",
8        "dojo/ready",
9        "dojo/keys",
10        "dijit/registry",
11        "dijit/typematic",
12        "dijit/_WidgetBase",
13        "dijit/_WidgetsInTemplateMixin",
14        "dijit/_TemplatedMixin",
15        "dijit/form/_TextBoxMixin",
16        "dojox/math/_base",
17        "dijit/TooltipDialog",
18        "dojo/text!./templates/Standard.html",
19        "dojox/calc/_Executor", // template
20        "dijit/Menu", // template
21        "dijit/MenuItem", // template
22        "dijit/form/ComboButton", // template
23        "dijit/form/Button", // template
24        "dijit/form/TextBox" // template
25], function(declare, lang, has, win, event, domStyle, ready, keys, registry, typematic, WidgetBase, WidgetsInTemplateMixin, TemplatedMixin, _TextBoxMixin, math, TooltipDialog, template, calc){
26
27        /*=====
28                WidgetBase = dijit._WidgetBase;
29                WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
30                TemplatedMixin = dijit._TemplatedMixin;
31        =====*/
32        return declare(
33                "dojox.calc.Standard",
34                [WidgetBase, TemplatedMixin, WidgetsInTemplateMixin],
35        {
36                // summary:
37                //              The dialog layout for a standard 4 function/algebraic calculator
38                //
39                templateString: template,
40
41                readStore:null,
42                writeStore:null,
43                functions: [],
44
45                executorLoaded: function(){
46                        // summary
47                        //      load in the stores after executor is loaded (the stores need executor to be loaded because it parses them)
48                        ready(lang.hitch(this, function(){
49                                this.loadStore(this.readStore, true);
50                                this.loadStore(this.writeStore);
51                        }));
52                },
53
54                saveFunction: function(name, args, body){
55                        // summary
56                        //      make the function with executor
57                        this.functions[name] = this.executor.normalizedFunction(name, args, body);
58                        this.functions[name].args = args;
59                        this.functions[name].body = body;
60                },
61
62                loadStore: function(store, isReadOnly){
63                        // summary
64                        //      load an entire store, and make it publicly editable/viewable based on isReadOnly
65                        if(!store){
66                                return;
67                        }
68                        store.query({}).forEach(lang.hitch(this, function(item){
69                                lang.hitch(this, isReadOnly ? this.executor.normalizedFunction : this.saveFunction)(item.name, item.args, item.body);
70                        }));
71                },
72
73                parseTextbox: function(){
74                        // summary
75                        //      parse the contents of the textboxWidget and display the answer somewhere (depending on the layout)
76                        var text = this.textboxWidget.textbox.value;
77                        if(text == "" && this.commandList.length > 0){
78                                this.setTextboxValue(this.textboxWidget, this.commandList[this.commandList.length-1]);
79                                text = this.textboxWidget.textbox.value;
80                        }
81                        if(text!=""){
82                                var ans = this.executor.eval(text);
83
84                                if((typeof ans == "number" && isNaN(ans))){
85                                        if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
86                                                this.commandList.push(text);
87                                        }
88                                        this.print(text, false);
89                                        this.print("Not a Number", true);
90                                }else if(((typeof ans == "object" && "length" in ans) || typeof ans != "object") && typeof ans != "function" && ans != null){
91                                        this.executor.eval("Ans="+ans);
92                                        // add it to the command list as well
93                                        if(this.commandList.length == 0 || this.commandList[this.commandList.length - 1] != text){
94                                                this.commandList.push(text);
95                                        }
96                                        this.print(text, false);
97                                        this.print(ans, true);
98                                }
99                                this.commandIndex = this.commandList.length-1;
100                                //this.displayBox.textbox.scrollTop=this.displayBox.textbox.scrollHeight;
101                                if(this.hasDisplay){
102                                        this.displayBox.scrollTop=this.displayBox.scrollHeight;
103                                }
104                                //this.clearText();
105                                //this.textboxWidget.focus();
106                                _TextBoxMixin.selectInputText(this.textboxWidget.textbox);
107
108                        }else{
109                                this.textboxWidget.focus();
110                        }
111                },
112                cycleCommands: function(count, node, event){
113                        // summary
114                        //      cycle through the commands that the user has entered
115                        //      it does not wrap around
116                        if(count == -1 || this.commandList.length==0){
117                                return;
118                        }
119                        var keyNum = event.charOrCode;
120                        //up arrow
121                        if(keyNum == keys.UP_ARROW){
122                                this.cycleCommandUp();
123                        }else if(keyNum == keys.DOWN_ARROW){
124                                this.cycleCommandDown();
125                        }
126                },
127                cycleCommandUp: function(){
128                        // summary
129                        //      cycle up through the list of commands the user has entered already
130                        if(this.commandIndex-1<0){
131                                this.commandIndex=0;
132                        }else{
133                                this.commandIndex--;
134                        }
135                        this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
136                },
137                cycleCommandDown: function(){
138                        // summary
139                        //      cycle down through the list of commands the user has entered already
140                        if(this.commandIndex+1>=this.commandList.length){
141                                this.commandIndex=this.commandList.length;
142                                this.setTextboxValue(this.textboxWidget, "");
143                        }else{
144                                this.commandIndex++;
145                                this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
146                        }
147
148                },
149                onBlur: function(){
150                        // summary
151                        //      IE is lacking in function when it comes to the text boxes, so here, make it work like other browsers do by forcing a node.selectionStart and End onto it
152                        if(has('ie')){
153                                var tr = win.doc.selection.createRange().duplicate();
154                                var selectedText = tr.text || '';
155                                var ntr = this.textboxWidget.textbox.createTextRange();
156                                tr.move("character",0);
157                                ntr.move("character",0);
158                                try{
159                                        ntr.setEndPoint("EndToEnd", tr);
160                                        this.textboxWidget.textbox.selectionEnd = (this.textboxWidget.textbox.selectionStart = String(ntr.text).replace(/\r/g,"").length) + selectedText.length;
161
162                                }catch(e){}
163                        }
164                },
165                onKeyPress: function(e){
166                        // summary
167                        // handle key input for Enter and operators
168                        if(e.charOrCode == keys.ENTER){
169                                this.parseTextbox();
170                                // stop form submissions
171                                event.stop(e);
172                        }else if(e.charOrCode == '!' || e.charOrCode == '^' || e.charOrCode == '*' || e.charOrCode == '/' || e.charOrCode == '-' || e.charOrCode == '+'){
173                                if(has('ie')){
174                                        var tr = win.doc.selection.createRange().duplicate();
175                                        var selectedText = tr.text || '';
176                                        var ntr = this.textboxWidget.textbox.createTextRange();
177                                        tr.move("character",0);
178                                        ntr.move("character",0);
179                                        try{
180                                                ntr.setEndPoint("EndToEnd", tr);
181                                                this.textboxWidget.textbox.selectionEnd = (this.textboxWidget.textbox.selectionStart = String(ntr.text).replace(/\r/g,"").length) + selectedText.length;
182
183                                        }catch(e){}
184                                }
185
186                                if(this.textboxWidget.get("value")==""){
187                                        this.setTextboxValue(this.textboxWidget, "Ans");
188                                }else if(this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox, event.charOrCode)){
189                                        this.setTextboxValue(this.textboxWidget, "Ans");//this.insertText("Ans");
190                                        // move the cursor to the end of "Ans"
191                                        _TextBoxMixin.selectInputText(this.textboxWidget.textbox, this.textboxWidget.textbox.value.length, this.textboxWidget.textbox.value.length);
192                                }
193                        }
194                },
195                insertMinus: function(){
196                        // summary
197                        //      insert a minus sign when they press (-) in the combo button
198                        this.insertText('-');
199                },
200                print: function(text, isRight){
201                        // summary
202                        //      print the answer (typically) to the display or the input box
203                        var t = "<span style='display:block;";
204                        if(isRight){
205                                t += "text-align:right;'>";
206                        }else{
207                                t += "text-align:left;'>";
208                        }
209                        t += text+"<br></span>";
210                        if(this.hasDisplay){
211                                this.displayBox.innerHTML += t;
212                        }else{// if there is not a display box, put the answer in the input box
213                                this.setTextboxValue(this.textboxWidget, text);
214                        }
215                        //this.setTextboxValue(this.displayBox, this.displayBox.get('value')+'\n'+text);
216                },
217                setTextboxValue: function(widget, val){
218                        // summary
219                        //      set a widget's value
220                        widget.set('value', val);
221                },
222                putInAnsIfTextboxIsHighlighted: function(node){
223                        // summary
224                        //      try seeing if the textbox is highlighted completely so you know if Ans should be put in for an operator like +
225                        //console.log("Entered "+node.selectionStart + " "+ node.selectionEnd);
226                        if(typeof node.selectionStart == "number"){ // not-IE
227                                if(node.selectionStart==0 && node.selectionEnd == node.value.length){
228                                        //node.value = "Ans";
229                                        //dijit.selectInputText(node, node.value.length, node.value.length);
230                                        return true;
231                                }
232                        }else if(document.selection){ // IE
233                                //console.log("Entered 2");
234                                var range = document.selection.createRange();
235                                //console.log("Range: "+range.text +" Node: "+node.value);
236                                if(node.value == range.text){
237                                        //this.insertText("Ans");
238                                        return true;
239                                }
240                        }
241                        return false;
242                },
243                clearText: function(){
244                        // summary
245                        //      this clears the input box if it has content, but if it does not it clears the display
246                        if(this.hasDisplay && this.textboxWidget.get('value')==""){
247                                this.displayBox.innerHTML = "";//this.setTextboxValue(this.displayBox, "");
248                        }else{
249                                this.setTextboxValue(this.textboxWidget, "");
250                        }
251                        this.textboxWidget.focus();
252                },
253                /*insertMinusSign: function(){
254                        //
255                        var v = this.subtract.get('label');
256                        if(v != '(-)' && this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
257                                this.insertText("Ans-");
258                                return;
259                        }
260                        this.insertText('-');
261                },*/
262                insertOperator: function(newText){
263                        // summary
264                        //      insert an operator with a button
265                        if(typeof newText == "object"){
266                                newText = newText = registry.getEnclosingWidget(newText["target"]).value;
267                        }
268                        if(this.textboxWidget.get("value") == "" || this.putInAnsIfTextboxIsHighlighted(this.textboxWidget.textbox)){
269                                newText = "Ans"+newText;
270                        }
271                        this.insertText(newText);
272                },
273                insertText: function(newText){//(node, newText){
274                        // summary
275                        //      insert text to the textboxWidget node
276                        setTimeout(lang.hitch(this, function(){
277
278                        var node = this.textboxWidget.textbox;
279                        if(node.value==""){
280                                node.selectionStart = 0;
281                                node.selectionEnd = 0;
282                        }
283                        if(typeof newText == "object"){
284                                newText = newText = registry.getEnclosingWidget(newText["target"]).value;
285                        }
286
287                        var value = node.value.replace(/\r/g,'');
288                        if(typeof node.selectionStart == "number"){ // not-IE
289                                var pos = node.selectionStart;
290                                var cr = 0;
291                                if(has('opera')){
292                                        cr = (node.value.substring(0,pos).match(/\r/g) || []).length;
293                                }
294                                node.value = value.substring(0, node.selectionStart-cr) + newText + value.substring(node.selectionEnd-cr);
295                                node.focus();
296                                pos += newText.length;
297                                //node.setSelectionRange(pos, pos);
298                                _TextBoxMixin.selectInputText(this.textboxWidget.textbox, pos, pos);
299                        }else if(document.selection){ // IE
300                                if(this.handle){
301                                        clearTimeout(this.handle);
302                                        this.handle = null;
303                                }
304                                node.focus();
305                                this.handle = setTimeout(function(){
306                                        var range = document.selection.createRange();
307                                        range.text = newText;
308                                        // show cursor
309                                        range.select();
310                                        this.handle = null;
311                                }, 0);
312
313                        }
314                        }), 0);
315                },
316                hasDisplay: false,
317                postCreate: function(){
318                        // summary
319                        //      run startup, see if there is an upper display box, etc
320                        this.handle = null;
321                        this.commandList = [];
322                        this.commandIndex = 0;
323
324                        if(this.displayBox){
325                                this.hasDisplay = true;
326                        }
327                        if(this.toFracButton && !calc.toFrac){
328                                domStyle.set(this.toFracButton.domNode, { visibility: "hidden" });
329                        }
330                        if(this.functionMakerButton && !calc.FuncGen){
331                                domStyle.set(this.functionMakerButton.domNode, { visibility: "hidden" });
332                        }
333                        if(this.grapherMakerButton && !calc.Grapher){
334                                domStyle.set(this.grapherMakerButton.domNode, { visibility: "hidden" });
335                        }
336                        this._connects.push(typematic.addKeyListener(this.textboxWidget.textbox,
337                                        {
338                                                charOrCode:keys.UP_ARROW,
339                                                shiftKey:false,
340                                                metaKey:false,
341                                                ctrlKey:false // ALT is optional since its unspecified
342                                        },
343                                        this, this.cycleCommands, 200, 200));
344                        this._connects.push(typematic.addKeyListener(this.textboxWidget.textbox,
345                                        {
346                                                charOrCode:keys.DOWN_ARROW,
347                                                shiftKey:false,
348                                                metaKey:false,
349                                                ctrlKey:false // ALT is optional since its unspecified
350                                        },
351                                        this, this.cycleCommands, 200, 200));
352
353
354                        //onClick="this.insertText(document.getElementById('textbox'), '\u221A')"
355                        //this.sqrt.set("onClick", lang.hitch(this, "insertText", this.textboxWidget, '\u221A'));
356                        //this.pi.set("onClick", lang.hitch(this, "insertText", this.textboxWidget, '\u03C0'));
357                        this.startup()
358                }
359        });
360
361});
Note: See TracBrowser for help on using the repository browser.