Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

1701 wiersze
59 KiB

  1. /*!
  2. * Monday Webforms for CoreMedia v1.9.0, (c) 2018 Monday Consulting GmbH
  3. *
  4. * @see https://monday-webforms.com/
  5. */
  6. /*global define, window, document, jQuery, exports, require */
  7. ;(function(factory) {
  8. "use strict";
  9. if (typeof define === 'function' && define.amd) {
  10. // AMD. Register as an anonymous module.
  11. define(['jquery'], factory);
  12. } else if (typeof exports === 'object' && typeof require === 'function') {
  13. // Node/CommonJS
  14. factory(require('jquery'));
  15. } else {
  16. // Browser globals
  17. factory(jQuery);
  18. }
  19. }(function($) {
  20. "use strict";
  21. // polyfill for customevent for IE10
  22. (function() {
  23. function CustomEvent(event, params) {
  24. params = params || {bubbles: false, cancelable: false, detail: undefined};
  25. var evt = document.createEvent('CustomEvent');
  26. evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
  27. return evt;
  28. }
  29. CustomEvent.prototype = window.Event.prototype;
  30. window.CustomEvent = CustomEvent;
  31. })();
  32. var EVENTS = {
  33. AJAX_FINISHED: "mwf-ajax-finished",
  34. AJAX_ERROR: "mwf-ajax-error",
  35. FILL_DROPDOWN: "mwf-fill-dropdown",
  36. FILL_SELECTION: "mwf-fill-selection",
  37. FILL_HIDDEN: "mwf-fill-hidden",
  38. SUGGESTION_SELECTED: "mwf-suggestion-selected",
  39. VALUE_CHANGED: "mwf-value-changed"
  40. },
  41. defaultSettings = {};
  42. function triggerEvent(el, eventName, options) {
  43. var event;
  44. if (window.CustomEvent) {
  45. event = new CustomEvent(eventName, options);
  46. } else {
  47. event = document.createEvent('CustomEvent');
  48. event.initCustomEvent(eventName, true, true, options);
  49. }
  50. el.dispatchEvent(event);
  51. }
  52. function defaultsInternal(variant) {
  53. return variant === undefined ?
  54. defaultSettings.default : $.extend(true, {}, defaultSettings.default, defaultSettings[variant]);
  55. }
  56. /**
  57. * Monday Webforms jQuery-Plugin
  58. * @constructor
  59. */
  60. function Webforms(elem, settings) {
  61. var
  62. plugin = this,
  63. $elem = $(elem),
  64. operators = {},
  65. formdata = {},
  66. filenames = {},
  67. uiState = {
  68. visible: {},
  69. hidden: {},
  70. writable: {},
  71. readonly: {},
  72. optional: {},
  73. mandatory: {},
  74. disabled: {},
  75. enabled: {}
  76. },
  77. stateMapping = {
  78. visible: 'hidden',
  79. hidden: 'visible',
  80. writable: 'readonly',
  81. readonly: 'writable',
  82. optional: 'mandatory',
  83. mandatory: 'optional',
  84. disabled: 'enabled',
  85. enabled: 'disabled'
  86. },
  87. $form = $elem.is('form') ? $elem : $elem.find("form"),
  88. formName = $form.data('mwf-form'),
  89. formId = $form.data('mwf-id'),
  90. targetUrl = null,
  91. statisticsUrl = settings.statisticsUrl;
  92. if (!statisticsUrl || 0 === statisticsUrl.length) {
  93. statisticsUrl = null
  94. }
  95. if (formId === undefined) {
  96. formId = formName;
  97. }
  98. plugin.settings = settings;
  99. targetUrl = plugin.settings.url;
  100. /* internal utility functions
  101. ----------------------------------------------------------------------------------------------------------- */
  102. function updateUI(fields, conditionId, cond) {
  103. var s, i, inverseState, isTrue, isFalse, state, input,
  104. conditionalFieldsState = {
  105. 'visible': [], 'hidden': [],
  106. 'writable': [], 'readonly': [],
  107. 'optional': [], 'mandatory': [],
  108. 'enabled': [], 'disabled': []
  109. };
  110. // clear UI state of this condition
  111. for (s in uiState) {
  112. if (uiState.hasOwnProperty(s)) {
  113. delete uiState[s][conditionId];
  114. }
  115. }
  116. for (i = 0; i < fields.length; i++) {
  117. input = fields[i].input;
  118. state = fields[i].state;
  119. if (cond) {
  120. conditionalFieldsState[state].push(input);
  121. }
  122. uiState[state][conditionId] = conditionalFieldsState[state];
  123. inverseState = stateMapping[state];
  124. isTrue = containsState(state, input);
  125. isFalse = containsState(inverseState, input);
  126. if (isTrue) {
  127. plugin.settings.operations[state]($form, fields[i]);
  128. if (plugin.settings.onConditionTrue !== undefined) {
  129. plugin.settings.onConditionTrue($form, fields[i], state);
  130. }
  131. } else if (isFalse || !isTrue) {
  132. plugin.settings.operations[inverseState]($form, fields[i]);
  133. if (plugin.settings.onConditionFalse !== undefined) {
  134. plugin.settings.onConditionFalse($form, fields[i], inverseState);
  135. }
  136. }
  137. }
  138. }
  139. function containsState(type, input) {
  140. var state = uiState[type], cond;
  141. for (cond in state) {
  142. if (state.hasOwnProperty(cond) && $.inArray(input, state[cond]) > -1) {
  143. return true;
  144. }
  145. }
  146. return false;
  147. }
  148. function valueChanged($elem) {
  149. if (!$elem.is(":file")) {
  150. formdata = serializeForm($form);
  151. $form.trigger("mwf-valuechange", $elem);
  152. }
  153. }
  154. function serializeForm($form) {
  155. var o = {}, a = $form.serializeArray(), name;
  156. $.each(a, function() {
  157. var $input = $form.find('[name="' + this.name + '"]'),
  158. value = this.value || '',
  159. key;
  160. if (value === 'EMPTY_VALUE') value = '';
  161. if ($input.is(':radio') || $input.is(':checkbox') || $input.is('select')) {
  162. if (!o.hasOwnProperty(this.name)) {
  163. o[this.name] = [];
  164. }
  165. try {
  166. key = JSON.parse(value).k;
  167. } catch (ex) {
  168. // do nothing
  169. }
  170. o[this.name].push((key !== undefined) ? key : value);
  171. } else if ($input.is(':hidden')) {
  172. try {
  173. key = JSON.parse(value).v;
  174. } catch (ex) {
  175. // do nothing
  176. }
  177. o[this.name] = (key !== undefined) ? key : value;
  178. } else {
  179. o[this.name] = value;
  180. }
  181. });
  182. $form.find("input:checkbox:not(:checked),input:radio:not(:checked)").each(function() {
  183. name = $(this).attr('name');
  184. if (!o.hasOwnProperty(name)) {
  185. o[name] = '';
  186. }
  187. });
  188. return o;
  189. }
  190. function valueLabel(name, v) {
  191. var l = [];
  192. $.each($form.find('[name="' + name + '"]'), function() {
  193. var $input = $(this);
  194. if ($input.is(':radio') || $input.is(':checkbox')) {
  195. if ($.inArray($input.data('mwf-value'), v) !== -1) {
  196. l.push($input.data('mwf-label'));
  197. }
  198. } else if ($input.is('select')) {
  199. $.each($input.find('option'), function() {
  200. var $option = $(this);
  201. if ($.inArray($option.data('mwf-value'), v) !== -1) {
  202. l.push($option.data('mwf-label'));
  203. }
  204. });
  205. } else if ($input.is(':file')) {
  206. $.merge(l, filenames[name]);
  207. } else {
  208. l.push(v);
  209. }
  210. });
  211. return l;
  212. }
  213. /* API functions
  214. ----------------------------------------------------------------------------------------------------------- */
  215. function maxSelected(array, max) {
  216. var m = Number(max), l = (array !== null) ? array.length : 0;
  217. return (l < m);
  218. }
  219. function minSelected(array, min) {
  220. var m = Number(min), l = (array !== null) ? array.length : 0;
  221. return (l > m);
  222. }
  223. function isSelected(array, s) {
  224. return array !== null && $.inArray(s, array) > -1;
  225. }
  226. function parseAge(format, str) {
  227. if (str === null) {
  228. return null;
  229. }
  230. var date = parseDate(format, str), today = new Date();
  231. return Math.floor((today - date) / (365.25 * 24 * 60 * 60 * 1000));
  232. }
  233. function parseDate(format, date) {
  234. if (date === null) {
  235. return null;
  236. }
  237. return $.format.date(date, format);
  238. }
  239. function isEmptyList(array) {
  240. var i, s;
  241. if (array !== null) {
  242. for (i = 0; i < array.length; i++) {
  243. s = String(array[i]);
  244. if (s !== null && s !== '' && s !== 'EMPTY_VALUE') {
  245. return false;
  246. }
  247. }
  248. }
  249. return true;
  250. }
  251. function ajaxFillSelection($elem, attr, initial) {
  252. var data = $.extend(formdata, attr.data);
  253. if ((attr.createEntry === undefined)) {
  254. attr.createEntry = (attr.type === 'checkbox') ? plugin.settings.createCheckBox : plugin.settings.createRadio;
  255. }
  256. if ((attr.onFillSelection === undefined)) {
  257. attr.onFillSelection = plugin.settings.onFillSelection;
  258. }
  259. $.ajax({
  260. url: attr.url,
  261. type: 'POST',
  262. data: data,
  263. traditional: true,
  264. cache: false
  265. })
  266. .done(function(json) {
  267. var pre = attr.preselected.split(','), i, entry;
  268. $elem.find('[data-mwf-mutable]').remove();
  269. for (i in json) {
  270. if (json.hasOwnProperty(i)) {
  271. entry = json[i];
  272. $elem.append(attr.createEntry($form, attr.name, entry, $.inArray(entry.k, pre) !== -1));
  273. }
  274. }
  275. if (initial) $elem.trigger('change');
  276. attr.onFillSelection($form, $elem);
  277. triggerEvent(document, EVENTS.FILL_SELECTION, {detail: {$form: $form, $elem: $elem}});
  278. })
  279. .fail(function(jqXHR, textStatus, errorThrown) {
  280. plugin.settings.onAjaxError(jqXHR, textStatus, errorThrown);
  281. });
  282. }
  283. function ajaxFillHidden($elem, attr) {
  284. var data = $.extend(formdata, attr.data);
  285. $.ajax({
  286. url: attr.url,
  287. type: 'POST',
  288. data: data,
  289. traditional: true,
  290. cache: false
  291. })
  292. .done(function(json) {
  293. $elem.val(JSON.stringify(json));
  294. $elem.attr('data-mwf-value', json.v);
  295. $elem.trigger('change');
  296. triggerEvent(document, EVENTS.FILL_HIDDEN, {detail: {$form: $form, $elem: $elem}});
  297. })
  298. .fail(function(jqXHR, textStatus, errorThrown) {
  299. plugin.settings.onAjaxError(jqXHR, textStatus, errorThrown);
  300. });
  301. }
  302. function ajaxFillDropdown($elem, attr, initial) {
  303. var data = $.extend(formdata, attr.data);
  304. if ((attr.createOption === undefined)) {
  305. attr.createOption = plugin.settings.createOption;
  306. }
  307. if ((attr.onFillDropdown === undefined)) {
  308. attr.onFillDropdown = plugin.settings.onFillDropdown;
  309. }
  310. $.ajax({
  311. url: attr.url,
  312. type: 'POST',
  313. data: data,
  314. traditional: true,
  315. cache: false
  316. })
  317. .done(function(json) {
  318. var $option, i, entry, pre = attr.preselected.split(',');
  319. $elem.find('[data-mwf-mutable]').remove();
  320. for (i in json) {
  321. if (json.hasOwnProperty(i)) {
  322. entry = json[i];
  323. $option = attr.createOption($form, entry, $.inArray(entry.k, pre) !== -1);
  324. $elem.append($option);
  325. }
  326. }
  327. if (initial) $elem.trigger('change');
  328. attr.onFillDropdown($form, $elem);
  329. triggerEvent(document, EVENTS.FILL_DROPDOWN, {detail: {$form: $form, $elem: $elem}});
  330. })
  331. .fail(function(jqXHR, textStatus, errorThrown) {
  332. plugin.settings.onAjaxError(jqXHR, textStatus, errorThrown);
  333. });
  334. }
  335. function ajaxAutocomplete($elem, attr) {
  336. var chars = 1;
  337. if (attr.params.chars !== undefined) {
  338. chars = attr.params.chars;
  339. }
  340. var onSelect = function(selection) {
  341. triggerEvent(document, EVENTS.SUGGESTION_SELECTED, {
  342. detail: {
  343. $form: $form,
  344. $elem: $elem,
  345. id: formId,
  346. selection: selection,
  347. params: attr.params
  348. }
  349. });
  350. if ($.isFunction(attr.onSelect)) {
  351. attr.onSelect(arguments);
  352. }
  353. };
  354. $elem.autocomplete({
  355. paramName: 'query',
  356. params: attr.data,
  357. serviceUrl: attr.url,
  358. maxHeight: 150,
  359. noCache: true,
  360. minChars: chars,
  361. type: 'POST',
  362. onSelect: onSelect,
  363. autoSelectFirst: true,
  364. sendFormData: true,
  365. transformResult: function(response) {
  366. response = JSON.parse(response);
  367. return {
  368. suggestions: $.map(response, function(entry, key) {
  369. return {value: entry.v, data: entry.k};
  370. })
  371. };
  372. }
  373. });
  374. }
  375. function ajaxSubmit(opt) {
  376. var $buttons = $form.find(':button').filter(':not(:disabled)'),
  377. data = {_parentUrl: window.location.href};
  378. if (plugin.settings.appendUrlVars) {
  379. $.extend(data, $.getUrlVars(window.location.search));
  380. delete data.view;
  381. }
  382. $.extend(data, $.getUrlVars(opt.query), opt.data, $form.serializeObject());
  383. if (opt.onSubmit !== undefined) {
  384. if (!opt.onSubmit($form, opt.url, opt.query)) {
  385. return;
  386. }
  387. }
  388. $buttons.prop('disabled', true);
  389. $.ajax({
  390. url: opt.url,
  391. type: 'POST',
  392. data: data,
  393. traditional: true,
  394. cache: false
  395. })
  396. .done(function(data, textStatus, jqXHR) {
  397. if (jqXHR && jqXHR.getResponseHeader("webforms_redirect")) {
  398. if (opt.onRedirect !== undefined) {
  399. opt.onRedirect($form, data, textStatus, jqXHR);
  400. }
  401. var timeout = (jqXHR.getResponseHeader('webforms_redirect_delay') || 0) * 1000;
  402. setTimeout(function() {
  403. location.assign(jqXHR.getResponseHeader('webforms_redirect'));
  404. }, timeout);
  405. if (!timeout) {
  406. return;
  407. }
  408. }
  409. $elem = $elem.replaceWithPush(data);
  410. $form = $elem.is('form') ? $elem : $elem.find("form");
  411. if (opt.onSuccess !== undefined) {
  412. opt.onSuccess($form, data, textStatus, jqXHR);
  413. }
  414. triggerEvent(document, EVENTS.AJAX_FINISHED, {detail: {$dest: $elem}});
  415. })
  416. .fail(function(jqXHR, textStatus, errorThrown) {
  417. if (opt.onError !== undefined) {
  418. opt.onError($form, jqXHR, textStatus, errorThrown);
  419. }
  420. $buttons.prop('disabled', false);
  421. triggerEvent(document, EVENTS.AJAX_ERROR, {
  422. detail: {
  423. $dest: $elem,
  424. jqXHR: jqXHR,
  425. textStatus: textStatus,
  426. errorThrown: errorThrown
  427. }
  428. })
  429. });
  430. }
  431. function createCondition(conditionId, conjunction, conditions, fields) {
  432. var checkCondition = function() {
  433. var all = true, any = false, condTrue, i, formValue, cond;
  434. for (i = 0; i < conditions.length; i++) {
  435. cond = conditions[i];
  436. if (!cond) {
  437. continue;
  438. }
  439. formValue = formdata[cond[1]];
  440. if (formValue === undefined) {
  441. formValue = cond[4];
  442. }
  443. condTrue = operators[cond[2]](formValue, cond[3]);
  444. if (condTrue) {
  445. any = true;
  446. } else {
  447. all = false;
  448. }
  449. if (!conjunction && any) {
  450. break;
  451. }
  452. }
  453. updateUI(fields, conditionId, (all || (!conjunction && any)));
  454. };
  455. // register event listener
  456. $form.on('mwf-valuechange', function(e, input) {
  457. var cond, i;
  458. for (i = 0; i < conditions.length; i++) {
  459. cond = conditions[i];
  460. if (!cond) {
  461. continue;
  462. }
  463. if ($(input).attr("name") === conditions[i][1]) {
  464. checkCondition();
  465. }
  466. }
  467. });
  468. // check conditions initially
  469. checkCondition();
  470. if (plugin.settings.onConditionCreated !== undefined) {
  471. plugin.settings.onConditionCreated($form, conditionId, conjunction, conditions, fields);
  472. }
  473. }
  474. function createCalculatedValue(calcValueId, js, fields, formVariables, updateValue) {
  475. updateValue = (updateValue === undefined) ? plugin.settings.updateCalculatedValue : updateValue;
  476. var name,
  477. id = calcValueId,
  478. vars = formVariables,
  479. fct,
  480. calculate = function() {
  481. var state = $.extend({}, fields, formdata, vars),
  482. result = fct(state),
  483. $field = $form.find('[data-mwf-id="' + id + '"]');
  484. updateValue($form, id, result);
  485. $field.val(result).trigger('change');
  486. };
  487. try {
  488. eval('fct = function(s) {' + js + '}');
  489. } catch (ex) {
  490. $.logError(ex.message);
  491. }
  492. // register event listener
  493. $form.on('mwf-valuechange', function(e, input) {
  494. for (name in fields) {
  495. if (fields.hasOwnProperty(name) && $(input).attr('name') === name) {
  496. calculate();
  497. break;
  498. }
  499. }
  500. });
  501. }
  502. function recursiveEach(obj, callback, maxDeep) {
  503. var history = [], deep = -1, _recursiveEach;
  504. if (maxDeep === undefined) {
  505. maxDeep = Number.MAX_VALUE;
  506. }
  507. _recursiveEach = function(obj, callback) {
  508. var p, o, i, names = Object.getOwnPropertyNames(obj);
  509. deep++;
  510. for (i = 0; i < names.length; i++) {
  511. p = names[i];
  512. o = obj[p];
  513. if (typeof o === "object") {
  514. if (deep < maxDeep && $.inArray(o, history) === -1) {
  515. history.push(o);
  516. _recursiveEach(o, callback);
  517. }
  518. } else {
  519. if (callback.call(obj, obj, p, o) === false) {
  520. break;
  521. }
  522. }
  523. }
  524. deep--;
  525. };
  526. _recursiveEach(obj, callback);
  527. }
  528. /* condition operators
  529. ----------------------------------------------------------------------------------------------------------- */
  530. operators.contains = function(formValue, value) {
  531. if (formValue === null || value === null) {
  532. return false;
  533. }
  534. return formValue.indexOf(value) !== -1;
  535. };
  536. operators.containsnot = function(formValue, value) {
  537. if (formValue === null || value === null) {
  538. return false;
  539. }
  540. return formValue.indexOf(value) === -1;
  541. };
  542. operators.startswith = function(formValue, value) {
  543. if (formValue === null || value === null) {
  544. return false;
  545. }
  546. return formValue.match(new RegExp("^" + value)) == value;
  547. };
  548. operators.endswith = function(formValue, value) {
  549. if (formValue === null || value === null) {
  550. return false;
  551. }
  552. return formValue.match(new RegExp(value + "$")) == value;
  553. };
  554. operators.equal = function(formValue, value) {
  555. if (formValue === null || value === null) {
  556. return formValue === value;
  557. }
  558. var f1 = parseFloat(formValue.replace(',', '.')),
  559. f2 = parseFloat(value.replace(',', '.'));
  560. return (!isNaN(f1) && !isNaN(f2) && f1 === f2) || (formValue === value);
  561. };
  562. operators.notequal = function(formValue, value) {
  563. if (formValue === null || value === null) {
  564. return formValue !== value;
  565. }
  566. var f1 = parseFloat(formValue.replace(',', '.')),
  567. f2 = parseFloat(value.replace(',', '.'));
  568. return (!isNaN(f1) && !isNaN(f2) && f1 !== f2) || (formValue !== value);
  569. };
  570. operators.empty = function(formValue, value) {
  571. return formValue === null || formValue === '';
  572. };
  573. operators.notempty = function(formValue, value) {
  574. return formValue !== null && formValue !== '';
  575. };
  576. operators.emptylist = function(formValue, value) {
  577. return isEmptyList(formValue);
  578. };
  579. operators.notemptylist = function(formValue, value) {
  580. return !isEmptyList(formValue);
  581. };
  582. operators.selected = function(formValue, value) {
  583. if (formValue === null || value === null) {
  584. return false;
  585. }
  586. return $.inArray(value, formValue) !== -1;
  587. };
  588. operators.notselected = function(formValue, value) {
  589. if (formValue === null || value === null) {
  590. return false;
  591. }
  592. return $.inArray(value, formValue) === -1;
  593. };
  594. operators.minselected = function(formValue, value) {
  595. var l = (formValue === null) ? 0 : formValue.length;
  596. return l > Number(value);
  597. };
  598. operators.maxselected = function(formValue, value) {
  599. var l = (formValue === null) ? 0 : formValue.length;
  600. return l < Number(value);
  601. };
  602. operators.lessthan = function(formValue, value) {
  603. if (formValue === null || value === null) {
  604. return false;
  605. }
  606. var f1 = parseFloat(formValue.replace(',', '.')),
  607. f2 = parseFloat(value.replace(',', '.'));
  608. return (!isNaN(f1) && !isNaN(f2) && f1 < f2);
  609. };
  610. operators.greaterthan = function(formValue, value) {
  611. if (formValue === null || value === null) {
  612. return false;
  613. }
  614. var f1 = parseFloat(formValue.replace(',', '.')),
  615. f2 = parseFloat(value.replace(',', '.'));
  616. return (!isNaN(f1) && !isNaN(f2) && f1 > f2);
  617. };
  618. /* public methods
  619. ----------------------------------------------------------------------------------------------------------- */
  620. plugin.formSubmit = function(opt) {
  621. ajaxSubmit({
  622. url: targetUrl,
  623. id: formId,
  624. query: (opt.query !== undefined) ? opt.query : '',
  625. onSubmit: (opt.submit !== undefined) ? opt.submit : plugin.settings.onSubmit,
  626. onSuccess: (opt.success !== undefined) ? opt.success : plugin.settings.onSuccess,
  627. onError: (opt.error !== undefined) ? opt.error : plugin.settings.onAjaxError,
  628. onRedirect: (opt.redirect !== undefined) ? opt.redirect : plugin.settings.onRedirect
  629. });
  630. };
  631. plugin.gotoPage = function(opt) {
  632. ajaxSubmit({
  633. url: targetUrl,
  634. id: formId,
  635. query: opt.query.concat('&_target', opt.page, '=', opt.page),
  636. onSubmit: (opt.submit !== undefined) ? opt.submit : plugin.settings.onSubmit,
  637. onSuccess: (opt.success !== undefined) ? opt.success : plugin.settings.onSuccess,
  638. onError: (opt.error !== undefined) ? opt.error : plugin.settings.onAjaxError,
  639. onRedirect: (opt.redirect !== undefined) ? opt.redirect : plugin.settings.onRedirect
  640. });
  641. };
  642. plugin.init = function() {
  643. recursiveEach(settings, function(obj, property, value) {
  644. if (typeof value === 'string' && value.trim().substring(0, 8) === 'function') {
  645. try {
  646. eval('obj[property] =' + value);
  647. } catch (ex) {
  648. $.logError(ex.message);
  649. }
  650. }
  651. }, 1);
  652. formdata = serializeForm($form);
  653. $form.on('change', function(event) {
  654. valueChanged($(event.target));
  655. if (statisticsUrl !== null) {
  656. $.ajax({
  657. url: statisticsUrl
  658. });
  659. statisticsUrl = null;
  660. }
  661. });
  662. if (targetUrl === undefined) {
  663. $.logError('No target URL specified.')
  664. }
  665. $.each($form.find('[data-mwf-submit]'), function() {
  666. var attr = $(this).data('mwf-submit'),
  667. query = (attr.query !== undefined) ? attr.query : '',
  668. onSuccess = (attr.success !== undefined) ? attr.success : plugin.settings.onSuccess,
  669. onRedirect = (attr.redirect !== undefined) ? attr.redirect : plugin.settings.onRedirect,
  670. onError = (attr.error !== undefined) ? attr.error : plugin.settings.onAjaxError,
  671. onSubmit = (attr.submit !== undefined) ? attr.submit : plugin.settings.onSubmit;
  672. switch (attr.type) {
  673. case 'next':
  674. case 'back':
  675. case 'goto':
  676. query = query.concat('&_target', attr.page, '=', attr.page);
  677. break;
  678. case 'cancel':
  679. case 'exit':
  680. case 'finish':
  681. query = query.concat('&_', attr.type, '=1');
  682. break;
  683. }
  684. $(this).on('click', function() {
  685. ajaxSubmit({
  686. url: targetUrl,
  687. id: formId,
  688. query: query,
  689. onSubmit: onSubmit,
  690. onSuccess: onSuccess,
  691. onError: onError,
  692. onRedirect: onRedirect
  693. });
  694. });
  695. });
  696. $.each($form.find('[data-mwf-bind]'), function() {
  697. var name = $(this).data('mwf-bind'),
  698. $elem = $(this);
  699. $form.on('mwf-valuechange', function(e, input) {
  700. var v, l;
  701. if ($(input).attr('name') === name) {
  702. v = formdata[name];
  703. l = valueLabel(name, v);
  704. plugin.settings.updateFormValue($form, $elem, name, l);
  705. triggerEvent(document, EVENTS.VALUE_CHANGED, {
  706. detail: {
  707. $form: $form,
  708. $elem: $elem,
  709. name: name,
  710. value: l
  711. }
  712. });
  713. return false;
  714. }
  715. });
  716. });
  717. $.each($form.find('[data-mwf-fileupload]'), function() {
  718. var $upload = $(this),
  719. attr = $(this).data('mwf-fileupload'),
  720. $dropzone = $upload.find('[data-mwf-dropzone]'),
  721. $files = $upload.find('[data-mwf-files]'),
  722. $fileInput = $upload.find('input:file'),
  723. multiple = $fileInput.attr('multiple') !== undefined,
  724. useXhr = (!multiple && $.support.xhrFileUpload) || $.support.xhrFormDataFileUpload,
  725. count = 0,
  726. pendingList = [],
  727. errorRows = [],
  728. enabled = true,
  729. $buttons = null;
  730. $upload.find('[data-mwf-file-upload-all]').on('click', function() {
  731. pendingList.forEach(function(data) {
  732. data.submit();
  733. });
  734. pendingList = [];
  735. });
  736. $upload.find('[data-mwf-file-delete-all]').on('click', function() {
  737. $files.find('[data-mwf-file-delete]').trigger('click');
  738. pendingList = [];
  739. });
  740. $upload.on('disable', function() {
  741. enabled = false;
  742. $upload.fileupload('disable');
  743. $upload.addClass('mwf-upload-disabled');
  744. $upload.find(':button').prop('disabled', true);
  745. $fileInput.prop('disabled', true);
  746. });
  747. $upload.on('enable', function() {
  748. enabled = true;
  749. $upload.fileupload('enable');
  750. $upload.removeClass('mwf-upload-disabled');
  751. $upload.find(':button').prop('disabled', false);
  752. $fileInput.prop('disabled', false);
  753. });
  754. $dropzone.on('dragover', function() {
  755. if (enabled) {
  756. $(this).addClass('mwf-upload-dragover');
  757. }
  758. });
  759. $dropzone.on('dragleave drop', function() {
  760. $(this).removeClass('mwf-upload-dragover');
  761. });
  762. $upload.fileupload({
  763. url: attr.url,
  764. paramName: attr.name,
  765. dataType: 'json',
  766. dropZone: $dropzone,
  767. fileInput: $fileInput,
  768. previewMaxWidth: attr.previewMaxWidth,
  769. previewMaxHeight: attr.previewMaxHeight,
  770. previewCrop: true,
  771. maxNumberOfFiles: 1,
  772. formData: {xhr: useXhr},
  773. add: function(e, data) {
  774. var $this = $upload;
  775. if (!enabled) {
  776. return false;
  777. }
  778. $.each(errorRows, function(index, $row) {
  779. $row.remove();
  780. });
  781. if (multiple || count === 0) {
  782. count++;
  783. } else {
  784. return false;
  785. }
  786. pendingList.push(data);
  787. data.process(function() {
  788. return $this.fileupload('process', data);
  789. }).always(function() {
  790. $.each(data.files, function(index, file) {
  791. var $row = plugin.settings.createUploadFileRow($form, attr, file);
  792. data.context = $row;
  793. $row.find('[data-mwf-file-upload]').data(data).on('click', function() {
  794. pendingList.splice($.inArray(data, pendingList), 1);
  795. data.submit();
  796. });
  797. $row.find('[data-mwf-file-delete]').data(data).on('click', function() {
  798. $row.remove();
  799. pendingList.splice($.inArray(data, pendingList), 1);
  800. count--;
  801. });
  802. $row.find('[data-mwf-file-preview]').append(file.preview);
  803. $files.append($row);
  804. });
  805. if (attr.autoUpload === true) {
  806. data.submit();
  807. }
  808. });
  809. },
  810. submit: function(e, data) {
  811. if ($buttons === null) {
  812. $buttons = $form.find(':button').filter(':not(:disabled)');
  813. $buttons.prop('disabled', true);
  814. }
  815. },
  816. progress: function(e, data) {
  817. var progress = parseInt(data.loaded / data.total * 100, 10);
  818. if (data.context) {
  819. data.context.each(function() {
  820. data.context.find('[data-mwf-file-progress]').attr('aria-valuenow', progress).css('display', 'block').children().first().css('width', progress + '%').text(progress + '%');
  821. });
  822. }
  823. },
  824. done: function(e, data) {
  825. var files = (typeof data.result === 'string') ? JSON.parse(data.result).files : data.result.files;
  826. $.each(files, function(index, file) {
  827. var $row = plugin.settings.createDownloadFileRow($form, attr, file);
  828. if (data.context !== undefined) {
  829. data.context.replaceWith($row)
  830. } else {
  831. $files.append($row);
  832. }
  833. if (file.error === undefined) {
  834. $row.find('[data-mwf-file-delete]').on('click', function() {
  835. if (file.delete_url) {
  836. $.ajax({
  837. url: file.delete_url
  838. });
  839. }
  840. $row.remove();
  841. pendingList.splice($.inArray(data, pendingList), 1);
  842. // update filenames
  843. if (filenames.hasOwnProperty(attr.name)) {
  844. filenames[attr.name].splice($.inArray(file.name, filenames[attr.name]), 1);
  845. $form.trigger("mwf-valuechange", data.fileInput);
  846. }
  847. count--;
  848. });
  849. // update filenames
  850. if (!filenames.hasOwnProperty(attr.name)) {
  851. filenames[attr.name] = [];
  852. }
  853. filenames[attr.name].push(file.name);
  854. $form.trigger("mwf-valuechange", data.fileInput);
  855. } else {
  856. $row.find('[data-mwf-file-delete]').on('click', function() {
  857. $row.remove();
  858. pendingList.splice($.inArray(data, pendingList), 1);
  859. });
  860. errorRows.push($row);
  861. count--;
  862. }
  863. });
  864. },
  865. fail: function(e, data) {
  866. $.each(data.files, function(index, file) {
  867. var $row = plugin.settings.createDownloadFileRow($form, attr, {
  868. name: file.name,
  869. size: file.size,
  870. error: attr.labels.error
  871. });
  872. $row.find('[data-mwf-file-delete]').data(data).on('click', function() {
  873. $row.remove();
  874. pendingList.splice($.inArray(data, pendingList), 1);
  875. });
  876. errorRows.push($row);
  877. count--;
  878. if (data.context !== undefined) {
  879. data.context.replaceWith($row)
  880. } else {
  881. $files.append($row);
  882. }
  883. });
  884. },
  885. always: function(e, data) {
  886. if ($buttons !== null && $upload.fileupload('active') === 1) {
  887. $buttons.prop('disabled', false);
  888. $buttons = null;
  889. }
  890. }
  891. });
  892. // preload existing files
  893. $.ajax({
  894. url: attr.url,
  895. dataType: "json",
  896. data: {_name: attr.name, _do: 'files'}
  897. }).done(function(result) {
  898. $upload.fileupload('option', 'done').call($upload, $.Event('done'), {result: result});
  899. count = result.files.length;
  900. });
  901. });
  902. $.each($form.find('[data-mwf-datasource]'), function() {
  903. var def = {
  904. params: {},
  905. data: {}
  906. },
  907. attr = $.extend(true, {}, def, $(this).data('mwf-datasource')),
  908. $elem = $(this);
  909. switch (attr.type) {
  910. case 'checkbox':
  911. case 'radio':
  912. ajaxFillSelection($elem, attr, true);
  913. $form.on('mwf-valuechange', function(e, input) {
  914. if ($.trim(attr.params.dependsOn)) {
  915. $.each(attr.params.dependsOn.split(','), function(i, v) {
  916. if ($(input).attr('name') === v) {
  917. ajaxFillSelection($elem, attr, false);
  918. return false;
  919. }
  920. });
  921. }
  922. });
  923. break;
  924. case 'selection':
  925. ajaxFillDropdown($elem, attr, true);
  926. $form.on('mwf-valuechange', function(e, input) {
  927. if ($.trim(attr.params.dependsOn)) {
  928. $.each(attr.params.dependsOn.split(','), function(i, v) {
  929. if ($(input).attr('name') === v) {
  930. ajaxFillDropdown($elem, attr, false);
  931. return false;
  932. }
  933. });
  934. }
  935. });
  936. break;
  937. case 'suggestion':
  938. ajaxAutocomplete($elem, attr);
  939. break;
  940. case 'hidden':
  941. ajaxFillHidden($elem, attr, true);
  942. $form.on('mwf-valuechange', function(e, input) {
  943. if ($.trim(attr.params.dependsOn)) {
  944. $.each(attr.params.dependsOn.split(','), function(i, v) {
  945. if ($(input).attr('name') === v) {
  946. ajaxFillHidden($elem, attr, false);
  947. return false;
  948. }
  949. });
  950. }
  951. });
  952. break;
  953. default:
  954. $.logError(attr.type === undefined ?
  955. 'Please specifiy the datasource type (checkbox, radio, selection or suggestion).' :
  956. 'Unknown datasource type "'.concat(attr.type, '".'));
  957. }
  958. });
  959. $.each(plugin.settings.conditions, function() {
  960. createCondition($(this).attr('id'), $(this).attr('conjunction'), $(this).attr('conditions'), $(this).attr('fields'));
  961. });
  962. $.each(plugin.settings.calculatedValues, function() {
  963. createCalculatedValue($(this).attr('id'), $(this).attr('js'), $(this).attr('fields'), $(this).attr('vars'));
  964. });
  965. plugin.settings.onInit($form);
  966. };
  967. plugin.init();
  968. }
  969. /* default plugin settings
  970. ----------------------------------------------------------------------------------------------------------- */
  971. defaultSettings.default = {
  972. appendUrlVars: false,
  973. operations: {},
  974. conditions: [],
  975. calculatedValues: [],
  976. fileuploadOptions: {},
  977. onConditionTrue: undefined,
  978. onConditionFalse: undefined,
  979. statisticsUrl: null
  980. };
  981. defaultSettings.default.operations['visible'] = function($form, field) {
  982. var $field = $form.find('[data-mwf-container="' + field.input + '"]');
  983. $field.removeAttr('disabled');
  984. $field.removeClass('mwf-hidden');
  985. };
  986. defaultSettings.default.operations['hidden'] = function($form, field) {
  987. var $field = $form.find('[data-mwf-container="' + field.input + '"]');
  988. $field.attr("disabled", "true");
  989. $field.addClass('mwf-hidden');
  990. };
  991. defaultSettings.default.operations['writable'] = function($form, field) {
  992. var $field = $form.find('[data-mwf-id="' + field.input + '"]');
  993. $field.removeAttr('readonly');
  994. };
  995. defaultSettings.default.operations['readonly'] = function($form, field) {
  996. var $field = $form.find('[data-mwf-id="' + field.input + '"]');
  997. $field.val(field.value);
  998. $field.attr("readonly", "true");
  999. };
  1000. defaultSettings.default.operations['enabled'] = function($form, field) {
  1001. var $field = $form.find('[data-mwf-id="' + field.input + '"]');
  1002. $field.removeAttr('disabled');
  1003. $field.trigger('enable');
  1004. };
  1005. defaultSettings.default.operations['disabled'] = function($form, field) {
  1006. var $field = $form.find('[data-mwf-id="' + field.input + '"]');
  1007. $field.attr("disabled", "true");
  1008. $field.trigger('disable');
  1009. };
  1010. defaultSettings.default.operations['optional'] = function($form, field) {
  1011. var $label = $form.find('label[for="' + field.input + '"]');
  1012. $label.children('span.mwf-required').remove();
  1013. };
  1014. defaultSettings.default.operations['mandatory'] = function($form, field) {
  1015. var $label = $form.find('label[for="' + field.input + '"]'),
  1016. $span = $('<span></span>').attr('class', 'mwf-required').text('*');
  1017. $label.children('span.mwf-required').remove();
  1018. $label.append($span);
  1019. };
  1020. defaultSettings.default.createOption = function($form, entry, selected) {
  1021. var $option = $('<option></option>')
  1022. .attr('data-mwf-value', entry.k)
  1023. .attr('data-mwf-label', entry.v)
  1024. .attr('data-mwf-mutable', '')
  1025. .attr('value', JSON.stringify(entry))
  1026. .append(entry.v);
  1027. if (selected) {
  1028. $option.attr('selected', true);
  1029. }
  1030. return $option;
  1031. };
  1032. defaultSettings.default.createRadio = function($form, name, entry, checked) {
  1033. var $span, $input, $label;
  1034. $span = $('<span></span>')
  1035. .attr('class', 'mwf-option')
  1036. .attr('data-mwf-mutable', '');
  1037. $input = $('<input/>')
  1038. .attr('type', 'radio')
  1039. .attr('id', entry.i)
  1040. .attr('data-mwf-id', entry.i)
  1041. .attr('data-mwf-value', entry.k)
  1042. .attr('data-mwf-label', entry.v)
  1043. .attr('value', JSON.stringify(entry))
  1044. .attr('name', name)
  1045. .attr('class', 'mwf-radio');
  1046. if (checked) {
  1047. $input.attr('checked', 'checked');
  1048. }
  1049. $label = $('<label></label>')
  1050. .attr('for', entry.i).append(entry.v);
  1051. $span.append($input);
  1052. $span.append(' ');
  1053. $span.append($label);
  1054. return $span;
  1055. };
  1056. defaultSettings.default.createCheckBox = function($form, name, entry, checked) {
  1057. var $span, $input, $label;
  1058. $span = $('<span></span>')
  1059. .attr('class', 'mwf-option')
  1060. .attr('data-mwf-mutable', '');
  1061. $input = $('<input/>')
  1062. .attr('type', 'checkbox')
  1063. .attr('id', entry.i)
  1064. .attr('data-mwf-id', entry.i)
  1065. .attr('data-mwf-value', entry.k)
  1066. .attr('data-mwf-label', entry.v)
  1067. .attr('value', JSON.stringify(entry))
  1068. .attr('name', name)
  1069. .attr('class', 'mwf-checkbox');
  1070. if (checked) {
  1071. $input.attr('checked', 'checked');
  1072. }
  1073. $label = $('<label></label>')
  1074. .attr('for', entry.i).append(entry.v);
  1075. $span.append($input);
  1076. $span.append(' ');
  1077. $span.append($label);
  1078. return $span;
  1079. };
  1080. defaultSettings.default.updateFormValue = function($form, $elem, name, v) {
  1081. $elem.html($.isArray(v) ? v.join(', ') : v);
  1082. };
  1083. defaultSettings.default.createUploadFileRow = function($form, attr, file) {
  1084. var $row, $fileinfo, $meta, $preview, $ul, $name, $size, $buttons, $upload, $delete, $span, $progress, $error;
  1085. $row = $('<div/>').attr('data-mwf-file', '').attr('class', 'mwf-upload-row');
  1086. $fileinfo = $('<div/>').attr('class', 'mwf-upload-fileinfo');
  1087. $preview = $('<div/>').attr('data-mwf-file-preview', '').attr('class', 'mwf-upload-preview');
  1088. $meta = $('<div/>').attr('class', 'mwf-upload-metadata');
  1089. $ul = $('<ul/>');
  1090. $name = $('<li>').text(attr.labels.name + ': ' + file.name);
  1091. $size = $('<li>').text(attr.labels.size + ': ' + $.formatSize(file.size));
  1092. $buttons = $('<div/>').attr('class', ' mwf-upload-actions');
  1093. $upload = $('<button>').attr('data-mwf-file-upload', '').attr('class', 'mwf-upload-upload').text(attr.labels.upload);
  1094. $delete = $('<button>').attr('data-mwf-file-delete', '').attr('class', 'mwf-upload-delete').text(attr.labels.del);
  1095. $span = $('<span>').css('width', '0%');
  1096. $progress = $('<div/>').attr('data-mwf-file-progress', '').attr('class', 'mwf-upload-progressbar');
  1097. $error = $('<div/>').attr('data-mwf-file-error', '').attr('class', 'mwf-upload-error');
  1098. $buttons.append($delete);
  1099. if (attr.autoUpload === false) {
  1100. $buttons.append($upload);
  1101. }
  1102. $ul.append($name);
  1103. $ul.append($size);
  1104. $meta.append($ul);
  1105. $fileinfo.append($preview);
  1106. $fileinfo.append($meta);
  1107. $progress.append($span);
  1108. $row.append($fileinfo);
  1109. $row.append($buttons);
  1110. $row.append($error);
  1111. $row.append($progress);
  1112. return $row;
  1113. };
  1114. defaultSettings.default.createDownloadFileRow = function($form, attr, file) {
  1115. var $row, $fileinfo, $meta, $preview, $image, $ul, $name, $size, $buttons, $delete, $span, $error;
  1116. $row = $('<div/>').attr('data-mwf-file', '').attr('class', 'mwf-upload-row');
  1117. $fileinfo = $('<div/>').attr('class', 'mwf-upload-fileinfo');
  1118. $preview = $('<div/>').attr('data-mwf-preview', '').attr('class', 'mwf-upload-preview');
  1119. $meta = $('<div/>').attr('class', 'mwf-upload-metadata');
  1120. $ul = $('<ul/>');
  1121. $name = $('<li>').text(attr.labels.name + ': ' + file.name);
  1122. $size = $('<li>').text(attr.labels.size + ': ' + $.formatSize(file.size));
  1123. $buttons = $('<div/>').attr('class', ' mwf-upload-actions');
  1124. $delete = $('<button>').attr('data-mwf-file-delete', '').attr('class', 'mwf-upload-delete').text(attr.labels.del);
  1125. $buttons.append($delete);
  1126. $ul.append($name);
  1127. $ul.append($size);
  1128. $meta.append($ul);
  1129. if (file.thumbnail_url) {
  1130. $image = $('<img/>').attr('src', file.thumbnail_url);
  1131. $preview.append($image);
  1132. }
  1133. $fileinfo.append($preview);
  1134. $fileinfo.append($meta);
  1135. $row.append($fileinfo);
  1136. $row.append($buttons);
  1137. if (file.error) {
  1138. $error = $('<div/>').attr('data-mwf-file-error', '').attr('class', 'mwf-upload-error');
  1139. $span = $('<span>').text(file.error);
  1140. $error.append($span);
  1141. $row.append($error);
  1142. }
  1143. return $row;
  1144. };
  1145. defaultSettings.default.updateCalculatedValue = function($form, id, value) {
  1146. $form.find('[data-mwf-value="' + id + '"]').text(value).html();
  1147. };
  1148. defaultSettings.default.onAjaxError = function(jqXHR, status, error) {
  1149. $.logError(jqXHR.responseText);
  1150. };
  1151. defaultSettings.default.onSubmit = function($form, url, query) {
  1152. return true;
  1153. };
  1154. defaultSettings.default.onConditionCreated = function($form, conditionId, conjunction, conditions, fields) {
  1155. // do nothing
  1156. };
  1157. defaultSettings.default.onFillDropdown = function($form, $elem) {
  1158. // do nothing
  1159. };
  1160. defaultSettings.default.onFillSelection = function($form, $elem) {
  1161. // do nothing
  1162. };
  1163. defaultSettings.default.onInit = function($form) {
  1164. // do nothing
  1165. };
  1166. /* plugin related jQuery functions
  1167. --------------------------------------------------------------------------------------------------------------- */
  1168. $.fn.webforms = function(opt) {
  1169. var dataKey = 'webforms', $this = $(this), $form = $this, settings, id, s;
  1170. if ($this.data('mwf-form') === undefined) {
  1171. $form = $this.find('[data-mwf-form]');
  1172. }
  1173. if ($form.length === 0) {
  1174. return;
  1175. }
  1176. id = $form.dataWithDefault('mwf-id', $form.data('mwf-form'));
  1177. settings = $form.dataWithDefault('mwf-settings', {});
  1178. s = {
  1179. id: id,
  1180. type: 'GET',
  1181. appendUrlVars: false
  1182. };
  1183. $.extend(true, s, defaultsInternal(settings.variant), settings, opt);
  1184. if ($this.is('form') || $this.find('form').length > 0) {
  1185. return $this.each(function() {
  1186. var instance = $this.data(dataKey);
  1187. if (instance && instance.dispose) {
  1188. instance.dispose();
  1189. }
  1190. instance = new Webforms($this, s);
  1191. $this.data(dataKey, instance);
  1192. });
  1193. } else {
  1194. s.selector = $this;
  1195. $.mwfAjaxReplace(s);
  1196. }
  1197. };
  1198. $.fn.webforms.defaults = function(variant) {
  1199. if (variant === undefined) {
  1200. return defaultSettings.default;
  1201. } else {
  1202. if (defaultSettings[variant] === undefined) {
  1203. defaultSettings[variant] = {};
  1204. }
  1205. return defaultSettings[variant];
  1206. }
  1207. };
  1208. /* general jQuery utility functions
  1209. --------------------------------------------------------------------------------------------------------------- */
  1210. $.fn.replaceWithPush = function(elem) {
  1211. var $elem = $(elem);
  1212. this.replaceWith($elem);
  1213. return $elem;
  1214. };
  1215. $.fn.dataWithDefault = function(key, def) {
  1216. var value = this.data(key);
  1217. return (value !== undefined) ? value : def;
  1218. };
  1219. if (typeof $.fn.serializeObject === 'undefined') {
  1220. $.fn.serializeObject = function() {
  1221. var o = {}, a = this.serializeArray();
  1222. $.each(a, function() {
  1223. if (o[this.name] !== undefined) {
  1224. if (!o[this.name].push) {
  1225. o[this.name] = [o[this.name]];
  1226. }
  1227. o[this.name].push(this.value || '');
  1228. } else {
  1229. o[this.name] = this.value || '';
  1230. }
  1231. });
  1232. return o;
  1233. };
  1234. }
  1235. if (typeof $.logError === 'undefined') {
  1236. $.extend({
  1237. logError: function(msg) {
  1238. try {
  1239. if (msg !== undefined && typeof window.console !== 'undefined') {
  1240. console.error(msg);
  1241. }
  1242. } catch (ex) {
  1243. }
  1244. }
  1245. });
  1246. }
  1247. $.extend({
  1248. mwfAjaxReplace: function(opt) {
  1249. var $dest = $(opt.selector), data = {}, optinId, s;
  1250. if ($dest.length > 0) {
  1251. optinId = $.getOptinIdFromHash(opt.id);
  1252. if (optinId !== null) {
  1253. data._optinId = optinId;
  1254. if (typeof history.replaceState !== 'undefined') {
  1255. history.replaceState({}, document.title, window.location.pathname);
  1256. } else {
  1257. window.location.hash = '';
  1258. }
  1259. $('html, body').animate({
  1260. scrollTop: $dest.offset().top
  1261. });
  1262. }
  1263. s = {
  1264. url: null,
  1265. type: 'POST',
  1266. appendUrlVars: false
  1267. };
  1268. // Create the final settings object
  1269. $.extend(s, opt);
  1270. if (s.appendUrlVars) {
  1271. $.extend(data, $.getUrlVars(window.location.search));
  1272. delete data.view;
  1273. }
  1274. $.extend(data, $.getUrlVars(s.query), opt.data);
  1275. $.ajax({
  1276. url: s.url,
  1277. type: s.type,
  1278. data: data,
  1279. traditional: true,
  1280. cache: false
  1281. })
  1282. .done(function(data, textStatus, jqXHR) {
  1283. if (jqXHR && jqXHR.getResponseHeader("webforms_redirect")) {
  1284. location.assign(jqXHR.getResponseHeader("webforms_redirect"));
  1285. return;
  1286. }
  1287. $dest = $dest.replaceWithPush(data);
  1288. if (s.onSuccess !== undefined) {
  1289. s.onSuccess(data, textStatus, jqXHR);
  1290. }
  1291. triggerEvent(document, EVENTS.AJAX_FINISHED, {detail: {$dest: $dest}});
  1292. })
  1293. .fail(function(jqXHR, textStatus, errorThrown) {
  1294. if (s.onError !== undefined) {
  1295. s.onError(jqXHR, textStatus, errorThrown);
  1296. } else {
  1297. $.logError(jqXHR.responseText);
  1298. }
  1299. triggerEvent(document, EVENTS.AJAX_ERROR, {
  1300. detail: {
  1301. $dest: $dest,
  1302. jqXHR: jqXHR,
  1303. textStatus: textStatus,
  1304. errorThrown: errorThrown
  1305. }
  1306. });
  1307. })
  1308. }
  1309. },
  1310. getUrlVars: function(url) {
  1311. var params = {}, i, param, pos, key, value, length;
  1312. if (typeof url === "string" && url.length > 0) {
  1313. if (url[0] === '?') {
  1314. url = url.substring(1);
  1315. }
  1316. url = url.split('&');
  1317. for (i = 0, length = url.length; i < length; i++) {
  1318. if (!url[i] || 0 === url[i].length) {
  1319. continue;
  1320. }
  1321. param = url[i];
  1322. pos = param.indexOf('=');
  1323. if (pos >= 0) {
  1324. key = param.substr(0, pos);
  1325. value = param.substr(pos + 1);
  1326. } else {
  1327. key = param;
  1328. value = '';
  1329. }
  1330. value = decodeURIComponent(value);
  1331. if (params[key] === undefined) {
  1332. params[key] = value;
  1333. } else if (params[key] instanceof Array) {
  1334. params[key].push(value);
  1335. } else {
  1336. params[key] = [params[key], value];
  1337. }
  1338. }
  1339. }
  1340. return params;
  1341. },
  1342. getUrlVar: function(url, name) {
  1343. return $.getUrlVars(url)[name];
  1344. },
  1345. getOptinIdFromHash: function(id) {
  1346. // legacy hash = mwf:uuid
  1347. // new hash = mwf:formId:uuid
  1348. var hash = location.hash.replace('#', ''),
  1349. idx = hash.indexOf("mwf:");
  1350. if (idx !== -1) {
  1351. var elements = hash.split(":");
  1352. if (elements.length === 2 || elements[1] === String(id)) {
  1353. return hash.substring(idx + 4, hash.length);
  1354. }
  1355. }
  1356. return null;
  1357. },
  1358. formatSize: function(bytes) {
  1359. if (typeof bytes !== 'number') {
  1360. return '';
  1361. }
  1362. if (bytes >= 1000000000) {
  1363. return (bytes / 1000000000).toFixed(2) + ' GB';
  1364. }
  1365. if (bytes >= 1000000) {
  1366. return (bytes / 1000000).toFixed(2) + ' MB';
  1367. }
  1368. return (bytes / 1000).toFixed(2) + ' KB';
  1369. }
  1370. });
  1371. /* register event handler
  1372. --------------------------------------------------------------------------------------------------------------- */
  1373. $(document).ready(function() {
  1374. var $document = $(document);
  1375. $document.on(EVENTS.AJAX_FINISHED, function(event) {
  1376. var $dest = event.originalEvent.detail.$dest;
  1377. $dest.webforms( {});
  1378. });
  1379. $('[data-mwf-form]').each(function() {
  1380. $(this).webforms({});
  1381. });
  1382. });
  1383. }));