Skip to content

Instantly share code, notes, and snippets.

@macu
Created December 15, 2013 18:34
Show Gist options
  • Select an option

  • Save macu/7976454 to your computer and use it in GitHub Desktop.

Select an option

Save macu/7976454 to your computer and use it in GitHub Desktop.
Form fields injection and sanitize number fields on submit.
<form data-includes="#anotherForm,[name=someField]" method="get">
<p>Fields from elsewhere in the document will be included on submit.</p>
<input type="submit" value="Submit!" />
</form>
<form id="anotherForm">
<input type="hidden" name="willBeIncluded" value=":)" />
<input type="number" name="willBeIncludedAndSanitized" min="1" data-sanitize="int" />
<input type="checkbox" name="willBeIncludedIfChecked" value="itWasChecked" />
</form>
<select name="someField">
<option value="a">Option A</option>
<option value="b">Option B</option>
</select>
$(function() {
// SANITIZE NUMBER FIELDS ON SUBMIT
$("form").on("submit", function() {
sanitizeFields(this);
});
// FORM FIELD INJECTION ON SUBMIT
$("form[data-includes]").on("submit", function() {
includeFields(this);
});
});
/**
* Ensures number field values are numbers in the [min, max] range.
* If the `data-sanitize` attribute of inputs is `int`, values are floored.
*
* @param {jQuery object or selector} source The field(s) to sanitize.
*/
function sanitizeFields(source) {
var $source = $(source);
// compile all fields to sanitize
// (filter gets direct; find gets descendants)
var fieldTypes = "[type=number]";
var $fields = $source.filter(fieldTypes).add($source.find(fieldTypes));
// sanitize each field
$fields.each(function() {
var $f = $(this);
var val = $f.val();
var min = $f.attr("min"), max = $f.attr("max");
// round values if sanitize=int
if ($f.data("sanitize") == "int") {
val = parseInt(val);
min = parseInt(min);
max = parseInt(max);
} else {
val = parseFloat(val);
min = parseFloat(min);
max = parseFloat(max);
}
// ensure val is number
if (isNaN(val)) val = isNaN(min) ? 0 : min;
// ensure val in range
if (!isNaN(min) && val < min) val = min;
if (!isNaN(max) && val > max) val = max;
// substitute sanitized value
$f.val(val);
});
}
/**
* Copies fields from source forms to the target form.
* If the source is not provided, the value of the `data-includes` attribute
* of the target form is used. The source may specify fields directly, and/or
* specify forms from which all input fields will be included.
*
* @param {jQuery selector} target The form to insert fields into.
* @param {jQuery selector} source The field(s) or form(s) to include.
* @see sanitizeFields
*/
function includeFields(target, source) {
// target to closest form
var $target = $(target).closest("form");
// source defaults to target form's `includes` attribute
var $source = $(source || $target.data("includes"));
// compile all fields to include
// (filter gets direct; find gets descendants)
var fieldTypes = "input,select";
var $fields = $source.filter(fieldTypes).add($source.find(fieldTypes));
// sanitize fields before insertion
sanitizeFields($fields);
// insert each field into the target form
$fields.each(function() {
var $f = $(this);
// exclude unchecked checkboxes and radios
if ($f.is("[type=checkbox]") || $f.is("[type=radio]")) {
if (!$f.is(":checked")) return;
}
// append as hidden field
$("<input type='hidden'/>")
.attr("name", $f.attr("name")).val($f.val())
.appendTo($target);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment