Skip to content

Commit 7504312

Browse files
committed
Version 1.1.4 with support for some testing, and a number of fixes.
1 parent 550221a commit 7504312

5 files changed

+182
-47
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ http://plugins.jquery.com/jquery-maxsubmit/
9797

9898
## History
9999

100+
1.1.4 Rewrite to support testing; listing of the items that will be submitted
100101
1.1.3 Fixed count of HTML5 input elements
101102
1.1.2 Updated metadata for plugins.jquery.com
102103
1.1.1 Fixed syntax error messaing with Chrome

index.php

+15-1
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,21 @@
1010

1111
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
1212
<script type="text/javascript" src="jquery.maxsubmit.js"></script>
13+
<script type="text/javascript" src="jquery.maxsubmittest.js"></script>
1314

1415
<!-- Here the application could pass in a translated message suitable for the language of the end user -->
1516
<script type="text/javascript">
1617
jQuery(document).ready(function($) {
18+
// Protect the form.
1719
$('form#form1').maxSubmit({
1820
max_count: 2,
1921
max_exceeded_message: "This form has too many fields.\n\n"
2022
+ " Found {form_count} fields, so with a maximum of {max_count} supported by the server, some data will be lost.\n\n"
2123
+ " You may continue and submit, or cancel."
2224
});
25+
26+
// Allow inspection of what will be submitted (test the form).
27+
jQuery('.test-maxsubmit').maxSubmitTest();
2328
});
2429
</script>
2530

@@ -37,6 +42,9 @@
3742

3843
<style type="text/css">
3944
.text_label, .radio_label, .select_label, .doc_label {cursor: pointer; border-bottom: green dotted 1px;}
45+
.test-maxsubmit a {cursor: pointer; border: 2px solid #ffaaaa; padding: 3px;}
46+
table {border: 1px solid #000000; border-collapse:collapse;}
47+
table td, table th {border: 1px solid #666666; margin: 0; padding: 3px;}
4048
</style>
4149
</head>
4250

@@ -127,6 +135,12 @@ function getFormSubmissionLimit($default = false)
127135
<form method="post" id="form1">
128136
<h2>Mandatory form items: will count as one submitted parameter each</h2>
129137

138+
<div class="test-maxsubmit">
139+
<p>
140+
<a>Click here to see what the form will submit</a>
141+
<p>
142+
</div>
143+
130144
<p>
131145
<input type="text" name="text1" value="<?php echo $input['text1']; ?>" />
132146
<span class="text_label" title="Click to toggle toggle the enabled state">(text counts as one parameter)</span>
@@ -201,7 +215,7 @@ function getFormSubmissionLimit($default = false)
201215
</p>
202216

203217
<p>
204-
<input type="submit" value="Submit" /> (also a mandatory submitted parameter)
218+
<input type="submit" value="Submit" name="submit" /> (also a mandatory submitted parameter)
205219
</p>
206220
</form>
207221
</body>

jquery-maxsubmit.jquery.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"maxinputvars",
88
"suhosin"
99
],
10-
"version": "1.1.3",
10+
"version": "1.1.4",
1111
"author": {
1212
"name": "Jason Judge",
1313
"url": "https://github.com/judgej"

jquery.maxsubmit.js

+80-45
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Copyright 2013-2014 Academe Computing Ltd
33
* Released under the MIT license
44
* Author: Jason Judge <[email protected]>
5-
* Version: 1.1.3
5+
* Version: 1.1.4
66
*/
77
/**
88
* jquery.maxsubmit.js
@@ -20,8 +20,13 @@
2020
*/
2121

2222
(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+
*/
2328
$.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.
2530
return this.each(function() {
2631

2732
var settings = $.extend({
@@ -61,49 +66,8 @@
6166
// We have a form, so count up the form items that will be
6267
// submitted to the server.
6368

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;
10771

10872
if (form_count > settings.max_count) {
10973
// If the user cancels, then abort the form submit.
@@ -119,5 +83,76 @@
11983
return this;
12084
});
12185
};
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+
};
122157
}(jQuery));
123158

jquery.maxsubmittest.js

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* Copyright 2013-2014 Academe Computing Ltd
3+
* Released under the MIT license
4+
* Author: Jason Judge <[email protected]>
5+
* Version: 1.1.1
6+
*/
7+
/**
8+
* jquery.maxsubmittest.js
9+
*
10+
* Used to look at what jquery.maxsubmit is counting as fields that will be submitted.
11+
* To use:
12+
* 1. Include this script, jquery.maxSubmitTest.js, after jquery.maxSubmit.js
13+
* 2. Add the following HTML to the page, within the form you want to test:
14+
* <div class="test-maxsubmit"><a>Test MaxSubmit</a></div>
15+
* 3. Initialise the test function:
16+
* $('.test-maxsubmit').maxSubmitTest();
17+
* When you click on the "Test MaxSubmit" text, a table will be inserted immediately below it,
18+
* within div.test-maxsubmit. The table will list the field types, names and values, which can be
19+
* compared to what Firebug or similar shows is being posted.
20+
*/
21+
22+
(function($) {
23+
/**
24+
* TBC
25+
*/
26+
$.fn.maxSubmitTest = function() {
27+
return this.each(function() {
28+
$(this).click(function() {
29+
// Get the list of elements.
30+
var fields = $(this).closest('form').maxSubmitCount(true);
31+
32+
// Create a table for populating with the results.
33+
// Remove the table if it already exists.
34+
$(this).closest('div').find('table').remove();
35+
36+
// New table element and give it a header.
37+
var table = document.createElement('table');
38+
$(table).append('<tr><th>Index</th><th>Type</th><th>Name</th><th>Value</th></tr>');
39+
40+
// Add each element as a row.
41+
for (var i = 0; i < fields.length; i++) {
42+
var tr = document.createElement('tr');
43+
44+
var td_index = document.createElement('td');
45+
var td_type = document.createElement('td');
46+
var td_name = document.createElement('td');
47+
var td_value = document.createElement('td');
48+
49+
$(td_index).append('' + (i+1));
50+
51+
if ($(fields[i]).prop('tagName') == 'OPTION') {
52+
$(td_type).append($(fields[i]).closest('select').get(0).type);
53+
} else {
54+
$(td_type).append(fields[i].type);
55+
}
56+
57+
// Get the name of the element.
58+
// If a multiselect list, then we need to go to the parent to get
59+
// the name.
60+
if ($(fields[i]).prop('tagName') == 'OPTION') {
61+
$(td_name).append($(fields[i]).closest('select').attr('name'));
62+
} else {
63+
$(td_name).append(fields[i].name);
64+
}
65+
66+
// Get the value, encoding entities for display.
67+
$(td_value).append($('<div/>').text($(fields[i]).val()).html());
68+
69+
// Build up the row.
70+
tr.appendChild(td_index);
71+
tr.appendChild(td_type);
72+
tr.appendChild(td_name);
73+
tr.appendChild(td_value);
74+
75+
// Add the row to the table.
76+
table.appendChild(tr);
77+
}
78+
79+
// Put the new table into the page.
80+
$(this).closest('div').append(table);
81+
});
82+
});
83+
};
84+
}(jQuery));
85+

0 commit comments

Comments
 (0)