var AIRTIME = (function(AIRTIME){ var mod, oSchedTable, SB_SELECTED_CLASS = "sb-selected", CURSOR_SELECTED_CLASS = "cursor-selected-row", NOW_PLAYING_CLASS = "sb-now-playing", $sbContent, $sbTable, $toolbar, $ul, $lib, cursors = [], cursorIds = [], showInstanceIds = [], headerFooter = []; if (AIRTIME.showbuilder === undefined) { AIRTIME.showbuilder = {}; } mod = AIRTIME.showbuilder; function checkError(json) { if (json.error !== undefined) { alert(json.error); } } mod.timeout = undefined; mod.timestamp = -1; mod.showInstances = []; mod.resetTimestamp = function() { mod.timestamp = -1; }; mod.setTimestamp = function(timestamp) { mod.timestamp = timestamp; }; mod.getTimestamp = function() { if (mod.timestamp !== undefined) { return mod.timestamp; } else { return -1; } }; mod.setShowInstances = function(showInstances) { mod.showInstances = showInstances; }; mod.getShowInstances = function() { return mod.showInstances; }; mod.refresh = function() { mod.resetTimestamp(); oSchedTable.fnDraw(); }; mod.checkSelectButton = function() { var $selectable = $sbTable.find("tbody").find("input:checkbox"); if ($selectable.length !== 0) { AIRTIME.button.enableButton("btn-group #timeline-select", true); } else { AIRTIME.button.disableButton("btn-group #timeline-select", true); } }; mod.checkTrimButton = function() { var $over = $sbTable.find(".sb-over.sb-allowed"); if ($over.length !== 0) { AIRTIME.button.enableButton("icon-cut", true); } else { AIRTIME.button.disableButton("icon-cut", true); } }; mod.checkDeleteButton = function() { var $selected = $sbTable.find("tbody").find("input:checkbox").filter(":checked"); if ($selected.length !== 0) { AIRTIME.button.enableButton("icon-trash", true); } else { AIRTIME.button.disableButton("icon-trash", true); } }; mod.checkJumpToCurrentButton = function() { var $current = $sbTable.find("."+NOW_PLAYING_CLASS); if ($current.length !== 0) { AIRTIME.button.enableButton("icon-step-forward", true); } else { AIRTIME.button.disableButton("icon-step-forward", true); } }; mod.checkCancelButton = function() { var $current = $sbTable.find(".sb-current-show.sb-allowed"), //this user type should be refactored into a separate users module later //when there's more time and more JS will need to know user data. userType = localStorage.getItem('user-type'); if ($current.length !== 0 && (userType === 'A' || userType === 'P')) { AIRTIME.button.enableButton("icon-ban-circle", true); } else { AIRTIME.button.disableButton("icon-ban-circle", true); } }; mod.checkToolBarIcons = function() { AIRTIME.library.checkAddButton(); mod.checkSelectButton(); mod.checkTrimButton(); mod.checkDeleteButton(); mod.checkJumpToCurrentButton(); mod.checkCancelButton(); }; mod.selectCursor = function($el) { $el.addClass(CURSOR_SELECTED_CLASS); mod.checkToolBarIcons(); }; mod.removeCursor = function($el) { $el.removeClass(CURSOR_SELECTED_CLASS); mod.checkToolBarIcons(); }; /* * sNot is an optional string to filter selected elements by. (ex removing the currently playing item) */ mod.getSelectedData = function(sNot) { var $selected = $sbTable.find("tbody").find("input:checkbox").filter(":checked").parents("tr"), aData = [], i, length, $item; if (sNot !== undefined) { $selected = $selected.not("."+sNot); } for (i = 0, length = $selected.length; i < length; i++) { $item = $($selected.get(i)); aData.push($item.data('aData')); } return aData.reverse(); }; mod.selectAll = function () { $inputs = $sbTable.find("input:checkbox"); $inputs.attr("checked", true); $trs = $inputs.parents("tr"); $trs.addClass(SB_SELECTED_CLASS); mod.checkToolBarIcons(); }; mod.selectNone = function () { $inputs = $sbTable.find("input:checkbox"); $inputs.attr("checked", false); $trs = $inputs.parents("tr"); $trs.removeClass(SB_SELECTED_CLASS); mod.checkToolBarIcons(); }; mod.disableUI = function() { $lib.block({ message: "", theme: true, applyPlatformOpacityRules: false }); $sbContent.block({ message: "", theme: true, applyPlatformOpacityRules: false }); }; mod.enableUI = function() { $lib.unblock(); $sbContent.unblock(); //Block UI changes the postion to relative to display the messages. $lib.css("position", "static"); $sbContent.css("position", "static"); }; mod.fnItemCallback = function(json) { checkError(json); mod.getSelectedCursors(); oSchedTable.fnDraw(); mod.enableUI(); }; mod.getSelectedCursors = function() { cursorIds = []; /* We need to keep record of which show the cursor belongs to * in the case where more than one show is displayed in the show builder * because header and footer rows have the same id */ showInstanceIds = []; /* Keeps track if the row is a footer. We need to do this because * header and footer rows have the save cursorIds and showInstanceId * so both will be selected in the draw callback */ headerFooter = []; cursors = $(".cursor-selected-row"); for (i = 0; i < cursors.length; i++) { cursorIds.push(($(cursors.get(i)).attr("id"))); showInstanceIds.push(($(cursors.get(i)).attr("si_id"))); if ($(cursors.get(i)).hasClass("sb-footer")) { headerFooter.push("f"); } else { headerFooter.push("n"); } } }; mod.fnAdd = function(aMediaIds, aSchedIds) { mod.disableUI(); $.post("/showbuilder/schedule-add", {"format": "json", "mediaIds": aMediaIds, "schedIds": aSchedIds}, mod.fnItemCallback ); }; mod.fnMove = function(aSelect, aAfter) { mod.disableUI(); $.post("/showbuilder/schedule-move", {"format": "json", "selectedItem": aSelect, "afterItem": aAfter}, mod.fnItemCallback ); }; mod.fnRemove = function(aItems) { mod.disableUI(); if (confirm("Delete selected item(s)?")) { $.post( "/showbuilder/schedule-remove", {"items": aItems, "format": "json"}, mod.fnItemCallback ); }else{ mod.enableUI(); } }; mod.fnRemoveSelectedItems = function() { var aData = mod.getSelectedData(), i, length, temp, aItems = []; for (i=0, length = aData.length; i < length; i++) { temp = aData[i]; aItems.push({"id": temp.id, "instance": temp.instance, "timestamp": temp.timestamp}); } mod.fnRemove(aItems); }; mod.fnServerData = function fnBuilderServerData( sSource, aoData, fnCallback ) { aoData.push( { name: "timestamp", value: mod.getTimestamp()} ); aoData.push( { name: "instances", value: mod.getShowInstances()} ); aoData.push( { name: "format", value: "json"} ); if (mod.fnServerData.hasOwnProperty("start")) { aoData.push( { name: "start", value: mod.fnServerData.start} ); } if (mod.fnServerData.hasOwnProperty("end")) { aoData.push( { name: "end", value: mod.fnServerData.end} ); } if (mod.fnServerData.hasOwnProperty("ops")) { aoData.push( { name: "myShows", value: mod.fnServerData.ops.myShows} ); aoData.push( { name: "showFilter", value: mod.fnServerData.ops.showFilter} ); } $.ajax({ "dataType": "json", "type": "POST", "url": sSource, "data": aoData, "success": function(json) { mod.setTimestamp(json.timestamp); mod.setShowInstances(json.instances); mod.getSelectedCursors(); fnCallback(json); } }); }; mod.builderDataTable = function() { $sbContent = $('#show_builder'); $lib = $("#library_content"), $sbTable = $sbContent.find('table'); /* * Icon hover states in the toolbar. */ $sbContent.on("mouseenter", "#timeline-select .dropdown-toggle", function(ev) { $el = $(this); if (!$el.hasClass("ui-state-disabled")) { $el.addClass("ui-state-hover"); $("#timeline-select .caret").contextMenu(true); } else { $("#timeline-select .caret").contextMenu(false); } }); $sbContent.on("mouseleave", ".fg-toolbar ul li", function(ev) { $el = $(this); if (!$el.hasClass("ui-state-disabled")) { $el.removeClass("ui-state-hover"); } }); oSchedTable = $sbTable.dataTable( { "aoColumns": [ /* checkbox */ {"mDataProp": "allowed", "sTitle": "", "sWidth": "15px", "sClass": "sb-checkbox"}, /* Type */ {"mDataProp": "image", "sTitle": "", "sClass": "library_image sb-image", "sWidth": "16px"}, /* starts */ {"mDataProp": "starts", "sTitle": "Start", "sClass": "sb-starts", "sWidth": "60px"}, /* ends */ {"mDataProp": "ends", "sTitle": "End", "sClass": "sb-ends", "sWidth": "60px"}, /* runtime */ {"mDataProp": "runtime", "sTitle": "Duration", "sClass": "library_length sb-length", "sWidth": "65px"}, /* title */ {"mDataProp": "title", "sTitle": "Title", "sClass": "sb-title"}, /* creator */ {"mDataProp": "creator", "sTitle": "Creator", "sClass": "sb-creator"}, /* album */ {"mDataProp": "album", "sTitle": "Album", "sClass": "sb-album"}, /* cue in */ {"mDataProp": "cuein", "sTitle": "Cue In", "bVisible": false, "sClass": "sb-cue-in"}, /* cue out */ {"mDataProp": "cueout", "sTitle": "Cue Out", "bVisible": false, "sClass": "sb-cue-out"}, /* fade in */ {"mDataProp": "fadein", "sTitle": "Fade In", "bVisible": false, "sClass": "sb-fade-in"}, /* fade out */ {"mDataProp": "fadeout", "sTitle": "Fade Out", "bVisible": false, "sClass": "sb-fade-out"} ], "bJQueryUI": true, "bSort": false, "bFilter": false, "bProcessing": true, "bServerSide": true, "bInfo": false, "bAutoWidth": false, "bStateSave": true, "fnStateSaveParams": function (oSettings, oData) { //remove oData components we don't want to save. delete oData.oSearch; delete oData.aoSearchCols; }, "fnStateSave": function fnStateSave(oSettings, oData) { localStorage.setItem('datatables-timeline', JSON.stringify(oData)); $.ajax({ url: "/usersettings/set-timeline-datatable", type: "POST", data: {settings : oData, format: "json"}, dataType: "json" }); }, "fnStateLoad": function fnBuilderStateLoad(oSettings) { var settings = localStorage.getItem('datatables-timeline'); if (settings !== "") { return JSON.parse(settings); } }, "fnStateLoadParams": function (oSettings, oData) { var i, length, a = oData.abVisCols; //putting serialized data back into the correct js type to make //sure everything works properly. for (i = 0, length = a.length; i < length; i++) { if (typeof(a[i]) === "string") { a[i] = (a[i] === "true") ? true : false; } } a = oData.ColReorder; for (i = 0, length = a.length; i < length; i++) { if (typeof(a[i]) === "string") { a[i] = parseInt(a[i], 10); } } oData.iCreate = parseInt(oData.iCreate, 10); }, "fnServerData": mod.fnServerData, "fnRowCallback": function fnRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { var i, length, sSeparatorHTML, fnPrepareSeparatorRow, $node, cl="", //background-color to imitate calendar color. r,g,b,a, $nRow = $(nRow), $image, $div, headerIcon; fnPrepareSeparatorRow = function fnPrepareSeparatorRow(sRowContent, sClass, iNodeIndex) { $node = $(nRow.children[iNodeIndex]); $node.html(sRowContent); $node.attr('colspan',100); for (i = iNodeIndex + 1, length = nRow.children.length; i < length; i = i+1) { $node = $(nRow.children[i]); $node.html(""); $node.attr("style", "display : none"); } $nRow.addClass(sClass); }; if (aData.header === true) { //remove the column classes from all tds. $nRow.find('td').removeClass(); $node = $(nRow.children[0]); $node.html(""); cl = 'sb-header'; if (aData.record === true) { headerIcon = (aData.soundcloud_id > 0) ? "soundcloud" : "recording"; $div = $("
", { "class": "small-icon " + headerIcon }); $node.append($div); } else if (aData.rebroadcast === true) { $div = $("
", { "class": "small-icon rebroadcast" }); $node.append($div); } sSeparatorHTML = ''+aData.title+''; if (aData.rebroadcast === true) { sSeparatorHTML += ''+aData.rebroadcast_title+''; } sSeparatorHTML += ''; if (aData.startDate === aData.endDate) { sSeparatorHTML += ''+aData.startDate+''+aData.startTime+''; sSeparatorHTML +='-'+aData.endTime+''; } else { sSeparatorHTML += ''+aData.startDate+''+aData.startTime+''; sSeparatorHTML +='-'+aData.endDate+''+aData.endTime+''; } sSeparatorHTML += ''; fnPrepareSeparatorRow(sSeparatorHTML, cl, 1); } else if (aData.footer === true) { //remove the column classes from all tds. $nRow.find('td').removeClass(); $node = $(nRow.children[0]); cl = 'sb-footer'; //check the show's content status. if (aData.runtime > 0) { $node.html(''); cl = cl + ' ui-state-highlight'; } else { $node.html(''); cl = cl + ' ui-state-error'; } sSeparatorHTML = ''+aData.fRuntime+''; fnPrepareSeparatorRow(sSeparatorHTML, cl, 1); } else if (aData.empty === true) { //remove the column classes from all tds. $nRow.find('td').removeClass(); $node = $(nRow.children[0]); $node.html(''); sSeparatorHTML = 'Show Empty'; cl = cl + " sb-empty odd"; fnPrepareSeparatorRow(sSeparatorHTML, cl, 1); } else if (aData.record === true) { //remove the column classes from all tds. $nRow.find('td').removeClass(); $node = $(nRow.children[0]); $node.html(''); sSeparatorHTML = 'Recording From Line In'; cl = cl + " sb-record odd"; fnPrepareSeparatorRow(sSeparatorHTML, cl, 1); } else { //add the play function if the file exists on disk. $image = $nRow.find('td.sb-image'); //check if the file exists. if (aData.image === true) { $image.html('') .click(function() { open_show_preview(aData.instance, aData.pos); return false; }); } else { $image.html(''); $image.find(".ui-icon-alert").qtip({ content: { text: "Airtime is unsure about the status of this file. This can happen when the file is on a remote drive that is unaccessible or the file is in a directory that isn't \"watched\" anymore." }, style: { classes: "ui-tooltip-dark" }, show: 'mouseover', hide: 'mouseout' }); } $node = $(nRow.children[0]); if (aData.allowed === true && aData.scheduled >= 1) { $node.html(''); } else { $node.html(''); } } //add the show colour to the leftmost td if (aData.footer !== true) { if ($nRow.hasClass('sb-header')) { a = 1; } else if ($nRow.hasClass('odd')) { a = 0.3; } else if ($nRow.hasClass('even')) { a = 0.4; } //convert from hex to rgb. r = parseInt((aData.backgroundColor).substring(0,2), 16); g = parseInt((aData.backgroundColor).substring(2,4), 16); b = parseInt((aData.backgroundColor).substring(4,6), 16); $nRow.find('td:first').css('background', 'rgba('+r+', '+g+', '+b+', '+a+')'); } //save some info for reordering purposes. $nRow.data({"aData": aData}); if (aData.scheduled === 1) { $nRow.addClass(NOW_PLAYING_CLASS); } else if (aData.scheduled === 0) { $nRow.addClass("sb-past"); } else { $nRow.addClass("sb-future"); } if (aData.allowed !== true) { $nRow.addClass("sb-not-allowed"); } else { $nRow.addClass("sb-allowed"); $nRow.attr("id", aData.id); $nRow.attr("si_id", aData.instance); } //status used to colour tracks. if (aData.status === 2) { $nRow.addClass("sb-boundry"); } else if (aData.status === 0) { $nRow.addClass("sb-over"); } if (aData.currentShow === true) { $nRow.addClass("sb-current-show"); } //call the context menu so we can prevent the event from propagating. $nRow.find('td:gt(1)').click(function(e){ $(this).contextMenu({x: e.pageX, y: e.pageY}); return false; }); }, //remove any selected nodes before the draw. "fnPreDrawCallback": function( oSettings ) { //make sure any dragging helpers are removed or else they'll be stranded on the screen. $("#draggingContainer").remove(); }, "fnDrawCallback": function fnBuilderDrawCallback(oSettings, json) { var wrapperDiv, markerDiv, $td, aData, elements, i, length, temp, $cursorRows, $table = $(this), $parent = $table.parent(), $tr, //use this array to cache DOM heights then we can detach the table to manipulate it to increase speed. heights = []; clearTimeout(mod.timeout); //only create the cursor arrows if the library is on the page. if ($lib.length > 0 && $lib.filter(":visible").length > 0) { $cursorRows = $sbTable.find("tbody tr.sb-future.sb-allowed:not(.sb-header, .sb-empty)"); //need to get heights of tds while elements are still in the DOM. for (i = 0, length = $cursorRows.length; i < length; i++) { $td = $($cursorRows.get(i)).find("td:first"); heights.push($td.height()); } //detach the table to increase speed. $table.detach(); for (i = 0, length = $cursorRows.length; i < length; i++) { $td = $($cursorRows.get(i)).find("td:first"); if ($td.hasClass("dataTables_empty")) { $parent.append($table); return false; } wrapperDiv = $("
", { "class": "innerWrapper", "css": { "height": heights[i] } }); markerDiv = $("
", { "class": "marker" }); $td.append(markerDiv).wrapInner(wrapperDiv); } //re-highlight selected cursors before draw took place for (i = 0; i < cursorIds.length; i++) { if (headerFooter[i] == "f") { $tr = $table.find("tbody tr.sb-footer[id="+cursorIds[i]+"][si_id="+showInstanceIds[i]+"]"); } else { $tr = $table.find("tr[id="+cursorIds[i]+"][si_id="+showInstanceIds[i]+"]"); } /* If the currently playing track's cursor is selected, * and that track is deleted, the cursor position becomes * unavailble. We have to check the position is available * before re-highlighting it. */ if ($tr.find(".sb-checkbox").children().hasClass("innerWrapper")) { mod.selectCursor($tr); /* If the selected cursor is the footer row we need to * explicitly select it because that row does not have * innerWrapper class */ } else if ($tr.hasClass("sb-footer")) { mod.selectCursor($tr); } } //if there is only 1 cursor on the page highlight it by default. if ($cursorRows.length === 1) { $td = $cursorRows.find("td:first"); if (!$td.hasClass("dataTables_empty")) { $cursorRows.addClass("cursor-selected-row"); } } $parent.append($table); } //order of importance of elements for setting the next timeout. elements = [ $sbTable.find("tr."+NOW_PLAYING_CLASS), $sbTable.find("tbody").find("tr.sb-future.sb-footer, tr.sb-future.sb-header").filter(":first") ]; //check which element we should set a timeout relative to. for (i = 0, length = elements.length; i < length; i++) { temp = elements[i]; if (temp.length > 0) { aData = temp.data("aData"); // max time interval // setTimeout allows only up to (2^31)-1 millisecs timeout value maxRefreshInterval = Math.pow(2, 31) - 1; refreshInterval = aData.refresh * 1000; if(refreshInterval > maxRefreshInterval){ refreshInterval = maxRefreshInterval; } mod.timeout = setTimeout(mod.refresh, refreshInterval); //need refresh in milliseconds break; } } mod.checkToolBarIcons(); }, "oColVis": { "aiExclude": [ 0, 1 ] }, "oColReorder": { "iFixedColumns": 2 }, // R = ColReorderResize, C = ColVis "sDom": 'R<"dt-process-rel"r><"sb-padded"<"H"C>><"dataTables_scrolling sb-padded"t>', "sAjaxDataProp": "schedule", "sAjaxSource": "/showbuilder/builder-feed" }); $sbTable.find("tbody").on("click", "input:checkbox", function(ev) { var $cb = $(this), $tr = $cb.parents("tr"), $prev; if ($cb.is(":checked")) { if (ev.shiftKey) { $prev = $sbTable.find("tbody").find("tr."+SB_SELECTED_CLASS).eq(-1); $prev.nextUntil($tr) .addClass(SB_SELECTED_CLASS) .find("input:checkbox") .attr("checked", true) .end(); } $tr.addClass(SB_SELECTED_CLASS); } else { $tr.removeClass(SB_SELECTED_CLASS); } mod.checkToolBarIcons(); }); var sortableConf = (function(){ var origTrs, aItemData = [], oPrevData, fnAdd, fnMove, fnReceive, fnUpdate, i, html, helperData, draggingContainer; fnAdd = function() { var aMediaIds = [], aSchedIds = []; for(i = 0; i < aItemData.length; i++) { aMediaIds.push({"id": aItemData[i].id, "type": aItemData[i].ftype}); } aSchedIds.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp}); mod.fnAdd(aMediaIds, aSchedIds); }; fnMove = function() { var aSelect = [], aAfter = []; for(i = 0; i < helperData.length; i++) { aSelect.push({"id": helperData[i].id, "instance": helperData[i].instance, "timestamp": helperData[i].timestamp}); } aAfter.push({"id": oPrevData.id, "instance": oPrevData.instance, "timestamp": oPrevData.timestamp}); mod.fnMove(aSelect, aAfter); }; fnReceive = function(event, ui) { var aItems = []; AIRTIME.library.addToChosen(ui.item); aItems = AIRTIME.library.getSelectedData(); origTrs = aItems; html = ui.helper.html(); AIRTIME.library.removeFromChosen(ui.item); }; fnUpdate = function(event, ui) { var prev = ui.item.prev(); //can't add items outside of shows. if (prev.find("td:first").hasClass("dataTables_empty") || prev.length === 0) { alert("Cannot schedule outside a show."); ui.item.remove(); return; } //if item is added after a footer, add the item after the last item in the show. if (prev.hasClass("sb-footer")) { prev = prev.prev(); } aItemData = []; oPrevData = prev.data("aData"); //item was dragged in if (origTrs !== undefined) { $sbTable.find("tr.ui-draggable") .empty() .after(html); aItemData = origTrs; origTrs = undefined; fnAdd(); } //item was reordered. else { ui.item .empty() .after(draggingContainer.html()); aItemData.push(ui.item.data("aData")); fnMove(); } }; return { placeholder: "sb-placeholder ui-state-highlight", forcePlaceholderSize: true, distance: 10, helper: function(event, item) { var selected = mod.getSelectedData(NOW_PLAYING_CLASS), thead = $("#show_builder_table thead"), colspan = thead.find("th").length, trfirst = thead.find("tr:first"), width = trfirst.width(), height = trfirst.height(), message; //if nothing is checked select the dragged item. if (selected.length === 0) { selected = [item.data("aData")]; } if (selected.length === 1) { message = "Moving "+selected.length+" Item."; } else { message = "Moving "+selected.length+" Items."; } draggingContainer = $('') .addClass('sb-helper') .append('') .find("td") .attr("colspan", colspan) .width(width) .height(height) .addClass("ui-state-highlight") .append(message) .end(); helperData = selected; return draggingContainer; }, items: 'tr:not(:first, :last, .sb-header, .sb-not-allowed, .sb-past, .sb-now-playing, .sb-empty)', cancel: '.sb-footer', receive: fnReceive, update: fnUpdate, start: function(event, ui) { /* var elements = $sbTable.find('tr input:checked').parents('tr') .not(ui.item) .not("."+NOW_PLAYING_CLASS); //remove all other items from the screen, //don't remove ui.item or else we can not get position information when the user drops later. elements.remove(); */ var elements = $sbTable.find('tr input:checked').parents('tr').not("."+NOW_PLAYING_CLASS); elements.hide(); } }; }()); $sbTable.sortable(sortableConf); //start setup of the builder toolbar. $toolbar = $(".sb-content .fg-toolbar"); $menu = $("
"); $menu.append("
" + "" + "" + "
") .append("
" + "
") .append("
" + "
") .append("
" + "
") .append("
" + "
"); $toolbar.append($menu); $menu = undefined; $('#timeline-sa').click(function(){mod.selectAll();}); $('#timeline-sn').click(function(){mod.selectNone();}); //cancel current show $toolbar.find('.icon-ban-circle') .click(function() { var $tr, data, msg = 'Cancel Current Show?'; if (AIRTIME.button.isDisabled('icon-ban-circle') === true) { return; } $tr = $sbTable.find('tr.sb-future:first'); if ($tr.hasClass('sb-current-show')) { data = $tr.data("aData"); if (data.record === true) { msg = 'Stop recording current show?'; } if (confirm(msg)) { var url = "/Schedule/cancel-current-show"; $.ajax({ url: url, data: {format: "json", id: data.instance}, success: function(data){ var oTable = $sbTable.dataTable(); oTable.fnDraw(); } }); } } }); //jump to current $toolbar.find('.icon-step-forward') .click(function() { if (AIRTIME.button.isDisabled('icon-step-forward') === true) { return; } var $scroll = $sbContent.find(".dataTables_scrolling"), scrolled = $scroll.scrollTop(), scrollingTop = $scroll.offset().top, current = $sbTable.find("."+NOW_PLAYING_CLASS), currentTop = current.offset().top; $scroll.scrollTop(currentTop - scrollingTop + scrolled); }); //delete overbooked tracks. $toolbar.find('.icon-cut') .click(function() { if (AIRTIME.button.isDisabled('icon-cut') === true) { return; } var temp, aItems = [], trs = $sbTable.find(".sb-over.sb-future.sb-allowed"); trs.each(function(){ temp = $(this).data("aData"); aItems.push({"id": temp.id, "instance": temp.instance, "timestamp": temp.timestamp}); }); mod.fnRemove(aItems); }); //delete selected tracks $toolbar.find('.icon-trash') .click(function() { if (AIRTIME.button.isDisabled('icon-trash') === true) { return; } mod.fnRemoveSelectedItems(); }); //add events to cursors. $sbTable.find("tbody").on("click", "div.marker", function(event) { var $tr = $(this).parents("tr"), $trs; if ($tr.hasClass(CURSOR_SELECTED_CLASS)) { mod.removeCursor($tr); } else { mod.selectCursor($tr); } if (event.ctrlKey === false) { $trs = $sbTable.find('.'+CURSOR_SELECTED_CLASS).not($tr); mod.removeCursor($trs); } return false; }); //begin context menu initialization. $.contextMenu({ selector: '.sb-content table tbody tr:not(.sb-empty, .sb-footer, .sb-header, .sb-record) td:not(.sb-checkbox, .sb-image)', trigger: "left", ignoreRightClick: true, build: function($el, e) { var items, $tr = $el.parent(), data = $tr.data("aData"), cursorClass = "cursor-selected-row", callback; function processMenuItems(oItems) { //define a preview callback. if (oItems.preview !== undefined) { callback = function() { open_show_preview(data.instance, data.pos); }; oItems.preview.callback = callback; } //define a select cursor callback. if (oItems.selCurs !== undefined) { callback = function() { var $tr = $(this).parents('tr').next(); mod.selectCursor($tr); }; oItems.selCurs.callback = callback; } //define a remove cursor callback. if (oItems.delCurs !== undefined) { callback = function() { var $tr = $(this).parents('tr').next(); mod.removeCursor($tr); }; oItems.delCurs.callback = callback; } //define a delete callback. if (oItems.del !== undefined) { callback = function() { AIRTIME.showbuilder.fnRemove([{ id: data.id, timestamp: data.timestamp, instance: data.instance }]); }; oItems.del.callback = callback; } //only show the cursor selecting options if the library is visible on the page. if ($tr.next().find('.marker').length === 0) { delete oItems.selCurs; delete oItems.delCurs; } //check to include either select or remove cursor. else { if ($tr.next().hasClass(cursorClass)) { delete oItems.selCurs; } else { delete oItems.delCurs; } } items = oItems; } request = $.ajax({ url: "/showbuilder/context-menu", type: "GET", data: {id : data.id, format: "json"}, dataType: "json", async: false, success: function(json){ processMenuItems(json.items); } }); return { items: items }; } }); }; return AIRTIME; }(AIRTIME || {}));