You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

script.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. var elemAdd = document.querySelector("#add");
  2. var elemName = elemAdd.querySelector(".name");
  3. var elemSuggestions = elemAdd.querySelector(".suggestions");
  4. var elemList = document.querySelector("#list");
  5. elemSuggestions.show = function() {
  6. elemSuggestions.className = "suggestions";
  7. elemSuggestions.style.display = "block";
  8. }
  9. elemSuggestions.hide = function() {
  10. elemSuggestions.className = "suggestions hidden";
  11. setTimeout(function() {
  12. elemSuggestions.style.display = "none";
  13. }, 100);
  14. }
  15. elemSuggestions.hide();
  16. var events = WebEvents();
  17. var words = [];
  18. function capitalize(word) {
  19. var first = word[0].toUpperCase();
  20. return first + word.substring(1);
  21. }
  22. function remove(index) {
  23. var elem;
  24. for (var i in elemList.childNodes) {
  25. var e = elemList.childNodes[i];
  26. var eindex = parseInt(e.querySelector(".index").value);
  27. if (eindex == index) {
  28. elem = e;
  29. break;
  30. }
  31. }
  32. if (!elem)
  33. return;
  34. elem.className += " hidden";
  35. setTimeout(function() {
  36. elem.parentNode.removeChild(elem);
  37. }, 1000);
  38. }
  39. function add(word, index, animate) {
  40. if (!word)
  41. return;
  42. var elem = document.createElement("div");
  43. if (animate)
  44. elem.className = "elem hidden";
  45. else
  46. elem.className = "elem";
  47. var elemName = document.createElement("span");
  48. elemName.className = "name";
  49. elemName.textContent = capitalize(word);
  50. var elemIndex = document.createElement("input");
  51. elemIndex.className = "index";
  52. elemIndex.value = index;
  53. elemIndex.type = "hidden";
  54. var elemOk = document.createElement("span");
  55. elemOk.className = "ok";
  56. elemOk.addEventListener("click", function() {
  57. if (/remove-pending/.test(elem.className))
  58. return;
  59. elem.className += " remove-pending";
  60. post("/remove/"+index);
  61. });
  62. elem.appendChild(elemIndex);
  63. elem.appendChild(elemName);
  64. elem.appendChild(elemOk);
  65. list.insertBefore(elem, list.firstChild);
  66. if (animate) {
  67. setTimeout(function() {
  68. elem.className = "elem";
  69. }, 100);
  70. }
  71. }
  72. function request(method, url, cb) {
  73. var xhr = new XMLHttpRequest();
  74. xhr.addEventListener("load", function() {
  75. var obj;
  76. try {
  77. obj = JSON.parse(xhr.responseText);
  78. if (cb)
  79. cb(null, JSON.parse(xhr.responseText));
  80. } catch (err) {
  81. console.log(xhr.responseText);
  82. if (cb)
  83. cb(err);
  84. }
  85. });
  86. xhr.addEventListener("error", function(err) {
  87. if (cb)
  88. cb(err);
  89. });
  90. xhr.open(method, url);
  91. xhr.send();
  92. }
  93. function get(url, cb) {
  94. request("GET", url, cb);
  95. }
  96. function post(url, cb) {
  97. request("POST", url, cb);
  98. }
  99. function clearChildren(elem) {
  100. while (elem.firstChild) {
  101. elem.removeChild(elem.firstChild);
  102. }
  103. }
  104. elemAdd.addEventListener("submit", function(evt) {
  105. evt.preventDefault();
  106. if (elemName.value == "")
  107. return;
  108. post("/add/"+encodeURIComponent(elemName.value));
  109. elemName.value = "";
  110. });
  111. function displaySuggestions() {
  112. setTimeout(function() {
  113. var name = elemName.value;
  114. var suggestions = words
  115. .filter(function(w) {
  116. return w.name.indexOf(name.toLowerCase()) !== -1;
  117. })
  118. .sort(function(a, b) {
  119. return a.count - b.count;
  120. });
  121. clearChildren(elemSuggestions);
  122. suggestions.forEach(function(w) {
  123. var elem = document.createElement("div");
  124. elem.className = "suggestion";
  125. elem.textContent = capitalize(w.name);
  126. elemSuggestions.insertBefore(elem, elemSuggestions.firstChild);
  127. elem.addEventListener("click", function() {
  128. console.log(w);
  129. post("/add/"+encodeURIComponent(w.name));
  130. elemSuggestions.hide();
  131. elemName.value = "";
  132. elemName.blur();
  133. });
  134. });
  135. if (suggestions.length > 0)
  136. elemSuggestions.show();
  137. else
  138. elemSuggestions.hide();
  139. }, 10);
  140. }
  141. elemName.addEventListener("keydown", displaySuggestions);
  142. elemName.addEventListener("focus", displaySuggestions);
  143. elemName.addEventListener("blur", function(evt) {
  144. setTimeout(function() {
  145. elemSuggestions.hide();
  146. }, 100);
  147. });
  148. events.on("add", function(evt) {
  149. add(evt.name, evt.index, true);
  150. var word = words.filter(function(w) {
  151. return w.name === evt.name;
  152. })[0];
  153. if (word)
  154. word.count += 1;
  155. else
  156. words.push({ name: evt.name, count: 1 });
  157. });
  158. events.on("remove", function(evt) {
  159. remove(evt.index);
  160. });
  161. events.on("connection", function() {
  162. clearChildren(elemList);
  163. get("/list", function(err, list) {
  164. list.forEach(function(word, index) { add(word, index); });
  165. });
  166. });
  167. get("/words", function(err, w) {
  168. if (err)
  169. return console.error(err);
  170. words = w;
  171. });