Created
January 14, 2015 03:09
-
-
Save learner-long-life/b70753208c9e9f23b773 to your computer and use it in GitHub Desktop.
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
// First, checks if it isn't implemented yet. | |
// from http://stackoverflow.com/questions/610406/javascript-equivalent-to-printf-string-format | |
if (!String.prototype.format) { | |
String.prototype.format = function() { | |
var args = arguments; | |
return this.replace(/{(\d+)}/g, function(match, number) { | |
return typeof args[number] != 'undefined' | |
? args[number] | |
: match | |
; | |
}); | |
}; | |
} | |
// Define an assert method, from https://gist.github.com/kaheglar/1042463 | |
$.assert = function(condition, msg) { | |
if (!condition) { | |
$.error(msg); | |
} | |
}; | |
/* | |
* Function for .each iterator to convert an | |
* input object into an HTML form input tag of the right type, | |
* with the class .input | |
*/ | |
function createFormInput(index, value) { | |
if (!value || !value.type || (value.required == undefined) || !value.name) { | |
return; | |
} | |
// Create the formatted string for the div, with classname == value.name | |
var divString = '<div class="{0}"></div>'.format(value.name) | |
$('form').append(divString) | |
var className = "."+value.name; | |
// Create the required string | |
var requiredString = value.required ? 'required' : ''; | |
// Create and add the legend string to the div | |
var legendString = '<legend>{0}</legend>'.format(value.name) | |
$(className).append(legendString) | |
// Handle text inputs | |
if (value.type === "text") { | |
var inputString = '<input class="input" type="text" name="{0}" {1}></input>'.format( | |
value.name, requiredString); | |
$(className).append(inputString) | |
// Handle radio group inputs | |
} else if (value.type === "radioGroup") { | |
var baseString = '<input class="input" type="radio" name="{0}" value="{1}">{2}</input>'; | |
for (var i = 0; i < value.choices.length; i++) { | |
var choice = value.choices[i]; | |
var inputString = baseString.format( | |
value.name, choice.value, choice.label); | |
$(className).append(inputString); | |
} | |
// Handle select inputs | |
} else if (value.type === "select") { | |
var baseString = '<option value={0}>{1}</option>'; | |
var selectString = "<select class='input' id={0} name={0} {1}></select>".format( | |
value.name, requiredString); | |
$(className).append(selectString); | |
for (var i = 0; i < value.options.length; i++) { | |
var option = value.options[i]; | |
var inputString = baseString.format(option.value, option.text); | |
$("select#"+value.name).append(inputString); | |
} | |
$(className).append("</select>"); | |
// Select the newly added object and make it unselected (blank default) | |
$("#"+value.name).prop("selectedIndex", -1); | |
} | |
// Add a red asterisk as a visual reminder that a field is required | |
if (value.required) { | |
$(className).append('<span class="asterisk">✱</span>'); | |
} | |
} | |
function ajaxPostSuccess(msg) { | |
if (msg) { | |
//alert("Successfully submitted!"); | |
} else { | |
alert("Unknown error !"); | |
} | |
} | |
function sendJSON(actionURL, sendData) { | |
$.ajax({ | |
type: "POST", | |
url: actionURL, | |
dataType: "json", | |
success: ajaxPostSuccess, | |
data: sendData | |
}).error(function() { | |
console.error("Some error occurred while posting the Ajax request."); | |
}); | |
} | |
function serializeInputs(formInputs) { | |
var object = {}; | |
function serializeInput(index, input) { | |
var inputName = $(input).attr('name'); | |
$.assert(inputName !== undefined); | |
// Handle radio buttons differently | |
if ($(input).attr('type') === 'radio') { | |
var radioString = 'input[name={0}]:checked'.format(inputName); | |
var radioChecked = $(radioString); | |
// Only add a key-value pair if exactly one radio button was checked | |
if (radioChecked.length === 1) { | |
object[inputName] = $(radioChecked[0]).val(); | |
} | |
} else { | |
var value = $(input).val(); | |
if (value.length > 0) { | |
object[inputName] = $(input).val(); | |
} | |
} | |
} | |
$.each(formInputs, serializeInput); | |
return object; | |
} | |
/* | |
* Handler function to parse Ajax response with dynamic form content. | |
*/ | |
function createForm(obj) { | |
var action = obj.action; | |
// As a test, we can set the form action to the given URL | |
// but we actually want to replace the default form submission behavior | |
// to be an Ajax request instead. | |
//$('form').attr('action', action); | |
var inputs = obj.inputs; | |
$.each(inputs, createFormInput); | |
// This doesn't appear to work (the keys are correct, but all the values are blank) | |
// var sendData = $("form").serializeArray(); | |
var form = $('form'); | |
var submitButton = $('input[type="submit"]'); | |
var anyError = false; | |
// Helper function, defined in this scope to get access to anyError | |
// TODO There is probably a better way to do this. | |
function validateInput(index, inputTag) { | |
// Convert to a jQuery object | |
inputTag = $(inputTag); | |
var inputName = inputTag.attr("name"); | |
// Create a new CSS class for the error message that is based on the | |
// original input's name | |
var errorName = "error-" + inputName; | |
// Handle both the case of empty text inputs, and empty select inputs | |
if (inputTag.attr("required") && | |
((!inputTag.val()) || (inputTag.val().length === 0) || (inputTag.prop("selectedIndex") === -1))) { | |
// If an input is required and there is no text, add an error message | |
var errorString = '<p id="{0}">Required field!</p>'.format( | |
errorName); | |
// Append it to the div with the right class matching this input name | |
// only if there is not already an error message. | |
if ($("#"+errorName).length === 0) { | |
$('.'+inputName).append(errorString); | |
} | |
anyError = true; | |
// Exit the function now, so we don't just remove the error we just | |
// added below. | |
return; | |
} | |
// If there exists an error message, and there is no longer an error | |
// (guaranteed in this branch), then remove the error message | |
if ($("#"+errorName).length !== 0) { | |
$("#"+errorName).remove(); | |
} | |
} | |
// Make sure there is exactly one form on the page, and we have it | |
$.assert(form.length === 1); | |
form.submit(function(event){ | |
event.preventDefault(); | |
anyError = false; | |
// Iterate through all the form elements (".input") and if they are required, | |
// make sure their value is not empty | |
$.each($('.input'), validateInput); | |
if (anyError) { | |
// If there is any error, exit now and do not send JSON request. | |
return; | |
} | |
var sendData = serializeInputs($('.input')); | |
sendJSON(action, sendData); | |
// After we send JSON, remove our form elements so that we can | |
// tell something happened. | |
form.remove(); | |
var successString = '<p>Successfully submitted AJAX post: {0}</p>'.format( | |
JSON.stringify(sendData)); | |
$('body').append(successString); | |
}); | |
} | |
$.ajax({ | |
url : 'http://bennysidelinger.com/formModel.php', | |
type : "GET", | |
crossDomain: true, | |
dataType: 'json', | |
success: function(data){ | |
console.log(data); | |
createForm(data); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment