Guest User

Untitled

a guest
Jul 22nd, 2018
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.15 KB | None | 0 0
  1. // Implement push-style templating methods on the Element class.
  2. // This defines a clean but arbitrarily powerful templating.
  3. // Templates completely lack non-HTML code containing only markup
  4. // to define the structure _and_ example data.
  5. //
  6. // These method can be used to first parse a template into DOM
  7. // and then manipulate sub-elements of that DOM in a convenient
  8. // and structured way to transform the DOM into something that
  9. // can be immediately inserted to browser DOM.
  10. //
  11. // Templates are completely unaware of how the programmer transforms
  12. // them into real UI output freeing the designer of any necessity of
  13. // learning anything non-HTML/CSS.
  14. Element.implement({
  15. _tplThrowExceptions: true,
  16. tplThrowExceptions: function(setting) {
  17. this._tplThrowExceptions = setting;
  18. },
  19. /**
  20. * Loops over _data_ cycling the element set matching _repeaterSel_.
  21. * This can be used to embed a list of data items into a template.
  22. * The predefined elements in the template are cycled, so arbitrary
  23. * odd-even patterns can be used.
  24. *
  25. * Example:
  26. * // <table><tr class="odd">
  27. * // <td>col1</td><td>col2</td><td>col3</td></tr>
  28. * // <tr class="even">
  29. * // <td>col1</td><td>col2</td><td>col3</td></tr></table>
  30. * tableEl.repeat("tr", data, function(el, dataItem) {
  31. * el.embed("td", dataItem.col1, dataItem.col2, dataItem.col3);
  32. * });
  33. */
  34. repeat: function(repeaterSel, data, handler) {
  35. var repeaters = this.getElements(repeaterSel);
  36. var firstRepeater = repeaters[0];
  37. var nextRepeater = 0;
  38. data.each(function(item, index) {
  39. var repeater = repeaters[nextRepeater % repeaters.length];
  40. var el = repeater.clone();
  41. handler.call(el, item, index, data);
  42. // Has to be injected BEFORE the first repeater for the
  43. // resulting order to match the order of data items.
  44. el.inject(firstRepeater, "before");
  45. ++nextRepeater;
  46. });
  47. repeaters.dispose();
  48. return this;
  49. },
  50. /**
  51. * Embeds a values passed as arguments to elements
  52. * matched by _selector_.
  53. *
  54. * _selector_ can also define both the DOM selector _and_
  55. * the attribute to embed. If no attribute is specified,
  56. * 'html' is used which simply sets the innerHTML value of
  57. * the matched elements.
  58. * The number of matched elements must be at least the number of
  59. * embeddable values passed.
  60. *
  61. * Example:
  62. * // fooEl = <div><h2 class="title">Foo title</h2>
  63. * // <p class="text">Foo text</p></div>
  64. * fooEl.embed(".title, .text", foo.title, foo.text)
  65. */
  66. embed: function(selector) {
  67. var match = selector.match(/^(.+?)@([a-z]+)$/i);
  68. var attr;
  69. if (match) {
  70. selector = match[1];
  71. attr = match[2];
  72. } else {
  73. attr = "html";
  74. }
  75. var values = $A(arguments).slice(1).flatten();
  76. var targets = this.getElements(selector);
  77. if (this._tplThrowExceptions && targets.length < values.length)
  78. throw new Error("Target elements are fewer than values");
  79. values.each(function(value, index) {
  80. if (typeof targets[index] !== "undefined")
  81. targets[index].set(attr, value);
  82. });
  83. return this;
  84. },
  85. /**
  86. * Same as _embed_ but automatically extracts values out
  87. * of an object.
  88. *
  89. * Example:
  90. * // fooEl = <div><h2 class="title">Foo title</h2>
  91. * // <p class="text">Foo text</p></div>
  92. * fooEl.embedObj(".title, .text", foo, ["title", "text"])
  93. */
  94. embedObj: function(selector, object, attrs) {
  95. return this.embed(selector, attrs.map(function(attr) {
  96. return object[attr];
  97. }));
  98. }
  99. });
  100.  
  101. /**
  102. * Generates Python style range objects.
  103. */
  104. function $range(start, end, step) {
  105. if (typeof end === "undefined") {
  106. end = start;
  107. start = 0;
  108. }
  109. if (typeof step === "undefined")
  110. step = 1;
  111. var ret = [];
  112. for (var i = start; i < end; i = i + step)
  113. ret.push(i);
  114. return ret;
  115. }
  116.  
  117.  
  118. var Lightbox = new Class({
  119. Implements: [Options, Events],
  120. options: {
  121. position: {position: "center"},
  122. show: false,
  123. html: null,
  124. domOptions: {
  125. classes: {"lightbox": true},
  126. opacity: 0.0
  127. }
  128. },
  129. initialize: function(options) {
  130. this.setOptions(options || {});
  131.  
  132. var domOptions = $merge({}, this.options.domOptions);
  133. domOptions["class"] = $H(domOptions.classes).getKeys().join(" ");
  134. delete domOptions.classes;
  135.  
  136. var el = this._el = new Element("div", domOptions);
  137.  
  138. var tween = el.get("tween", {duration: 150});
  139. this._onKeyPress = this._onKeyPress.bind(this);
  140. tween.addEvent("complete", function() {
  141. window.addEvent("keydown", this._onKeyPress);
  142. this.fireEvent("show");
  143. }.bind(this));
  144.  
  145. this._mask = new Mask($(document.body), {
  146. hideOnClick: true,
  147. onHide: this.hide.bind(this)
  148. });
  149. var rePos = this._position.bind(this);
  150. window.addEvent("resize", rePos);
  151. window.addEvent("scroll", rePos);
  152.  
  153. if (this.options.show) this.show();
  154. if (this.options.html) this.setHtml(options.html);
  155. }
  156. });
  157. Lightbox.implement({
  158. _onKeyPress: function(e) {
  159. if (e.key === "esc") {
  160. this.hide();
  161. window.removeEvent(this._onKeyPress);
  162. }
  163. },
  164. show: function() {
  165. if (!this._showing) {
  166. this._showing = true;
  167. var el = this.getEl();
  168. el.inject($(document.body));
  169. this.fireEvent("beforeShow");
  170. el.show();
  171. this._position();
  172. el.tween("opacity", 1.0);
  173. this._mask.show();
  174. }
  175. },
  176. hide: function() {
  177. if (this._showing) {
  178. this._showing = false;
  179. this._el.tween("opacity", 0.0);
  180. this._mask.hide();
  181. }
  182. },
  183. setHtml: function(html) {
  184. UpdateManager.update(this.getEl(), html);
  185. this._position();
  186. },
  187. getEl: function() {
  188. return this._el;
  189. },
  190. _position: function() {
  191. this.getEl().position(this.options.position);
  192. this._mask.position();
  193. }
  194. });
  195.  
  196. AjaxLightbox = new Class({
  197. Extends: Lightbox,
  198. options: {
  199. requestClass: Request
  200. },
  201. _show: function() {
  202. Lightbox.prototype.show.call(this);
  203. },
  204. show: function() {
  205. if (!this._loaded) {
  206. this._loaded = true;
  207. var requestClass = this.options.requestClass;
  208. new requestClass({
  209. url: this.options.url,
  210. onSuccess: function(response) {
  211. try {
  212. this._handleResponse(response);
  213. this._show();
  214. } catch (e) {
  215. console.error(e);
  216. }
  217. }.bind(this)
  218. }).GET();
  219. } else {
  220. this._show();
  221. }
  222. },
  223. _handleResponse: function(responseText) {
  224. console.warning("An AjaxLightbox must define the _handleResponse method");
  225. }
  226. });
  227.  
  228. // *** SIIT EDASI TULEB APP-SPECIFIC KOOD
  229.  
  230. P_LIGHTBOX_POSITION = {
  231. edge: "centerTop",
  232. position: "centerTop",
  233. offset: {y: 50}
  234. };
  235.  
  236. MyBookmarksLightbox = new Class({
  237. Extends: AjaxLightbox,
  238. options: {
  239. requestClass: Request.JSON,
  240. url: "/my-bookmarks/",
  241. domOptions: {
  242. classes: {"my-bookmarks": true}
  243. },
  244. position: P_LIGHTBOX_POSITION
  245. },
  246. _handleResponse: function(response) {
  247. this._titles = response["data"];
  248. var tplEl = this._tplEl = new Element("div", {"html": response["tpl"]});
  249. this._pageIndex = 0;
  250. this._pageCount = Math.ceil(this._titles.length / 10);
  251. this._fillTpl();
  252. },
  253. _fillTpl: function(update) {
  254. var tplEl = this._tplEl.clone();
  255.  
  256. var indexStart = this._pageIndex * 10;
  257. var titles = this._titles.slice(indexStart, indexStart + 10);
  258.  
  259. tplEl.repeat("tbody tr", titles, function(title, index) {
  260. this.embed("td",
  261. (indexStart + index + 1) + ". " + title["title"],
  262. title["created"]);
  263. });
  264.  
  265. if (update) {
  266. tplEl.getElement("table").replaces(this.getEl().getElement("table"));
  267. } else {
  268. tplEl.getElement("a.prev").addEvent("click", function() {
  269. this._pageIndex = Math.max(0, this._pageIndex - 1);
  270. this._fillTpl();
  271. }.bind(this));
  272. tplEl.getElement("a.next").addEvent("click", function() {
  273. this._pageIndex = Math.min(this._pageCount - 1, this._pageIndex + 1);
  274. this._fillTpl();
  275. }.bind(this));
  276. new Elements(tplEl.getElements("a.page").slice(1)).destroy();
  277.  
  278. var self = this;
  279. tplEl.repeat("a.page", $range(this._pageCount), function(index) {
  280. this.set("html", index + 1);
  281. this.addEvent("click", function() {
  282. self._pageIndex = index;
  283. self._fillTpl();
  284. return false;
  285. });
  286. });
  287.  
  288. this.getEl().empty();
  289. tplEl.getChildren().inject(this.getEl());
  290. }
  291. }
  292. });
  293.  
  294. FormLightbox = new Class({
  295. Extends: AjaxLightbox,
  296. options: {
  297. domOptions: {
  298. classes: {"form": true}
  299. }
  300. },
  301. _handleResponse: function(responseText) {
  302. this.setHtml(responseText);
  303. var doSubmit = this._doSubmit.bind(this);
  304. this.getForm().addEvent("submit", doSubmit);
  305. this.getSubmitButton().addEvent("click", doSubmit);
  306. this.getCancelButton().addEvent("click", function() {
  307. this.hide();
  308. return false;
  309. }.bind(this));
  310. },
  311. _doSubmit: function() {
  312. new Request.JSON({
  313. url: this.getForm().action,
  314. onSuccess: function(response) {
  315. this.fireEvent("success", response);
  316. }.bind(this)
  317. }).POST(this.getForm());
  318. return false;
  319. },
  320. getSubmitButton: function() {
  321. return this.getEl().getElement("button[type=submit]");
  322. },
  323. getCancelButton: function() {
  324. return this.getEl().getElement("a.cancel");
  325. },
  326. getForm: function() {
  327. return this.getEl().getElement("form");
  328. }
  329. });
  330.  
  331. PFormLightbox = new Class({
  332. Extends: FormLightbox,
  333. options: {
  334. position: P_LIGHTBOX_POSITION,
  335. overtexts: {}
  336. },
  337. initialize: function(options) {
  338. this.parent(options);
  339. this.addEvents({
  340. "beforeShow": this._onBeforeShow.bind(this),
  341. "show": this._onShow.bind(this)
  342. });
  343. }
  344. });
  345. PFormLightbox.implement({
  346. _getAllFields: function() {
  347. return this.getEl().getElements("input[title], textarea[title]");
  348. },
  349. _getFirstField: function() {
  350. return this.getEl().getElement("input, textarea, button[type=submit]");
  351. },
  352. _onBeforeShow: function() {
  353. var defaultOpts = {
  354. positionOptions: {offset: {x: 10}},
  355. poll: true
  356. };
  357. this._getAllFields().each(function(field) {
  358. var customOpts = this.options.overtexts[field.id || field.name];
  359. var opts = $merge(defaultOpts, customOpts);
  360. new OverText(field, opts);
  361. }.bind(this));
  362. },
  363. _onShow: function() {
  364. var firstField = this._getFirstField();
  365. firstField.addEventOnce("keydown", function() {
  366. var overText = this.retrieve("OverText");
  367. if (overText) overText.hide();
  368. });
  369. firstField.focus();
  370. var overText = firstField.retrieve("OverText");
  371. if (overText) overText.show();
  372. }
  373. });
Add Comment
Please, Sign In to add comment