Skip to content

Instantly share code, notes, and snippets.

@miere
Last active May 5, 2020 11:25
Show Gist options
  • Save miere/5651578 to your computer and use it in GitHub Desktop.
Save miere/5651578 to your computer and use it in GitHub Desktop.
define( function() {
function isValidElement(element) {
var nodeName = element[0].nodeName.toUpperCase(), invalidInputTypes = [ "BUTTON", "SUBMIT", "CLEAR" ]
var result = ((nodeName != "BUTTON") && !(nodeName == "INPUT" && (invalidInputTypes.contains( element.attr(
"type" ).toUpperCase() ))))
return result
}
function wireFormElementAgainstObject(element, object) {
var name, structure, path, value
element.change( function() {
name = $( this ).attr( "name" )
structure = name.split( "." )
path = ""
for ( var i = 0; i < structure.length; i++)
path += '["' + structure[i] + '"]'
if (element[0].nodeName.toUpperCase() == "INPUT" && element.attr( "type" ) == "checkbox")
value = $( this ).is( ":checked" )
else
value = $( this ).val()
eval( "object" + path + " = value" )
} )
}
function setValue(element, value) {
if (element[0].nodeName.toUpperCase() == "INPUT" && element.attr( "type" ) == "checkbox")
element.attr( "checked", (value) )
else if (element[0].nodeName.toUpperCase() == "INPUT" && element.attr( "type" ) == "radio" && !value)
$( element ).find( "input:radio[name='" + element.attr( "name" ) + "']" ).attr( 'checked', false )
else if (element[0].nodeName.toUpperCase() == "INPUT" && element.attr( "type" ) == "radio")
$( element ).find( "input:radio[name='" + element.attr( "name" ) + "'][value='" + value + "']" ).attr(
"checked", true )
else
element.val( value )
}
function wireObjectAgainstFormElement(object, element, loadNullValuesFromForm) {
var data = createHierarchyAndGetObjectNodeData( object, element )
methodName = data.name.charAt( 0 ).toUpperCase() + data.name.substring( 1 )
data.target["set" + methodName] = function(val) {
data.target[data.name] = val
setValue( element, val )
}
data.target["get" + methodName] = function() {
return data.target[data.name]
}
if (loadNullValuesFromForm && (data.target[data.name] == undefined || data.target[data.name] == null))
data.target[data.name] = element.val()
data.target["set" + methodName]( data.target[data.name] )
}
function createHierarchyAndGetObjectNodeData(object, element) {
var name = element.attr( "name" ), target = object
if (!name) {
console.warn( "Can't wire element " + element + ": no attribute name found." )
name = ""
}
else if (name.contains( "." )) {
target = createHierarchyAndReturnLastCursor( object, name )
name = name.replace( /^.*\.([^\.]+)$/, "$1" )
}
return {
name : name,
target : target
}
}
function createHierarchyAndReturnLastCursor(object, path) {
var cursor, newPath = path.split( "." )
cursor = object
for ( var i = 0; i < newPath.length - 1; i++) {
if (!cursor[newPath[i]] && i != (newPath.length - 1))
cursor[newPath[i]] = {}
cursor = cursor[newPath[i]]
}
return cursor
}
function retrieveValidDataElementsFromRootElement(rootElement) {
return rootElement.find( "input, select, textarea" )
}
return {
wireToModel : function(args) {
var elements = retrieveValidDataElementsFromRootElement( args.formObject )
$( elements ).each( function(i, element) {
element = $( element )
if (!isValidElement( element ))
return;
wireObjectAgainstFormElement( args.model, element, args.loadNullValuesFromForm )
wireFormElementAgainstObject( element, args.model )
} )
if (args.debug)
console.log( args.model )
}
}
} )
var form = $("#formId")
var model = null
// Retrieve your data
function loadFormData(){
$.ajax({
url: "/some/rest/json",
success: wireObjectToForm
})
}
// Wire you data against some form
// - when you change its fields it will change the object attributes
// - when you change object attributes with setter then the respectively form field will be changed
// - form fields and object attributes are binded by the name attribute on html field
function wireObjectToForm( response ) {
form.wireToModel( {
formObject : form,
model : object,
// when some html field has value, but your model is set to null
// then you can force to read this value from form insted of keep the null value
loadNullValuesFromForm : true
})
model = response
}
// apply your validation agains the model insted of
function validateForm(){
if ( model.property != "something" )
throw "Bad property"
}
function onSubmitForm(){
validateForm()
$.ajax({
url: "/some/rest/json",
type: "POST",
dataType: "json",
// submit your model
data: model,
success: onSaveWithSuccess
})
}
function onSaveWithSuccess(){
alert( "it works" )
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment