Skip to content

Commit

Permalink
Version 1.1.4 with support for some testing, and a number of fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
judgej committed Mar 2, 2014
1 parent 550221a commit 7504312
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 47 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ http://plugins.jquery.com/jquery-maxsubmit/

## History

1.1.4 Rewrite to support testing; listing of the items that will be submitted
1.1.3 Fixed count of HTML5 input elements
1.1.2 Updated metadata for plugins.jquery.com
1.1.1 Fixed syntax error messaing with Chrome
Expand Down
16 changes: 15 additions & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@

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

<!-- Here the application could pass in a translated message suitable for the language of the end user -->
<script type="text/javascript">
jQuery(document).ready(function($) {
// Protect the form.
$('form#form1').maxSubmit({
max_count: 2,
max_exceeded_message: "This form has too many fields.\n\n"
+ " Found {form_count} fields, so with a maximum of {max_count} supported by the server, some data will be lost.\n\n"
+ " You may continue and submit, or cancel."
});

// Allow inspection of what will be submitted (test the form).
jQuery('.test-maxsubmit').maxSubmitTest();
});
</script>

Expand All @@ -37,6 +42,9 @@

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

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

<div class="test-maxsubmit">
<p>
<a>Click here to see what the form will submit</a>
<p>
</div>

<p>
<input type="text" name="text1" value="<?php echo $input['text1']; ?>" />
<span class="text_label" title="Click to toggle toggle the enabled state">(text counts as one parameter)</span>
Expand Down Expand Up @@ -201,7 +215,7 @@ function getFormSubmissionLimit($default = false)
</p>

