diff --git a/smash/web/static/js/subject.js b/smash/web/static/js/subject.js new file mode 100644 index 0000000000000000000000000000000000000000..caa51b2a38e7f5774a21988afc8193be181d5284 --- /dev/null +++ b/smash/web/static/js/subject.js @@ -0,0 +1,240 @@ +function createColumn(dataType, name, filter, visible, renderFunction) { + if (renderFunction === undefined) { + renderFunction = function (data, type, row, meta) { + return row[dataType]; + } + } + return { + "type": dataType, + "name": name, + "filter": filter, + "visible": visible, + "render": renderFunction + }; +} + +function getColumns(type) { + var result = []; + result.push(createColumn("nd_number", "ND", "string_filter", true)); + result.push(createColumn("screening_number", "Screening", "string_filter", true)); + result.push(createColumn("first_name", "First name", "string_filter", true)); + result.push(createColumn("last_name", "Last name", "string_filter", true)); + result.push(createColumn("date_born", "Date of birth", null, false)); + result.push(createColumn("default_location", "Location", "location_filter", true)); + result.push(createColumn("dead", "Deceased", "yes_no_filter", true)); + result.push(createColumn("resigned", "Resigned", "yes_no_filter", true)); + result.push(createColumn("postponed", "Postponed", "yes_no_filter", true)); + result.push(createColumn("information_sent", "Info sent", "yes_no_filter", true)); + result.push(createColumn("type", "Type", "type_filter", true)); + result.push(createColumn("id", "Id", null, false)); + for (var i = 1; i <= 8; i++) { + var renderFunction = (function () { + var x = i; + return function (data, type, row, meta) { + return create_visit_row(row.visits[x - 1]); + }; + })(); + + result.push(createColumn("visit_" + i, "Visit " + i, "visit_filter", true, renderFunction)); + + } + result.push(createColumn("id", "Edit", null, true, function (data, type, row, meta) { + return '<a href="#" type="button" class="btn btn-block btn-default">Edit</a>'; + })); + return result; + +} + +function createHeader(columnsDefinition) { + var header = document.createElement("thead"); + var headerRow = document.createElement("tr"); + header.appendChild(headerRow); + for (var i = 0; i < columnsDefinition.length; i++) { + var column = columnsDefinition[i]; + var element = document.createElement("th"); + element.innerHTML = column.name; + headerRow.appendChild(element); + } + return header; +} + +function createFilter(columnsDefinition) { + var footer = document.createElement("tfoot"); + footer.style.display = "table-header-group"; + var footerRow = document.createElement("tr"); + footer.appendChild(footerRow); + for (var i = 0; i < columnsDefinition.length; i++) { + var column = columnsDefinition[i]; + var element = document.createElement("th"); + if (column.filter !== null) { + element.innerHTML = "<div name='" + column.filter + "'>" + column.name + "</div>"; + } + footerRow.appendChild(element); + } + return footer; +} + +function create_visit_row(visit) { + var color = "white"; + var text = "---"; + if (visit !== undefined && visit !== null) { + if (visit.status === "DONE") { + color = "green"; + text = "OK"; + } else if (visit.status === "MISSED") { + color = "pink"; + text = "MISSED"; + } else if (visit.status === "UPCOMING") { + color = "#00ffff"; + text = "UPCOMING"; + } else if (visit.status === "EXCEEDED") { + color = "orange"; + text = "EXCEEDED"; + } else if (visit.status === "SHOULD_BE_IN_PROGRESS") { + color = "orange"; + text = "IN PROGRESS (NO APPOINTMENTS)"; + } else if (visit.status === "IN_PROGRESS") { + color = "lightgreen"; + text = "IN PROGRESS"; + } + text += "<br/>" + visit.datetime_start + " - " + visit.datetime_end; + } + return "<div style='background-color:" + color + "';width:100%;height:100%>" + text + "</div>"; +} + +function createVisibilityCheckboxes(checkboxesElement, columns) { + var row = null; + for (var i = 0; i < columns.length; i++) { + if (i % 10 === 0) { + row = document.createElement("div"); + row.style.display = "table-row"; + checkboxesElement.appendChild(row); + } + var column = columns[i]; + var element = document.createElement("div"); + element.style.display = "table-cell"; + var checked = ""; + if (column.visible) { + checked = "checked"; + } + element.innerHTML = "<input type='checkbox' " + checked + " data-column='" + i + "' name='" + column.type + "'/>" + column.name; + row.appendChild(element); + } + +} + +function createSubjectsTable(params) { + var tableElement = params.tableElement; + var worker_locations = params.worker_locations; + var getSubjectEditUrl = params.getSubjectEditUrl; + var subject_types_url = params.subject_types_url; + var locations_url = params.locations_url; + var subjects_url = params.subjects_url; + var columnsDefinition = params.columns; + + tableElement.appendChild(createHeader(columnsDefinition)); + tableElement.appendChild(createFilter(columnsDefinition)); + tableElement.appendChild(document.createElement("tbody")); + createVisibilityCheckboxes(params.checkboxesElement, columnsDefinition); + + var table; + $(tableElement).find('tfoot div[name="string_filter"]').each(function () { + var title = $(this).text(); + $(this).html('<input type="text" style="width:80px" placeholder="' + title + '" />'); + }); + + $(tableElement).find('tfoot div[name="yes_no_filter"]').each(function () { + $(this).html('<select style="width:60px" ><option value selected="selected">---</option><option value="true">YES</option><option value="false">NO</option></select>'); + }); + + $(tableElement).find('tfoot div[name="visit_filter"]').each(function () { + $(this).html('<select style="width:60px" >' + + '<option value selected="selected">---</option>' + + '<option value="MISSED">MISSED</option>' + + '<option value="DONE">DONE</option>' + + '<option value="EXCEED">EXCEED</option>' + + '<option value="IN_PROGRESS">IN PROGRESS</option>' + + '<option value="SHOULD_BE_IN_PROGRESS">SHOULD BE IN PROGRESS</option>' + + '<option value="UPCOMING">UPCOMING</option>' + + '</select>'); + }); + + $(tableElement).find('tfoot div[name="location_filter"]').each(function () { + var obj = $(this); + obj.html('<select style="width:80px"><option value selected="selected">---</option></select>'); + var select = $('select', obj); + $.get(locations_url, function (data) { + $.each(data.locations, function (index, location) { + select.append('<option value="' + location.id + '">' + location.name + '</option>'); + }); + if (worker_locations.length === 1) { + select.val(worker_locations[0].id); + } + }); + + }); + $(tableElement).find('tfoot div[name="type_filter"]').each(function () { + var obj = $(this); + obj.html('<select style="width:80px"><option value selected="selected">---</option></select>'); + var select = $('select', obj); + $.get(subject_types_url, function (data) { + $.each(data.types, function (index, type) { + select.append('<option value="' + type.id + '">' + type.name + '</option>'); + }); + }); + }); + + + $(function () { + var columns = []; + var columnDefs = []; + for (var i = 0; i < columnsDefinition.length; i++) { + var column = columnsDefinition[i]; + columns.push({"data": column.type}); + columnDefs.push({"targets": i, "render": column.render, visible: column.visible}); + } + + + table = $('#table').DataTable({ + pageLength: 25, + serverSide: true, + processing: true, + responsive: true, + ajax: subjects_url, + columns: columns, + columnDefs: columnDefs, + order: [[0, 'desc']] + }); + + $('#table tbody').on('click', 'a', function () { + var data = table.row($(this).parents('tr')).data(); + window.location.href = getSubjectEditUrl(data.id.toString()); + }); + + // Apply the search + table.columns().every(function () { + var that = this; + + $('input', this.footer()).on('keyup change', function () { + if (that.search() !== this.value) { + that.search(this.value).draw(); + } + }); + $('select', this.footer()).on('keyup change', function () { + if (that.search() !== this.value) { + that.search(this.value).draw(); + } + }); + }); + $('#table_filter').css("display", "null"); + }); + $('#visible-column-checkboxes input').on('click', function (e) { + var visible = $(this).is(":checked"); + + // Get the column API object + var column = table.column($(this).attr('data-column')); + console.log($(this).attr('data-column')); + // Toggle the visibility + column.visible(visible); + }); +} \ No newline at end of file diff --git a/smash/web/templates/subjects/index.html b/smash/web/templates/subjects/index.html index a708edf65ce4bee892a009be8c2cffe5172ffd5f..5d1b71485ed61161555b8cf9ce0b087ae1cf0865 100644 --- a/smash/web/templates/subjects/index.html +++ b/smash/web/templates/subjects/index.html @@ -24,156 +24,15 @@ <i class="fa fa-plus"></i> Add new subject </a> - <div id="visible-column-checkboxes" style="display:table"> - <div style="display:table-row"> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="0" name="nd_number"/>ND - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="1" name="screening_number"/>Screening - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="2" name="first_name"/>First name - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="3" name="last_name"/>Last name - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="4" name="default_location"/>Default location - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="5" name="dead"/>Deceased - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="6" name="resigned"/>Resigned - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="7" name="postponed"/>Postponed - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="8" name="information_sent"/>Info sent - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="9" name="type"/>Type - </div> - </div> - <div style="display:table-row"> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="10" name="visit_1"/>Visit 1 - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="11" name="visit_2"/>Visit 2 - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="12" name="visit_3"/>Visit 3 - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="13" name="visit_4"/>Visit 4 - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="14" name="visit_5"/>Visit 5 - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="15" name="visit_6"/>Visit 6 - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="16" name="visit_7"/>Visit 7 - </div> - <div style="display:table-cell"> - <input type="checkbox" checked data-column="17" name="visit_8"/>Visit 8 - </div> - </div> - </div> </div> <div class="box-body"> <table id="table" class="table table-bordered table-striped table-responsive"> - <thead> - <tr> - <th>ND</th> - <th>Screening</th> - <th>First name</th> - <th>Last name</th> - <th>Default location</th> - <th>Deceased</th> - <th>Resigned</th> - <th>Postponed</th> - <th>Info sent</th> - <th>Type</th> - <th>Visit 1</th> - <th>Visit 2</th> - <th>Visit 3</th> - <th>Visit 4</th> - <th>Visit 5</th> - <th>Visit 6</th> - <th>Visit 7</th> - <th>Visit 8</th> - <th>Edit</th> - </tr> - </thead> - <tfoot style="display: table-header-group;"> - <tr> - <th> - <div name="string_filter">ND</div> - </th> - <th> - <div name="string_filter">Screening number</div> - </th> - <th> - <div name="string_filter">Name</div> - </th> - <th> - <div name="string_filter">Surname</div> - </th> - <th> - <div name="location_filter">---</div> - </th> - <th> - <div name="yes_no_filter">---</div> - </th> - <th> - <div name="yes_no_filter">---</div> - </th> - <th> - <div name="yes_no_filter">---</div> - </th> - <th> - <div name="yes_no_filter">---</div> - </th> - <th> - <div name="type_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - <th> - <div name="visit_filter">---</div> - </th> - </tr> - </tfoot> - - <tbody> - </tbody> </table> </div> + <h3>Visible columns</h3> + <div id="visible-column-checkboxes" style="display:table; width:100%"> + </div> {% endblock maincontent %} {% block scripts %} @@ -181,199 +40,29 @@ <script src="{% static 'AdminLTE/plugins/datatables/jquery.dataTables.min.js' %}"></script> <script src="{% static 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js' %}"></script> + <script src="{% static 'js/subject.js' %}"></script> <script> - var table; - $('#table').find('tfoot div[name="string_filter"]').each(function () { - var title = $(this).text(); - $(this).html('<input type="text" style="width:80px" placeholder="' + title + '" />'); - }); - - $('#table').find('tfoot div[name="yes_no_filter"]').each(function () { - $(this).html('<select style="width:60px" ><option value selected="selected">---</option><option value="true">YES</option><option value="false">NO</option></select>'); - }); - - $('#table').find('tfoot div[name="visit_filter"]').each(function () { - $(this).html('<select style="width:60px" >' + - '<option value selected="selected">---</option>' + - '<option value="MISSED">MISSED</option>' + - '<option value="DONE">DONE</option>' + - '<option value="EXCEED">EXCEED</option>' + - '<option value="IN_PROGRESS">IN PROGRESS</option>' + - '<option value="SHOULD_BE_IN_PROGRESS">SHOULD BE IN PROGRESS</option>' + - '<option value="UPCOMING">UPCOMING</option>' + - '</select>'); - }); - - $('#table').find('tfoot div[name="location_filter"]').each(function () { - var obj = $(this); - obj.html('<select style="width:80px"><option value selected="selected">---</option></select>'); - var select = $('select', obj); - $.get("{% url 'web.api.locations' %}", function (data) { - $.each(data.locations, function (index, location) { - select.append('<option value="' + location.id + '">' + location.name + '</option>'); - }); - {% if worker.locations.all.count == 1 %} - select.val({{ worker.locations.first.id}}); - {% endif %} - }); - - }); - $('#table').find('tfoot div[name="type_filter"]').each(function () { - var obj = $(this); - obj.html('<select style="width:80px"><option value selected="selected">---</option></select>'); - var select = $('select', obj); - $.get("{% url 'web.api.subject_types' %}", function (data) { - $.each(data.types, function (index, type) { - select.append('<option value="' + type.id + '">' + type.name + '</option>'); - }); - }); - - }); - - function create_visit_row(visit) { - var color = "white"; - var text = "---"; - if (visit !== undefined && visit !== null) { - if (visit.status === "DONE") { - color = "green"; - text = "OK"; - } else if (visit.status === "MISSED") { - color = "pink"; - text = "MISSED"; - } else if (visit.status === "UPCOMING") { - color = "#00ffff"; - text = "UPCOMING"; - } else if (visit.status === "EXCEEDED") { - color = "orange"; - text = "EXCEEDED"; - } else if (visit.status === "SHOULD_BE_IN_PROGRESS") { - color = "orange"; - text = "IN PROGRESS (NO APPOINTMENTS)"; - } else if (visit.status === "IN_PROGRESS") { - color = "lightgreen"; - text = "IN PROGRESS"; - } - text += "<br/>" + visit.datetime_start + " - " + visit.datetime_end; - } - return "<div style='background-color:" + color + "';width:100%;height:100%>" + text + "</div>"; + function getSubjectEditUrl(id) { + return "{% url 'web.views.subject_edit' 12345 %}".replace(/12345/, id); } - $(function () { - table = $('#table').DataTable({ - pageLength: 25, - serverSide: true, - processing: true, - responsive: true, - ajax: "{% url 'web.api.subjects' list_type %}", - columns: [ - {"data": "nd_number"}, - {"data": "screening_number"}, - {"data": "first_name"}, - {"data": "last_name"}, - {"data": "default_location"}, - {"data": "dead"}, - {"data": "resigned"}, - {"data": "postponed"}, - {"data": "information_sent"}, - {"data": "type"}, - {"data": "visit_1"}, - {"data": "visit_2"}, - {"data": "visit_3"}, - {"data": "visit_4"}, - {"data": "visit_5"}, - {"data": "visit_6"}, - {"data": "visit_7"}, - {"data": "visit_8"}, - {"data": null} - ], - columnDefs: [{ - "targets": 10, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[0]); - } - }, { - "targets": 11, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[1]); - } - }, { - "targets": 12, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[2]); - } - }, { - "targets": 13, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[3]); - } - }, { - "targets": 14, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[4]); - } - }, { - "targets": 15, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[5]); - } - }, { - "targets": 16, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[6]); - } - }, { - "targets": 17, - "render": function (data, type, row, meta) { - return create_visit_row(row.visits[7]); - } - }, { - "targets": 18, - "data": "id", - "defaultContent": '<a href="#" type="button" class="btn btn-block btn-default">Edit</a>' - }], - order: [[0, 'desc']] - }); - {% if worker.locations.all.count == 1 %} - table.columns(4).search({{ worker.locations.first.id}}).draw(); - {% endif %} - - $('#table tbody').on('click', 'a', function () { - var data = table.row($(this).parents('tr')).data(); - var url = "{% url 'web.views.subject_edit' 12345 %}".replace(/12345/, data.id.toString()); - window.location.href = url; - }); - - // Apply the search - table.columns().every(function () { - var that = this; - - $('input', this.footer()).on('keyup change', function () { - if (that.search() !== this.value) { - that - .search(this.value) - .draw(); - } - }); - $('select', this.footer()).on('keyup change', function () { - if (that.search() !== this.value) { - that - .search(this.value) - .draw(); - } - }); - }); - $('#table_filter').css("display", "none"); - }); - $('#visible-column-checkboxes input').on('click', function (e) { - var visible = $(this).is(":checked"); - - // Get the column API object - var column = table.column($(this).attr('data-column')); - console.log($(this).attr('data-column')); - // Toggle the visibility - column.visible(visible); - }); + var worker_locations = []; + {% for location in worker.locations.all %} + worker_locations.push({id: location.id, name: location.name}); + {% endfor %} + + createSubjectsTable({ + getSubjectEditUrl: getSubjectEditUrl, + worker_locations: worker_locations, + subject_types_url: "{% url 'web.api.subject_types' %}", + locations_url: "{% url 'web.api.locations' %}", + subjects_url: "{% url 'web.api.subjects' list_type %}", + tableElement: document.getElementById("table"), + columns: getColumns("{{ list_type }}"), + checkboxesElement: document.getElementById("visible-column-checkboxes") + }) + ; </script> {% endblock scripts %}