From 8ceee0d28c819e56df252de3c20c4dae9c8ed60d Mon Sep 17 00:00:00 2001 From: Matthieu Lalonde Date: Fri, 2 Nov 2012 19:51:43 -0400 Subject: [PATCH] MODIF - More listview datatable goodness --- resources/js/app.js | 1 - resources/js/libs/utils.js | 19 ++ resources/js/main.js | 9 + resources/js/views/app.js | 2 +- resources/js/views/client.js | 8 + resources/js/views/list.js | 353 ++++++++++++++++++++++++++++- resources/js/views/main.js | 1 - resources/templates/view-list.html | 2 +- 8 files changed, 383 insertions(+), 12 deletions(-) diff --git a/resources/js/app.js b/resources/js/app.js index dacff1c..1e894f0 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -214,7 +214,6 @@ _ // FIXME: This needs to take client states into account var __fnAppEventClientLoaded = function () { if (!that.Views.Main.getView(server.get("hostname"))) { - console.log(server); that.Views.Main.setView(server.client.attributes.hostname, new ClientView({ /*el: that.Views.App.Layout.panes.center , */server: server diff --git a/resources/js/libs/utils.js b/resources/js/libs/utils.js index c2577f8..4047214 100644 --- a/resources/js/libs/utils.js +++ b/resources/js/libs/utils.js @@ -14,4 +14,23 @@ if (typeof Object.size !== "function") { } Object.size = fnSize; +} + + +if (!String.prototype.pad) { + String.prototype.pad = function(l, s) { + return (l -= this.length) > 0 + ? (s = new Array(Math.ceil(l / s.length) + 1).join(s)).substr(0, s.length) + this + s.substr(0, l - s.length) + : this; + }; +} + +function songMSTimeFormat(v, record) +{ + return songTimeFormat(v/1000) +} + +function songTimeFormat(v, record) +{ + return Math.floor(v / 60).toFixed().pad(2, "0") + ":" + (v % 60).toFixed().pad(2, "0"); } \ No newline at end of file diff --git a/resources/js/main.js b/resources/js/main.js index d81a17b..44e3fbe 100644 --- a/resources/js/main.js +++ b/resources/js/main.js @@ -7,8 +7,13 @@ require.config({ "jquery-ui": ["jquery"] , "jquery-event-drag": ["jquery"] , "jquery-layout": ["jquery", "jquery-ui"] + , "datatables": ["jquery"] + , "dt-scroller": ["datatables"] + , "dt-tabletools": ["datatables"] + , "dt-colreorder": ["datatables"] + , "bootstrap-contextmenu": ["bootstrap"] , "jquery": { @@ -57,7 +62,11 @@ require.config({ , "jquery-ui": "../vendors/jquery/ui/1.9.0/jquery-ui-all" , "jquery-event-drag": "../vendors/jquery/event-drag/2.2/jquery.event.drag" , "jquery-layout": "../vendors/jquery/layout/1.2.0/jquery.layout.min" + , "datatables": "../vendors/jquery/datatables/1.9.4/media/js/jquery.dataTables.min" + , "dt-scroller": "../vendors/jquery/datatables/1.9.4/extras/Scroller/media/js/dataTables.scroller.min" + , "dt-tabletools": "../vendors/jquery/datatables/1.9.4/extras/TableTools/media/js/TableTools.min" + , "dt-colreorder": "../vendors/jquery/datatables/1.9.4/extras/ColReorder/media/js/ColReorder.min" , "bootstrap": "../vendors/bootstrap/2.1.1/js/bootstrap.min" , "bootstrap-contextmenu": "../vendors/bootstrap/contextmenu/59986df48f/js/bootstrap-contextmenu" diff --git a/resources/js/views/app.js b/resources/js/views/app.js index 6f58692..5fb63e7 100644 --- a/resources/js/views/app.js +++ b/resources/js/views/app.js @@ -30,7 +30,7 @@ define([ var that = this; - that.Layout = that.$el.layout({ + that.Layout = that.$el.Layout({ //applyDefaultStyles: true defaults: { closable: false diff --git a/resources/js/views/client.js b/resources/js/views/client.js index 10256cd..9c70cc6 100644 --- a/resources/js/views/client.js +++ b/resources/js/views/client.js @@ -83,10 +83,16 @@ _ minSize: 100 , size: 200 , closable: true + , onresize: function (pane, $pane, state, options) { + that.Views.Browser.resize(pane, $pane, state, options); + } } , center: { minSize: 200 + , onresize: function (pane, $pane, state, options) { + that.Views.List.resize(pane, $pane, state, options); + } } }); @@ -113,6 +119,7 @@ _ that._initLayout(); } + that.Views.List.show(); this.$el.show(); //console.debug(that.Server.client.collections.databases[that.Server.client.collections.databasesInfo.get("dmap_listing").at(0).id].get("dmap_listing")); } @@ -121,6 +128,7 @@ _ var that = this ; + that.Views.List.hide(); this.$el.hide(); } }); diff --git a/resources/js/views/list.js b/resources/js/views/list.js index 607d0b8..9010e6b 100644 --- a/resources/js/views/list.js +++ b/resources/js/views/list.js @@ -5,14 +5,24 @@ /*jslint browser:true */ /*jslint devel:true */ define([ - "jquery" + "underscore" + , "jquery" , "backbone" , "bootstrap" , "text!../../templates/view-list.html" + + , "jquery-ui" + , "jquery-event-drag" + + , "datatables" + , "dt-scroller" + , "dt-tabletools" + , "dt-colreorder" ] , function ( -$ +_ +, $ , Backbone , Bootstrap @@ -23,19 +33,257 @@ $ var List = Backbone.View.extend({ 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.innerHTML = tmplListView; + $(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.innerHTML = tmplListView; + + $(options.el).html(tmplListView); this.el = options.el; this.$el = $(this.el); @@ -43,20 +291,109 @@ $ List.__super__.initialize.apply(this, arguments); - this.$el.find("table:first").html("

" + this.type + "

"); + //this.$el.find("table:first").html("

" + this.type + "

"); return this; } - , render: function () { - return this.$el; + , resize: function (height) { + var that = this + ; + + that.$el.find(".dataTables_scrollBody").height(that.$el.innerHeight() - 20); + } + + , render: function () { + var that = this + , initialHeight = that.$el.innerHeight() - 20 + ; + + this.dataTable = this.$el.find("table:first").dataTable({ + sScrollY: initialHeight + "px" + , sDom: "RTrtS" + , oColReorder: { + iFixedColumns: 1 + } + , bInfo: false + , bLengthChange: false + , bAutoWidth: false + , bFilter: true + , bDeferRender: true + , bStateSave: false//true + , bScrollCollapse: true + , sHeightMatch: "auto" + , sEmptyTable: "" + //, bProcessing: true + //, bServerSide: true + + // Default sorting order + , aaSorting: [[2, "asc"], [6, "asc"], [3, "asc"], [5, "asc"], [4, "asc"]] + + , aaData: that.collection.toJSON() + + , aoColumns: that.tableSchema + + , oTableTools: { + sRowSelect: "single" + , sSelectedClass: "selected" + , aButtons: [] + } +/* + , fnCreatedRow: function(nRow, aData, iDataIndex) { + // 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) { + // 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(); + } + } + */ + }); + } , show: function () { var that = this ; - this.$el.show(); + if (!that.dataTable) { + that.render(); + } + + that.$el.show(); } , hide: function () { diff --git a/resources/js/views/main.js b/resources/js/views/main.js index 8c4dbad..844ccf5 100644 --- a/resources/js/views/main.js +++ b/resources/js/views/main.js @@ -71,7 +71,6 @@ _ console.debug("Show view: "+ name);//, that.$el, that.children[name], that.children[name].$el); if (that.children[name] && that.children[name].$el) { - console.log(that.$el.find(that.children[name].$el)); if (that.$el.find(that.children[name].$el).length === 0) { that.$el.append(that.children[name].$el); } diff --git a/resources/templates/view-list.html b/resources/templates/view-list.html index ba1db96..5ec81cd 100644 --- a/resources/templates/view-list.html +++ b/resources/templates/view-list.html @@ -1 +1 @@ -

" + this.type + "

\ No newline at end of file +
\ No newline at end of file