* Move tab functionality to a separate module

* Fix broken library placeholders
* Restrict tab width and add text panning to tab name
* General bugfixing and cleanup of tab functionality
This commit is contained in:
Duncan Sommerville 2015-09-15 18:53:25 -04:00
parent 0d80f857d3
commit 8dcea06077
9 changed files with 272 additions and 225 deletions

View file

@ -56,6 +56,7 @@ class ShowbuilderController extends Zend_Controller_Action
$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');
$this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/timepicker/jquery.ui.timepicker.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/tabs.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
$this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/main_builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/showbuilder/main_builder.js?'.$CC_CONFIG['airtime_version'],'text/javascript');

View file

@ -481,6 +481,14 @@ li.ui-state-default {
overflow-x: hidden; /* Show the y-direction scrollbar (magic!) */ overflow-x: hidden; /* Show the y-direction scrollbar (magic!) */
} }
.tab-name {
float: left;
max-width: 150px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.inner_editor_wrapper { .inner_editor_wrapper {
max-height: 60%; max-height: 60%;
overflow-x: hidden; overflow-x: hidden;

View file

@ -289,3 +289,20 @@ function getUsabilityHint() {
}); });
} }
function getPanTextFunctions() {
return {
mousein: function () {
var sw = $(this)[0].scrollWidth-parseFloat($(this).css("textIndent")), iw = $(this).innerWidth();
if (sw > iw) {
$(this).stop().animate({
textIndent: "-" + (sw + 1 - iw) + "px"
}, sw * 8);
}
},
mouseout: function () {
$(this).stop().animate({
textIndent: "0"
}, 500);
}
}
}

View file

