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.
 
 
 
 
 
 

989 lines
26 KiB

  1. // jquery.repeater version 1.1.3
  2. // https://github.com/DubFriend/jquery.repeater
  3. // (MIT) 06-12-2015
  4. // Brian Detering <BDeterin@gmail.com> (http://www.briandetering.net/)
  5. (function ($) {
  6. 'use strict';
  7. var identity = function (x) {
  8. return x;
  9. };
  10. var isArray = function (value) {
  11. return $.isArray(value);
  12. };
  13. var isObject = function (value) {
  14. return !isArray(value) && (value instanceof Object);
  15. };
  16. var isNumber = function (value) {
  17. return value instanceof Number;
  18. };
  19. var isFunction = function (value) {
  20. return value instanceof Function;
  21. };
  22. var indexOf = function (object, value) {
  23. return $.inArray(value, object);
  24. };
  25. var inArray = function (array, value) {
  26. return indexOf(array, value) !== -1;
  27. };
  28. var foreach = function (collection, callback) {
  29. for(var i in collection) {
  30. if(collection.hasOwnProperty(i)) {
  31. callback(collection[i], i, collection);
  32. }
  33. }
  34. };
  35. var last = function (array) {
  36. return array[array.length - 1];
  37. };
  38. var argumentsToArray = function (args) {
  39. return Array.prototype.slice.call(args);
  40. };
  41. var extend = function () {
  42. var extended = {};
  43. foreach(argumentsToArray(arguments), function (o) {
  44. foreach(o, function (val, key) {
  45. extended[key] = val;
  46. });
  47. });
  48. return extended;
  49. };
  50. var mapToArray = function (collection, callback) {
  51. var mapped = [];
  52. foreach(collection, function (value, key, coll) {
  53. mapped.push(callback(value, key, coll));
  54. });
  55. return mapped;
  56. };
  57. var mapToObject = function (collection, callback, keyCallback) {
  58. var mapped = {};
  59. foreach(collection, function (value, key, coll) {
  60. key = keyCallback ? keyCallback(key, value) : key;
  61. mapped[key] = callback(value, key, coll);
  62. });
  63. return mapped;
  64. };
  65. var map = function (collection, callback, keyCallback) {
  66. return isArray(collection) ?
  67. mapToArray(collection, callback) :
  68. mapToObject(collection, callback, keyCallback);
  69. };
  70. var pluck = function (arrayOfObjects, key) {
  71. return map(arrayOfObjects, function (val) {
  72. return val[key];
  73. });
  74. };
  75. var filter = function (collection, callback) {
  76. var filtered;
  77. if(isArray(collection)) {
  78. filtered = [];
  79. foreach(collection, function (val, key, coll) {
  80. if(callback(val, key, coll)) {
  81. filtered.push(val);
  82. }
  83. });
  84. }
  85. else {
  86. filtered = {};
  87. foreach(collection, function (val, key, coll) {
  88. if(callback(val, key, coll)) {
  89. filtered[key] = val;
  90. }
  91. });
  92. }
  93. return filtered;
  94. };
  95. var call = function (collection, functionName, args) {
  96. return map(collection, function (object, name) {
  97. return object[functionName].apply(object, args || []);
  98. });
  99. };
  100. //execute callback immediately and at most one time on the minimumInterval,
  101. //ignore block attempts
  102. var throttle = function (minimumInterval, callback) {
  103. var timeout = null;
  104. return function () {
  105. var that = this, args = arguments;
  106. if(timeout === null) {
  107. timeout = setTimeout(function () {
  108. timeout = null;
  109. }, minimumInterval);
  110. callback.apply(that, args);
  111. }
  112. };
  113. };
  114. var mixinPubSub = function (object) {
  115. object = object || {};
  116. var topics = {};
  117. object.publish = function (topic, data) {
  118. foreach(topics[topic], function (callback) {
  119. callback(data);
  120. });
  121. };
  122. object.subscribe = function (topic, callback) {
  123. topics[topic] = topics[topic] || [];
  124. topics[topic].push(callback);
  125. };
  126. object.unsubscribe = function (callback) {
  127. foreach(topics, function (subscribers) {
  128. var index = indexOf(subscribers, callback);
  129. if(index !== -1) {
  130. subscribers.splice(index, 1);
  131. }
  132. });
  133. };
  134. return object;
  135. };
  136. // jquery.input version 0.0.0
  137. // https://github.com/DubFriend/jquery.input
  138. // (MIT) 09-04-2014
  139. // Brian Detering <BDeterin@gmail.com> (http://www.briandetering.net/)
  140. (function ($) {
  141. 'use strict';
  142. var createBaseInput = function (fig, my) {
  143. var self = mixinPubSub(),
  144. $self = fig.$;
  145. self.getType = function () {
  146. throw 'implement me (return type. "text", "radio", etc.)';
  147. };
  148. self.$ = function (selector) {
  149. return selector ? $self.find(selector) : $self;
  150. };
  151. self.disable = function () {
  152. self.$().prop('disabled', true);
  153. self.publish('isEnabled', false);
  154. };
  155. self.enable = function () {
  156. self.$().prop('disabled', false);
  157. self.publish('isEnabled', true);
  158. };
  159. my.equalTo = function (a, b) {
  160. return a === b;
  161. };
  162. my.publishChange = (function () {
  163. var oldValue;
  164. return function (e, domElement) {
  165. var newValue = self.get();
  166. if(!my.equalTo(newValue, oldValue)) {
  167. self.publish('change', { e: e, domElement: domElement });
  168. }
  169. oldValue = newValue;
  170. };
  171. }());
  172. return self;
  173. };
  174. var createInput = function (fig, my) {
  175. var self = createBaseInput(fig, my);
  176. self.get = function () {
  177. return self.$().val();
  178. };
  179. self.set = function (newValue) {
  180. self.$().val(newValue);
  181. };
  182. self.clear = function () {
  183. self.set('');
  184. };
  185. my.buildSetter = function (callback) {
  186. return function (newValue) {
  187. callback.call(self, newValue);
  188. };
  189. };
  190. return self;
  191. };
  192. var inputEqualToArray = function (a, b) {
  193. a = isArray(a) ? a : [a];
  194. b = isArray(b) ? b : [b];
  195. var isEqual = true;
  196. if(a.length !== b.length) {
  197. isEqual = false;
  198. }
  199. else {
  200. foreach(a, function (value) {
  201. if(!inArray(b, value)) {
  202. isEqual = false;
  203. }
  204. });
  205. }
  206. return isEqual;
  207. };
  208. var createInputButton = function (fig) {
  209. var my = {},
  210. self = createInput(fig, my);
  211. self.getType = function () {
  212. return 'button';
  213. };
  214. self.$().on('change', function (e) {
  215. my.publishChange(e, this);
  216. });
  217. return self;
  218. };
  219. var createInputCheckbox = function (fig) {
  220. var my = {},
  221. self = createInput(fig, my);
  222. self.getType = function () {
  223. return 'checkbox';
  224. };
  225. self.get = function () {
  226. var values = [];
  227. self.$().filter(':checked').each(function () {
  228. values.push($(this).val());
  229. });
  230. return values;
  231. };
  232. self.set = function (newValues) {
  233. newValues = isArray(newValues) ? newValues : [newValues];
  234. self.$().each(function () {
  235. $(this).prop('checked', false);
  236. });
  237. foreach(newValues, function (value) {
  238. self.$().filter('[value="' + value + '"]')
  239. .prop('checked', true);
  240. });
  241. };
  242. my.equalTo = inputEqualToArray;
  243. self.$().change(function (e) {
  244. my.publishChange(e, this);
  245. });
  246. return self;
  247. };
  248. var createInputEmail = function (fig) {
  249. var my = {},
  250. self = createInputText(fig, my);
  251. self.getType = function () {
  252. return 'email';
  253. };
  254. return self;
  255. };
  256. var createInputFile = function (fig) {
  257. var my = {},
  258. self = createBaseInput(fig, my);
  259. self.getType = function () {
  260. return 'file';
  261. };
  262. self.get = function () {
  263. return last(self.$().val().split('\\'));
  264. };
  265. self.clear = function () {
  266. // http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery
  267. this.$().each(function () {
  268. $(this).wrap('<form>').closest('form').get(0).reset();
  269. $(this).unwrap();
  270. });
  271. };
  272. self.$().change(function (e) {
  273. my.publishChange(e, this);
  274. // self.publish('change', self);
  275. });
  276. return self;
  277. };
  278. var createInputHidden = function (fig) {
  279. var my = {},
  280. self = createInput(fig, my);
  281. self.getType = function () {
  282. return 'hidden';
  283. };
  284. self.$().change(function (e) {
  285. my.publishChange(e, this);
  286. });
  287. return self;
  288. };
  289. var createInputMultipleFile = function (fig) {
  290. var my = {},
  291. self = createBaseInput(fig, my);
  292. self.getType = function () {
  293. return 'file[multiple]';
  294. };
  295. self.get = function () {
  296. // http://stackoverflow.com/questions/14035530/how-to-get-value-of-html-5-multiple-file-upload-variable-using-jquery
  297. var fileListObject = self.$().get(0).files || [],
  298. names = [], i;
  299. for(i = 0; i < (fileListObject.length || 0); i += 1) {
  300. names.push(fileListObject[i].name);
  301. }
  302. return names;
  303. };
  304. self.clear = function () {
  305. // http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery
  306. this.$().each(function () {
  307. $(this).wrap('<form>').closest('form').get(0).reset();
  308. $(this).unwrap();
  309. });
  310. };
  311. self.$().change(function (e) {
  312. my.publishChange(e, this);
  313. });
  314. return self;
  315. };
  316. var createInputMultipleSelect = function (fig) {
  317. var my = {},
  318. self = createInput(fig, my);
  319. self.getType = function () {
  320. return 'select[multiple]';
  321. };
  322. self.get = function () {
  323. return self.$().val() || [];
  324. };
  325. self.set = function (newValues) {
  326. self.$().val(
  327. newValues === '' ? [] : isArray(newValues) ? newValues : [newValues]
  328. );
  329. };
  330. my.equalTo = inputEqualToArray;
  331. self.$().change(function (e) {
  332. my.publishChange(e, this);
  333. });
  334. return self;
  335. };
  336. var createInputPassword = function (fig) {
  337. var my = {},
  338. self = createInputText(fig, my);
  339. self.getType = function () {
  340. return 'password';
  341. };
  342. return self;
  343. };
  344. var createInputRadio = function (fig) {
  345. var my = {},
  346. self = createInput(fig, my);
  347. self.getType = function () {
  348. return 'radio';
  349. };
  350. self.get = function () {
  351. return self.$().filter(':checked').val() || null;
  352. };
  353. self.set = function (newValue) {
  354. if(!newValue) {
  355. self.$().each(function () {
  356. $(this).prop('checked', false);
  357. });
  358. }
  359. else {
  360. self.$().filter('[value="' + newValue + '"]').prop('checked', true);
  361. }
  362. };
  363. self.$().change(function (e) {
  364. my.publishChange(e, this);
  365. });
  366. return self;
  367. };
  368. var createInputRange = function (fig) {
  369. var my = {},
  370. self = createInput(fig, my);
  371. self.getType = function () {
  372. return 'range';
  373. };
  374. self.$().change(function (e) {
  375. my.publishChange(e, this);
  376. });
  377. return self;
  378. };
  379. var createInputSelect = function (fig) {
  380. var my = {},
  381. self = createInput(fig, my);
  382. self.getType = function () {
  383. return 'select';
  384. };
  385. self.$().change(function (e) {
  386. my.publishChange(e, this);
  387. });
  388. return self;
  389. };
  390. var createInputText = function (fig) {
  391. var my = {},
  392. self = createInput(fig, my);
  393. self.getType = function () {
  394. return 'text';
  395. };
  396. self.$().on('change keyup keydown', function (e) {
  397. my.publishChange(e, this);
  398. });
  399. return self;
  400. };
  401. var createInputTextarea = function (fig) {
  402. var my = {},
  403. self = createInput(fig, my);
  404. self.getType = function () {
  405. return 'textarea';
  406. };
  407. self.$().on('change keyup keydown', function (e) {
  408. my.publishChange(e, this);
  409. });
  410. return self;
  411. };
  412. var createInputURL = function (fig) {
  413. var my = {},
  414. self = createInputText(fig, my);
  415. self.getType = function () {
  416. return 'url';
  417. };
  418. return self;
  419. };
  420. var buildFormInputs = function (fig) {
  421. var inputs = {},
  422. $self = fig.$;
  423. var constructor = fig.constructorOverride || {
  424. button: createInputButton,
  425. text: createInputText,
  426. url: createInputURL,
  427. email: createInputEmail,
  428. password: createInputPassword,
  429. range: createInputRange,
  430. textarea: createInputTextarea,
  431. select: createInputSelect,
  432. 'select[multiple]': createInputMultipleSelect,
  433. radio: createInputRadio,
  434. checkbox: createInputCheckbox,
  435. file: createInputFile,
  436. 'file[multiple]': createInputMultipleFile,
  437. hidden: createInputHidden
  438. };
  439. var addInputsBasic = function (type, selector) {
  440. var $input = isObject(selector) ? selector : $self.find(selector);
  441. $input.each(function () {
  442. var name = $(this).attr('name');
  443. inputs[name] = constructor[type]({
  444. $: $(this)
  445. });
  446. });
  447. };
  448. var addInputsGroup = function (type, selector) {
  449. var names = [],
  450. $input = isObject(selector) ? selector : $self.find(selector);
  451. if(isObject(selector)) {
  452. inputs[$input.attr('name')] = constructor[type]({
  453. $: $input
  454. });
  455. }
  456. else {
  457. // group by name attribute
  458. $input.each(function () {
  459. if(indexOf(names, $(this).attr('name')) === -1) {
  460. names.push($(this).attr('name'));
  461. }
  462. });
  463. foreach(names, function (name) {
  464. inputs[name] = constructor[type]({
  465. $: $self.find('input[name="' + name + '"]')
  466. });
  467. });
  468. }
  469. };
  470. if($self.is('input, select, textarea')) {
  471. if($self.is('input[type="button"], button, input[type="submit"]')) {
  472. addInputsBasic('button', $self);
  473. }
  474. else if($self.is('textarea')) {
  475. addInputsBasic('textarea', $self);
  476. }
  477. else if(
  478. $self.is('input[type="text"]') ||
  479. $self.is('input') && !$self.attr('type')
  480. ) {
  481. addInputsBasic('text', $self);
  482. }
  483. else if($self.is('input[type="password"]')) {
  484. addInputsBasic('password', $self);
  485. }
  486. else if($self.is('input[type="email"]')) {
  487. addInputsBasic('email', $self);
  488. }
  489. else if($self.is('input[type="url"]')) {
  490. addInputsBasic('url', $self);
  491. }
  492. else if($self.is('input[type="range"]')) {
  493. addInputsBasic('range', $self);
  494. }
  495. else if($self.is('select')) {
  496. if($self.is('[multiple]')) {
  497. addInputsBasic('select[multiple]', $self);
  498. }
  499. else {
  500. addInputsBasic('select', $self);
  501. }
  502. }
  503. else if($self.is('input[type="file"]')) {
  504. if($self.is('[multiple]')) {
  505. addInputsBasic('file[multiple]', $self);
  506. }
  507. else {
  508. addInputsBasic('file', $self);
  509. }
  510. }
  511. else if($self.is('input[type="hidden"]')) {
  512. addInputsBasic('hidden', $self);
  513. }
  514. else if($self.is('input[type="radio"]')) {
  515. addInputsGroup('radio', $self);
  516. }
  517. else if($self.is('input[type="checkbox"]')) {
  518. addInputsGroup('checkbox', $self);
  519. }
  520. else {
  521. //in all other cases default to a "text" input interface.
  522. addInputsBasic('text', $self);
  523. }
  524. }
  525. else {
  526. addInputsBasic('button', 'input[type="button"], button, input[type="submit"]');
  527. addInputsBasic('text', 'input[type="text"]');
  528. addInputsBasic('password', 'input[type="password"]');
  529. addInputsBasic('email', 'input[type="email"]');
  530. addInputsBasic('url', 'input[type="url"]');
  531. addInputsBasic('range', 'input[type="range"]');
  532. addInputsBasic('textarea', 'textarea');
  533. addInputsBasic('select', 'select:not([multiple])');
  534. addInputsBasic('select[multiple]', 'select[multiple]');
  535. addInputsBasic('file', 'input[type="file"]:not([multiple])');
  536. addInputsBasic('file[multiple]', 'input[type="file"][multiple]');
  537. addInputsBasic('hidden', 'input[type="hidden"]');
  538. addInputsGroup('radio', 'input[type="radio"]');
  539. addInputsGroup('checkbox', 'input[type="checkbox"]');
  540. }
  541. return inputs;
  542. };
  543. $.fn.inputVal = function (newValue) {
  544. var $self = $(this);
  545. var inputs = buildFormInputs({ $: $self });
  546. if($self.is('input, textarea, select')) {
  547. if(typeof newValue === 'undefined') {
  548. return inputs[$self.attr('name')].get();
  549. }
  550. else {
  551. inputs[$self.attr('name')].set(newValue);
  552. return $self;
  553. }
  554. }
  555. else {
  556. if(typeof newValue === 'undefined') {
  557. return call(inputs, 'get');
  558. }
  559. else {
  560. foreach(newValue, function (value, inputName) {
  561. inputs[inputName].set(value);
  562. });
  563. return $self;
  564. }
  565. }
  566. };
  567. $.fn.inputOnChange = function (callback) {
  568. var $self = $(this);
  569. var inputs = buildFormInputs({ $: $self });
  570. foreach(inputs, function (input) {
  571. input.subscribe('change', function (data) {
  572. callback.call(data.domElement, data.e);
  573. });
  574. });
  575. return $self;
  576. };
  577. $.fn.inputDisable = function () {
  578. var $self = $(this);
  579. call(buildFormInputs({ $: $self }), 'disable');
  580. return $self;
  581. };
  582. $.fn.inputEnable = function () {
  583. var $self = $(this);
  584. call(buildFormInputs({ $: $self }), 'enable');
  585. return $self;
  586. };
  587. $.fn.inputClear = function () {
  588. var $self = $(this);
  589. call(buildFormInputs({ $: $self }), 'clear');
  590. return $self;
  591. };
  592. }(jQuery));
  593. $.fn.repeaterVal = function () {
  594. var parse = function (raw) {
  595. var parsed = [];
  596. foreach(raw, function (val, key) {
  597. var parsedKey = [];
  598. if(key !== "undefined") {
  599. parsedKey.push(key.match(/^[^\[]*/)[0]);
  600. parsedKey = parsedKey.concat(map(
  601. key.match(/\[[^\]]*\]/g),
  602. function (bracketed) {
  603. return bracketed.replace(/[\[\]]/g, '');
  604. }
  605. ));
  606. parsed.push({
  607. val: val,
  608. key: parsedKey
  609. });
  610. }
  611. });
  612. return parsed;
  613. };
  614. var build = function (parsed) {
  615. if(
  616. parsed.length === 1 &&
  617. (parsed[0].key.length === 0 || parsed[0].key.length === 1 && !parsed[0].key[0])
  618. ) {
  619. return parsed[0].val;
  620. }
  621. foreach(parsed, function (p) {
  622. p.head = p.key.shift();
  623. });
  624. var grouped = (function () {
  625. var grouped = {};
  626. foreach(parsed, function (p) {
  627. if(!grouped[p.head]) {
  628. grouped[p.head] = [];
  629. }
  630. grouped[p.head].push(p);
  631. });
  632. return grouped;
  633. }());
  634. var built;
  635. if(/^[0-9]+$/.test(parsed[0].head)) {
  636. built = [];
  637. foreach(grouped, function (group) {
  638. built.push(build(group));
  639. });
  640. }
  641. else {
  642. built = {};
  643. foreach(grouped, function (group, key) {
  644. built[key] = build(group);
  645. });
  646. }
  647. return built;
  648. };
  649. return build(parse($(this).inputVal()));
  650. };
  651. $.fn.repeater = function (fig) {
  652. fig = fig || {};
  653. $(this).each(function () {
  654. var $self = $(this);
  655. var show = fig.show || function () {
  656. $(this).show();
  657. };
  658. var hide = fig.hide || function (removeElement) {
  659. removeElement();
  660. };
  661. var $list = $self.find('[data-repeater-list]').first();
  662. var $filterNested = function ($items, repeaters) {
  663. return $items.filter(function () {
  664. return repeaters ?
  665. $(this).closest(
  666. pluck(repeaters, 'selector').join(',')
  667. ).length === 0 : true;
  668. });
  669. };
  670. var $items = function () {
  671. return $filterNested($list.find('[data-repeater-item]'), fig.repeaters);
  672. };
  673. var $itemTemplate = $list.find('[data-repeater-item]')
  674. .first().clone().hide();
  675. var $firstDeleteButton = $(this).find('[data-repeater-item]').first()
  676. .find('[data-repeater-delete]');
  677. if(fig.isFirstItemUndeletable && $firstDeleteButton) {
  678. $firstDeleteButton.remove();
  679. }
  680. var getGroupName = function () {
  681. var groupName = $list.data('repeater-list');
  682. return fig.$parent ?
  683. fig.$parent.data('item-name') + '[' + groupName + ']' :
  684. groupName;
  685. };
  686. var initNested = function ($listItems) {
  687. if(fig.repeaters) {
  688. $listItems.each(function () {
  689. var $item = $(this);
  690. foreach(fig.repeaters, function (nestedFig) {
  691. $item.find(nestedFig.selector).repeater(extend(
  692. nestedFig, { $parent: $item }
  693. ));
  694. });
  695. });
  696. }
  697. };
  698. var $foreachRepeaterInItem = function (repeaters, $item, cb) {
  699. if(repeaters) {
  700. foreach(repeaters, function (nestedFig) {
  701. cb.call($item.find(nestedFig.selector)[0], nestedFig);
  702. });
  703. }
  704. };
  705. var setIndexes = function ($items, groupName, repeaters) {
  706. $items.each(function (index) {
  707. var $item = $(this);
  708. $item.data('item-name', groupName + '[' + index + ']');
  709. $filterNested($item.find('[name]'), repeaters)
  710. .each(function () {
  711. var $input = $(this);
  712. // match non empty brackets (ex: "[foo]")
  713. var matches = $input.attr('name').match(/\[[^\]]+\]/g);
  714. var name = matches ?
  715. // strip "[" and "]" characters
  716. last(matches).replace(/\[|\]/g, '') :
  717. $input.attr('name');
  718. var newName = groupName + '[' + index + '][' + name + ']' +
  719. ($input.is(':checkbox') || $input.attr('multiple') ? '[]' : '');
  720. $input.attr('name', newName);
  721. $foreachRepeaterInItem(repeaters, $item, function (nestedFig) {
  722. var $repeater = $(this);
  723. setIndexes(
  724. $filterNested($repeater.find('[data-repeater-item]'), nestedFig.repeaters || []),
  725. groupName + '[' + index + ']' +
  726. '[' + $repeater.find('[data-repeater-list]').first().data('repeater-list') + ']',
  727. nestedFig.repeaters
  728. );
  729. });
  730. });
  731. });
  732. $list.find('input[name][checked]')
  733. .removeAttr('checked')
  734. .prop('checked', true);
  735. };
  736. setIndexes($items(), getGroupName(), fig.repeaters);
  737. initNested($items());
  738. if(fig.ready) {
  739. fig.ready(function () {
  740. setIndexes($items(), getGroupName(), fig.repeaters);
  741. });
  742. }
  743. var appendItem = (function () {
  744. var setItemsValues = function ($item, values, repeaters) {
  745. if(values) {
  746. var inputNames = {};
  747. $filterNested($item.find('[name]'), repeaters).each(function () {
  748. var key = $(this).attr('name').match(/\[([^\]]*)(\]|\]\[\])$/)[1];
  749. inputNames[key] = $(this).attr('name');
  750. });
  751. $item.inputVal(map(values, identity, function (name) {
  752. return inputNames[name];
  753. }));
  754. }
  755. $foreachRepeaterInItem(repeaters, $item, function (nestedFig) {
  756. var $repeater = $(this);
  757. $filterNested(
  758. $repeater.find('[data-repeater-item]'),
  759. nestedFig.repeaters
  760. )
  761. .each(function () {
  762. setItemsValues(
  763. $(this),
  764. nestedFig.defaultValues,
  765. nestedFig.repeaters || []
  766. );
  767. });
  768. });
  769. };
  770. return function ($item) {
  771. $list.append($item);
  772. setIndexes($items(), getGroupName(), fig.repeaters);
  773. $item.find('[name]').each(function () {
  774. $(this).inputClear();
  775. });
  776. setItemsValues($item, fig.defaultValues, fig.repeaters);
  777. };
  778. }());
  779. var addItem = function () {
  780. var $item = $itemTemplate.clone();
  781. appendItem($item);
  782. if(fig.repeaters) {
  783. initNested($item);
  784. }
  785. show.call($item.get(0));
  786. };
  787. $self.children().each(function () {
  788. if(
  789. !$(this).is('[data-repeater-list]') &&
  790. $(this).find('[data-repeater-list]').length === 0
  791. ) {
  792. if($(this).is('[data-repeater-create]')) {
  793. $(this).click(addItem);
  794. }
  795. else if($(this).find('[data-repeater-create]').length !== 0) {
  796. $(this).find('[data-repeater-create]').click(addItem);
  797. }
  798. }
  799. });
  800. $list.on('click', '[data-repeater-delete]', function () {
  801. var self = $(this).closest('[data-repeater-item]').get(0);
  802. hide.call(self, function () {
  803. $(self).remove();
  804. setIndexes($items(), getGroupName(), fig.repeaters);
  805. });
  806. });
  807. });
  808. return this;
  809. };
  810. }(jQuery));