/script/lib/settings/classes/setting.js

https://github.com/TomTasche/Announcify.js · JavaScript · 645 lines · 490 code · 118 blank · 37 comment · 60 complexity · 1191ea434d20151b3989e29b3b9d7768 MD5 · raw file

  1. //
  2. // Copyright (c) 2011 Frank Kohlhepp
  3. // https://github.com/frankkohlhepp/fancy-settings
  4. // License: LGPL v2.1
  5. //
  6. (function () {
  7. var settings,
  8. Bundle;
  9. settings = new Store("settings");
  10. Bundle = new Class({
  11. // Attributes:
  12. // - tab
  13. // - group
  14. // - name
  15. // - type
  16. //
  17. // Methods:
  18. // - initialize
  19. // - createDOM
  20. // - setupDOM
  21. // - addEvents
  22. // - get
  23. // - set
  24. "Implements": Events,
  25. "initialize": function (params) {
  26. this.params = params;
  27. this.params.searchString = "•" + this.params.tab + "•" + this.params.group + "•";
  28. this.createDOM();
  29. this.setupDOM();
  30. this.addEvents();
  31. if (this.params.name !== undefined) {
  32. this.set(settings.get(this.params.name), true);
  33. }
  34. this.params.searchString = this.params.searchString.toLowerCase();
  35. },
  36. "addEvents": function () {
  37. this.element.addEvent("change", (function (event) {
  38. if (this.params.name !== undefined) {
  39. settings.set(this.params.name, this.get());
  40. }
  41. this.fireEvent("action", this.get());
  42. }).bind(this));
  43. },
  44. "get": function () {
  45. return this.element.get("value");
  46. },
  47. "set": function (value, noChangeEvent) {
  48. this.element.set("value", value);
  49. if (noChangeEvent !== true) {
  50. this.element.fireEvent("change");
  51. }
  52. return this;
  53. }
  54. });
  55. Bundle.Description = new Class({
  56. // text
  57. "Extends": Bundle,
  58. "addEvents": undefined,
  59. "get": undefined,
  60. "set": undefined,
  61. "initialize": function (params) {
  62. this.params = params;
  63. this.params.searchString = "";
  64. this.createDOM();
  65. this.setupDOM();
  66. },
  67. "createDOM": function () {
  68. this.bundle = new Element("div", {
  69. "class": "setting bundle description"
  70. });
  71. this.container = new Element("div", {
  72. "class": "setting container description"
  73. });
  74. this.element = new Element("p", {
  75. "class": "setting element description"
  76. });
  77. },
  78. "setupDOM": function () {
  79. if (this.params.text !== undefined) {
  80. this.element.set("html", this.params.text);
  81. }
  82. this.element.inject(this.container);
  83. this.container.inject(this.bundle);
  84. }
  85. });
  86. Bundle.Button = new Class({
  87. // label, text
  88. // action -> click
  89. "Extends": Bundle,
  90. "get": undefined,
  91. "set": undefined,
  92. "initialize": function (params) {
  93. this.params = params;
  94. this.params.searchString = "•" + this.params.tab + "•" + this.params.group + "•";
  95. this.createDOM();
  96. this.setupDOM();
  97. this.addEvents();
  98. this.params.searchString = this.params.searchString.toLowerCase();
  99. },
  100. "createDOM": function () {
  101. this.bundle = new Element("div", {
  102. "class": "setting bundle button"
  103. });
  104. this.container = new Element("div", {
  105. "class": "setting container button"
  106. });
  107. this.element = new Element("input", {
  108. "class": "setting element button",
  109. "type": "button"
  110. });
  111. this.label = new Element("label", {
  112. "class": "setting label button"
  113. });
  114. },
  115. "setupDOM": function () {
  116. if (this.params.label !== undefined) {
  117. this.label.set("html", this.params.label);
  118. this.label.inject(this.container);
  119. this.params.searchString += this.params.label + "•";
  120. }
  121. if (this.params.text !== undefined) {
  122. this.element.set("value", this.params.text);
  123. this.params.searchString += this.params.text + "•";
  124. }
  125. this.element.inject(this.container);
  126. this.container.inject(this.bundle);
  127. },
  128. "addEvents": function () {
  129. this.element.addEvent("click", (function () {
  130. this.fireEvent("action");
  131. }).bind(this));
  132. }
  133. });
  134. Bundle.Text = new Class({
  135. // label, text, masked
  136. // action -> change & keyup
  137. "Extends": Bundle,
  138. "createDOM": function () {
  139. this.bundle = new Element("div", {
  140. "class": "setting bundle text"
  141. });
  142. this.container = new Element("div", {
  143. "class": "setting container text"
  144. });
  145. this.element = new Element("input", {
  146. "class": "setting element text",
  147. "type": "text"
  148. });
  149. this.label = new Element("label", {
  150. "class": "setting label text"
  151. });
  152. },
  153. "setupDOM": function () {
  154. if (this.params.label !== undefined) {
  155. this.label.set("html", this.params.label);
  156. this.label.inject(this.container);
  157. this.params.searchString += this.params.label + "•";
  158. }
  159. if (this.params.text !== undefined) {
  160. this.element.set("placeholder", this.params.text);
  161. this.params.searchString += this.params.text + "•";
  162. }
  163. if (this.params.masked === true) {
  164. this.element.set("type", "password");
  165. this.params.searchString += "password" + "•";
  166. }
  167. this.element.inject(this.container);
  168. this.container.inject(this.bundle);
  169. },
  170. "addEvents": function () {
  171. var change = (function (event) {
  172. if (this.params.name !== undefined) {
  173. settings.set(this.params.name, this.get());
  174. }
  175. this.fireEvent("action", this.get());
  176. }).bind(this);
  177. this.element.addEvent("change", change);
  178. this.element.addEvent("keyup", change);
  179. }
  180. });
  181. Bundle.Checkbox = new Class({
  182. // label
  183. // action -> change
  184. "Extends": Bundle,
  185. "createDOM": function () {
  186. this.bundle = new Element("div", {
  187. "class": "setting bundle checkbox"
  188. });
  189. this.container = new Element("div", {
  190. "class": "setting container checkbox"
  191. });
  192. this.element = new Element("input", {
  193. "id": String.uniqueID(),
  194. "class": "setting element checkbox",
  195. "type": "checkbox",
  196. "value": "true"
  197. });
  198. this.label = new Element("label", {
  199. "class": "setting label checkbox",
  200. "for": this.element.get("id")
  201. });
  202. },
  203. "setupDOM": function () {
  204. this.element.inject(this.container);
  205. this.container.inject(this.bundle);
  206. if (this.params.label !== undefined) {
  207. this.label.set("html", this.params.label);
  208. this.label.inject(this.container);
  209. this.params.searchString += this.params.label + "•";
  210. }
  211. },
  212. "get": function () {
  213. return this.element.get("checked");
  214. },
  215. "set": function (value, noChangeEvent) {
  216. this.element.set("checked", value);
  217. if (noChangeEvent !== true) {
  218. this.element.fireEvent("change");
  219. }
  220. return this;
  221. }
  222. });
  223. Bundle.Slider = new Class({
  224. // label, max, min, step, display, displayModifier
  225. // action -> change
  226. "Extends": Bundle,
  227. "initialize": function (params) {
  228. this.params = params;
  229. this.params.searchString = "•" + this.params.tab + "•" + this.params.group + "•";
  230. this.createDOM();
  231. this.setupDOM();
  232. this.addEvents();
  233. if (this.params.name !== undefined) {
  234. this.set((settings.get(this.params.name) || 0), true);
  235. } else {
  236. this.set(0, true);
  237. }
  238. this.params.searchString = this.params.searchString.toLowerCase();
  239. },
  240. "createDOM": function () {
  241. this.bundle = new Element("div", {
  242. "class": "setting bundle slider"
  243. });
  244. this.container = new Element("div", {
  245. "class": "setting container slider"
  246. });
  247. this.element = new Element("input", {
  248. "class": "setting element slider",
  249. "type": "range"
  250. });
  251. this.label = new Element("label", {
  252. "class": "setting label slider"
  253. });
  254. this.display = new Element("span", {
  255. "class": "setting display slider"
  256. });
  257. },
  258. "setupDOM": function () {
  259. if (this.params.label !== undefined) {
  260. this.label.set("html", this.params.label);
  261. this.label.inject(this.container);
  262. this.params.searchString += this.params.label + "•";
  263. }
  264. if (this.params.max !== undefined) {
  265. this.element.set("max", this.params.max);
  266. }
  267. if (this.params.min !== undefined) {
  268. this.element.set("min", this.params.min);
  269. }
  270. if (this.params.step !== undefined) {
  271. this.element.set("step", this.params.step);
  272. }
  273. this.element.inject(this.container);
  274. if (this.params.display === true) {
  275. if (this.params.displayModifier !== undefined) {
  276. this.display.set("text", this.params.displayModifier(0));
  277. } else {
  278. this.display.set("text", 0);
  279. }
  280. this.display.inject(this.container);
  281. }
  282. this.container.inject(this.bundle);
  283. },
  284. "addEvents": function () {
  285. this.element.addEvent("change", (function (event) {
  286. if (this.params.name !== undefined) {
  287. settings.set(this.params.name, this.get());
  288. }
  289. if (this.params.displayModifier !== undefined) {
  290. this.display.set("text", this.params.displayModifier(this.get()));
  291. } else {
  292. this.display.set("text", this.get());
  293. }
  294. this.fireEvent("action", this.get());
  295. }).bind(this));
  296. },
  297. "get": function () {
  298. return Number.from(this.element.get("value"));
  299. },
  300. "set": function (value, noChangeEvent) {
  301. this.element.set("value", value);
  302. if (noChangeEvent !== true) {
  303. this.element.fireEvent("change");
  304. } else {
  305. if (this.params.displayModifier !== undefined) {
  306. this.display.set("text", this.params.displayModifier(Number.from(value)));
  307. } else {
  308. this.display.set("text", Number.from(value));
  309. }
  310. }
  311. return this;
  312. }
  313. });
  314. Bundle.PopupButton = new Class({
  315. // label, options[{value, text}]
  316. // action -> change
  317. "Extends": Bundle,
  318. "createDOM": function () {
  319. this.bundle = new Element("div", {
  320. "class": "setting bundle popup-button"
  321. });
  322. this.container = new Element("div", {
  323. "class": "setting container popup-button"
  324. });
  325. this.element = new Element("select", {
  326. "class": "setting element popup-button"
  327. });
  328. this.label = new Element("label", {
  329. "class": "setting label popup-button"
  330. });
  331. if (this.params.options === undefined) { return; }
  332. // convert array syntax into object syntax for options
  333. function arrayToObject(option) {
  334. if (typeOf(option) == "array") {
  335. option = {
  336. "value": option[0],
  337. "text": option[1] || option[0],
  338. };
  339. }
  340. return option;
  341. }
  342. // convert arrays
  343. if (typeOf(this.params.options) == "array") {
  344. var values = [];
  345. this.params.options.each((function(values, option) {
  346. values.push(arrayToObject(option));
  347. }).bind(this, values));
  348. this.params.options = { "values": values };
  349. }
  350. var groups;
  351. if (this.params.options.groups !== undefined) {
  352. groups = {};
  353. this.params.options.groups.each((function (groups, group) {
  354. this.params.searchString += (group) + "•";
  355. groups[group] = (new Element("optgroup", {
  356. "label": group,
  357. }).inject(this.element));
  358. }).bind(this, groups));
  359. }
  360. if (this.params.options.values !== undefined) {
  361. this.params.options.values.each((function(groups, option) {
  362. option = arrayToObject(option);
  363. this.params.searchString += (option.text || option.value) + "•";
  364. // find the parent of this option - either a group or the main element
  365. var parent;
  366. if (option.group && this.params.options.groups) {
  367. if ((option.group - 1) in this.params.options.groups) {
  368. option.group = this.params.options.groups[option.group-1];
  369. }
  370. if (option.group in groups) {
  371. parent = groups[option.group];
  372. }
  373. else {
  374. parent = this.element;
  375. }
  376. }
  377. else {
  378. parent = this.element;
  379. }
  380. (new Element("option", {
  381. "value": option.value,
  382. "text": option.text || option.value,
  383. })).inject(parent);
  384. }).bind(this, groups));
  385. }
  386. },
  387. "setupDOM": function () {
  388. if (this.params.label !== undefined) {
  389. this.label.set("html", this.params.label);
  390. this.label.inject(this.container);
  391. this.params.searchString += this.params.label + "•";
  392. }
  393. this.element.inject(this.container);
  394. this.container.inject(this.bundle);
  395. }
  396. });
  397. Bundle.ListBox = new Class({
  398. // label, options[{value, text}]
  399. // action -> change
  400. "Extends": Bundle.PopupButton,
  401. "createDOM": function () {
  402. this.bundle = new Element("div", {
  403. "class": "setting bundle list-box"
  404. });
  405. this.container = new Element("div", {
  406. "class": "setting container list-box"
  407. });
  408. this.element = new Element("select", {
  409. "class": "setting element list-box",
  410. "size": "2"
  411. });
  412. this.label = new Element("label", {
  413. "class": "setting label list-box"
  414. });
  415. if (this.params.options === undefined) { return; }
  416. this.params.options.each((function (option) {
  417. this.params.searchString += (option[1] || option[0]) + "•";
  418. (new Element("option", {
  419. "value": option[0],
  420. "text": option[1] || option[0]
  421. })).inject(this.element);
  422. }).bind(this));
  423. },
  424. "get": function () {
  425. return (this.element.get("value") || undefined);
  426. }
  427. });
  428. Bundle.RadioButtons = new Class({
  429. // label, options[{value, text}]
  430. // action -> change
  431. "Extends": Bundle,
  432. "createDOM": function () {
  433. var settingID = String.uniqueID();
  434. this.bundle = new Element("div", {
  435. "class": "setting bundle radio-buttons"
  436. });
  437. this.label = new Element("label", {
  438. "class": "setting label radio-buttons"
  439. });
  440. this.containers = [];
  441. this.elements = [];
  442. this.labels = [];
  443. if (this.params.options === undefined) { return; }
  444. this.params.options.each((function (option) {
  445. var optionID,
  446. container;
  447. this.params.searchString += (option[1] || option[0]) + "•";
  448. optionID = String.uniqueID();
  449. container = (new Element("div", {
  450. "class": "setting container radio-buttons"
  451. })).inject(this.bundle);
  452. this.containers.push(container);
  453. this.elements.push((new Element("input", {
  454. "id": optionID,
  455. "name": settingID,
  456. "class": "setting element radio-buttons",
  457. "type": "radio",
  458. "value": option[0]
  459. })).inject(container));
  460. this.labels.push((new Element("label", {
  461. "class": "setting element-label radio-buttons",
  462. "for": optionID,
  463. "text": option[1] || option[0]
  464. })).inject(container));
  465. }).bind(this));
  466. },
  467. "setupDOM": function () {
  468. if (this.params.label !== undefined) {
  469. this.label.set("html", this.params.label);
  470. this.label.inject(this.bundle, "top");
  471. this.params.searchString += this.params.label + "•";
  472. }
  473. },
  474. "addEvents": function () {
  475. this.bundle.addEvent("change", (function (event) {
  476. if (this.params.name !== undefined) {
  477. settings.set(this.params.name, this.get());
  478. }
  479. this.fireEvent("action", this.get());
  480. }).bind(this));
  481. },
  482. "get": function () {
  483. var checkedEl = this.elements.filter((function (el) {
  484. return el.get("checked");
  485. }).bind(this));
  486. return (checkedEl[0] && checkedEl[0].get("value"));
  487. },
  488. "set": function (value, noChangeEvent) {
  489. var desiredEl = this.elements.filter((function (el) {
  490. return (el.get("value") === value);
  491. }).bind(this));
  492. desiredEl[0] && desiredEl[0].set("checked", true);
  493. if (noChangeEvent !== true) {
  494. this.bundle.fireEvent("change");
  495. }
  496. return this;
  497. }
  498. });
  499. this.Setting = new Class({
  500. "initialize": function (container) {
  501. this.container = container;
  502. },
  503. "create": function (params) {
  504. var types,
  505. bundle;
  506. // Available types
  507. types = {
  508. "description": "Description",
  509. "button": "Button",
  510. "text": "Text",
  511. "checkbox": "Checkbox",
  512. "slider": "Slider",
  513. "popupButton": "PopupButton",
  514. "listBox": "ListBox",
  515. "radioButtons": "RadioButtons"
  516. };
  517. if (types.hasOwnProperty(params.type)) {
  518. bundle = new Bundle[types[params.type]](params);
  519. bundle.bundleContainer = this.container;
  520. bundle.bundle.inject(this.container);
  521. return bundle;
  522. } else {
  523. throw "invalidType";
  524. }
  525. }
  526. });
  527. }());