Basic integration of table widget into Dashboard podcasts view

This commit is contained in:
Albert Santoni 2015-09-16 18:32:16 -04:00
parent 39b2bd6a86
commit 71919ad529
5 changed files with 211 additions and 114 deletions

View file

@ -1,6 +1,7 @@
<?php <?php
require_once('CORSHelper.php'); require_once('CORSHelper.php');
require_once(__DIR__.'/../common/widgets/Table.php');
class ShowbuilderController extends Zend_Controller_Action class ShowbuilderController extends Zend_Controller_Action
{ {
@ -51,6 +52,8 @@ class ShowbuilderController extends Zend_Controller_Action
$this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.min.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/dataTables.colReorder.min.css?'.$CC_CONFIG['airtime_version']);
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/library.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/library.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/library/events/library_showbuilder.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/events/library_showbuilder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$headScript = $this->view->headScript();
AirtimeTableView::injectTableJavaScriptDependencies($headScript, $baseUrl, $CC_CONFIG['airtime_version']);
// PLUPLOAD // PLUPLOAD
$this->view->headScript()->appendFile($baseUrl.'js/libs/dropzone.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/libs/dropzone.min.js?'.$CC_CONFIG['airtime_version'],'text/javascript');

View file

@ -730,7 +730,7 @@ th.library_checkbox {
Podcasts Podcasts
~~~~~~~~~~~~~~~~ */ ~~~~~~~~~~~~~~~~ */
#podcast_table { #podcast_table_filter {
display: none; display: none;
} }

View file

@ -728,10 +728,7 @@ var AIRTIME = (function(AIRTIME) {
}); });
/* TODO: implement podcast datatable
* mod.podcastDataTable = $("#podcast_table").dataTable({});
*/
mod.podcastDataTable = mod.libraryDataTable;
/* ############################################ /* ############################################
END DATATABLES END DATATABLES
@ -860,8 +857,11 @@ var AIRTIME = (function(AIRTIME) {
var selected = $("a[href$='"+location.hash+"']"); var selected = $("a[href$='"+location.hash+"']");
if (selected.parent().data("selection-id") == AIRTIME.library.MediaTypeEnum.PODCAST) { if (selected.parent().data("selection-id") == AIRTIME.library.MediaTypeEnum.PODCAST) {
$("#library_display_wrapper").hide(); $("#library_display_wrapper").hide();
oTable = mod.podcastDataTable.show(); $('#podcast_table_wrapper').show();
oTable = mod.podcastDataTable;
} else { } else {
$('#podcast_table_wrapper').hide();
$("#library_display_wrapper").show();
oTable = mod.libraryDataTable; oTable = mod.libraryDataTable;
} }
@ -1231,8 +1231,33 @@ var AIRTIME = (function(AIRTIME) {
}; };
} }
}); });
}; };
/** Create the podcast datatable widget */
mod.initPodcastDatatable = function()
{
var aoColumns = [
/* Title */ { "sTitle" : $.i18n._("Title") , "mDataProp" : "track_title" , "sClass" : "library_title" , "sWidth" : "170px" },
/* Creator */ { "sTitle" : $.i18n._("Creator") , "mDataProp" : "artist_name" , "sClass" : "library_creator" , "sWidth" : "160px" },
/* Upload Time */ { "sTitle" : $.i18n._("Uploaded") , "mDataProp" : "utime" , "bVisible" : false , "sClass" : "library_upload_time" , "sWidth" : "155px" },
/* Website */ { "sTitle" : $.i18n._("Website") , "mDataProp" : "info_url" , "bVisible" : false , "sClass" : "library_url" , "sWidth" : "150px" },
/* Year */ { "sTitle" : $.i18n._("Year") , "mDataProp" : "year" , "bVisible" : false , "sClass" : "library_year" , "sWidth" : "60px" },
];
var ajaxSourceURL = baseUrl+"rest/media";
//Set up the div with id "podcast_table" as a datatable.
mod.podcastDataTable = AIRTIME.widgets.table.init(
$('#podcast_table'), //DOM node to create the table inside.
true, //Enable item selection
{ //Datatables overrides.
'aoColumns' : aoColumns,
'sAjaxSource' : ajaxSourceURL
});
}
mod.libraryInit = libraryInit; mod.libraryInit = libraryInit;
return AIRTIME; return AIRTIME;
@ -1400,6 +1425,9 @@ var validationTypes = {
$(document).ready(function() { $(document).ready(function() {
AIRTIME.library.initPodcastDatatable();
$("#advanced-options").on("click", function() { $("#advanced-options").on("click", function() {
resizeAdvancedSearch(); resizeAdvancedSearch();
}); });

View file

@ -143,7 +143,7 @@ AIRTIME = (function(AIRTIME) {
if (selected.parent().data("selection-id") == AIRTIME.library.MediaTypeEnum.PODCAST) { if (selected.parent().data("selection-id") == AIRTIME.library.MediaTypeEnum.PODCAST) {
$("#library_display_wrapper").hide(); $("#library_display_wrapper").hide();
$("#podcast_table").show(); $("#podcast_table_wrapper").show();
t = AIRTIME.library.podcastDataTable; t = AIRTIME.library.podcastDataTable;
} else { } else {
@ -152,7 +152,7 @@ AIRTIME = (function(AIRTIME) {
} }
$("#library_display_wrapper").show(); $("#library_display_wrapper").show();
$("#podcast_table").hide(); $("#podcast_table_wrapper").hide();
t = oTable; t = oTable;
} }

View file

@ -15,7 +15,8 @@ var AIRTIME = (function(AIRTIME) {
var self; var self;
var self = AIRTIME.widgets.table; var self = AIRTIME.widgets.table;
//Constants
//Constants and enumerations
self.SELECTION_MODE = { self.SELECTION_MODE = {
SINGLE : 0, SINGLE : 0,
MULTI_SHIFT : 1, MULTI_SHIFT : 1,
@ -37,13 +38,11 @@ var AIRTIME = (function(AIRTIME) {
self.init = function(wrapperDOMNode, bItemSelection, dataTablesOptions) { self.init = function(wrapperDOMNode, bItemSelection, dataTablesOptions) {
self._$wrapperDOMNode = $(wrapperDOMNode); self._$wrapperDOMNode = $(wrapperDOMNode);
//TODO: If selection is enabled, add in the checkbox column. // If selection is enabled, add in the checkbox column.
if (bItemSelection) { if (bItemSelection) {
dataTablesOptions["aoColumns"].unshift( dataTablesOptions["aoColumns"].unshift(
/* Checkbox */ { "sTitle" : "", "mData" : self._datatablesCheckboxDataDelegate, "bSortable" : false , "bSearchable" : false , "sWidth" : "16px" , "sClass" : "library_checkbox" } /* Checkbox */ { "sTitle" : "", "mData" : self._datatablesCheckboxDataDelegate, "bSortable" : false , "bSearchable" : false , "sWidth" : "16px" , "sClass" : "library_checkbox" }
); );
dataTablesOptions["fnRowCallback"] = self._rowCreatedCallback;
} }
var options = { var options = {
@ -69,10 +68,10 @@ var AIRTIME = (function(AIRTIME) {
"iOverlayFade": 0 "iOverlayFade": 0
}, },
// z = ColResize, R = ColReorder, C = ColVis // z = ColResize, R = ColReorder, C = ColVis
"sDom": 'Rf<"dt-process-rel"r><"H"<"library_toolbar"C>><"dataTables_scrolling"t<"#library_empty"<"#library_empty_image"><"#library_empty_text">>><"F"lip>>', "sDom": 'Rf<"dt-process-rel"r><"H"<"table_toolbar"C>><"dataTables_scrolling"t<"#library_empty"<"#library_empty_image"><"#library_empty_text">>><"F"lip>>',
"fnServerData": self._fetchData, "fnServerData": self._fetchData,
"fnDrawCallback" : self._tableDrawCallback //"fnDrawCallback" : self._tableDrawCallback
}; };
//Override any options with those passed in as arguments to this constructor. //Override any options with those passed in as arguments to this constructor.
@ -83,6 +82,9 @@ var AIRTIME = (function(AIRTIME) {
self._datatable = self._$wrapperDOMNode.dataTable(options); self._datatable = self._$wrapperDOMNode.dataTable(options);
self._setupEventHandlers(bItemSelection);
return self._datatable;
}; };
self._handleAjaxError = function(r) { self._handleAjaxError = function(r) {
@ -105,7 +107,6 @@ var AIRTIME = (function(AIRTIME) {
var echo = aoData[0].value; //Datatables state tracking. Must be included. var echo = aoData[0].value; //Datatables state tracking. Must be included.
//getUsabilityHint();
var sortColName = ""; var sortColName = "";
var sortDir = ""; var sortDir = "";
if (oSettings.aaSorting.length > 0) { if (oSettings.aaSorting.length > 0) {
@ -129,7 +130,7 @@ var AIRTIME = (function(AIRTIME) {
json = []; json = [];
json.aaData = rawResponseJSON; json.aaData = rawResponseJSON;
json.iTotalRecords = jqXHR.getResponseHeader('X-TOTAL-COUNT'); json.iTotalRecords = jqXHR.getResponseHeader('X-TOTAL-COUNT');
json.iTotalDisplayRecords = json.iTotalRecords;//rawResponseJSON.length; json.iTotalDisplayRecords = json.iTotalRecords;
json.sEcho = echo; json.sEcho = echo;
//Pass it along to datatables. //Pass it along to datatables.
@ -178,36 +179,112 @@ var AIRTIME = (function(AIRTIME) {
return "check"; return "check";
}; };
/*
self._rowCreatedCallback = function(nRow, aData, iDisplayIndex) { self._rowCreatedCallback = function(nRow, aData, iDisplayIndex) {
// Bind click event
$(nRow).click(function(e) {
e.stopPropagation();
e.preventDefault();
document.getSelection().removeAllRanges();
//alert( 'You clicked on '+aData.track_title+'\'s row' + iDisplayIndex);
var selectionMode = self.SELECTION_MODE.SINGLE;
if (e.shiftKey) {
selectionMode = self.SELECTION_MODE.MULTI_SHIFT;
} else if (e.ctrlKey) {
selectionMode = self.SELECTION_MODE.MULTI_CTRL;
}
self.selectRow(nRow, aData, selectionMode, iDisplayIndex);
});
return nRow; return nRow;
};
};*/
/*
self._tableDrawCallback = function(oSettings) { self._tableDrawCallback = function(oSettings) {
$('input.airtime_table_checkbox').click(function(e) {
$this = $(this);
var iVisualRowIdx = $this.parent().parent().index(); };*/
self.selectRow($this.parent().parent(), null, self.SELECTION_MODE.MULTI_CTRL, iVisualRowIdx); //Always multiselect for checkboxes
e.stopPropagation();
return true; /* Set up global event handlers for the datatable.
* @param bItemSelection Whether or not row selection behaviour should be enabled for this widget.
* */
self._setupEventHandlers = function(bItemSelection) {
/** This table row event handler is created once and catches events for any row. (It's less resource intensive
* than having a per-row callback...)
*/
if (bItemSelection) {
$(self._datatable, 'tbody tr').on('click contextmenu', 'tr', function (e) {
var aData = $(this).data(); //Neat trick - thanks DataTables!
var iDisplayIndex = $(this).index(); //The index of the row in the current page in the table.
var nRow = this;
e.stopPropagation();
e.preventDefault();
document.getSelection().removeAllRanges();
var selectionMode = self.SELECTION_MODE.SINGLE;
if (e.shiftKey) {
selectionMode = self.SELECTION_MODE.MULTI_SHIFT;
} else if (e.ctrlKey) {
selectionMode = self.SELECTION_MODE.MULTI_CTRL;
}
if (e.button == 2) {
selectionMode = self.SELECTION_MODE.SINGLE;
}
self.selectRow(nRow, aData, selectionMode, iDisplayIndex);
});
$(self._datatable, 'tbody tr').on('click', 'input.airtime_table_checkbox', function(e) {
$this = $(this);
var iVisualRowIdx = $this.parent().parent().index();
var aData = $this.parent().parent().data();
var selectionMode = self.SELECTION_MODE.MULTI_CTRL; //Behaviour for checkboxes.
if (e.shiftKey) {
selectionMode = self.SELECTION_MODE.MULTI_SHIFT;
}
self.selectRow($this.parent().parent(), aData, selectionMode, iVisualRowIdx); //Always multiselect for checkboxes
e.stopPropagation();
return true;
});
}
$(self._datatable).on('init', function(e) {
self._setupToolbarButtons(true, {});
}); });
}
self._setupToolbarButtons = function(bIncludeDefaultActions, extraButtons) {
var $menu = self._$wrapperDOMNode.parent().parent().find("div.table_toolbar");
$menu.addClass("btn-toolbar");
if (bIncludeDefaultActions)
{
$menu
.append(
"<div class='btn-group' title=" + $.i18n._('New') + ">" +
"<button class='btn btn-small btn-new' id='sb-new'>" +
"<i class='icon-white icon-plus'></i>" +
"<span>" + $.i18n._('New') + "</span>" +
"</button>" +
"</div>"
).append(
"<div class='btn-group' title=" + $.i18n._('Edit') + ">" +
"<button class='btn btn-small' id='sb-edit'>" +
"<i class='icon-white icon-pencil'></i>" +
"<span>" + $.i18n._('Edit') + "</span>" +
"</button>" +
"</div>"
);
$menu.append(
"<div class='btn-group' title=" + $.i18n._('Delete') + ">" +
"<button class='btn btn-small btn-danger' id='sb-trash'>" +
"<i class='icon-white icon-trash'></i>" +
"<span>" + $.i18n._('Delete') + "</span>" +
"</button>" +
"</div>"
);
}
};
self._clearSelection = function() {
self._selectedRows = [];
//self._selectedRowVisualIdxMap = [];
self._selectedRowVisualIdxMin = self.HUGE_INT;
self._selectedRowVisualIdxMax = -1;
self._$wrapperDOMNode.find('.selected').removeClass('selected');
self._$wrapperDOMNode.find('input.airtime_table_checkbox').attr('checked', false);
}; };
/** @param nRow is a tr DOM node (non-jQuery) /** @param nRow is a tr DOM node (non-jQuery)
@ -225,94 +302,83 @@ var AIRTIME = (function(AIRTIME) {
var $nRow = $(nRow); var $nRow = $(nRow);
/* //Regular single left-click mode
var foundAtIdx = $.inArray(aData, self._selectedRows) if (selectionMode == self.SELECTION_MODE.SINGLE) {
if (foundAtIdx >= 0 && self._selectedRows.length > 1) { self._clearSelection();
self._selectedRows.splice(foundAtIdx, 1);
$nRow.removeClass('selected');
$nRow.find('input.airtime_table_checkbox').attr('checked', false);
*/
if (false) {
} else {
//Regular single left-click mode
if (selectionMode == self.SELECTION_MODE.SINGLE) {
self._clearSelection(); self._selectedRows.push(aData);
self._selectedRowVisualIdxMin = iVisualRowIdx;
self._selectedRowVisualIdxMax = iVisualRowIdx;
//self._selectedRowVisualIdxMap[iVisualRowIdx] = aData;
$nRow.addClass('selected');
$nRow.find('input.airtime_table_checkbox').attr('checked', true);
}
//Ctrl-click multi row selection mode
else if (selectionMode == self.SELECTION_MODE.MULTI_CTRL) {
var foundAtIdx = $.inArray(aData, self._selectedRows)
console.log('checkbox mouse', iVisualRowIdx, foundAtIdx);
//XXX: Debugging -- Bug here-ish
if (foundAtIdx >= 0) {
console.log(aData, self._selectedRows[foundAtIdx]);
} else {
console.log("clicked row not detected as already selected");
}
if (foundAtIdx >= 0 && self._selectedRows.length > 1) {
self._selectedRows.splice(foundAtIdx, 1);
$nRow.removeClass('selected');
$nRow.find('input.airtime_table_checkbox').attr('checked', false);
}
else {
self._selectedRows.push(aData); self._selectedRows.push(aData);
self._selectedRowVisualIdxMin = iVisualRowIdx; self._selectedRowVisualIdxMin = iVisualRowIdx;
self._selectedRowVisualIdxMax = iVisualRowIdx; self._selectedRowVisualIdxMax = iVisualRowIdx;
//self._selectedRowVisualIdxMap[iVisualRowIdx] = aData;
$nRow.addClass('selected'); $nRow.addClass('selected');
$nRow.find('input.airtime_table_checkbox').attr('checked', true); $nRow.find('input.airtime_table_checkbox').attr('checked', true);
} }
//Ctrl-click multi row selection mode
else if (selectionMode == self.SELECTION_MODE.MULTI_CTRL) {
var foundAtIdx = $.inArray(aData, self._selectedRows)
if (foundAtIdx >= 0 && self._selectedRows.length > 1) {
self._selectedRows.splice(foundAtIdx, 1);
$nRow.removeClass('selected');
$nRow.find('input.airtime_table_checkbox').attr('checked', false);
}
else {
self._selectedRows.push(aData);
self._selectedRowVisualIdxMin = iVisualRowIdx;
self._selectedRowVisualIdxMax = iVisualRowIdx;
$nRow.addClass('selected');
$nRow.find('input.airtime_table_checkbox').attr('checked', true);
}
}
//Shift-click multi row selection mode
else if (selectionMode == self.SELECTION_MODE.MULTI_SHIFT) {
//If there's no rows selected, just behave like single selection.
if (self._selectedRows.length == 0) {
return self.selectRow(nRow, aData, self.SELECTION_MODE.SINGLE, iVisualRowIdx);
}
if (iVisualRowIdx > self._selectedRowVisualIdxMax) {
self._selectedRowVisualIdxMax = iVisualRowIdx;
}
if (iVisualRowIdx < self._selectedRowVisualIdxMin) {
self._selectedRowVisualIdxMin = iVisualRowIdx;
}
var selectionStartRowIdx = Math.min(iVisualRowIdx, self._selectedRowVisualIdxMin);
var selectionEndRowIdx = Math.min(iVisualRowIdx, self._selectedRowVisualIdxMax);
//We can assume there's at least 1 row already selected now.
var allRows = self._datatable.fnGetData();
self._selectedRows = [];
for (var i = self._selectedRowVisualIdxMin; i <= self._selectedRowVisualIdxMax; i++)
{
self._selectedRows.push(allRows[i]);
$row = $($nRow.parent().children()[i]);
$row.addClass('selected');
$row.find('input.airtime_table_checkbox').attr('checked', true);
}
}
else {
console.log("Unimplemented selection mode");
}
} }
}; //Shift-click multi row selection mode
else if (selectionMode == self.SELECTION_MODE.MULTI_SHIFT) {
//If there's no rows selected, just behave like single selection.
if (self._selectedRows.length == 0) {
return self.selectRow(nRow, aData, self.SELECTION_MODE.SINGLE, iVisualRowIdx);
}
if (iVisualRowIdx > self._selectedRowVisualIdxMax) {
self._selectedRowVisualIdxMax = iVisualRowIdx;
}
if (iVisualRowIdx < self._selectedRowVisualIdxMin) {
self._selectedRowVisualIdxMin = iVisualRowIdx;
}
var selectionStartRowIdx = Math.min(iVisualRowIdx, self._selectedRowVisualIdxMin);
var selectionEndRowIdx = Math.min(iVisualRowIdx, self._selectedRowVisualIdxMax);
//We can assume there's at least 1 row already selected now.
var allRows = self._datatable.fnGetData();
self._selectedRows = [];
for (var i = self._selectedRowVisualIdxMin; i <= self._selectedRowVisualIdxMax; i++)
{
self._selectedRows.push(allRows[i]);
$row = $($nRow.parent().children()[i]);
$row.addClass('selected');
$row.find('input.airtime_table_checkbox').attr('checked', true);
}
}
else {
console.log("Unimplemented selection mode");
}
self._clearSelection = function() {
self._selectedRows = [];
//self._selectedRowVisualIdxMap = [];
self._selectedRowVisualIdxMin = self.HUGE_INT;
self._selectedRowVisualIdxMax = -1;
self._$wrapperDOMNode.find('.selected').removeClass('selected');
self._$wrapperDOMNode.find('input.airtime_table_checkbox').attr('checked', false);
}; };
self.getSelectedRows = function() { self.getSelectedRows = function() {