Skip to content

Hacky fix to handle radioButtons and skipEmpty #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion example/js2form.example.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,65 @@
<label><input type="radio" name="foo.radio" value="4"> 4</label>
</dd>
</dl>


<table>
<tbody>
<tr>
<th>Phone</th>
<td><input type="text" id="phone" name="phone" /></td>
</tr>
<tr>
<th>Address</th>
<td>
<table id="addressInfo" class="condensed-table">
<tr>
<th>Street 1</th>
<td><input type="text" id="address.street1" name="address.street1" /></td>
</tr>
<tr>
<th>Street 2</th>
<td><input type="text" id="address.street2" name="address.street2" /></td>
</tr>
<tr>
<th>City</th>
<td><input type="text" id="address.city" name="address.city" /></td>
</tr>
<tr>
<th>State</th>
<td><input type="text" id="address.state" name="address.state" /></td>
</tr>
<tr>
<th>Zip</th>
<td><input type="text" id="address.zip" name="address.zip" /></td>
</tr>
<tr>
<th>Country</th>
<td><input type="text" id="address.country" name="address.country" /></td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>

<button type="button" onclick="getJson()">Get JSON</button>
<button type="reset">Reset form</button>

</form>

<div>
<textarea id="src" cols="70" rows="20">
{
"phone":"444-444-4444",
"address":{
"street1": "12345",
"street2": "main st",
"city": "SF",
"state": "CA",
"zip": "94444",
"country": "USA"
},
"foo":{
"radio":"3",
"name":{
Expand Down Expand Up @@ -131,7 +183,7 @@
{
var data = document.getElementById('src').value;
data = JSON.parse(data);
js2form(document.getElementById('testForm'), data);
js2form(document.getElementById('testForm'), data, '.', null, true);
}
</script>
</body>
Expand Down
26 changes: 16 additions & 10 deletions src/form2js.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ var form2js = (function()
* @param rootNode {Element|String} root form element (or it's id) or array of root elements
* @param delimiter {String} structure parts delimiter defaults to '.'
* @param skipEmpty {Boolean} should skip empty text values, defaults to true
* @param emptyToNull {Boolean} should empty values be converted to null?
* @param nodeCallback {Function} custom function to get node value
* @param useIdIfEmptyName {Boolean} if true value of id attribute of field will be used if name of field is empty
*/
function form2js(rootNode, delimiter, skipEmpty, nodeCallback, useIdIfEmptyName)
function form2js(rootNode, delimiter, skipEmpty, emptyToNull, nodeCallback, useIdIfEmptyName)
{
if (typeof skipEmpty == 'undefined' || skipEmpty == null) skipEmpty = true;
if (typeof emptyToNull == 'undefined' || emptyToNull == null) emptyToNull = true;
if (typeof delimiter == 'undefined' || delimiter == null) delimiter = '.';
if (arguments.length < 5) useIdIfEmptyName = false;
if (arguments.length < 6) useIdIfEmptyName = false;

rootNode = typeof rootNode == 'string' ? document.getElementById(rootNode) : rootNode;

Expand All @@ -52,7 +54,7 @@ var form2js = (function()
i = 0;

/* If rootNode is array - combine values */
if (rootNode.constructor == Array || (typeof NodeList != "undefined" && rootNode.constructor == NodeList))
if (rootNode.constructor == Array || (typeof NodeList != 'undefined' && rootNode.constructor == NodeList))
{
while(currNode = rootNode[i++])
{
Expand All @@ -64,7 +66,7 @@ var form2js = (function()
formValues = getFormValues(rootNode, nodeCallback, useIdIfEmptyName);
}

return processNameValues(formValues, skipEmpty, delimiter);
return processNameValues(formValues, skipEmpty, emptyToNull, delimiter);
}

/**
Expand All @@ -73,7 +75,7 @@ var form2js = (function()
* @param skipEmpty if true skips elements with value == '' or value == null
* @param delimiter
*/
function processNameValues(nameValues, skipEmpty, delimiter)
function processNameValues(nameValues, skipEmpty, emptyToNull, delimiter)
{
var result = {},
arrays = {},
Expand All @@ -92,9 +94,12 @@ var form2js = (function()
{
value = nameValues[i].value;

if (emptyToNull && (value === '')) { value = null; }
if (skipEmpty && (value === '' || value === null)) continue;

name = nameValues[i].name;
if (typeof name === 'undefined') continue;

_nameParts = name.split(delimiter);
nameParts = [];
currResult = result;
Expand Down Expand Up @@ -242,8 +247,11 @@ var form2js = (function()
result = [callbackResult];
}
else if (fieldName != '' && node.nodeName.match(/INPUT|TEXTAREA/i)) {
fieldValue = getFieldValue(node);
result = [ { name: fieldName, value: fieldValue} ];
fieldValue = getFieldValue(node);
if (fieldValue == null && node.type == 'radio')
result = [];
else
result = [ { name: fieldName, value: fieldValue} ];
}
else if (fieldName != '' && node.nodeName.match(/SELECT/i)) {
fieldValue = getFieldValue(node);
Expand Down Expand Up @@ -274,8 +282,6 @@ var form2js = (function()
switch (fieldNode.type.toLowerCase()) {
case 'radio':
case 'checkbox':
if (fieldNode.checked && fieldNode.value === "true") return true;
if (!fieldNode.checked && fieldNode.value === "true") return false;
if (fieldNode.checked) return fieldNode.value;
break;

Expand Down Expand Up @@ -312,7 +318,7 @@ var form2js = (function()

if (!multiple) return selectNode.value;

for (options = selectNode.getElementsByTagName("option"), i = 0, l = options.length; i < l; i++)
for (options = selectNode.getElementsByTagName('option'), i = 0, l = options.length; i < l; i++)
{
if (options[i].selected) result.push(options[i].value);
}
Expand Down
27 changes: 20 additions & 7 deletions src/js2form.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,20 @@ var js2form = (function()
* @param delimiter
* @param nodeCallback
* @param useIdIfEmptyName
* @param shouldClean should we empty out fields first?
*/
function js2form(rootNode, data, delimiter, nodeCallback, useIdIfEmptyName)
function js2form(rootNode, data, delimiter, nodeCallback, useIdIfEmptyName, shouldClean)
{
if (arguments.length < 3) delimiter = '.';
if (arguments.length < 4) nodeCallback = null;
if (arguments.length < 5) useIdIfEmptyName = false;
if (arguments.length < 6) shouldClean = true;

var fieldValues,
formFieldsByName;

fieldValues = object2array(data);
formFieldsByName = getFields(rootNode, useIdIfEmptyName, delimiter, {}, true);
formFieldsByName = getFields(rootNode, useIdIfEmptyName, delimiter, {}, shouldClean);

for (var i = 0; i < fieldValues.length; i++)
{
Expand All @@ -77,14 +79,25 @@ var js2form = (function()

if (field instanceof Array)
{
for(i = 0; i < field.length; i++)
for (i = 0; i < field.length; i++)
{
if (field[i].value == value) field[i].checked = true;
}
if (field[i].type == "radio"){
field[i].checked = false
if (typeof value != "undefined" && value !== null && field[i].value == value || field[i].value == value.toString() )
field[i].checked = true;
}
else{
if (value == 'on' || value == 'true' || value == '1')
field[i].checked = true;
else
field[i].checked = false
}
}
}
else if (_inputOrTextareaRegexp.test(field.nodeName))
{
field.value = value;
if (value)
field.value = value;
}
else if (/SELECT/i.test(field.nodeName))
{
Expand Down Expand Up @@ -306,4 +319,4 @@ var js2form = (function()

return js2form;

})();
})();