<p>
<input type="submit" value="Submit" /> (also a mandatory submitted parameter)
<input type="submit" value="Submit" name="submit" /> (also a mandatory submitted parameter)
</p>
</form>
</body>
Expand Down
2 changes: 1 addition & 1 deletion jquery-maxsubmit.jquery.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"maxinputvars",
"suhosin"
],
"version": "1.1.3",
"version": "1.1.4",
"author": {
"name": "Jason Judge",
"url": "https://github.com/judgej"
Expand Down
125 changes: 80 additions & 45 deletions jquery.maxsubmit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright 2013-2014 Academe Computing Ltd
* Released under the MIT license
* Author: Jason Judge <[email protected]>
* Version: 1.1.3
* Version: 1.1.4
*/
/**
* jquery.maxsubmit.js
Expand All @@ -20,8 +20,13 @@
*/

(function($) {
/**
* Set a trigger on a form to pop up a warning if the fields to be submitted
* exceed a specified maximum.
* Usage: $('form#selector').maxSubmit({options});
*/
$.fn.maxSubmit = function(options) {
// this.each() is the wrapper for each selected group of checkboxes.
// this.each() is the wrapper for each form.
return this.each(function() {

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

// textarea fields count as one submitted field each.
var form_count = $('textarea:enabled', this).length;

// Input fields of all types except checkboxes and radio buttons will
// all post one parameter.
// reset inputs are not submitted to the server and files are handled
// separately.
form_count += $('input:enabled', this)
.not("[type='checkbox']")
.not("[type='radio']")
.not("[type='file']")
.not("[type='reset']")
.length;

// Checkboxes will post only if checked.
$('input:checkbox:enabled', this).each(function() {
if (this.checked) form_count++;
});

// Single-select lists will always post one value.
$('select:enabled:not([multiple])', this).each(function() {
form_count++;
});

// Multi-select lists will post one parameter for each selected item.
$('select:enabled[multiple]', this).each(function() {
// The select item value is null if no options are selected.
var select = $(this).val();
if (select !== null) form_count += select.length;
});

// Each radio button group will post one parameter, regardless of how many
// radio buttons a group contains.
// Count the radio groups
var rgroups = [];
$('input:enabled:radio').each(function(index, el) {
var i;
for(i = 0; i < rgroups.length; i++) {
if (rgroups[i] == $(el).attr('name')) return;
}
rgroups.push($(el).attr('name'));
});
form_count += rgroups.length;
// For now, add one for the submit button.
var form_count = $(this).maxSubmitCount() + 1;

if (form_count > settings.max_count) {
// If the user cancels, then abort the form submit.
Expand All @@ -119,5 +83,76 @@
return this;
});
};

/**
* Count the number of fields that will be posted in a form.
* If return_elements is true, then an array of elements will be returned
* instead of the count. This is handy for testing.
* TODO: elements without names will not be submitted.
* Another approach may be to get all input fields at once using $("form :input")
* then knock out the ones that we don't want. That would keep the same order as the
* items would be submitted.
*/
$.fn.maxSubmitCount = function(return_elements) {
// Text fields and submit buttons will all post one parameter.

// Find the textareas.
// These will count as one post parameter each.
var fields = $('textarea:enabled[name]', this).toArray();

// Find the basic textual input fields (text, email, number, date and similar).
// These will count as one post parameter each.
// We deal with checkboxes, radio buttons sparately.
// Checkboxes will post only if checked, so exclude any that are not checked.
// There may be multiple form submit buttons, but only one will be posted with the
// form, assuming the form has been submitted by the user with a button.
// An image submit will post two fields - an x and y coordinate.
fields = fields.concat(
$('input:enabled[name]', this)
// Data items that are handled later.
.not("[type='checkbox']:not(:checked)")
.not("[type='radio']")
.not("[type='file']")
.not("[type='reset']")
// Submit form items.
.not("[type='submit']")
.not("[type='button']")
.not("[type='image']")
.toArray()
);

// Single-select lists will always post one value.
fields = fields.concat(
$('select:enabled[name]', this)
.not('[multiple]')
.toArray()
);

// Multi-select lists will post one parameter for each selected option.
// The parent select is $(this).parent() with its name being $(this).parent().attr('name')
$('select[multiple]:enabled[name] option:selected', this).each(function() {
// We collect all the options that have been selected.
fields = fields.concat(this);
});

// Each radio button group will post one parameter.
// We assume all checked radio buttons will be posted.
fields = fields.concat(
$('input:enabled:radio:checked', this)
.toArray()
);

// TODO: provide an option to return an array of objects containing the form field names,
// types and values, in a form that can be compared to what is actually posted.
if (typeof(return_elements) === 'undefined') return_elements = false;

if (return_elements === true) {
// Return the full list of elements for analysis.
return fields;
} else {
// Just return the number of elements matched.
return fields.length;
}
};
}(jQuery));

85 changes: 85 additions & 0 deletions jquery.maxsubmittest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Copyright 2013-2014 Academe Computing Ltd
* Released under the MIT license
* Author: Jason Judge <[email protected]>
* Version: 1.1.1
*/
/**
* jquery.maxsubmittest.js
*
* Used to look at what jquery.maxsubmit is counting as fields that will be submitted.
* To use:
* 1. Include this script, jquery.maxSubmitTest.js, after jquery.maxSubmit.js
* 2. Add the following HTML to the page, within the form you want to test:
* <div class="test-maxsubmit"><a>Test MaxSubmit</a></div>
* 3. Initialise the test function:
* $('.test-maxsubmit').maxSubmitTest();
* When you click on the "Test MaxSubmit" text, a table will be inserted immediately below it,
* within div.test-maxsubmit. The table will list the field types, names and values, which can be
* compared to what Firebug or similar shows is being posted.
*/

(function($) {
/**
* TBC
*/
$.fn.maxSubmitTest = function() {
return this.each(function() {
$(this).click(function() {
// Get the list of elements.
var fields = $(this).closest('form').maxSubmitCount(true);

// Create a table for populating with the results.
// Remove the table if it already exists.
$(this).closest('div').find('table').remove();

// New table element and give it a header.
var table = document.createElement('table');
$(table).append('<tr><th>Index</th><th>Type</th><th>Name</th><th>Value</th></tr>');

// Add each element as a row.
for (var i = 0; i < fields.length; i++) {
var tr = document.createElement('tr');

var td_index = document.createElement('td');
var td_type = document.createElement('td');
var td_name = document.createElement('td');
var td_value = document.createElement('td');

$(td_index).append('' + (i+1));

if ($(fields[i]).prop('tagName') == 'OPTION') {
$(td_type).append($(fields[i]).closest('select').get(0).type);
} else {
$(td_type).append(fields[i].type);
}

// Get the name of the element.
// If a multiselect list, then we need to go to the parent to get
// the name.
if ($(fields[i]).prop('tagName') == 'OPTION') {
$(td_name).append($(fields[i]).closest('select').attr('name'));
} else {
$(td_name).append(fields[i].name);
}

// Get the value, encoding entities for display.
$(td_value).append($('<div/>').text($(fields[i]).val()).html());

// Build up the row.
tr.appendChild(td_index);
tr.appendChild(td_type);
tr.appendChild(td_name);
tr.appendChild(td_value);

// Add the row to the table.
table.appendChild(tr);
}

// Put the new table into the page.
$(this).closest('div').append(table);
});
});
};
}(jQuery));

0 comments on commit 7504312

Please sign in to comment.