So I've got this HTML snippet to generate the table above:
<div class="container"> <table id="actionTabDataTable" class="table table-striped table-bordered" cellspacing="0" width="100%"></table> </div> <!-- Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true"> × </span> </button> <h4 class="modal-title" id="myModalLabel"> Please tell us about the job <span id="name"></span> has: </h4> </div> <div class="modal-body"> <form> <div class="form-group"> <label for="job"> Job title </label> <input type="text" class="form-control" id="job" name="job" /> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal"> Close </button> <button type="button" class="btn btn-primary"> Add </button> </div> </div> </div> </div>
And I want to be able to interact with the underlying data which is an array of objects generated from a form further back in the mists of time... or at least earlier in the process anyway. So I use the following snippet of JavaScript:
var data = [{ "name": "John Smith", "jobs": [ "Bottle Washer", "Bus Boy" ] }, { "name": "Jane Smith", "jobs": [ "Head Chef", "Barmaid" ] }, { "name": "Barry Smith" }]; $(function(){ var table = $("#actionTabDataTable").DataTable({ "data": data, "columns": [{ "title": "Name", "data": "name" }, { "title": "Jobs", "orderable": false, "data": "jobs", "render": function(d) { if (d) { return $("<ul></ul>", { "class": "list-group" }).append(function() { var lis = []; for (var i = 0; i < d.length; i++) { lis.push($("<li></li>", { "text": d[i], "class": "list-group-item" }).append($("<i></i>", { "class": "glyphicon glyphicon-remove" })).append($("<i></i>", { "class": "glyphicon glyphicon-edit", "data-toggle": "modal", "data-target": "#myModal" }))); } return lis; }).prop("outerHTML"); } else { return "No jobs"; } } }, { "title": "Action", "orderable": false, "render": function() { return $("<button></button>", { "class": "btn btn-primary", "text": "Add", "data-toggle": "modal", "data-target": "#myModal" }).append($("<i></i>", { "class": "glyphicon glyphicon-plus" })).prop("outerHTML"); } }] }); $("#actionTabDataTable tbody").on("click", ".glyphicon-remove", function() { var d = table.row($(this).parents("tr")).data(); var job = $(this).parents("li").text(); $.each(data, function(k, v) { if (v.name === d.name) { console.log(v.jobs.length); for (var i = 0; i < v.jobs.length; i++) { if (v.jobs[i] === job) { v.jobs.splice(i, 1); !v.jobs.length && delete v.jobs; break; } } } }); table.clear().rows.add(data).draw(); }).on("click", ".glyphicon-edit", function() { var d = table.row($(this).parents("tr")).data(); var job = $(this).parents("li").text(); $("#name").text(d.name); $("#job").val(job); $("#myModal").data({ "original": d, "job": job }).find(".btn-primary").text("Update"); }).on("click", ".btn-primary", function() { var d = table.row($(this).parents("tr")).data(); $("#myModal").data("original", d); $("#name").text(d.name); }); $("#myModal").on("click", ".btn-primary", function() { var d = $("#myModal").data("original"); var j = $("#myModal").data("job"); $.each(data, function(k, v) { if (v.name === d.name) { if ($("#myModal").find(".btn-primary").text() === "Update") { $.each(v.jobs, function(a, b) { if (b === j) { v.jobs[a] = $("#job").val(); } }); } else { if (v.hasOwnProperty("jobs") && Array.isArray(v.jobs)) { v.jobs.push($("#job").val()); } else { v.jobs = [$("#job").val()]; } } } }); table.clear().rows.add(data).draw(); $("#myModal").modal("hide"); }).on("hidden.bs.modal", function() { $("#job").val(""); $("#myModal") .removeData("original") .removeData("job") .find(".btn-primary") .text("Add"); }); });
Basically this allows us to interact with the underlying data used to generate the table without having to worry about rendering the data again. It's up and running here.
I've had to tweak the CSS a little as well, here it is:
.list-group { text-align: left; margin-bottom:0; } .glyphicon { padding: 0 0 0 10px; cursor: pointer; float:right; }
No comments:
Post a Comment