|
193 | 193 | $prompt = $fieldGroup.find(selector.prompt),
|
194 | 194 | $calendar = $field.closest(selector.uiCalendar),
|
195 | 195 | defaultValue = $field.data(metadata.defaultValue) || '',
|
196 |
| - isCheckbox = $element.is(selector.uiCheckbox), |
| 196 | + isCheckbox = $field.is(selector.checkbox), |
197 | 197 | isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'),
|
198 | 198 | isCalendar = $calendar.length > 0 && module.can.useElement('calendar'),
|
199 | 199 | isErrored = $fieldGroup.hasClass(className.error)
|
|
227 | 227 | $calendar = $field.closest(selector.uiCalendar),
|
228 | 228 | $prompt = $fieldGroup.find(selector.prompt),
|
229 | 229 | defaultValue = $field.data(metadata.defaultValue),
|
230 |
| - isCheckbox = $element.is(selector.uiCheckbox), |
| 230 | + isCheckbox = $field.is(selector.checkbox), |
231 | 231 | isDropdown = $element.is(selector.uiDropdown) && module.can.useElement('dropdown'),
|
232 | 232 | isCalendar = $calendar.length > 0 && module.can.useElement('calendar'),
|
233 | 233 | isErrored = $fieldGroup.hasClass(className.error)
|
|
244 | 244 | module.verbose('Resetting dropdown value', $element, defaultValue);
|
245 | 245 | $element.dropdown('restore defaults', true);
|
246 | 246 | } else if (isCheckbox) {
|
247 |
| - module.verbose('Resetting checkbox value', $element, defaultValue); |
| 247 | + module.verbose('Resetting checkbox value', $field, defaultValue); |
248 | 248 | $field.prop('checked', defaultValue);
|
249 | 249 | } else if (isCalendar) {
|
250 | 250 | $calendar.calendar('set date', defaultValue);
|
|
533 | 533 | : rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule,
|
534 | 534 | requiresValue = prompt.search('{value}') !== -1,
|
535 | 535 | requiresName = prompt.search('{name}') !== -1,
|
536 |
| - $label, |
537 |
| - name, |
538 | 536 | parts,
|
539 | 537 | suffixPrompt
|
540 | 538 | ;
|
|
551 | 549 | prompt = prompt.replace(/{min}/g, parts[0]);
|
552 | 550 | prompt = prompt.replace(/{max}/g, parts[1]);
|
553 | 551 | }
|
| 552 | + if (ancillary && ['match', 'different'].indexOf(ruleName) >= 0) { |
| 553 | + prompt = prompt.replace(/{ruleValue}/g, module.get.fieldLabel(ancillary, true)); |
| 554 | + } |
554 | 555 | if (requiresValue) {
|
555 | 556 | prompt = prompt.replace(/{value}/g, $field.val());
|
556 | 557 | }
|
557 | 558 | if (requiresName) {
|
558 |
| - $label = $field.closest(selector.group).find('label').eq(0); |
559 |
| - name = $label.length === 1 |
560 |
| - ? $label.text() |
561 |
| - : $field.prop('placeholder') || settings.text.unspecifiedField; |
562 |
| - prompt = prompt.replace(/{name}/g, name); |
| 559 | + prompt = prompt.replace(/{name}/g, module.get.fieldLabel($field)); |
563 | 560 | }
|
564 | 561 | prompt = prompt.replace(/{identifier}/g, field.identifier);
|
565 | 562 | prompt = prompt.replace(/{ruleValue}/g, ancillary);
|
|
599 | 596 | // refresh selector cache
|
600 | 597 | (instance || module).refresh();
|
601 | 598 | },
|
602 |
| - field: function (identifier) { |
| 599 | + field: function (identifier, strict) { |
603 | 600 | module.verbose('Finding field with identifier', identifier);
|
604 | 601 | identifier = module.escape.string(identifier);
|
605 | 602 | var t;
|
|
621 | 618 | }
|
622 | 619 | module.error(error.noField.replace('{identifier}', identifier));
|
623 | 620 |
|
624 |
| - return $('<input/>'); |
| 621 | + return strict ? $() : $('<input/>'); |
625 | 622 | },
|
626 |
| - fields: function (fields) { |
| 623 | + fields: function (fields, strict) { |
627 | 624 | var
|
628 | 625 | $fields = $()
|
629 | 626 | ;
|
630 | 627 | $.each(fields, function (index, name) {
|
631 |
| - $fields = $fields.add(module.get.field(name)); |
| 628 | + $fields = $fields.add(module.get.field(name, strict)); |
632 | 629 | });
|
633 | 630 |
|
634 | 631 | return $fields;
|
635 | 632 | },
|
| 633 | + fieldLabel: function (identifier, useIdAsFallback) { |
| 634 | + var $field = typeof identifier === 'string' |
| 635 | + ? module.get.field(identifier) |
| 636 | + : identifier, |
| 637 | + $label = $field.closest(selector.group).find('label').eq(0) |
| 638 | + ; |
| 639 | + |
| 640 | + return $label.length === 1 |
| 641 | + ? $label.text() |
| 642 | + : $field.prop('placeholder') || (useIdAsFallback ? identifier : settings.text.unspecifiedField); |
| 643 | + }, |
636 | 644 | validation: function ($field) {
|
637 | 645 | var
|
638 | 646 | fieldValidation,
|
|
655 | 663 |
|
656 | 664 | return fieldValidation || false;
|
657 | 665 | },
|
658 |
| - value: function (field) { |
| 666 | + value: function (field, strict) { |
659 | 667 | var
|
660 | 668 | fields = [],
|
661 |
| - results |
| 669 | + results, |
| 670 | + resultKeys |
662 | 671 | ;
|
663 | 672 | fields.push(field);
|
664 |
| - results = module.get.values.call(element, fields); |
| 673 | + results = module.get.values.call(element, fields, strict); |
| 674 | + resultKeys = Object.keys(results); |
665 | 675 |
|
666 |
| - return results[field]; |
| 676 | + return resultKeys.length > 0 ? results[resultKeys[0]] : undefined; |
667 | 677 | },
|
668 |
| - values: function (fields) { |
| 678 | + values: function (fields, strict) { |
669 | 679 | var
|
670 |
| - $fields = Array.isArray(fields) |
671 |
| - ? module.get.fields(fields) |
| 680 | + $fields = Array.isArray(fields) && fields.length > 0 |
| 681 | + ? module.get.fields(fields, strict) |
672 | 682 | : $field,
|
673 | 683 | values = {}
|
674 | 684 | ;
|
|
786 | 796 |
|
787 | 797 | field: function (identifier) {
|
788 | 798 | module.verbose('Checking for existence of a field with identifier', identifier);
|
789 |
| - identifier = module.escape.string(identifier); |
790 |
| - if (typeof identifier !== 'string') { |
791 |
| - module.error(error.identifier, identifier); |
792 |
| - } |
793 | 799 |
|
794 |
| - return ( |
795 |
| - $field.filter('#' + identifier).length > 0 |
796 |
| - || $field.filter('[name="' + identifier + '"]').length > 0 |
797 |
| - || $field.filter('[data-' + metadata.validate + '="' + identifier + '"]').length > 0 |
798 |
| - ); |
| 800 | + return module.get.field(identifier, true).length > 0; |
799 | 801 | },
|
800 | 802 |
|
801 | 803 | },
|
|
819 | 821 | },
|
820 | 822 | },
|
821 | 823 |
|
| 824 | + checkErrors: function (errors, internal) { |
| 825 | + if (!errors || errors.length === 0) { |
| 826 | + if (!internal) { |
| 827 | + module.error(settings.error.noErrorMessage); |
| 828 | + } |
| 829 | + |
| 830 | + return false; |
| 831 | + } |
| 832 | + if (!internal) { |
| 833 | + errors = typeof errors === 'string' |
| 834 | + ? [errors] |
| 835 | + : errors; |
| 836 | + } |
| 837 | + |
| 838 | + return errors; |
| 839 | + }, |
822 | 840 | add: {
|
823 | 841 | // alias
|
824 | 842 | rule: function (name, rules) {
|
|
862 | 880 | module.refreshEvents();
|
863 | 881 | },
|
864 | 882 | prompt: function (identifier, errors, internal) {
|
| 883 | + errors = module.checkErrors(errors); |
| 884 | + if (errors === false) { |
| 885 | + return; |
| 886 | + } |
865 | 887 | var
|
866 | 888 | $field = module.get.field(identifier),
|
867 | 889 | $fieldGroup = $field.closest($group),
|
868 | 890 | $prompt = $fieldGroup.children(selector.prompt),
|
869 | 891 | promptExists = $prompt.length > 0
|
870 | 892 | ;
|
871 |
| - errors = typeof errors === 'string' |
872 |
| - ? [errors] |
873 |
| - : errors; |
874 | 893 | module.verbose('Adding field error state', identifier);
|
875 | 894 | if (!internal) {
|
876 | 895 | $fieldGroup
|
|
903 | 922 | }
|
904 | 923 | },
|
905 | 924 | errors: function (errors) {
|
| 925 | + errors = module.checkErrors(errors); |
| 926 | + if (errors === false) { |
| 927 | + return; |
| 928 | + } |
906 | 929 | module.debug('Adding form error messages', errors);
|
907 | 930 | module.set.error();
|
908 |
| - $message |
909 |
| - .html(settings.templates.error(errors)) |
| 931 | + var customErrors = [], |
| 932 | + tempErrors |
910 | 933 | ;
|
| 934 | + if ($.isPlainObject(errors)) { |
| 935 | + $.each(Object.keys(errors), function (i, id) { |
| 936 | + if (module.checkErrors(errors[id], true) !== false) { |
| 937 | + if (settings.inline) { |
| 938 | + module.add.prompt(id, errors[id]); |
| 939 | + } else { |
| 940 | + tempErrors = module.checkErrors(errors[id]); |
| 941 | + if (tempErrors !== false) { |
| 942 | + $.each(tempErrors, function (index, tempError) { |
| 943 | + customErrors.push(settings.prompt.addErrors |
| 944 | + .replace(/{name}/g, module.get.fieldLabel(id)) |
| 945 | + .replace(/{error}/g, tempError)); |
| 946 | + }); |
| 947 | + } |
| 948 | + } |
| 949 | + } |
| 950 | + }); |
| 951 | + } else { |
| 952 | + customErrors = errors; |
| 953 | + } |
| 954 | + if (customErrors.length > 0) { |
| 955 | + $message |
| 956 | + .html(settings.templates.error(customErrors)) |
| 957 | + ; |
| 958 | + } |
911 | 959 | },
|
912 | 960 | },
|
913 | 961 |
|
|
1012 | 1060 | $el = $(el),
|
1013 | 1061 | $parent = $el.parent(),
|
1014 | 1062 | isCheckbox = $el.filter(selector.checkbox).length > 0,
|
1015 |
| - isDropdown = $parent.is(selector.uiDropdown) && module.can.useElement('dropdown'), |
1016 |
| - $calendar = $el.closest(selector.uiCalendar), |
1017 |
| - isCalendar = $calendar.length > 0 && module.can.useElement('calendar'), |
| 1063 | + isDropdown = ($parent.is(selector.uiDropdown) || $el.is(selector.uiDropdown)) && module.can.useElement('dropdown'), |
| 1064 | + $calendar = $el.closest(selector.uiCalendar), |
| 1065 | + isCalendar = $calendar.length > 0 && module.can.useElement('calendar'), |
1018 | 1066 | value = isCheckbox
|
1019 | 1067 | ? $el.is(':checked')
|
1020 | 1068 | : $el.val()
|
1021 | 1069 | ;
|
1022 | 1070 | if (isDropdown) {
|
1023 |
| - $parent.dropdown('save defaults'); |
| 1071 | + if ($parent.is(selector.uiDropdown)) { |
| 1072 | + $parent.dropdown('save defaults'); |
| 1073 | + } else { |
| 1074 | + $el.dropdown('save defaults'); |
| 1075 | + } |
1024 | 1076 | } else if (isCalendar) {
|
1025 | 1077 | $calendar.calendar('refresh');
|
1026 | 1078 | }
|
|
1320 | 1372 | ? String(value + '').trim()
|
1321 | 1373 | : String(value + ''));
|
1322 | 1374 |
|
1323 |
| - return ruleFunction.call(field, value, ancillary, $module); |
| 1375 | + return ruleFunction.call(field, value, ancillary, module); |
1324 | 1376 | }
|
1325 | 1377 | ;
|
1326 | 1378 | if (!isFunction(ruleFunction)) {
|
|
1581 | 1633 | notExactly: '{name} cannot be set to exactly "{ruleValue}"',
|
1582 | 1634 | contain: '{name} must contain "{ruleValue}"',
|
1583 | 1635 | containExactly: '{name} must contain exactly "{ruleValue}"',
|
1584 |
| - doesntContain: '{name} cannot contain "{ruleValue}"', |
| 1636 | + doesntContain: '{name} cannot contain "{ruleValue}"', |
1585 | 1637 | doesntContainExactly: '{name} cannot contain exactly "{ruleValue}"',
|
1586 | 1638 | minLength: '{name} must be at least {ruleValue} characters',
|
1587 | 1639 | exactLength: '{name} must be exactly {ruleValue} characters',
|
|
1592 | 1644 | minCount: '{name} must have at least {ruleValue} choices',
|
1593 | 1645 | exactCount: '{name} must have exactly {ruleValue} choices',
|
1594 | 1646 | maxCount: '{name} must have {ruleValue} or less choices',
|
| 1647 | + addErrors: '{name}: {error}', |
1595 | 1648 | },
|
1596 | 1649 |
|
1597 | 1650 | selector: {
|
|
1620 | 1673 | },
|
1621 | 1674 |
|
1622 | 1675 | error: {
|
1623 |
| - identifier: 'You must specify a string identifier for each field', |
1624 | 1676 | method: 'The method you called is not defined.',
|
1625 | 1677 | noRule: 'There is no rule matching the one you specified',
|
1626 | 1678 | noField: 'Field identifier {identifier} not found',
|
1627 | 1679 | noElement: 'This module requires ui {element}',
|
| 1680 | + noErrorMessage: 'No error message provided', |
1628 | 1681 | },
|
1629 | 1682 |
|
1630 | 1683 | templates: {
|
|
1881 | 1934 | },
|
1882 | 1935 |
|
1883 | 1936 | // matches another field
|
1884 |
| - match: function (value, identifier, $module) { |
1885 |
| - var |
1886 |
| - matchingValue, |
1887 |
| - matchingElement |
1888 |
| - ; |
1889 |
| - matchingElement = $module.find('[data-validate="' + identifier + '"]'); |
1890 |
| - if (matchingElement.length > 0) { |
1891 |
| - matchingValue = matchingElement.val(); |
1892 |
| - } else { |
1893 |
| - matchingElement = $module.find('#' + identifier); |
1894 |
| - if (matchingElement.length > 0) { |
1895 |
| - matchingValue = matchingElement.val(); |
1896 |
| - } else { |
1897 |
| - matchingElement = $module.find('[name="' + identifier + '"]'); |
1898 |
| - if (matchingElement.length > 0) { |
1899 |
| - matchingValue = matchingElement.val(); |
1900 |
| - } else { |
1901 |
| - matchingElement = $module.find('[name="' + identifier + '[]"]'); |
1902 |
| - if (matchingElement.length > 0) { |
1903 |
| - matchingValue = matchingElement; |
1904 |
| - } |
1905 |
| - } |
1906 |
| - } |
1907 |
| - } |
| 1937 | + match: function (value, identifier, module) { |
| 1938 | + var matchingValue = module.get.value(identifier, true); |
1908 | 1939 |
|
1909 | 1940 | return matchingValue !== undefined
|
1910 | 1941 | ? value.toString() === matchingValue.toString()
|
1911 | 1942 | : false;
|
1912 | 1943 | },
|
1913 | 1944 |
|
1914 | 1945 | // different than another field
|
1915 |
| - different: function (value, identifier, $module) { |
1916 |
| - // use either id or name of field |
1917 |
| - var |
1918 |
| - matchingValue, |
1919 |
| - matchingElement |
1920 |
| - ; |
1921 |
| - matchingElement = $module.find('[data-validate="' + identifier + '"]'); |
1922 |
| - if (matchingElement.length > 0) { |
1923 |
| - matchingValue = matchingElement.val(); |
1924 |
| - } else { |
1925 |
| - matchingElement = $module.find('#' + identifier); |
1926 |
| - if (matchingElement.length > 0) { |
1927 |
| - matchingValue = matchingElement.val(); |
1928 |
| - } else { |
1929 |
| - matchingElement = $module.find('[name="' + identifier + '"]'); |
1930 |
| - if (matchingElement.length > 0) { |
1931 |
| - matchingValue = matchingElement.val(); |
1932 |
| - } else { |
1933 |
| - matchingElement = $module.find('[name="' + identifier + '[]"]'); |
1934 |
| - if (matchingElement.length > 0) { |
1935 |
| - matchingValue = matchingElement; |
1936 |
| - } |
1937 |
| - } |
1938 |
| - } |
1939 |
| - } |
| 1946 | + different: function (value, identifier, module) { |
| 1947 | + var matchingValue = module.get.value(identifier, true); |
1940 | 1948 |
|
1941 | 1949 | return matchingValue !== undefined
|
1942 | 1950 | ? value.toString() !== matchingValue.toString()
|
|
0 commit comments