@ -76,35 +76,35 @@ var AIRTIME = (function(AIRTIME) {
mod.placeholder = function(mediaType) { mod.placeholder = function(mediaType) {
switch (mediaType) { switch (mediaType) {
// TODO: remove duplication in a nice way? // TODO: remove duplication in a nice way?
case MediaTypeEnum.FILE: case mod.MediaTypeEnum.FILE:
return { return {
"media": "tracks", "media": "tracks",
"icon": "icon-music", "icon": "icon-music",
"subtext": "Click 'Upload' to add some now.", "subtext": "Click 'Upload' to add some now.",
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/add-media/" "href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/add-media/"
}; };
case MediaTypeEnum.PLAYLIST: case mod.MediaTypeEnum.PLAYLIST:
return { return {
"media": "playlists", "media": "playlists",
"icon": "icon-list", "icon": "icon-list",
"subtext": "Click 'New' to create one now.", "subtext": "Click 'New' to create one now.",
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/" "href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
}; };
case MediaTypeEnum.BLOCK: case mod.MediaTypeEnum.BLOCK:
return { return {
"media": "smart blocks", "media": "smart blocks",
"icon": "icon-time", "icon": "icon-time",
"subtext": "Click 'New' to create one now.", "subtext": "Click 'New' to create one now.",
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/" "href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
}; };
case MediaTypeEnum.WEBSTREAM: case mod.MediaTypeEnum.WEBSTREAM:
return { return {
"media": "webstreams", "media": "webstreams",
"icon": "icon-random", "icon": "icon-random",
"subtext": "Click 'New' to create one now.", "subtext": "Click 'New' to create one now.",
"href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/" "href": "http://sourcefabric.booktype.pro/airtime-pro-for-broadcasters/library/"
}; };
case MediaTypeEnum.PODCAST: case mod.MediaTypeEnum.PODCAST:
return { return {
"media": "podcasts", "media": "podcasts",
"icon": "icon-headphones", "icon": "icon-headphones",
@ -448,7 +448,7 @@ var AIRTIME = (function(AIRTIME) {
openTabObjectIds.each(function(i, el) { openTabObjectIds.each(function(i, el) {
var v = parseInt($(el).val()); var v = parseInt($(el).val());
if ($.inArray(v, mediaIds) > -1) { if ($.inArray(v, mediaIds) > -1) {
AIRTIME.playlist.closeTab($(el).closest(".pl-content").attr("data-tab-id")); AIRTIME.tabs.closeTab($(el).closest(".pl-content").attr("data-tab-id"));
} }
}); });

View file

@ -157,27 +157,14 @@ $(document).ready(function () {
getUsabilityHint(); getUsabilityHint();
} }
}); });
},
"fnCreatedRow": function(nRow) {
$(nRow).find("td").hover(
function () {
var sw = $(this)[0].scrollWidth, iw = $(this).innerWidth();
if (sw > iw) {
$(this).stop().animate({
textIndent: "-" + (sw - iw) + "px"
}, sw * 8);
}
},
function () {
$(this).stop().animate({
textIndent: "0"
}, 500);
}
);
} }
}); });
}; };
var parent = $("#recent_uploads"),fn = getPanTextFunctions();
parent.on("mouseenter", "td", fn.mousein);
parent.on("mouseleave", "td", fn.mouseout);
self.isRecentUploadsRefreshTimerActive = false; self.isRecentUploadsRefreshTimerActive = false;
self.startRefreshingRecentUploads = function () { self.startRefreshingRecentUploads = function () {

View file

@ -12,9 +12,7 @@ var AIRTIME = (function(AIRTIME){
viewport, viewport,
$lib, $lib,
$pl, $pl,
widgetHeight, widgetHeight;
$tabCount = 0,
$openTabs = {};
function isTimeValid(time) { function isTimeValid(time) {
//var regExpr = new RegExp("^\\d{2}[:]\\d{2}[:]\\d{2}([.]\\d{1,6})?$"); //var regExpr = new RegExp("^\\d{2}[:]\\d{2}[:]\\d{2}([.]\\d{1,6})?$");
@ -356,17 +354,6 @@ var AIRTIME = (function(AIRTIME){
} }
} }
function updateActiveTabName(newTabName) {
/*
var nameElement = $(this);
//remove any newlines if user somehow snuck them in (easy to do if dragging/dropping text)
nameElement.text(nameElement.text().replace("\n", ""));
var name = $pl.find(".playlist_name_display").val();
*/
$(".nav.nav-tabs .active a > span.tab-name").text(newTabName);
}
function redrawLib() { function redrawLib() {
var dt = $lib.find("#library_display").dataTable(); var dt = $lib.find("#library_display").dataTable();
@ -394,7 +381,7 @@ var AIRTIME = (function(AIRTIME){
setCueEvents(); setCueEvents();
setFadeEvents(); setFadeEvents();
mod.setModified(json.modified); mod.setModified(json.modified);
updateActiveTabName(json.name); AIRTIME.tabs.setActiveTabName(json.name);
AIRTIME.playlist.validatePlaylistElements(); AIRTIME.playlist.validatePlaylistElements();
redrawLib(); redrawLib();
@ -425,10 +412,10 @@ var AIRTIME = (function(AIRTIME){
$('.zend_form + .spl-no-margin > div:has(*:visible):last').css('margin-left', 0); $('.zend_form + .spl-no-margin > div:has(*:visible):last').css('margin-left', 0);
} }
function getId(pl) { mod.getId = function(pl) {
pl = (pl === undefined) ? $pl : pl; pl = (pl === undefined) ? $pl : pl;
return parseInt(pl.find(".obj_id").val(), 10); return parseInt(pl.find(".obj_id").val(), 10);
} };
mod.getModified = function(pl) { mod.getModified = function(pl) {
pl = (pl === undefined) ? $pl : pl; pl = (pl === undefined) ? $pl : pl;
@ -443,115 +430,6 @@ var AIRTIME = (function(AIRTIME){
$pl.find(".title_obj_name").text(title); $pl.find(".title_obj_name").text(title);
} }
function setTabName(name) {
var id = $pl.data("tab-id");
$("#show_builder").find("[data-tab-id='" + id + "']").find(".tab-name").text(name);
}
/*
* Should all be moved to builder.js eventually
*/
function buildNewTab(json) {
AIRTIME.library.selectNone();
var tabId = $openTabs[json.type + json.id];
if (tabId !== undefined) {
AIRTIME.showbuilder.switchTab($("#pl-tab-content-" + tabId), $("#pl-tab-" + tabId));
return undefined;
}
$tabCount++;
var wrapper = "<div data-tab-type='" + json.type + "' data-tab-id='" + $tabCount + "' id='pl-tab-content-" + $tabCount + "' class='side_playlist pl-content'><div class='editor_pane_wrapper'></div></div>",
t = $("#show_builder").append(wrapper).find("#pl-tab-content-" + $tabCount),
pane = $(".editor_pane_wrapper:last"),
name = json.type == "md" ? // file
pane.append(json.html).find("#track_title").val() + $.i18n._(" - Metadata Editor")
: pane.append(json.html).find(".playlist_name_display").val(),
tab =
"<li data-tab-id='" + $tabCount + "' data-tab-type='" + json.type + "' id='pl-tab-" + $tabCount + "' role='presentation' class='active'>" +
"<a href='javascript:void(0)'><span class='tab-name'></span>" +
"<span href='#' class='lib_pl_close icon-remove'></span>" +
"</a>" +
"</li>",
tabs = $(".nav.nav-tabs");
if (json.id) {
$openTabs[json.type + json.id] = $tabCount;
}
$(".nav.nav-tabs li").removeClass("active");
tabs.append(tab);
tabs.find("#pl-tab-" + $tabCount + " span.tab-name").text(name);
var newTab = $("#pl-tab-" + $tabCount);
AIRTIME.showbuilder.switchTab(t, newTab);
return {wrapper: pane, tab: newTab, pane: t};
}
function openFileMdEditor(json) {
var newTab = buildNewTab(json);
if (newTab === undefined) {
return;
}
initFileMdEvents(newTab);
initialEvents();
}
function initFileMdEvents(newTab) {
newTab.tab.on("click", function() {
if (!$(this).hasClass('active')) {
AIRTIME.showbuilder.switchTab(newTab.pane, newTab.tab);
}
});
newTab.wrapper.find(".md-cancel").on("click", function() {
closeTab();
});
newTab.wrapper.find(".md-save").on("click", function() {
var file_id = newTab.wrapper.find('#file_id').val(),
data = newTab.wrapper.find("#edit-md-dialog form").serializeArray();
$.post(baseUrl+'library/edit-file-md', {format: "json", id: file_id, data: data}, function() {
// don't redraw the library table if we are on calendar page
// we would be on calendar if viewing recorded file metadata
if ($("#schedule_calendar").length === 0) {
oTable.fnStandingRedraw();
}
});
AIRTIME.playlist.closeTab();
});
newTab.wrapper.find('#edit-md-dialog').on("keyup", function(event) {
if (event.keyCode === 13) {
newTab.wrapper.find('.md-save').click();
}
});
}
function openPlaylist(json) {
var newTab = buildNewTab(json);
if (newTab === undefined) {
return;
}
newTab.tab.on("click", function() {
if (!$(this).hasClass('active')) {
AIRTIME.showbuilder.switchTab(newTab.pane, newTab.tab);
$.post(baseUrl+'playlist/edit',
{format: "json", id: newTab.pane.find(".obj_id").val(), type: newTab.pane.find(".obj_type").val()});
}
});
AIRTIME.playlist.init();
// functions in smart_blockbuilder.js
setupUI();
appendAddButton();
appendModAddButton();
removeButtonCheck();
}
function openPlaylistPanel() { function openPlaylistPanel() {
viewport = AIRTIME.utilities.findViewportDimensions(); viewport = AIRTIME.utilities.findViewportDimensions();
var screenWidth = Math.floor(viewport.width - 40); var screenWidth = Math.floor(viewport.width - 40);
@ -562,33 +440,6 @@ var AIRTIME = (function(AIRTIME){
$("#pl_edit").hide(); $("#pl_edit").hide();
} }
function closeTab(id) {
var curr = $(".active-tab"),
pane = id ? $(".pl-content[data-tab-id='" + id + "']") : curr,
tab = id ? $(".nav.nav-tabs [data-tab-id='" + id + "']") : $(".nav.nav-tabs .active"),
toPane = pane.next().length > 0 ? pane.next() : pane.prev(),
toTab = tab.next().length > 0 ? tab.next() : tab.prev(),
objId = pane.find(".obj_id").val(),
pl = id ? pane : $pl;
delete $openTabs[tab.attr("data-tab-type") + objId]; // Remove the closed tab from our open tabs array
// Remove the relevant DOM elements (the tab and the tab content)
tab.remove();
pl.remove();
if (pane.get(0) == curr.get(0)) { // Closing the current tab, otherwise we don't need to switch tabs
AIRTIME.showbuilder.switchTab(toPane, toTab);
}
// If we close a tab that was causing tabs to wrap to the next row, we need to resize to change the
// margin for the tab nav
AIRTIME.playlist.onResize();
}
mod.closeTab = function(id) {
closeTab(id);
};
//Purpose of this function is to iterate over all playlist elements //Purpose of this function is to iterate over all playlist elements
//and verify whether they can be previewed by the browser or not. If not //and verify whether they can be previewed by the browser or not. If not
//then the playlist element is greyed out //then the playlist element is greyed out
@ -937,7 +788,7 @@ var AIRTIME = (function(AIRTIME){
setTimeout(function(){$status.fadeOut("slow", function(){$status.empty()})}, 5000); setTimeout(function(){$status.fadeOut("slow", function(){$status.empty()})}, 5000);
$pl.find(".title_obj_name").val(name); $pl.find(".title_obj_name").val(name);
updateActiveTabName(name); AIRTIME.tabs.setActiveTabName(name);
var $ws_id = $(".active-tab .obj_id"); var $ws_id = $(".active-tab .obj_id");
$ws_id.attr("value", json.streamId); $ws_id.attr("value", json.streamId);
@ -985,26 +836,21 @@ var AIRTIME = (function(AIRTIME){
$(this).unbind("click"); // Prevent repeated clicks in quick succession from closing multiple tabs $(this).unbind("click"); // Prevent repeated clicks in quick succession from closing multiple tabs
var tabId = $(this).closest("li").attr("data-tab-id"); var tabId = $(this).closest("li").attr("data-tab-id");
//AIRTIME.showbuilder.switchTab($("#pl-tab-content-" + tabId), $("#pl-tab-" + tabId));
//$pl.hide();
// We need to update the text on the add button // We need to update the text on the add button
AIRTIME.library.checkAddButton(); AIRTIME.library.checkAddButton();
// We also need to run the draw callback to update how dragged items are drawn // We also need to run the draw callback to update how dragged items are drawn
AIRTIME.library.fnDrawCallback(); AIRTIME.library.fnDrawCallback();
var playlistNameElem = $pl.siblings("[data-tab-id='" + tabId + "']").find('.playlist_name_display'); var playlistNameElem = AIRTIME.tabs.get(tabId).find('.tab-name');
var name = ""; var name = playlistNameElem.text().trim();
if (playlistNameElem.val() !== undefined) {
name = playlistNameElem.val().trim();
}
if ((name == $.i18n._("Untitled Playlist") if ((name == $.i18n._("Untitled Playlist")
|| name == $.i18n._("Untitled Smart Block")) || name == $.i18n._("Untitled Smart Block"))
&& $pl.find(".spl_sortable .spl_empty").length == 1) { && $pl.find(".spl_sortable .spl_empty").length == 1) {
mod.fnDelete(undefined, tabId); mod.fnDelete(undefined, tabId);
} else { } else {
closeTab(tabId); AIRTIME.tabs.closeTab(tabId);
} }
$.ajax( { $.ajax( {
@ -1041,7 +887,7 @@ var AIRTIME = (function(AIRTIME){
} else { } else {
setTitleLabel(json.name); setTitleLabel(json.name);
setTabName(json.name); AIRTIME.tabs.setActiveTabName(json.name);
mod.setModified(json.modified); mod.setModified(json.modified);
if (obj_type == "block") { if (obj_type == "block") {
@ -1176,7 +1022,7 @@ var AIRTIME = (function(AIRTIME){
$.post(url, $.post(url,
{format: "json", type: 'playlist'}, {format: "json", type: 'playlist'},
function(json){ function(json){
openPlaylist(json); AIRTIME.tabs.openPlaylistTab(json);
redrawLib(); redrawLib();
}); });
}; };
@ -1189,7 +1035,7 @@ var AIRTIME = (function(AIRTIME){
$.post(url, $.post(url,
{format: "json"}, {format: "json"},
function(json){ function(json){
openPlaylist(json); AIRTIME.tabs.openPlaylistTab(json);
redrawLib(); redrawLib();
}); });
}; };
@ -1203,13 +1049,13 @@ var AIRTIME = (function(AIRTIME){
$.post(url, $.post(url,
{format: "json", type: 'block'}, {format: "json", type: 'block'},
function(json){ function(json){
openPlaylist(json); AIRTIME.tabs.openPlaylistTab(json);
redrawLib(); redrawLib();
}); });
}; };
mod.fileMdEdit = function(json) { mod.fileMdEdit = function(json) {
openFileMdEditor(json); AIRTIME.tabs.openFileMdEditorTab(json);
}; };
mod.fnEdit = function(id, type, url) { mod.fnEdit = function(id, type, url) {
@ -1219,7 +1065,7 @@ var AIRTIME = (function(AIRTIME){
$.post(url, $.post(url,
{format: "json", id: id, type: type}, {format: "json", id: id, type: type},
function(json){ function(json){
openPlaylist(json); AIRTIME.tabs.openPlaylistTab(json);
redrawLib(); redrawLib();
}); });
}; };
@ -1229,7 +1075,7 @@ var AIRTIME = (function(AIRTIME){
var url, id, lastMod, type, pl = (tabId === undefined) ? $pl : $('#pl-tab-content-' + tabId); var url, id, lastMod, type, pl = (tabId === undefined) ? $pl : $('#pl-tab-content-' + tabId);
stopAudioPreview(); stopAudioPreview();
id = (plid === undefined) ? getId(pl) : plid; id = (plid === undefined) ? mod.getId(pl) : plid;
lastMod = mod.getModified(pl); lastMod = mod.getModified(pl);
type = pl.find('.obj_type').val(); type = pl.find('.obj_type').val();
url = baseUrl+'playlist/delete'; url = baseUrl+'playlist/delete';
@ -1237,7 +1083,7 @@ var AIRTIME = (function(AIRTIME){
$.post(url, $.post(url,
{format: "json", ids: id, modified: lastMod, type: type}, {format: "json", ids: id, modified: lastMod, type: type},
function(json) { function(json) {
closeTab(tabId); AIRTIME.tabs.closeTab(tabId);
redrawLib(); redrawLib();
}); });
}; };
@ -1246,7 +1092,7 @@ var AIRTIME = (function(AIRTIME){
var url, id, lastMod; var url, id, lastMod;
stopAudioPreview(); stopAudioPreview();
id = (wsid === undefined) ? getId() : wsid; id = (wsid === undefined) ? mod.getId() : wsid;
lastMod = mod.getModified(); lastMod = mod.getModified();
type = $pl.find('.obj_type').val(); type = $pl.find('.obj_type').val();
url = baseUrl+'webstream/delete'; url = baseUrl+'webstream/delete';
@ -1254,7 +1100,7 @@ var AIRTIME = (function(AIRTIME){
$.post(url, $.post(url,
{format: "json", ids: id, modified: lastMod, type: type}, {format: "json", ids: id, modified: lastMod, type: type},
function(json){ function(json){
openPlaylist(json); AIRTIME.tabs.openPlaylistTab(json);
redrawLib(); redrawLib();
}); });
}; };
@ -1275,7 +1121,7 @@ var AIRTIME = (function(AIRTIME){
}; };
mod.fnOpenPlaylist = function(json) { mod.fnOpenPlaylist = function(json) {
openPlaylist(json); AIRTIME.tabs.openPlaylistTab(json);
}; };
mod.enableUI = function() { mod.enableUI = function() {
@ -1305,7 +1151,7 @@ var AIRTIME = (function(AIRTIME){
mod.replaceForm = function(json){ mod.replaceForm = function(json){
$pl.find('.editor_pane_wrapper').html(json.html); $pl.find('.editor_pane_wrapper').html(json.html);
openPlaylist(json); AIRTIME.tabs.openPlaylistTab(json);
}; };
@ -1576,21 +1422,17 @@ var AIRTIME = (function(AIRTIME){
}); });
}; };
mod.setAsActive = function() { mod.setupEventListeners = function() {
$pl = $(".active-tab"); initialEvents();
$.post(baseUrl + "playlist/change-playlist", {"id": getId(), "type": $pl.find('.obj_type').val()}); };
mod.setCurrent = function(pl) {
$pl = pl;
}; };
mod.init = function() { mod.init = function() {
AIRTIME.playlist.setAsActive(); AIRTIME.tabs.updateActiveTab();
if (!$pl) return;
//$pl.delegate("#spl_delete", {"click": function(ev){
// AIRTIME.playlist.fnDelete();
//}});
//
//$pl.delegate("#ws_delete", {"click": function(ev){
// AIRTIME.playlist.fnWsDelete();
//}});
$pl.delegate(".pl-waveform-cues-btn", {"click": function(ev){ $pl.delegate(".pl-waveform-cues-btn", {"click": function(ev){
AIRTIME.playlist.showCuesWaveform(ev); AIRTIME.playlist.showCuesWaveform(ev);

View file

@ -108,21 +108,6 @@ var AIRTIME = (function(AIRTIME){
} }
}; };
mod.switchTab = function(tab, el) {
$(".active-tab").hide().removeClass("active-tab");
tab.addClass("active-tab").show();
$(".nav.nav-tabs .active").removeClass("active");
el.addClass("active");
if (tab.hasClass("pl-content")) {
AIRTIME.playlist.setAsActive();
}
AIRTIME.playlist.onResize();
AIRTIME.library.fnRedraw();
};
mod.checkSelectButton = function() { mod.checkSelectButton = function() {
var $selectable = $sbTable.find("tr"); var $selectable = $sbTable.find("tr");

View file

@ -194,7 +194,7 @@ AIRTIME = (function(AIRTIME) {
$("#schedule-tab").on("click", function() { $("#schedule-tab").on("click", function() {
if (!$(this).hasClass('active')) { if (!$(this).hasClass('active')) {
AIRTIME.showbuilder.switchTab($("#show_builder .outer-datatable-wrapper"), $(this)); AIRTIME.tabs.switchTab($("#show_builder .outer-datatable-wrapper"), $(this));
} }
}); });

View file

@ -0,0 +1,207 @@
var AIRTIME = (function(AIRTIME){
var mod,
$tabCount = 0,
$openTabs = {},
$activeTab,
$activeTabPane;
if (AIRTIME.tabs === undefined) {
AIRTIME.tabs = {};
}
mod = AIRTIME.tabs;
/* #####################################################
Internal Functions
##################################################### */
function buildNewTab(json) {
AIRTIME.library.selectNone();
var tabId = $openTabs[json.type + json.id];
if (tabId !== undefined) {
mod.switchTab($("#pl-tab-content-" + tabId), $("#pl-tab-" + tabId));
return undefined;
}
$tabCount++;
var wrapper = "<div data-tab-type='" + json.type + "' data-tab-id='" + $tabCount + "' id='pl-tab-content-" + $tabCount + "' class='side_playlist pl-content'><div class='editor_pane_wrapper'></div></div>",
t = $("#show_builder").append(wrapper).find("#pl-tab-content-" + $tabCount),
pane = $(".editor_pane_wrapper:last"),
name = json.type == "md" ? // file
pane.append(json.html).find("#track_title").val() + $.i18n._(" - Metadata Editor")
: pane.append(json.html).find(".playlist_name_display").val(),
tab =
"<li data-tab-id='" + $tabCount + "' data-tab-type='" + json.type + "' id='pl-tab-" + $tabCount + "' role='presentation' class='active'>" +
"<a href='javascript:void(0)'><span class='tab-name'></span>" +
"<span href='#' class='lib_pl_close icon-remove'></span>" +
"</a>" +
"</li>",
tabs = $(".nav.nav-tabs");
if (json.id) {
$openTabs[json.type + json.id] = $tabCount;
}
$(".nav.nav-tabs li").removeClass("active");
tabs.append(tab);
tabs.find("#pl-tab-" + $tabCount + " span.tab-name").text(name);
var newTab = $("#pl-tab-" + $tabCount);
mod.switchTab(t, newTab);
return {wrapper: pane, tab: newTab, pane: t};
}
function initFileMdEvents(newTab) {
newTab.tab.on("click", function() {
if (!$(this).hasClass('active')) {
mod.switchTab(newTab.pane, newTab.tab);
}
});
newTab.wrapper.find(".md-cancel").on("click", function() {
mod.closeTab();
});
newTab.wrapper.find(".md-save").on("click", function() {
var file_id = newTab.wrapper.find('#file_id').val(),
data = newTab.wrapper.find("#edit-md-dialog form").serializeArray();
$.post(baseUrl+'library/edit-file-md', {format: "json", id: file_id, data: data}, function() {
// don't redraw the library table if we are on calendar page
// we would be on calendar if viewing recorded file metadata
if ($("#schedule_calendar").length === 0) {
oTable.fnStandingRedraw();
}
});
mod.closeTab();
});
newTab.wrapper.find('#edit-md-dialog').on("keyup", function(event) {
if (event.keyCode === 13) {
newTab.wrapper.find('.md-save').click();
}
});
}
/* #####################################################
External Functions
##################################################### */
mod.openFileMdEditorTab = function(json) {
var newTab = buildNewTab(json);
if (newTab === undefined) {
return;
}
initFileMdEvents(newTab);
AIRTIME.playlist.setupEventListeners();
};
mod.openPlaylistTab = function(json) {
var newTab = buildNewTab(json);
if (newTab === undefined) {
return;
}
newTab.tab.on("click", function() {
if (!$(this).hasClass('active')) {
mod.switchTab(newTab.pane, newTab.tab);
$.post(baseUrl+'playlist/edit', {
format: "json",
id: newTab.pane.find(".obj_id").val(),
type: newTab.pane.find(".obj_type").val()
});
}
});
AIRTIME.playlist.init();
// functions in smart_blockbuilder.js
setupUI();
appendAddButton();
appendModAddButton();
removeButtonCheck();
};
mod.closeTab = function(id) {
var pane = id ? mod.get(id, true) : $activeTabPane,
tab = id ? mod.get(id) : $activeTab,
toPane = pane.next().length > 0 ? pane.next() : pane.prev(),
toTab = tab.next().length > 0 ? tab.next() : tab.prev(),
objId = pane.find(".obj_id").val(),
contents = id ? pane : $activeTabPane;
delete $openTabs[tab.data("tab-type") + objId]; // Remove the closed tab from our open tabs array
// Remove the relevant DOM elements (the tab and the tab content)
tab.remove();
contents.remove();
if (pane.get(0) == $activeTabPane.get(0)) { // Closing the current tab, otherwise we don't need to switch tabs
mod.switchTab(toPane, toTab);
}
// If we close a tab that was causing tabs to wrap to the next row, we need to resize to change the
// margin for the tab nav
AIRTIME.playlist.onResize();
};
mod.switchTab = function(tabPane, tab) {
$activeTabPane.hide().removeClass("active-tab");
tabPane.addClass("active-tab").show();
$activeTab.removeClass("active");
tab.addClass("active");
mod.updateActiveTab();
AIRTIME.playlist.onResize();
AIRTIME.library.fnRedraw();
};
mod.setActiveTabName = function(name) {
$activeTab.find(".tab-name").text(name);
};
mod.updateActiveTab = function() {
$activeTabPane = $(".active-tab");
$activeTab = $(".nav.nav-tabs .active");
if ($activeTabPane.hasClass("pl-content")) {
mod.updatePlaylist();
}
};
mod.updatePlaylist = function() {
AIRTIME.playlist.setCurrent($activeTabPane);
$.post(baseUrl + "playlist/change-playlist", {
"id": AIRTIME.playlist.getId($activeTabPane),
"type": $activeTabPane.find('.obj_type').val()
});
};
mod.getActiveTab = function() {
return $activeTabPane;
};
mod.get = function(id, getContents) {
var allTabs = getContents ? $(".pl-content") : $(".nav.nav-tabs li");
if (id) {
var t = null;
allTabs.each(function() {
if ($(this).data("tab-id") == id) {
t = $(this);
}
});
// An id was passed in, but no tab with that id exists
return t;
}
return allTabs;
};
return AIRTIME;
}(AIRTIME || {}));
$(document).ready(function() {
var parent = $("#show_builder"), fn = getPanTextFunctions();
parent.on("mouseenter", ".tab-name", fn.mousein);
parent.on("mouseleave", ".tab-name", fn.mouseout);
});