form.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* Hackish form handling system. */
  2. function hasClass(e, cl) {
  3. return (" "+e.className+" ").match(" "+cl+" ");
  4. }
  5. function stopPropagation(e) {
  6. e.preventDefault && e.preventDefault();
  7. e.cancelBubble = true;
  8. }
  9. /* proxy for a form object, with appropriate encoder/decoder */
  10. function formElement(el) {
  11. this.el = el;
  12. }
  13. formElement.prototype = {
  14. get: function() {
  15. var el = this.el;
  16. if (el.type == "checkbox") {
  17. return el.checked;
  18. } else if (hasClass(el, "numeric")) {
  19. return parseInt(el.value);
  20. } else if (hasClass(el, "hex")) {
  21. return sjcl.codec.hex.toBits(el.value);
  22. } else if (hasClass(el, "base64")) {
  23. return sjcl.codec.base64.toBits(el.value);
  24. } else {
  25. return el.value;
  26. }
  27. },
  28. set: function(x) {
  29. var el = this.el;
  30. if (el.type == "checkbox") {
  31. el.checked = x; return;
  32. } else if (hasClass(el, "hex")) {
  33. if (typeof x !== 'string') {
  34. x = sjcl.codec.hex.fromBits(x);
  35. }
  36. x = x.toUpperCase().replace(/ /g,'').replace(/(.{8})/g, "$1 ").replace(/ $/, '');
  37. } else if (hasClass(el, "base64")) {
  38. if (typeof x !== 'string') {
  39. x = sjcl.codec.base64.fromBits(x);
  40. }
  41. x = x.replace(/\s/g,'').replace(/(.{32})/g, "$1\n").replace(/\n$/, '');
  42. }
  43. el.value = x;
  44. }
  45. }
  46. function radioGroup(name) {
  47. this.name = name;
  48. }
  49. radioGroup.prototype = {
  50. get: function() {
  51. var els = document.getElementsByName(this.name), i;
  52. for (i=0; i<els.length; i++) {
  53. if (els[i].checked) {
  54. return els[i].value;
  55. }
  56. }
  57. },
  58. set: function(x) {
  59. var els = document.getElementsByName(this.name), i;
  60. for (i=0; i<els.length; i++) {
  61. els[i].checked = (els[i].value == x);
  62. }
  63. }
  64. }
  65. function formHandler(formName, enterActions) {
  66. var i, els = [], tmp, name;
  67. this._elNames = [];
  68. tmp = document.getElementById(formName).getElementsByTagName('input');
  69. for (i=0; i<tmp.length; i++) { els.push(tmp[i]); }
  70. tmp = document.getElementById(formName).getElementsByTagName('textarea');
  71. for (i=0; i<tmp.length; i++) { els.push(tmp[i]); }
  72. for (i=0; i<els.length; i++) {
  73. name = els[i].name || els[i].id;
  74. /* enforce numeric properties of element */
  75. els[i].onkeypress = (function(e) {
  76. return function(ev) {
  77. ev = ev || window.event;
  78. var key = ev.keyCode || ev.which,
  79. keyst = String.fromCharCode(ev.charCode || ev.keyCode),
  80. ente = enterActions[e.name||e.id];
  81. if (ev.ctrlKey || ev.metaKey) {
  82. return;
  83. }
  84. (key == 13) && ente && ente();
  85. if (hasClass(e, 'numeric') && ev.charCode && !keyst.match(/[0-9]/)) {
  86. stopPropagation(ev); return false;
  87. } else if (hasClass(e, 'hex') && ev.charCode && !keyst.match(/[0-9a-fA-F ]/)) {
  88. stopPropagation(ev); return false;
  89. }
  90. }
  91. })(els[i]);
  92. if (els[i].type == 'radio') {
  93. if (this[name] === undefined) {
  94. this[name] = new radioGroup(name);
  95. this._elNames.push(name);
  96. }
  97. } else {
  98. /* code to get the value of an element */
  99. this[name] = new formElement(els[i]);
  100. this._elNames.push(name);
  101. }
  102. }
  103. }
  104. formHandler.prototype = {
  105. get:function() {
  106. var i, out = {}, en = this._elNames;
  107. for (i=0; i<en.length; i++) {
  108. out[en[i]] = this[en[i]].get();
  109. }
  110. return out;
  111. },
  112. set:function(o) {
  113. var i;
  114. for (i in o) {
  115. if (o.hasOwnProperty(i) && this.hasOwnProperty(i)) {
  116. this[i].set(o[i]);
  117. }
  118. }
  119. }
  120. }