SMAM (short for Send Me A Mail) is a free (as in freedom) contact form embedding software.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. var items = {
  2. name: 'form_name',
  3. addr: 'form_addr',
  4. subj: 'form_subj',
  5. text: 'form_text',
  6. };
  7. var server = getServer();
  8. var xhrSend = new XMLHttpRequest();
  9. // Returns the server's base URI based on the user's script tag
  10. // return: the SMAM server's base URI
  11. function getServer() {
  12. var scripts = document.getElementsByTagName('script');
  13. // Parsing all the <script> tags to find the URL to our file
  14. for(var i = 0; i < scripts.length; i++) {
  15. let script = scripts[i];
  16. if(script.src) {
  17. let url = script.src;
  18. // This should be our script
  19. if(url.match(/:[0-9]+\/form\.js$/)) {
  20. // Port has been found
  21. return url.match(/^(http:\/\/[^\/]+)/)[1];
  22. }
  23. }
  24. }
  25. }
  26. // Creates a form
  27. // id: HTML identifier of the document's block to create the form into
  28. // return: nothing
  29. function generateForm(id) {
  30. var el = document.getElementById(id);
  31. // Set the form's behaviour
  32. el.setAttribute('onsubmit', 'sendForm(); return false;');
  33. // Add an empty paragraph for status
  34. var status = document.createElement('p');
  35. status.setAttribute('id', 'form_status');
  36. el.appendChild(status);
  37. var input = {
  38. name: getField(items.name, 'Your name', false, 'input'), // TODO: configurable prefix
  39. addr: getField(items.addr, 'Your e-mail address', true, 'input'),
  40. subj: getField(items.subj, 'Your message\'s subject', false, 'input'),
  41. text: getField(items.text, 'Your message', false, 'textarea')
  42. };
  43. // Adding nodes to document
  44. el.appendChild(input.name);
  45. el.appendChild(input.addr);
  46. el.appendChild(input.subj);
  47. el.appendChild(input.text);
  48. // Adding submit button
  49. el.appendChild(getSubmitButton('form_subm', 'Send the mail'));
  50. // Setting the XHR callback
  51. xhrSend.onreadystatechange = function() {
  52. if(xhrSend.readyState == XMLHttpRequest.DONE) {
  53. let status = document.getElementById('form_status');
  54. status.setAttribute('class', '');
  55. if(xhrSend.status === 200) {
  56. cleanForm();
  57. status.setAttribute('class', 'success');
  58. status.innerHTML = 'Your message has been sent.';
  59. } else {
  60. status.setAttribute('class', 'failure');
  61. status.innerHTML = 'An error happened while sending your message, please retry later.';
  62. }
  63. }
  64. };
  65. }
  66. // Returns a form field
  67. // id: field HTML identifier
  68. // placeholder: placeholder text
  69. // email: boolean: is it an email field?
  70. // type: 'input' or 'textarea'
  71. // return: a div node containing a label and an input text field
  72. function getField(id, placeholder, email, type) {
  73. var field = document.createElement('div');
  74. field.setAttribute('id', id); // TODO: configurable prefix
  75. field.appendChild(getLabel(id, placeholder, type));
  76. field.appendChild(getInputField(id, placeholder, email, type));
  77. return field;
  78. }
  79. // Returns a label
  80. // id: field HTML identifier
  81. // content: label's inner content
  82. // type: 'input' or 'textarea'
  83. // return: a label node the field's description
  84. function getLabel(id, content, type) {
  85. var label = document.createElement('label');
  86. label.setAttribute('for', id + '_' + type);
  87. label.innerHTML = content;
  88. return label;
  89. }
  90. // Returns an input text field
  91. // id: field HTML identifier
  92. // placeholder: placeholder text, field description
  93. // email: boolean: is it an email field?
  94. // type: 'input' or 'textarea'
  95. // return: an input text or email field (depending on "email"'s value') with an
  96. // HTML id and a placeholder text
  97. function getInputField(id, placeholder, email, type) {
  98. var input = document.createElement(type);
  99. if(!type.localeCompare('input')) { // Set input type if input
  100. if(email) {
  101. input.setAttribute('type', 'email');
  102. } else {
  103. input.setAttribute('type', 'text');
  104. }
  105. }
  106. input.setAttribute('required', 'required');
  107. input.setAttribute('placeholder', placeholder);
  108. input.setAttribute('id', id + '_' + type);
  109. return input;
  110. }
  111. // Returns a submit button
  112. // id: button HTML identifier
  113. // text: button text
  114. // return: a div node containing the button
  115. function getSubmitButton(id, text) {
  116. var submit = document.createElement('div');
  117. submit.setAttribute('id', id);
  118. var button = document.createElement('button');
  119. button.setAttribute('type', 'submit');
  120. button.setAttribute('id', id);
  121. button.innerHTML = text;
  122. submit.appendChild(button);
  123. return submit;
  124. }
  125. // Send form data through the XHR object
  126. // return: nothing
  127. function sendForm() {
  128. // Clear status
  129. let status = document.getElementById('form_status');
  130. status.setAttribute('class', 'sending');
  131. status.innerHTML = 'Sending the e-mail';
  132. xhrSend.open('POST', server + '/send');
  133. xhrSend.setRequestHeader('Content-Type', 'application/json');
  134. xhrSend.send(JSON.stringify(getFormData()));
  135. }
  136. // Fetch form inputs from HTML elements
  137. // return: an object containing all the user's input
  138. function getFormData() {
  139. return {
  140. name: document.getElementById(items.name + '_input').value,
  141. addr: document.getElementById(items.addr + '_input').value,
  142. subj: document.getElementById(items.subj + '_input').value,
  143. text: document.getElementById(items.text + '_textarea').value
  144. }
  145. }
  146. // Empties the form fields
  147. // return: nothing
  148. function cleanForm() {
  149. document.getElementById(items.name + '_input').value = '';
  150. document.getElementById(items.addr + '_input').value = '';
  151. document.getElementById(items.subj + '_input').value = '';
  152. document.getElementById(items.text + '_textarea').value = '';
  153. }