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 %}