PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/js/calculator.js

https://gitlab.com/vince.omega/pos
JavaScript | 244 lines | 163 code | 33 blank | 48 comment | 12 complexity | 7401df965978f27d82294ae39b03c571 MD5 | raw file
  1. /*--------------------------------------------------
  2. // JCalculator - A Calculator Plugin for jQuery //
  3. // //
  4. // Author: Hitesh Agarwal //
  5. // Version: 1.0 //
  6. // Date: 14-feb 11 //
  7. // License: GNU General Public License v2.0 //
  8. // //
  9. --------------------------------------------------*/
  10. /*
  11. 1. Must include jquery and jquery-ui[js and css] before the script
  12. 2. Must include calculator.css
  13. usage:
  14. html: <div id="calculator1"></div>
  15. js: later
  16. */
  17. // @param params = later
  18. (function($) {
  19. $.fn.calculator = function(params){
  20. var settings = jQuery.extend({},$.fn.calculator.defaults, params);
  21. //iterate over every matched element
  22. return this.each(function(){
  23. var calc = $(this);
  24. if(!calc.hasClass('converted2calc')){
  25. calc.settings = $.meta ? $.extend({}, settings, calc.data()) : settings;
  26. $.fn.calculator.init(calc);
  27. // add class to chack later if calculator is ready to use
  28. calc.addClass('converted2calc');
  29. }
  30. });
  31. }
  32. $.fn.calculator.init = function(calc){
  33. calc.expression = '';
  34. calc.text = '0';
  35. calc._cleartextflag = false;
  36. calc._executable = true;
  37. calc._lastresult = null;
  38. //format calculator
  39. $.fn.calculator.format(calc).find('.calc-title-bar').text(calc.settings.title);
  40. /* Append Buttons
  41. ------------------*/
  42. for(i in $.fn.calculator.buttons){
  43. $.fn.calculator.format.addButton(calc, $.fn.calculator.buttons[i]);
  44. }
  45. calc.keydown(function(event){
  46. event.preventDefault();
  47. if($.fn.calculator.buttons[event.keyCode]){
  48. $.fn.calculator.buttons[event.keyCode].onPress(calc); // calling button's onPress event specified in button itself
  49. $.fn.calculator.action.updateDisplay(calc); // updating calculator's display as calculator text or expression may have changed during button's onpress event
  50. calc.settings.buttonPressed(); // firing event buttonPressed to execute custom code passed in calculator params
  51. }
  52. })
  53. // hide it if defaultOpen is false
  54. calc.settings.defaultOpen?'':calc.css({display:'none'});
  55. // make it draggable if movable is true
  56. (calc.settings.movable&&$.fn.draggable)?(calc.draggable({handle:'.calc-title-bar-container'}).find('.calc-title-bar-container').css('cursor','move')):'';
  57. // make it closable if movable is true
  58. calc.settings.movable?( $('<div class="calc-title-bar-button-close"></div>').button({icons: {primary: "ui-icon-close"}, text: false}).appendTo(calc.find('.calc-title-bar-container')).css({position:'absolute',right:2,top:2,width:15,height:14}).click(function(){calc.settings.hide(calc)}) ):'';
  59. // make it resizable if resizable is true
  60. (calc.settings.resizable&&$.fn.resizable)?calc.resizable({handles:'se'}).css({minHeight:160, minWidth:130}):'';
  61. $.fn.calculator.action.updateDisplay(calc);
  62. }
  63. $.fn.calculator.hide = function(calc) {
  64. calc.hide();
  65. };
  66. $.fn.calculator.show = function(calc) {
  67. calc.show();
  68. };
  69. // define our format function
  70. $.fn.calculator.format = function(calc) {
  71. return calc.addClass('calculator calc-wrapper ui-widget ui-corner-all ui-widget-content').html('<div class="calc-title-bar-container ui-widget-header" style="height:20px;left:0;position:absolute;right:0;top:0;"><div class="calc-title-bar" style="padding:2px 3px;"></div></div><div class="calc-container" style="position:absolute;left:4px;right:4px;top:22px;bottom:8px"><div class="calc-text-wrapper" style="height:20%;left:3px;position:absolute;right:0;top:3%;"><label class="calc-text" style="background:#fff;border:1px solid #CCC;bottom:0;left:4%;overflow:hidden;padding:20px;position:absolute;right:4%;top:0;text-align:right;vertical-align:middle;"></label></div><div class="calc-buttons-wrapper" style="bottom:4px;left:2px;position:absolute;right:2px;top:23%;"></div></div>').attr('tabindex',0).css({width:calc.settings.width, height:calc.settings.height, outline:'none', position:'relative', zIndex:99999}).focusin(function(){calc.find('.calc-text').css({backgroundColor:'#FFFFF2'})}).focusout(function(){calc.find('.calc-text').css({backgroundColor:''})});
  72. };
  73. $.fn.calculator.format.createButton = function(button){
  74. var style = (button.left)?'left:'+button.left+';':'';
  75. style += (button.top)?'top:'+button.top+';':'';
  76. style += (button.width)?'width:'+button.width+';':'';
  77. style += (button.height)?'height:'+button.height+';':'';
  78. return $('<div class="calc-button-wrapper" style="position:absolute;'+style+'"><div class="calc-button" style="left:0;right:0;bottom:0;position:absolute;text-align:center;text-decoration:none;top:0;">'+button.symbol+'</div></div>');
  79. }
  80. // function to add button
  81. $.fn.calculator.format.addButton = function(calc,button){
  82. $.fn.calculator.format.createButton(button).button().appendTo(calc.find('.calc-buttons-wrapper')).click(function(){
  83. button.onPress(calc); // calling button's onPress event specified in button itself
  84. $.fn.calculator.action.updateDisplay(calc); // updating calculator's display as calculator text or expression may have changed during button's onpress event
  85. calc.settings.buttonPressed(); // firing event buttonPressed to execute custom code passed in calculator params
  86. });
  87. }
  88. // calculator actions
  89. $.fn.calculator.action = {
  90. updateDisplay: function(calc){
  91. calc.find('.calc-text').text(calc.text);
  92. calc.settings.displayChanged(); // firing event displayChanged to execute custom code passed in calculator params
  93. },
  94. input: function(calc, button){
  95. if(calc._executable){
  96. if(calc.text.length < calc.settings.accuracy||calc._cleartextflag){
  97. var input = (calc.text=='0'||calc._cleartextflag)?((button.symbol=='.')?'0.':(button.symbol=='0')?'':button.symbol):calc.text+button.symbol;
  98. if($.fn.calculator.validate.input(input)){
  99. calc.text = input;
  100. calc.expression = calc.expression+((input=='0.')?input:button.symbol);
  101. calc._cleartextflag = false;
  102. }
  103. }
  104. calc._lastresult = null;
  105. }
  106. else{
  107. if($.fn.calculator.validate.expression(calc.expression)){
  108. calc.text = eval(calc.expression);
  109. calc._lastresult = calc.text + '';
  110. calc.text = (calc.text.toPrecision(calc.settings.accuracy).indexOf('e') == -1)?parseFloat( calc.text.toPrecision(calc.settings.accuracy)) + '':calc.text.toPrecision(calc.settings.accuracy);
  111. //calc.expression = calc.text;
  112. calc.expression = '';
  113. calc._executable = false;
  114. calc._cleartextflag = true; // clear display on next user input
  115. }
  116. if(calc._lastresult){
  117. calc.expression = calc._lastresult;
  118. calc._lastresult = null;
  119. }
  120. calc._cleartextflag = true; // clear display on next user input
  121. calc.expression = (calc.expression=='')?button.symbol:($.fn.calculator.validate.operation(calc.expression)?calc.expression.replace(/[-+/\*]$/,button.symbol):calc.expression+button.symbol);
  122. }
  123. }
  124. }
  125. $.fn.calculator.buttons = {
  126. /* index:{
  127. symbol:<button's symbol to show on calc>,
  128. onpress: <event to execute on button pressed [event param calc | the calculator itself]>,
  129. left:<button's left position in percentage inside calc buttons container>,
  130. top:<button's top position in percentage inside calc buttons container>,
  131. width:<button's width in percentage inside calc buttons container [optional | handle inside css either]>,
  132. height:<button's height in percentage inside calc buttons container [optional | handle inside css either]>,
  133. }
  134. */
  135. 96:{symbol:'0', keycode: 48, left:'4%', top:'80%', width:'44%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  136. 97:{symbol:'1', keycode: 49, left:'4%', top:'61%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  137. 98:{symbol:'2', keycode: 50, left:'28%', top:'61%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  138. 99:{symbol:'3', keycode: 51, left:'52%', top:'61%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  139. 100:{symbol:'4', keycode: 52, left:'4%', top:'42%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  140. 101:{symbol:'5', keycode: 53, left:'28%', top:'42%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  141. 102:{symbol:'6', keycode: 54, left:'52%', top:'42%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  142. 103:{symbol:'7', keycode: 55, left:'4%', top:'23%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  143. 104:{symbol:'8', keycode: 56, left:'28%', top:'23%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  144. 105:{symbol:'9', keycode: 57, left:'52%', top:'23%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  145. 110:{symbol:'.', keycode: 110, left:'52%', top:'80%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;$.fn.calculator.action.input(calc, this);} },
  146. 111:{symbol:'/', keycode: 111, left:'4%', top:'4%', width:'20%', height:'15%', onPress:function(calc){calc._executable = false;$.fn.calculator.action.input(calc, this);} },
  147. 106:{symbol:'*', keycode: 106, left:'28%', top:'4%', width:'20%', height:'15%', onPress:function(calc){calc._executable = false;$.fn.calculator.action.input(calc, this);} },
  148. 107:{symbol:'+', keycode: 107, left:'76%', top:'23%', width:'20%',height:'34%', onPress:function(calc){calc._executable = false;$.fn.calculator.action.input(calc, this);} },
  149. 109:{symbol:'-', keycode: 109, left:'52%', top:'4%', width:'20%', height:'15%', onPress:function(calc){calc._executable = false;$.fn.calculator.action.input(calc, this);} },
  150. 13:{symbol:'=', keycode: 13, left:'76%', top:'61%', width:'20%', height:'34%', onPress:function(calc){
  151. if($.fn.calculator.validate.expression(calc.expression)){
  152. calc.text = eval(calc.expression);
  153. calc._lastresult = calc.text + '';
  154. calc.text = (calc.text.toPrecision(calc.settings.accuracy).indexOf('e') == -1)?parseFloat( calc.text.toPrecision(calc.settings.accuracy)) + '':calc.text.toPrecision(calc.settings.accuracy);
  155. //calc.expression = calc.text;
  156. calc.expression = '';
  157. calc._executable = false;
  158. calc._cleartextflag = true; // clear display on next user input
  159. }
  160. else{
  161. calc.expression = calc.text;
  162. }
  163. }
  164. },
  165. 27:{symbol:'C', keycode: 27, left:'76%', top:'4%', width:'20%', height:'15%', onPress:function(calc){calc._executable = true;calc.expression = '';calc.text='0';}}
  166. }
  167. $.fn.calculator.validate = {
  168. input: function(text){
  169. return text.match(/^((0|(0\.[0-9]*))|([1-9][0-9]*|([1-9][0-9]*\.[0-9]*)|([1-9][0-9]*\.[0-9]*)|([1-9][0-9]*)))$/);
  170. },
  171. expression: function(expr){
  172. //alert(expr);
  173. return expr.match(/^\d{1,}(\.\d{1,})?[-+*/]\d{1,}(\.\d{1,})?$/);
  174. },
  175. operation: function(expr){
  176. return expr.match(/[-+/\*]$/);
  177. }
  178. }
  179. /* implementing jQuery UI functions in case no jquery ui found
  180. ----------------------------------------------------------------*/
  181. if(!$.fn.button){
  182. $.fn.button = function(){
  183. return this.each(function(){
  184. button = $(this);
  185. button.find('.calc-button').css({borderWidth:1,borderStyle:'solid',borderColor:'#CCCCCC',lineHeight:1.4,fontSize:'1em',cursor:'pointer',fontWeight:'bold'});
  186. })
  187. }
  188. }
  189. // plugin defaults
  190. $.fn.calculator.defaults = {
  191. defaultOpen: true,
  192. title: 'Calculator',
  193. accuracy: 12,
  194. width: 164,
  195. height: 180,
  196. movable: false,
  197. resizable: false,
  198. show: function(calc){
  199. $.fn.calculator.show(calc);
  200. },
  201. hide: function(calc){
  202. $.fn.calculator.hide(calc);
  203. },
  204. buttonPressed: function(calc, button){},
  205. displayChanged: function(calc, text, expression){}
  206. //expressionChanged: function(){calc, expression},
  207. //textChanged: function(){calc, text}
  208. //animations: false,
  209. };
  210. })(jQuery);