|
2 | 2 | * Copyright 2013-2014 Academe Computing Ltd |
3 | 3 | * Released under the MIT license |
4 | 4 | * Author: Jason Judge <[email protected]> |
5 | | - * Version: 1.1.3 |
| 5 | + * Version: 1.1.4 |
6 | 6 | */ |
7 | 7 | /** |
8 | 8 | * jquery.maxsubmit.js |
|
20 | 20 | */ |
21 | 21 |
|
22 | 22 | (function($) { |
| 23 | + /** |
| 24 | + * Set a trigger on a form to pop up a warning if the fields to be submitted |
| 25 | + * exceed a specified maximum. |
| 26 | + * Usage: $('form#selector').maxSubmit({options}); |
| 27 | + */ |
23 | 28 | $.fn.maxSubmit = function(options) { |
24 | | - // this.each() is the wrapper for each selected group of checkboxes. |
| 29 | + // this.each() is the wrapper for each form. |
25 | 30 | return this.each(function() { |
26 | 31 |
|
27 | 32 | var settings = $.extend({ |
|
61 | 66 | // We have a form, so count up the form items that will be |
62 | 67 | // submitted to the server. |
63 | 68 |
|
64 | | - // textarea fields count as one submitted field each. |
65 | | - var form_count = $('textarea:enabled', this).length; |
66 | | - |
67 | | - // Input fields of all types except checkboxes and radio buttons will |
68 | | - // all post one parameter. |
69 | | - // reset inputs are not submitted to the server and files are handled |
70 | | - // separately. |
71 | | - form_count += $('input:enabled', this) |
72 | | - .not("[type='checkbox']") |
73 | | - .not("[type='radio']") |
74 | | - .not("[type='file']") |
75 | | - .not("[type='reset']") |
76 | | - .length; |
77 | | - |
78 | | - // Checkboxes will post only if checked. |
79 | | - $('input:checkbox:enabled', this).each(function() { |
80 | | - if (this.checked) form_count++; |
81 | | - }); |
82 | | - |
83 | | - // Single-select lists will always post one value. |
84 | | - $('select:enabled:not([multiple])', this).each(function() { |
85 | | - form_count++; |
86 | | - }); |
87 | | - |
88 | | - // Multi-select lists will post one parameter for each selected item. |
89 | | - $('select:enabled[multiple]', this).each(function() { |
90 | | - // The select item value is null if no options are selected. |
91 | | - var select = $(this).val(); |
92 | | - if (select !== null) form_count += select.length; |
93 | | - }); |
94 | | - |
95 | | - // Each radio button group will post one parameter, regardless of how many |
96 | | - // radio buttons a group contains. |
97 | | - // Count the radio groups |
98 | | - var rgroups = []; |
99 | | - $('input:enabled:radio').each(function(index, el) { |
100 | | - var i; |
101 | | - for(i = 0; i < rgroups.length; i++) { |
102 | | - if (rgroups[i] == $(el).attr('name')) return; |
103 | | - } |
104 | | - rgroups.push($(el).attr('name')); |
105 | | - }); |
106 | | - form_count += rgroups.length; |
| 69 | + // For now, add one for the submit button. |
| 70 | + var form_count = $(this).maxSubmitCount() + 1; |
107 | 71 |
|
108 | 72 | if (form_count > settings.max_count) { |
109 | 73 | // If the user cancels, then abort the form submit. |
|
119 | 83 | return this; |
120 | 84 | }); |
121 | 85 | }; |
| 86 | + |
| 87 | + /** |
| 88 | + * Count the number of fields that will be posted in a form. |
| 89 | + * If return_elements is true, then an array of elements will be returned |
| 90 | + * instead of the count. This is handy for testing. |
| 91 | + * TODO: elements without names will not be submitted. |
| 92 | + * Another approach may be to get all input fields at once using $("form :input") |
| 93 | + * then knock out the ones that we don't want. That would keep the same order as the |
| 94 | + * items would be submitted. |
| 95 | + */ |
| 96 | + $.fn.maxSubmitCount = function(return_elements) { |
| 97 | + // Text fields and submit buttons will all post one parameter. |
| 98 | + |
| 99 | + // Find the textareas. |
| 100 | + // These will count as one post parameter each. |
| 101 | + var fields = $('textarea:enabled[name]', this).toArray(); |
| 102 | + |
| 103 | + // Find the basic textual input fields (text, email, number, date and similar). |
| 104 | + // These will count as one post parameter each. |
| 105 | + // We deal with checkboxes, radio buttons sparately. |
| 106 | + // Checkboxes will post only if checked, so exclude any that are not checked. |
| 107 | + // There may be multiple form submit buttons, but only one will be posted with the |
| 108 | + // form, assuming the form has been submitted by the user with a button. |
| 109 | + // An image submit will post two fields - an x and y coordinate. |
| 110 | + fields = fields.concat( |
| 111 | + $('input:enabled[name]', this) |
| 112 | + // Data items that are handled later. |
| 113 | + .not("[type='checkbox']:not(:checked)") |
| 114 | + .not("[type='radio']") |
| 115 | + .not("[type='file']") |
| 116 | + .not("[type='reset']") |
| 117 | + // Submit form items. |
| 118 | + .not("[type='submit']") |
| 119 | + .not("[type='button']") |
| 120 | + .not("[type='image']") |
| 121 | + .toArray() |
| 122 | + ); |
| 123 | + |
| 124 | + // Single-select lists will always post one value. |
| 125 | + fields = fields.concat( |
| 126 | + $('select:enabled[name]', this) |
| 127 | + .not('[multiple]') |
| 128 | + .toArray() |
| 129 | + ); |
| 130 | + |
| 131 | + // Multi-select lists will post one parameter for each selected option. |
| 132 | + // The parent select is $(this).parent() with its name being $(this).parent().attr('name') |
| 133 | + $('select[multiple]:enabled[name] option:selected', this).each(function() { |
| 134 | + // We collect all the options that have been selected. |
| 135 | + fields = fields.concat(this); |
| 136 | + }); |
| 137 | + |
| 138 | + // Each radio button group will post one parameter. |
| 139 | + // We assume all checked radio buttons will be posted. |
| 140 | + fields = fields.concat( |
| 141 | + $('input:enabled:radio:checked', this) |
| 142 | + .toArray() |
| 143 | + ); |
| 144 | + |
| 145 | + // TODO: provide an option to return an array of objects containing the form field names, |
| 146 | + // types and values, in a form that can be compared to what is actually posted. |
| 147 | + if (typeof(return_elements) === 'undefined') return_elements = false; |
| 148 | + |
| 149 | + if (return_elements === true) { |
| 150 | + // Return the full list of elements for analysis. |
| 151 | + return fields; |
| 152 | + } else { |
| 153 | + // Just return the number of elements matched. |
| 154 | + return fields.length; |
| 155 | + } |
| 156 | + }; |
122 | 157 | }(jQuery)); |
123 | 158 |
|
0 commit comments