mobiscroll.listbase.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. (function ($, undefined) {
  2. var ms = $.mobiscroll,
  3. defaults = {
  4. invalid: [],
  5. showInput: true,
  6. inputClass: ''
  7. };
  8. ms.presets.scroller.list = function (inst) {
  9. var orig = $.extend({}, inst.settings),
  10. s = $.extend(inst.settings, defaults, orig),
  11. layout = s.layout || (/top|bottom/.test(s.display) ? 'liquid' : ''),
  12. isLiquid = layout == 'liquid',
  13. origReadOnly = s.readonly,
  14. elm = $(this),
  15. input,
  16. prevent,
  17. id = this.id + '_dummy',
  18. lvl = 0,
  19. ilvl = 0,
  20. timer = {},
  21. currLevel,
  22. currWheelVector = [],
  23. wa = s.wheelArray || createWheelArray(elm),
  24. labels = generateLabels(lvl),
  25. fwv = firstWheelVector(wa),
  26. w = generateWheelsFromVector(fwv, lvl);
  27. /**
  28. * Disables the invalid items on the wheels
  29. * @param {Object} dw - the jQuery mobiscroll object
  30. * @param {Number} nrWheels - the number of the current wheels
  31. * @param {Array} whArray - The wheel array objects containing the wheel tree
  32. * @param {Array} whVector - the wheel vector containing the current keys
  33. */
  34. function setDisabled(dw, nrWheels, whArray, whVector) {
  35. var j,
  36. i = 0;
  37. while (i < nrWheels) {
  38. var currWh = $('.dwwl' + i, dw),
  39. inv = getInvalidKeys(whVector, i, whArray);
  40. for (j = 0; j < inv.length; j++) {
  41. $('.dw-li[data-val="' + inv[j] + '"]', currWh).removeClass('dw-v');
  42. }
  43. i++;
  44. }
  45. }
  46. /**
  47. * Returns the invalid keys of one wheel as an array
  48. * @param {Array} whVector - the wheel vector used to search for the wheel in the wheel array
  49. * @param {Number} index - index of the wheel in the wheel vector, that we are interested in
  50. * @param {Array} whArray - the wheel array we are searching in
  51. * @return {Array} - list of invalid keys
  52. */
  53. function getInvalidKeys(whVector, index, whArray) {
  54. var i = 0,
  55. n,
  56. whObjA = whArray,
  57. invalids = [];
  58. while (i < index) {
  59. var ii = whVector[i];
  60. //whObjA = whObjA[ii].children;
  61. for (n in whObjA) {
  62. if (whObjA[n].key == ii) {
  63. whObjA = whObjA[n].children;
  64. break;
  65. }
  66. }
  67. i++;
  68. }
  69. i = 0;
  70. while (i < whObjA.length) {
  71. if (whObjA[i].invalid) {
  72. invalids.push(whObjA[i].key);
  73. }
  74. i++;
  75. }
  76. return invalids;
  77. }
  78. /**
  79. * Creates a Boolean vector with true values (except one) that can be used as the readonly vector
  80. * n - the length of the vector
  81. * i - the index of the value that's going to be false
  82. */
  83. function createROVector(n, i) {
  84. var a = [];
  85. while (n) {
  86. a[--n] = true;
  87. }
  88. a[i] = false;
  89. return a;
  90. }
  91. /**
  92. * Creates a labels vector, from values if they are defined, otherwise from numbers
  93. * l - the length of the vector
  94. */
  95. function generateLabels(l) {
  96. var a = [],
  97. i;
  98. for (i = 0; i < l; i++) {
  99. a[i] = s.labels && s.labels[i] ? s.labels[i] : i;
  100. }
  101. return a;
  102. }
  103. /**
  104. * Creates the wheel array from the vector provided
  105. * wv - wheel vector containing the values that should be selected on the wheels
  106. * l - the length of the wheel array
  107. */
  108. function generateWheelsFromVector(wv, l, index) {
  109. var i = 0, j, obj, chInd,
  110. w = [[]],
  111. wtObjA = wa;
  112. if (l) { // if length is defined we need to generate that many wheels (even if they are empty)
  113. for (j = 0; j < l; j++) {
  114. if (isLiquid) {
  115. w[0][j] = {};
  116. } else {
  117. w[j] = [{}];
  118. }
  119. }
  120. }
  121. while (i < wv.length) { // we generate the wheels until the length of the wheel vector
  122. if (isLiquid) {
  123. w[0][i] = getWheelFromObjA(wtObjA, labels[i]);
  124. } else {
  125. w[i] = [getWheelFromObjA(wtObjA, labels[i])];
  126. }
  127. j = 0;
  128. chInd = undefined;
  129. while (j < wtObjA.length && chInd === undefined) {
  130. if (wtObjA[j].key == wv[i] && ((index !== undefined && i <= index) || index === undefined)) {
  131. chInd = j;
  132. }
  133. j++;
  134. }
  135. if (chInd !== undefined && wtObjA[chInd].children) {
  136. i++;
  137. wtObjA = wtObjA[chInd].children;
  138. } else if ((obj = getFirstValidItemObjOrInd(wtObjA)) && obj.children) {
  139. i++;
  140. wtObjA = obj.children;
  141. } else {
  142. return w;
  143. }
  144. }
  145. return w;
  146. }
  147. /**
  148. * Returns the first valid Wheel Node Object or its index from a Wheel Node Object Array
  149. * getInd - if it is true then the return value is going to be the index, otherwise the object itself
  150. */
  151. function getFirstValidItemObjOrInd(wtObjA, getInd) {
  152. if (!wtObjA) {
  153. return false;
  154. }
  155. var i = 0,
  156. obj;
  157. while (i < wtObjA.length) {
  158. if (!(obj = wtObjA[i++]).invalid) {
  159. return getInd ? i - 1 : obj;
  160. }
  161. }
  162. return false;
  163. }
  164. function getWheelFromObjA(objA, lbl) {
  165. var wheel = {
  166. keys: [],
  167. values: [],
  168. label: lbl
  169. },
  170. j = 0;
  171. while (j < objA.length) {
  172. wheel.values.push(objA[j].value);
  173. wheel.keys.push(objA[j].key);
  174. j++;
  175. }
  176. return wheel;
  177. }
  178. /**
  179. * Hides the last i number of wheels
  180. * i - the last number of wheels that has to be hidden
  181. */
  182. function hideWheels(dw, i) {
  183. $('.dwfl', dw).css('display', '').slice(i).hide();
  184. }
  185. /**
  186. * Generates the first wheel vector from the wheeltree
  187. * wt - the wheel tree object
  188. * uses the lvl global variable to determine the length of the vector
  189. */
  190. function firstWheelVector(wa) {
  191. var t = [],
  192. ndObjA = wa,
  193. obj,
  194. ok = true,
  195. i = 0;
  196. while (ok) {
  197. obj = getFirstValidItemObjOrInd(ndObjA);
  198. t[i++] = obj.key;
  199. ok = obj.children;
  200. if (ok) {
  201. ndObjA = ok;
  202. }
  203. }
  204. return t;
  205. }
  206. /**
  207. * Calculates the level of a wheel vector and the new wheel vector, depending on current wheel vector and the index of the changed wheel
  208. * wv - current wheel vector
  209. * index - index of the changed wheel
  210. */
  211. function calcLevelOfVector2(wv, index) {
  212. var t = [],
  213. ndObjA = wa,
  214. lvl = 0,
  215. next = false,
  216. i,
  217. childName,
  218. chInd;
  219. if (wv[lvl] !== undefined && lvl <= index) {
  220. i = 0;
  221. childName = wv[lvl];
  222. chInd = undefined;
  223. while (i < ndObjA.length && chInd === undefined) {
  224. if (ndObjA[i].key == wv[lvl] && !ndObjA[i].invalid) {
  225. chInd = i;
  226. }
  227. i++;
  228. }
  229. } else {
  230. chInd = getFirstValidItemObjOrInd(ndObjA, true);
  231. childName = ndObjA[chInd].key;
  232. }
  233. next = chInd !== undefined ? ndObjA[chInd].children : false;
  234. t[lvl] = childName;
  235. while (next) {
  236. ndObjA = ndObjA[chInd].children;
  237. lvl++;
  238. next = false;
  239. chInd = undefined;
  240. if (wv[lvl] !== undefined && lvl <= index) {
  241. i = 0;
  242. childName = wv[lvl];
  243. chInd = undefined;
  244. while (i < ndObjA.length && chInd === undefined) {
  245. if (ndObjA[i].key == wv[lvl] && !ndObjA[i].invalid) {
  246. chInd = i;
  247. }
  248. i++;
  249. }
  250. } else {
  251. chInd = getFirstValidItemObjOrInd(ndObjA, true);
  252. chInd = chInd === false ? undefined : chInd;
  253. childName = ndObjA[chInd].key;
  254. }
  255. next = chInd !== undefined && getFirstValidItemObjOrInd(ndObjA[chInd].children) ? ndObjA[chInd].children : false;
  256. t[lvl] = childName;
  257. }
  258. return {
  259. lvl: lvl + 1,
  260. nVector: t
  261. }; // return the calculated level and the wheel vector as an object
  262. }
  263. function createWheelArray(ul) {
  264. var wheelArray = [];
  265. lvl = lvl > ilvl++ ? lvl : ilvl;
  266. ul.children('li').each(function (index) {
  267. var that = $(this),
  268. c = that.clone();
  269. c.children('ul,ol').remove();
  270. var v = inst._processMarkup ? inst._processMarkup(c) : c.html().replace(/^\s\s*/, '').replace(/\s\s*$/, ''),
  271. inv = that.attr('data-invalid') ? true : false,
  272. wheelObj = {
  273. key: that.attr('data-val') === undefined || that.attr('data-val') === null ? index : that.attr('data-val'),
  274. value: v,
  275. invalid: inv,
  276. children: null
  277. },
  278. nest = that.children('ul,ol');
  279. if (nest.length) {
  280. wheelObj.children = createWheelArray(nest);
  281. }
  282. wheelArray.push(wheelObj);
  283. });
  284. ilvl--;
  285. return wheelArray;
  286. }
  287. $('#' + id).remove(); // Remove input if exists
  288. if (s.showInput) {
  289. input = $('<input type="text" id="' + id + '" value="" class="' + s.inputClass + '" placeholder="' + (s.placeholder || '') + '" readonly />').insertBefore(elm);
  290. s.anchor = input; // give the core the input element for the bubble positioning
  291. inst.attachShow(input);
  292. }
  293. if (!s.wheelArray) {
  294. elm.hide().closest('.ui-field-contain').trigger('create');
  295. }
  296. return {
  297. width: 50,
  298. wheels: w,
  299. layout: layout,
  300. headerText: false,
  301. formatValue: function (d) {
  302. if (currLevel === undefined) {
  303. currLevel = calcLevelOfVector2(d, d.length).lvl;
  304. }
  305. return d.slice(0, currLevel).join(' ');
  306. },
  307. parseValue: function (value) {
  308. return value ? (value + '').split(' ') : (s.defaultValue || fwv).slice(0);
  309. },
  310. onBeforeShow: function () {
  311. var t = inst.getArrayVal(true);
  312. currWheelVector = t.slice(0);
  313. s.wheels = generateWheelsFromVector(t, lvl, lvl);
  314. prevent = true;
  315. },
  316. onValueFill: function (v) {
  317. currLevel = undefined;
  318. if (input) {
  319. input.val(v);
  320. }
  321. },
  322. onShow: function (dw) {
  323. $('.dwwl', dw).on('mousedown touchstart', function () {
  324. clearTimeout(timer[$('.dwwl', dw).index(this)]);
  325. });
  326. },
  327. onDestroy: function () {
  328. if (input) {
  329. input.remove();
  330. }
  331. elm.show();
  332. },
  333. validate: function (dw, index, time) {
  334. var args = [],
  335. t = inst.getArrayVal(true),
  336. i = (index || 0) + 1,
  337. j,
  338. o;
  339. if ((index !== undefined && currWheelVector[index] != t[index]) || (index === undefined && !prevent)) {
  340. s.wheels = generateWheelsFromVector(t, null, index);
  341. o = calcLevelOfVector2(t, index === undefined ? t.length : index);
  342. currLevel = o.lvl;
  343. for (j = 0; j < t.length; j++) {
  344. t[j] = o.nVector[j] || 0;
  345. }
  346. while (i < o.lvl) {
  347. args.push(i++);
  348. }
  349. if (args.length) {
  350. s.readonly = createROVector(lvl, index);
  351. clearTimeout(timer[index]);
  352. timer[index] = setTimeout(function () {
  353. prevent = true;
  354. hideWheels(dw, o.lvl);
  355. currWheelVector = t.slice(0);
  356. inst.changeWheel(args, index === undefined ? time : 0, index !== undefined);
  357. s.readonly = origReadOnly;
  358. }, index === undefined ? 0 : time * 1000);
  359. return false;
  360. }
  361. } else {
  362. o = calcLevelOfVector2(t, t.length);
  363. currLevel = o.lvl;
  364. }
  365. currWheelVector = t.slice(0);
  366. setDisabled(dw, o.lvl, wa, t);
  367. hideWheels(dw, o.lvl);
  368. prevent = false;
  369. }
  370. };
  371. };
  372. })(jQuery);