diff --git a/static/js/tracker/render-hotlist-table.js b/static/js/tracker/render-hotlist-table.js
new file mode 100644
index 0000000..5004296
--- /dev/null
+++ b/static/js/tracker/render-hotlist-table.js
@@ -0,0 +1,436 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+/**
+ * This file contains JS functions used in rendering a hotlistissues table
+ */
+
+
+/**
+ * Helper function to set several attributes of an element at once.
+ * @param {Element} el element that is getting the attributes
+ * @param {dict} attrs Dictionary of {attrName: attrValue, ..}
+ */
+function setAttributes(el, attrs) {
+  for (let key in attrs) {
+    el.setAttribute(key, attrs[key]);
+  }
+}
+
+// TODO(jojwang): readOnly is currently empty string, figure out what it should be
+// ('True'/'False' 'yes'/'no'?).
+
+/**
+ * Helper function for creating a <td> element that contains the widgets of the row.
+ * @param {dict} tableRow dictionary {'projectName': 'name', .. } of relevant row info.
+ * @param {} readOnly.
+ * @param {boolean} userLoggedIn is the current user logged in.
+ * @return an element containing the widget elements
+ */
+function createWidgets(tableRow, readOnly, userLoggedIn) {
+  let widgets = document.createElement('td');
+  widgets.setAttribute('class', 'rowwidgets nowrap');
+
+  let gripper = document.createElement('i');
+  gripper.setAttribute('class', 'material-icons gripper');
+  gripper.setAttribute('title', 'Drag issue');
+  gripper.textContent = 'drag_indicator';
+  widgets.appendChild(gripper);
+
+  if (!readOnly) {
+    if (userLoggedIn) {
+      // TODO(jojwang): for bulk edit, only show a checkbox next to an issue that
+      // the user has permission to edit.
+      let checkbox = document.createElement('input');
+      setAttributes(checkbox, {'class': 'checkRangeSelect',
+        'id': 'cb_' + tableRow['issueRef'],
+        'type': 'checkbox'});
+      widgets.appendChild(checkbox);
+      widgets.appendChild(document.createTextNode(' '));
+
+      let star = document.createElement('a');
+      let starColor = tableRow['isStarred'] ? 'cornflowerblue' : 'gray';
+      let starred = tableRow['isStarred'] ? 'Un-s' : 'S';
+      setAttributes(star, {'class': 'star',
+        'id': 'star-' + tableRow['projectName'] + tableRow['localID'],
+        'style': 'color:' + starColor,
+        'title': starred + 'tar this issue',
+        'data-project-name': tableRow['projectName'],
+        'data-local-id': tableRow['localID']});
+      star.textContent = (tableRow['isStarred'] ? '\u2605' : '\u2606');
+      widgets.appendChild(star);
+    }
+  }
+  return widgets;
+}
+
+
+/**
+ * Helper function to set attributes and add Nodes for an ID cell.
+ * @param {Element} td element to be added to current row in table.
+ * @param {dict} tableRow dictionary {'projectName': 'name', .. } of relevant row info.
+ * @param {boolean} isCrossProject are issues in the table from more than one project.
+*/
+function createIDCell(td, tableRow, isCrossProject) {
+  td.classList.add('id');
+  let aLink = document.createElement('a');
+  aLink.setAttribute('href', tableRow['issueCleanURL']);
+  aLink.setAttribute('class', 'computehref');
+  let aLinkContent = (isCrossProject ? (tableRow['projectName'] + ':') : '' ) + tableRow['localID'];
+  aLink.textContent = aLinkContent;
+  td.appendChild(aLink);
+}
+
+function createProjectCell(td, tableRow) {
+  td.classList.add('project');
+  let aLink = document.createElement('a');
+  aLink.setAttribute('href', tableRow['projectURL']);
+  aLink.textContent = tableRow['projectName'];
+  td.appendChild(aLink);
+}
+
+function createEditableNoteCell(td, cell, projectName, localID, hotlistID) {
+  let textBox = document.createElement('textarea');
+  setAttributes(textBox, {
+    'id': `itemnote_${projectName}_${localID}`,
+    'placeholder': '---',
+    'class': 'itemnote rowwidgets',
+    'projectname': projectName,
+    'localid': localID,
+    'style': 'height:15px',
+  });
+  if (cell['values'].length > 0) {
+    textBox.value = cell['values'][0]['item'];
+  }
+  textBox.addEventListener('blur', function(e) {
+    saveNote(e.target, hotlistID);
+  });
+  debouncedKeyHandler = debounce(function(e) {
+    saveNote(e.target, hotlistID);
+  });
+  textBox.addEventListener('keyup', debouncedKeyHandler, false);
+  td.appendChild(textBox);
+}
+
+function enter_detector(e) {
+  if (e.which==13||e.keyCode==13) {
+    this.blur();
+  }
+}
+
+
+/**
+ * Helper function to set attributes and add Nodes for an Summary cell.
+ * @param {Element} td element to be added to current row in table.
+ * @param {dict} cell dictionary {'values': [], .. } of relevant cell info.
+ * @param {string=} projectName The name of the project the summary references.
+*/
+function createSummaryCell(td, cell, projectName) {
+  // TODO(jojwang): detect when links are present and make clicking on cell go
+  // to link, not issue details page
+  td.setAttribute('style', 'width:100%');
+  fillValues(td, cell['values']);
+  fillNonColumnLabels(td, cell['nonColLabels'], projectName);
+}
+
+
+/**
+ * Helper function to set attributes and add Nodes for an Attribute or Unfilterable cell.
+ * @param {Element} td element to be added to current row in table.
+ * @param {dict} cell dictionary {'type': 'Summary', .. } of relevant cell info.
+*/
+function createAttrAndUnfiltCell(td, cell) {
+  if (cell['noWrap'] == 'yes') {
+    td.className += ' nowrapspan';
+  }
+  if (cell['align']) {
+    td.setAttribute('align', cell['align']);
+  }
+  fillValues(td, cell['values']);
+}
+
+function createUrlCell(td, cell) {
+  td.classList.add('url');
+  cell.values.forEach((value) => {
+    let aLink = document.createElement('a');
+    aLink.href = value['item'];
+    aLink.target = '_blank';
+    aLink.rel = 'nofollow';
+    aLink.textContent = value['item'];
+    aLink.classList.add('fieldvalue_url');
+    td.appendChild(aLink);
+  });
+}
+
+function createIssuesCell(td, cell) {
+  td.classList.add('url');
+  if (cell.values.length > 0) {
+    cell.values.forEach( function(value, index, array) {
+      const span = document.createElement('span');
+      if (value['isDerived']) {
+        span.className = 'derived';
+      }
+      const a = document.createElement('a');
+      a.href = value['href'];
+      a.rel = 'nofollow"';
+      if (value['title']) {
+        a.title = value['title'];
+      }
+      if (value['closed']) {
+        a.style.textDecoration = 'line-through';
+      }
+      a.textContent = value['id'];
+      span.appendChild(a);
+      td.appendChild(span);
+      if (index != array.length-1) {
+        td.appendChild(document.createTextNode(', '));
+      }
+    });
+  } else {
+    td.textContent = '---';
+  }
+}
+
+/**
+ * Helper function to fill a td element with a cell's non-column labels.
+ * @param {Element} td element to be added to current row in table.
+ * @param {list} labels list of dictionaries with relevant (key, value) for
+ *   each label
+ * @param {string=} projectName The name of the project the labels reference.
+ */
+function fillNonColumnLabels(td, labels, projectName) {
+  labels.forEach( function(label) {
+    const aLabel = document.createElement('a');
+    setAttributes(aLabel,
+        {
+          'class': 'label',
+          'href': `/p/${projectName}/issues/list?q=label:${label['value']}`,
+        });
+    if (label['isDerived']) {
+      const i = document.createElement('i');
+      i.textContent = label['value'];
+      aLabel.appendChild(i);
+    } else {
+      aLabel.textContent = label['value'];
+    }
+    td.appendChild(document.createTextNode(' '));
+    td.appendChild(aLabel);
+  });
+}
+
+
+/**
+ * Helper function to fill a td element with a cell's value(s).
+ * @param {Element} td element to be added to current row in table.
+ * @param {list} values list of dictionaries with relevant (key, value) for each value
+ */
+function fillValues(td, values) {
+  if (values.length > 0) {
+    values.forEach( function(value, index, array) {
+      let span = document.createElement('span');
+      if (value['isDerived']) {
+        span.className = 'derived';
+      }
+      span.textContent = value['item'];
+      td.appendChild(span);
+      if (index != array.length-1) {
+        td.appendChild(document.createTextNode(', '));
+      }
+    });
+  } else {
+    td.textContent = '---';
+  }
+}
+
+
+/**
+ * Helper function to create a table row.
+ * @param {dict} tableRow dictionary {'projectName': 'name', .. } of relevant row info.
+ * @param {dict} pageSettings dict of relevant settings for the hotlist and user viewing the page.
+ */
+function renderHotlistRow(tableRow, pageSettings) {
+  let tr = document.createElement('tr');
+  if (pageSettings['cursor'] == tableRow['issueRef']) {
+    tr.setAttribute('class', 'ifOpened hoverTarget cursor_on drag_item');
+  } else {
+    tr.setAttribute('class', 'ifOpened hoverTarget cursor_off drag_item');
+  }
+
+  setAttributes(tr, {'data-idx': tableRow['idx'], 'data-id': tableRow['issueID'], 'issue-context-url': tableRow['issueContextURL']});
+  widgets = createWidgets(tableRow, pageSettings['readOnly'],
+    pageSettings['userLoggedIn']);
+  tr.appendChild(widgets);
+  tableRow['cells'].forEach(function(cell) {
+    let td = document.createElement('td');
+    td.setAttribute('class', 'col_' + cell['colIndex']);
+    if (cell['type'] == 'ID') {
+      createIDCell(td, tableRow, (pageSettings['isCrossProject'] == 'True'));
+    } else if (cell['type'] == 'summary') {
+      createSummaryCell(td, cell, tableRow['projectName']);
+    } else if (cell['type'] == 'note') {
+      if (pageSettings['ownerPerm'] || pageSettings['editorPerm']) {
+        createEditableNoteCell(
+          td, cell, tableRow['projectName'], tableRow['localID'],
+          pageSettings['hotlistID']);
+      } else {
+        createSummaryCell(td, cell, tableRow['projectName']);
+      }
+    } else if (cell['type'] == 'project') {
+      createProjectCell(td, tableRow);
+    } else if (cell['type'] == 'url') {
+      createUrlCell(td, cell);
+    } else if (cell['type'] == 'issues') {
+      createIssuesCell(td, cell);
+    } else {
+      createAttrAndUnfiltCell(td, cell);
+    }
+    tr.appendChild(td);
+  });
+  let directLinkURL = tableRow['issueCleanURL'];
+  let directLink = document.createElement('a');
+  directLink.setAttribute('class', 'directlink material-icons');
+  directLink.setAttribute('href', directLinkURL);
+  directLink.textContent = 'link'; // Renders as a link icon.
+  let lastCol = document.createElement('td');
+  lastCol.appendChild(directLink);
+  tr.appendChild(lastCol);
+  return tr;
+}
+
+
+/**
+ * Helper function to create the group header row
+ * @param {dict} group dict of relevant values for the current group
+ * @return a <tr> element to be added to the current <tbody>
+ */
+function renderGroupRow(group) {
+  let tr = document.createElement('tr');
+  tr.setAttribute('class', 'group_row');
+  let td = document.createElement('td');
+  setAttributes(td, {'colspan': '100', 'class': 'toggleHidden'});
+  let whenClosedImg = document.createElement('img');
+  setAttributes(whenClosedImg, {'class': 'ifClosed', 'src': '/static/images/plus.gif'});
+  td.appendChild(whenClosedImg);
+  let whenOpenImg = document.createElement('img');
+  setAttributes(whenOpenImg, {'class': 'ifOpened', 'src': '/static/images/minus.gif'});
+  td.appendChild(whenOpenImg);
+  tr.appendChild(td);
+
+  div = document.createElement('div');
+  div.textContent += group['rowsInGroup'];
+
+  div.textContent += (group['rowsInGroup'] == '1' ? ' issue:': ' issues:');
+
+  group['cells'].forEach(function(cell) {
+    let hasValue = false;
+    cell['values'].forEach(function(value) {
+      if (value['item'] !== 'None') {
+        hasValue = true;
+      }
+    });
+    if (hasValue) {
+      cell.values.forEach(function(value) {
+        div.textContent += (' ' + cell['groupName'] + '=' + value['item']);
+      });
+    } else {
+      div.textContent += (' -has:' + cell['groupName']);
+    }
+  });
+  td.appendChild(div);
+  return tr;
+}
+
+
+/**
+ * Builds the body of a hotlistissues table.
+ * @param {dict} tableData dict of relevant values from 'table_data'
+ * @param {dict} pageSettings dict of relevant settings for the hotlist and user viewing the page.
+ */
+function renderHotlistTable(tableData, pageSettings) {
+  let tbody;
+  let table = $('resultstable');
+
+  // TODO(jojwang): this would not work if grouping did not require a page refresh
+  // that wiped the table of all its children. This should be redone to be more
+  // robust.
+  // This loop only does anything when reranking is enabled.
+  for (i=0; i < table.childNodes.length; i++) {
+    if (table.childNodes[i].tagName == 'TBODY') {
+      table.removeChild(table.childNodes[i]);
+    }
+  }
+
+  tableData.forEach(function(tableRow) {
+    if (tableRow['group'] !== 'no') {
+      // add current tbody to table, need a new tbody with group row
+      if (typeof tbody !== 'undefined') {
+        table.appendChild(tbody);
+      }
+      tbody = document.createElement('tbody');
+      tbody.setAttribute('class', 'opened');
+      tbody.appendChild(renderGroupRow(tableRow['group']));
+    }
+    if (typeof tbody == 'undefined') {
+      tbody = document.createElement('tbody');
+    }
+    tbody.appendChild(renderHotlistRow(tableRow, pageSettings));
+  });
+  tbody.appendChild(document.createElement('tr'));
+  table.appendChild(tbody);
+
+  let stars = document.getElementsByClassName('star');
+  for (var i = 0; i < stars.length; ++i) {
+    let star = stars[i];
+    star.addEventListener('click', function(event) {
+      let projectName = event.target.getAttribute('data-project-name');
+      let localID = event.target.getAttribute('data-local-id');
+      _TKR_toggleStar(event.target, projectName, localID, null, null, null);
+    });
+  }
+}
+
+
+/**
+ * Activates the drag and drop functionality of the hotlistissues table.
+ * @param {dict} tableData dict of relevant values from the 'table_data' of
+ *  hotlistissues servlet. This is used when a drag and drop motion does not
+ *  result in any changes in the ordering of the issues.
+ * @param {dict} pageSettings dict of relevant settings for the hotlist and user
+ *  viewing the page.
+ * @param {str} hotlistID the number ID of the current hotlist
+*/
+function activateDragDrop(tableData, pageSettings, hotlistID) {
+  function onHotlistRerank(srcID, targetID, position) {
+    let data = {
+      target_id: targetID,
+      moved_ids: srcID,
+      split_above: position == 'above',
+      colspec: pageSettings['colSpec'],
+      can: pageSettings['can'],
+    };
+    CS_doPost(hotlistID + '/rerank.do', onHotlistResponse, data);
+  }
+
+  function onHotlistResponse(event) {
+    let xhr = event.target;
+    if (xhr.readyState != 4) {
+      return;
+    }
+    if (xhr.status != 200) {
+      window.console.error('200 page error');
+      // TODO(jojwang): fill this in more
+      return;
+    }
+    let response = CS_parseJSON(xhr);
+    renderHotlistTable(
+      (response['table_data'] == '' ? tableData : response['table_data']),
+      pageSettings);
+    // TODO(jojwang): pass pagination state to server
+    _initDragAndDrop($('resultstable'), onHotlistRerank, true);
+  }
+  _initDragAndDrop($('resultstable'), onHotlistRerank, true);
+}
