diff --git a/web/app/assets/javascripts/findMusician.js b/web/app/assets/javascripts/findMusician.js new file mode 100644 index 000000000..78acdfe3e --- /dev/null +++ b/web/app/assets/javascripts/findMusician.js @@ -0,0 +1,145 @@ +(function(context,$) { + "use strict"; + + context.JK = context.JK || {}; + context.JK.FindMusicianScreen = function(app) { + + var logger = context.JK.logger; + var musicians = {}; + var musicianCounts = [0, 0, 0]; + var musicianList; + + function removeSpinner() { + $('') + } + + function loadMusicians(queryString) { + addSpinner(); + + // squelch nulls and undefines + queryString = !!queryString ? queryString : ""; + + $.ajax({ + type: "GET", + url: "/api/musicians?" + queryString, + async: true, + success: afterLoadMusicians, + complete: removeSpinner, + error: app.ajaxError + }); + } + + function search() { + logger.debug("Searching for musicians..."); + clearResults(); + var queryString = ''; + + // instrument filter + var instruments = context.JK.InstrumentSelectorHelper.getSelectedInstruments('#find-musician-instrument'); + if (instruments !== null && instruments.length > 0) { + queryString += "instruments=" + instruments.join(','); + } + + // keyword filter + var keyword = $('#musician-keyword-srch').val(); + if (keyword !== null && keyword.length > 0 && keyword !== 'Search by Keyword') { + if (queryString.length > 0) { + queryString += "&"; + } + queryString += "keyword=" + $('#musician-keyword-srch').val(); + } + loadMusicians(queryString); + } + + function refreshDisplay() { + var priorVisible; + } + + function afterLoadMusicians(musicianList) { + // display the 'no musicians' banner if appropriate + var $noMusiciansFound = $('#musicians-none-found'); + if(musicianList.length == 0) { + $noMusiciansFound.show(); + } + else { + $noMusiciansFound.hide(); + } + + startMusicianLatencyChecks(musicianList); + context.JK.GA.trackFindMusicians(musicianList.length); + } + + /** + * Render a single musician line into the table. + * It will be inserted at the appropriate place according to the + * sortScore in musicianLatency. + */ + function renderMusician(musicianId) { + // store musician in the appropriate bucket and increment category counts + var musician = musicians[musicianId]; + + refreshDisplay(); + } + + function beforeShow(data) { + context.JK.InstrumentSelectorHelper.render('#find-musician-instrument'); + } + + function afterShow(data) { + clearResults(); + refreshDisplay(); + loadMusicians(); + } + + function clearResults() { + musicians = {}; + } + + function events() { + $('#musician-keyword-srch').focus(function() { + $(this).val(''); + }); + + $("#musician-keyword-srch").keypress(function(evt) { + if (evt.which === 13) { + evt.preventDefault(); + search(); + } + }); + $('#btn-refresh').on("click", search); + } + + /** + * Initialize, providing an instance of the MusicianLatency class. + */ + function initialize(latency) { + + var screenBindings = { + 'beforeShow': beforeShow, + 'afterShow': afterShow + }; + app.bindScreen('findMusician', screenBindings); + + musicianList = new context.JK.MusicianList(app); + + events(); + } + + this.initialize = initialize; + this.renderMusician = renderMusician; + this.afterShow = afterShow; + + // Following exposed for easier testing. + this.setMusician = setMusician; + this.clearResults = clearResults; + this.getCategoryEnum = getCategoryEnum; + + return this; + }; + + })(window,jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/instrumentSelector.js b/web/app/assets/javascripts/instrumentSelector.js new file mode 100644 index 000000000..0c75e8575 --- /dev/null +++ b/web/app/assets/javascripts/instrumentSelector.js @@ -0,0 +1,87 @@ +(function(context,$) { + + /** + * Javascript for managing genre selectors. + */ + + "use strict"; + + context.JK = context.JK || {}; + context.JK.GenreSelectorHelper = (function() { + + var logger = context.JK.logger; + var _genres = []; // will be list of structs: [ {label:xxx, value:yyy}, {...}, ... ] + + function loadGenres() { + var url = "/api/genres"; + $.ajax({ + type: "GET", + url: url, + async: false, // do this synchronously so the event handlers in events() can be wired up + success: genresLoaded + }); + } + + function reset(parentSelector, defaultGenre) { + defaultGenre = typeof(defaultGenre) == 'undefined' ? '' : defaultGenre; + $('select', parentSelector).val(defaultGenre); + } + + function genresLoaded(response) { + $.each(response, function(index) { + _genres.push({ + value: this.id, + label: this.description + }); + }); + } + + function render(parentSelector) { + $('select', parentSelector).empty(); + $('select', parentSelector).append(''); + var template = $('#template-genre-option').html(); + $.each(_genres, function(index, value) { + // value will be a dictionary entry from _genres: + // { value: xxx, label: yyy } + var genreOptionHtml = context.JK.fillTemplate(template, value); + $('select', parentSelector).append(genreOptionHtml); + }); + } + + function getSelectedGenres(parentSelector) { + var selectedGenres = []; + var selectedVal = $('select', parentSelector).val(); + if (selectedVal !== '') { + selectedGenres.push(selectedVal); + } + return selectedGenres; + } + + function setSelectedGenres(parentSelector, genreList) { + if (!genreList) { + return; + } + var values = []; + $.each(genreList, function(index, value) { + values.push(value.toLowerCase()); + }); + var selectedVal = $('select', parentSelector).val(values); + } + + function initialize() { + loadGenres(); + } + + var me = { // This will be our singleton. + initialize: initialize, + getSelectedGenres: getSelectedGenres, + setSelectedGenres: setSelectedGenres, + reset: reset, + render: render, + loadGenres: loadGenres + }; + + return me; + + })(); +})(window,jQuery); diff --git a/web/app/views/clients/_instrumentSelector.html.erb b/web/app/views/clients/_instrumentSelector.html.erb new file mode 100644 index 000000000..2455a2079 --- /dev/null +++ b/web/app/views/clients/_instrumentSelector.html.erb @@ -0,0 +1,3 @@ + diff --git a/web/app/views/clients/_musician_filter.html.erb b/web/app/views/clients/_musician_filter.html.erb new file mode 100644 index 000000000..83eb139f6 --- /dev/null +++ b/web/app/views/clients/_musician_filter.html.erb @@ -0,0 +1,20 @@ +
+
Filter Musician List:
+ + +
+ <%= render "instrumentSelector" %> +
+ + + +
+ REFRESH +
+
diff --git a/web/app/views/clients/_musicians.html.erb b/web/app/views/clients/_musicians.html.erb index 4a6eac046..ce50ff6ad 100644 --- a/web/app/views/clients/_musicians.html.erb +++ b/web/app/views/clients/_musicians.html.erb @@ -1,7 +1,7 @@
+
-
<%= image_tag "content/icon_musicians.png", {:height => 19, :width => 19} %>
@@ -9,5 +9,18 @@

musicians

<%= render "screen_navigation" %>
-

This feature not yet implemented

+
+
+ <%= render :partial => "musician_filter" %> +
+
+
+
+
+
+ +
+ There are no musicians found. +
+