Last active
December 31, 2015 18:49
-
-
Save dalgard/8029759 to your computer and use it in GitHub Desktop.
Sync some form controls with an object (http://codepen.io/dalgard/full/CkbKw)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This trick is a lazy way of two-way sync'ing some form controls with an options object. | |
Actually, the "sync'ing" consists in getting the values when needed and updating the fields | |
when changing something. It has its limits, but may work quite nicely. | |
Depends on: jQuery/Zepto | |
The code below works for checkboxes (boolean), text input (string), number input (number), | |
select lists (string) and json in textarea (object) | |
HTML: | |
<input type="checkbox" data-options="my_options" data-options-key="my_boolean_option"> | |
<input type="text" data-options="my_options" data-options-key="my_string_option"> | |
<input type="number" data-options="my_options" data-options-key="my_numerical_option"> | |
<select data-options="my_options" data-options-key="my_other_option"><option>first</option><option>second</option></select> | |
<textarea data-options="my_options" data-options-key="my_json_option" data-options-type="json"></textarea> | |
(<span class="error" data-options="my_options" data-options-error="my_json_option"></span>) | |
JS: | |
// on app init (probably should attach to your app's namespace ;)) | |
createOptions(window, "my_options"); | |
// get option value | |
window.my_options.some_option | |
// set option value (reflects on form control) | |
window.my_options = { some_option: "cool option, man" } | |
*/ | |
// Add options object to namespace[name] | |
function createOptions(namespace, name) { | |
// Hooray for ES5! | |
Object.defineProperty(namespace, name, { | |
get: function () { | |
var new_options = {}; | |
// Iterate over elements that belong to this particular collection of options | |
$("[data-options='" + name + "'][data-options-key]").each(function () { | |
var input = $(this), | |
type = input.attr("data-options-type") || input.attr("type"), | |
key = input.attr("data-options-key"), | |
value; | |
try { | |
if (type === "json") { | |
var json = JSON.parse(input.val() || "{}"); | |
value = (json instanceof Object ? json : {}); | |
} | |
else if (type === "checkbox") value = input.prop("checked"); | |
else if (type === "number") value = parseInt(input.val()); | |
else value = input.val(); | |
// Reset error message | |
input.removeClass("has-error"); | |
$("[data-options='" + name + "'][data-options-error='" + key + "']").text(""); | |
} | |
catch (e) { | |
value = (type === "json" ? {} : null); | |
// Output error message or bubble exception | |
input.addClass("has-error"); | |
var error_elem = $("[data-options='" + name + "'][data-options-error='" + key + "']"); | |
if (error_elem.length) error_elem.text(e.name + ": " + e.message); | |
else throw(e); | |
} | |
new_options[key] = value; | |
}); | |
return new_options; | |
}, | |
set: function (object) { | |
for (var key in object) { | |
if (object.hasOwnProperty(key)) { | |
var input = $("[data-options='" + name + "'][data-options-key='" + key + "']"), | |
type = input.attr("data-options-type") || input.attr("type"), | |
value = object[key]; | |
if (type === "json") input.val(JSON.stringify(value, null, 2)); | |
else if (type === "checkbox") input.prop("checked", value); | |
else input.val(value); | |
} | |
} | |
}, | |
enumerable: true | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment