<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<div class="container">
<div class="row clearfix">
<div class="">
<h3>Product Attributes</h3>
<table class="table table-bordered table-hover table-sortable table-striped" id="tab_logic">
<thead>
<tr>
<th class="text-center vcenter" style="width: 20px;"></th>
<th style="width: 300px;">Label</th>
<th>Description</th>
<th class="text-center vcenter"></th>
</tr>
</thead>
<tbody class="container-items tableForm">
<tr id='attr0' data-id="0" class="hidden">
<td data-name="sort" style="width: 20px;">
<span class="glyphicon glyphicon glyphicon-sort"></span>
</td>
<td data-name="label">
<input type="text" class="form-control" name="label" placeholder="Product Attribute Description" maxlength="255">
</td>
<td data-name="description">
<textarea class="form-control" rows="5" name="description" placeholder="Product Attribute Description"></textarea>
</td>
<td data-name="del" style="width: 90px;">
<button type="button" class="btn-remove btn btn-danger btn-xs row-remove"><span class="glyphicon glyphicon-minus"></span></button>
</td>
</tr>
</tbody>
</table>
</div>
<input type="hidden" name="serializedData" id="serializedData" value="default"/>
<a id="add_row" class="btn btn-success pull-right"><span class="glyphicon glyphicon-plus"></span> Add Product Attribute</a>
</div>
<div class="row clearfix">
<textarea id="debugSerialization" rows="4" cols="50"></textarea><br/>
<a id="rehydrateBtn" class="btn btn-info"><span class="glyphicon glyphicon-save"></span>Rehydrate</a>
</div>
</div>
.table-sortable tbody tr td:first-child {
cursor: move;
}
.table-sortable tbody tr td:last-child {
text-align: center;
}
function exportJSON(formTable, control)
{
if(!control)
{
//if control is not defined then used the debugger
control = $("#debugSerialization");
}
var ret = [];
$("tbody tr", formTable).not(".hidden").each(function (index) {
var item = {};
var tr = $(this);
tr.find(":input").not("button").each(function (j) {
var curInput = $(this);
item[curInput.data("name")] = curInput.val();
});
ret.push(item);
});
var json = JSON.stringify(ret);
console.log(json);
control.val(json);
}
function initSortable(formTable)
{
// Sortable Code
var fixHelperModified = function(e, tr) {
var $originals = tr.children();
var $helper = tr.clone();
$helper.children().each(function(index) {
//alert(index);
$(this).width($originals.eq(index).width());
});
return $helper;
};
$("tbody", formTable).sortable({
helper: fixHelperModified,
handle: "td:first",
update: function () { exportJSON(formTable); }
}).disableSelection();
$("thead", formTable).disableSelection();
}
function hydrateFormTable(formTable, data)
{
if (data) {
try {
var parsedJSON = JSON.parse(data);
console.log("parsed data is:", parsedJSON);
$.each(parsedJSON, function(k, v) {
//display the key and value pair
//console.log(k, v);
addRow(formTable, v);
});
} catch(e) {
console.log("error parsing the JSON",e);
}
}
}
function clearFormTable(formTable){
//remove any current rows
$("tbody tr", formTable).not(".hidden").remove();
}
function addRow(formTable, formData)
{
// Dynamic Rows Code
// Get max row id and set new id
var newid = 0;
$.each($("tr", formTable), function () {
if (parseInt($(this).data("id")) > newid) {
newid = parseInt($(this).data("id"));
}
});
newid++;
var tr = $("<tr></tr>", {
id: "attr" + newid,
"data-id": newid
});
// loop through each td and create new elements with name of newid
$.each($("tbody tr:nth(0) td", formTable), function () {
var cur_td = $(this);
var children = cur_td.children();
// add new td and element if it has a nane
if ($(this).data("name") !== undefined) {
var td = $("<td></td>", {
"data-name": $(cur_td).data("name")
});
var c = $(cur_td).find($(children[0]).prop('tagName')).clone().val("");
c.attr("name", $(cur_td).data("name") + '[' + newid + ']');
c.data("name", $(cur_td).data("name"));
c.appendTo($(td));
td.appendTo($(tr));
} else {
var td = $("<td></td>", {
'text': $('tr', formTable).length
}).appendTo($(tr));
}
});
//hydrate fields if there's data
if(formData !== undefined)
{
$.each(formData, function(i, j) {
console.log("adding input data:", i, j, $("[data-label]", tr));
$("td[data-name="+ i +"] :input", tr).val(j);
});
}
$(tr).appendTo(formTable);
$(tr).find("td button.row-remove").on("click", function () {
$(this).closest("tr").remove();
exportJSON(formTable);
});
}
function initTable(formTable){
initSortable(formTable);
addRow(formTable);
// $(":input", formTable).change(function () {
// console.log("there is an update");
// exportJSON(formTable, $("#debugSerialization"));
// });
//setup auto-hydrating
formTable.on('input', function () {
exportJSON(formTable);
});
}
$(document).ready(function() {
var formTable = $("#tab_logic");
var hiddenSerializedData = $("#serializedData");
$("#rehydrateBtn").click(function(){
clearFormTable(formTable);
//add rows with JSON data
hydrateFormTable(formTable, debugDataField.val());
});
initTable(formTable);
$("#add_row").on("click", function() {
addRow(formTable);
});
});