/*jslint laxbreak:true */ /*jslint laxcomma:true */ /*jslint loopfunc:true */ /*jslint strict:true */ /*jslint browser:true */ /*jslint devel:true */ define([ "underscore" , "jquery" , "backbone" , "bootstrap" , "text!../../templates/view-list.html" , "jquery-ui" , "jquery-event-drag" , "jquery-clone-styles" , "datatables" , "dt-scroller" , "dt-tabletools" , "dt-colreorder" ] , function ( _ , $ , Backbone , Bootstrap , tmplListView ) { "use strict"; var List = Backbone.View.extend({ options: { type: "playlist" } , dataTable: null , tableSchemaDefaults: { } , tableSchema: [ { // Now playing column mData: null , sTitle: "" , sDefaultContent: "" , bSortable: false , bSearchable: false , sWidth: "15px" , fnCreatedCell: function(nTd, sData, oData, iRow, iCol) { var span = document.createElement("span"); nTd.appendChild(span); } } , { mData: "dmap_itemname" , sTitle: "Title" , sDefaultContent: "Unknown" } , { mData: "daap_songartist" , sTitle: "Artist" , sDefaultContent: "Unknown" , aDataSort: [2, 6, 3, 5, 4] } , { mData: "daap_songalbum" , sTitle: "Album" , sDefaultContent: "Unknown" , aDataSort: [3, 6, 5, 4] } , { mData: "daap_songtracknumber" , sTitle: "Track" , sClass: "center" , sDefaultContent: "" /*, sType: "numeric"*/ , sWidth: "75px" , mRender: function(data, type, full) { if (data === "") { return ""; } else if (full.daap_songtrackcount) { return data + " of " + full.daap_songtrackcount; } else { return data; } } } , { mData: "daap_songdiscnumber" , sTitle: "Disc" , sClass: "center" , sDefaultContent: "Unknown" /*, sType: "numeric"*/ , sWidth: "50px" , mRender: function(data, type, full) { if (data === "") { return ""; } else if (full.daap_songdisccount) { return data + " of " + full.daap_songdisccount; } else { return data; } } } , { mData: "daap_songyear" , sTitle: "Year" , sClass: "center" , sDefaultContent: "" , sType: "numeric" , sWidth: "50px" } , { mData: "daap_songgenre" , sTitle: "Genre" , sClass: "center" , sDefaultContent: "" , bVisible: false } , { mData: "daap_songtime" , sTitle: "Time" , sClass: "center" , sDefaultContent: "" /*, sType: "numeric"*/ , sWidth: "75px" , bVisible: true , mRender: function(data, type, full) { if (data !== "") { return songMSTimeFormat(data); } else { return data; } } } , { mData: "daap_songuserrating" , sTitle: "Rating" , sClass: "center" , sType: "numeric" , sDefaultContent: "" , bVisible: false } , { mData: "dmap_itemid" , sTitle: "ID" , sClass: "center" , sDefaultContent: "" , bVisible: false } ] , detailsFields: [ { title: "Title" , field: "dmap_itemname" } , { title: "Artist" , field: "daap_songartist" } , { title: "Album" , field: "daap_songalbum" } , { title: "Composer" , field: "daap_songcomposer" } , { title: "Genre" , field: "daap_songgenre" } , { title: "Track Number" , field: "daap_songtracknumber" , render: function(data, full) { var value = data; if (data === "") { value = "Unknown"; } if (typeof full.daap_songtrackcount !== "undefined") { value += " of " + full.daap_songtrackcount; } return value; } } , { title: "Disc Number" , field: "daap_songdiscnumber" , render: function(data, full) { var value = data; if (typeof full.daap_songdisccount !== "undefined") { value += " of " + full.daap_songdisccount; } return value; } } , { title: "Year" , field: "daap_songyear" } , { title: "Rating" , field: "daap_songuserrating" } , { title: "Compilation" , field: "daap_songcompilation" , defaults: "No" , render: function (data, full) { return (data == 1 ? "Yes" : "No"); } } , { title: "Duration" , field: "daap_songtime" , render: function (data, full) { return songMSTimeFormat(data); } } , { title: "BPM" , field: "daap_songbeatsperminute" } , { title: "Bit Rate" , field: "daap_songbitrate" , render: function (data, full) { if (data > 0) { data += "kbps"; } return data; } } , { title: "Sample Rate" , field: "daap_songsamplerate" , render: function (data, full) { if (data !== "") { if (data > 1000) { data = (data / 1000) + "k"; } data += "Hz"; } return data; } } , { title: "Date added" , field: "daap_songdateadded" } ] , tableSort: [] , initialize: function (options) { _.bindAll(this , "resize" , "render" , "show" , "hide" ); var that = this ; if (options && options.el) { $(options.el).html(tmplListView); } else { options = options || {}; options.el = document.createElement("div"); options.el.id = "__view-playlist"; options.el.className = "playlist-view-container"; $(options.el).html(tmplListView); this.el = options.el; this.$el = $(this.el); } List.__super__.initialize.apply(this, arguments); if (that.options.type === "playlist" && that.options.collection) { that.options.collection.fetch(); that.options.collection.on("add", function __fnPlaylistAddRow(model) { if (that.dataTable) { that.dataTable.fnAddData(model.toJSON(), that.$el.is(":visible")); } }); } return this; } // FIXME: Sometimes the parent element's size is 0 and resizing fails. , resize: function () { var that = this , parentEl = that.options.parentEl || that.$el.parent() , parentWidth = parentEl.innerWidth() , parentHeight = parentEl.innerHeight() ; console.log(parentWidth, that.$el.innerWidth(), parentHeight, that.$el, parentEl); that.$el.find(".dataTables_scrollBody").height(that.$el.innerHeight() - 20); that.$el.width(parentWidth); that.$el.find(".dataTables_wrapper").width(parentWidth); that.$el.find(".dataTables_scrollBody").width(parentWidth); that.$el.find(".dataTables_scroll").width(parentWidth); that.$el.find(".dataTables_scrollHeadInner").width(parentWidth); that.$el.find(".dataTables_scrollHeadInner table").width(parentWidth); that.$el.parent().find("span[resizer='north']").width(parentWidth); } , render: function () { var that = this , initialHeight = that.$el.innerHeight() - 20 , dataTableOpts = { sScrollY: initialHeight + "px" , sDom: "RTrtS" , oColReorder: { iFixedColumns: 1 } , bInfo: false , bLengthChange: false , bAutoWidth: false , bFilter: true , bDeferRender: true , bStateSave: false//true , bScrollCollapse: true , bJQueryUI: true , sHeightMatch: "auto" , sEmptyTable: "" //, bProcessing: true //, bServerSide: true , aaData: that.collection.toJSON() , aoColumns: that.tableSchema , oTableTools: { sRowSelect: "single" , sSelectedClass: "selected" , aButtons: [] } , fnCreatedRow: function(nRow, aData, iDataIndex) { if (that.options.type !== "playlist") { $(nRow).draggable({ scope: "list-item" , stack: "droppable" , cursor: "copy" , revert: "invalid" , containment: "window" , revertDuration: 200 , scroll: false , start: function(event, ui) { $(this).fadeTo("fast", 0.5); } , stop: function(event, ui) { $(this).fadeTo(0, 1); } , helper: function (event) { var dragEl = $('
') .find("table") .append( $(this) .closest("tr") .clone() //.css($(this).getStyleObject()) .addClass("selected") ) .parent() ; //console.debug("Extracting draggable", this, dragEl); return dragEl.prependTo('body').css('zIndex',10000).show(); //return dragEl // .appendTo("body") // .css("zIndex", "5000") // .show(); } }) .data("hostname", that.options.client.hostname) .data("dbId", that.options.client.dbId) .data("item", aData.id) ; } // create a view for the row //var rowModel = that.collection.get(aData.id); //view.rows.push(new DtRowView({id: aData.id, el: nRow, model: rowModel})); } , fnServerData: function(sSource, aoData, fnCallback, settings) { console.log(sSource, aoData, fnCallback, settings); } /* // function used to populate the DataTable with the current // content of the collection var populateTable = function() { // clear out old row views var rows = []; // these 'meta' attributes are set by the collection's parse method var totalSize = that.collection.meta('totalSize'); var filteredSize = that.collection.meta('filteredSize'); return fnCallback({iTotalRecords: totalSize, iTotalDisplayRecords: filteredSize, aaData: that.collection.toJSON()}); }; aoData.shift(); // ignore sEcho var params = $.param(aoData); if (params != that.constraint) { // trigger param:change event with new parameters. Pass in // populateTable function so fnCallback can be called after // the data has been refreshed. Note that we cannot just call // fnDraw on the collection reset event since closure state // in the fnCallback passed to this method would be lost. that.trigger("param:change", params, populateTable); } else { // no filter change, just populate the table populateTable(); } } */ } ; // Default sorting order if (that.options.type !== "playlist") { dataTableOpts.aaSorting = [[2, "asc"], [6, "asc"], [3, "asc"], [5, "asc"], [4, "asc"]]; } else { var schemaLastItem = (that.tableSchema.length - 1); dataTableOpts.aaSorting = [[schemaLastItem, "asc"]]; that.tableSchema[schemaLastItem].mData = "order"; for (var i = 0; i < schemaLastItem; i++) { that.tableSchema[i].bSortable = false; } dataTableOpts.aoColumns = that.tableSchema; } this.dataTable = this.$el.find("table:first").dataTable(dataTableOpts); } , show: function () { var that = this ; if (!that.dataTable) { that.render(); } that.$el.show(); that.dataTable.fnDraw(); that.resize(); that._setPlayOrder(); } , hide: function () { var that = this ; this.$el.hide(); } , _setPlayOrder: function () { var that = this , playIndex = [] ; playIndex = _.map(that.dataTable.fnSettings().aiDisplay, function (id, index) { var itemData = that.dataTable.fnGetData(id) , itemIndex = {} ; if (that.options.type === "playlist") { itemIndex.hostname = itemData.server; itemIndex.dbId = itemData.database; itemIndex.playlist = true; } else { itemIndex.hostname = that.options.client.hostname; itemIndex.dbId = that.options.client.dbId; itemIndex.playlist = null; } itemIndex.dmap_itemname = itemData["dmap_itemname"]; itemIndex.daap_songartist = itemData["daap_songartist"]; itemIndex.daap_songtime = itemData["daap_songtime"]; itemIndex.type = itemData["daap_songformat"]; itemIndex.id = itemData["dmap_persistantid"] || itemData["dmap_itemid"] || itemData["dmap_containeritemid"] || itemData["id"]; return itemIndex; }); that.trigger("action:playorder", playIndex); } }); return List; });