Merge branch 'cc-84-smart-playlist' into devel
Conflicts: airtime_mvc/application/controllers/PlaylistController.php airtime_mvc/application/models/Scheduler.php
This commit is contained in:
commit
9516771099
24 changed files with 4016 additions and 52 deletions
|
@ -60,7 +60,7 @@ var AIRTIME = (function(AIRTIME) {
|
|||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
visibleChosenItems = {};
|
||||
return count;
|
||||
};
|
||||
|
||||
|
@ -123,7 +123,7 @@ var AIRTIME = (function(AIRTIME) {
|
|||
data.push(visibleChosenItems[id]);
|
||||
}
|
||||
}
|
||||
|
||||
visibleChosenItems = {};
|
||||
return data;
|
||||
};
|
||||
|
||||
|
@ -441,7 +441,6 @@ var AIRTIME = (function(AIRTIME) {
|
|||
$tr = $(el).parent();
|
||||
data = $tr.data("aData");
|
||||
AIRTIME.library.dblClickAdd(data.id, data.ftype);
|
||||
//AIRTIME.playlist.fnAddItems([data.id], undefined, 'after');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -318,8 +318,14 @@ var AIRTIME = (function(AIRTIME){
|
|||
$("#side_playlist")
|
||||
.empty()
|
||||
.append(json.html);
|
||||
|
||||
|
||||
setUpPlaylist();
|
||||
|
||||
// functions in smart_playlistbuilder.js
|
||||
setupUI();
|
||||
appendAddButton();
|
||||
removeButtonCheck();
|
||||
|
||||
}
|
||||
|
||||
//sets events dynamically for playlist entries (each row in the playlist)
|
||||
|
@ -656,6 +662,10 @@ var AIRTIME = (function(AIRTIME){
|
|||
});
|
||||
};
|
||||
|
||||
mod.fnOpenPlaylist = function(json) {
|
||||
openPlaylist(json);
|
||||
};
|
||||
|
||||
mod.enableUI = function() {
|
||||
|
||||
$lib.unblock();
|
||||
|
@ -664,6 +674,7 @@ var AIRTIME = (function(AIRTIME){
|
|||
//Block UI changes the postion to relative to display the messages.
|
||||
$lib.css("position", "static");
|
||||
$pl.css("position", "static");
|
||||
setupUI();
|
||||
};
|
||||
|
||||
function playlistResponse(json){
|
||||
|
|
376
airtime_mvc/public/js/airtime/playlist/smart_playlistbuilder.js
Normal file
376
airtime_mvc/public/js/airtime/playlist/smart_playlistbuilder.js
Normal file
|
@ -0,0 +1,376 @@
|
|||
$(document).ready(function() {
|
||||
setSmartPlaylistEvents();
|
||||
|
||||
$(".playlist_type_help_icon").qtip({
|
||||
content: {
|
||||
text: "A static playlist will save the criteria and generate the playlist content immediately." +
|
||||
"This allows you to edit and view it in the Playlist Builder before adding it to a show.<br /><br />" +
|
||||
"A dynamic playlist will only save the criteria. The playlist content will get generated upon " +
|
||||
"adding it to a show. You will not be able to view and edit it in the Playlist Builder."
|
||||
},
|
||||
hide: {
|
||||
delay: 500,
|
||||
fixed: true
|
||||
},
|
||||
style: {
|
||||
border: {
|
||||
width: 0,
|
||||
radius: 4
|
||||
},
|
||||
classes: "ui-tooltip-dark ui-tooltip-rounded"
|
||||
},
|
||||
position: {
|
||||
my: "left bottom",
|
||||
at: "right center"
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
function setSmartPlaylistEvents() {
|
||||
var form = $('#smart-playlist-form');
|
||||
|
||||
form.find('.criteria_add').live("click", function(){
|
||||
var div = $('dd[id="sp_criteria-element"]').children('div:visible:last').next();
|
||||
|
||||
div.show();
|
||||
div.children().removeAttr('disabled');
|
||||
div = div.next();
|
||||
if (div.length === 0) {
|
||||
$(this).hide();
|
||||
}
|
||||
appendAddButton();
|
||||
removeButtonCheck();
|
||||
});
|
||||
|
||||
form.find('a[id^="criteria_remove"]').live("click", function(){
|
||||
var curr = $(this).parent();
|
||||
var curr_pos = curr.index();
|
||||
var list = curr.parent();
|
||||
var list_length = list.find("div:visible").length;
|
||||
var count = list_length - curr_pos;
|
||||
var next = curr.next();
|
||||
var add_button = form.find('a[id="criteria_add"]');
|
||||
var item_to_hide;
|
||||
|
||||
//remove error message from current row, if any
|
||||
var error_element = curr.find('span[class="errors sp-errors"]');
|
||||
if (error_element.is(':visible')) {
|
||||
error_element.remove();
|
||||
}
|
||||
|
||||
/* assign next row to current row for all rows below and including
|
||||
* the row getting removed
|
||||
*/
|
||||
for (var i=0; i<count; i++) {
|
||||
var criteria = next.find('[name^="sp_criteria_field"]').val();
|
||||
curr.find('[name^="sp_criteria_field"]').val(criteria);
|
||||
|
||||
var modifier = next.find('[name^="sp_criteria_modifier"]').val();
|
||||
populateModifierSelect(curr.find('[name^="sp_criteria_field"]'));
|
||||
curr.find('[name^="sp_criteria_modifier"]').val(modifier);
|
||||
|
||||
var criteria_value = next.find('[name^="sp_criteria_value"]').val();
|
||||
curr.find('[name^="sp_criteria_value"]').val(criteria_value);
|
||||
|
||||
var id = curr.find('[name^="sp_criteria"]').attr('id');
|
||||
var index = id.charAt(id.length-1);
|
||||
/* if current and next row have the extra criteria value
|
||||
* (for 'is in the range' modifier), then assign the next
|
||||
* extra value to current and remove that element from
|
||||
* next row
|
||||
*/
|
||||
if (curr.find('[name^="sp_criteria_extra"]').attr("disabled") != "disabled"
|
||||
&& next.find('[name^="sp_criteria_extra"]').attr("disabled") != "disabled") {
|
||||
|
||||
var criteria_extra = next.find('[name^="sp_criteria_extra"]').val();
|
||||
curr.find('[name^="sp_criteria_extra"]').val(criteria_extra);
|
||||
disableAndHideExtraField(next.find(':first-child'), index+1);
|
||||
|
||||
/* if only the current row has the extra criteria value,
|
||||
* then just remove the current row's extra criteria element
|
||||
*/
|
||||
} else if (curr.find('[name^="sp_criteria_extra"]').attr("disabled") != "disabled"
|
||||
&& next.find('[name^="sp_criteria_extra"]').attr("disabled") == "disabled") {
|
||||
disableAndHideExtraField(curr.find(':first-child'), index);
|
||||
|
||||
/* if only the next row has the extra criteria value,
|
||||
* then add the extra criteria element to current row
|
||||
* and assign next row's value to it
|
||||
*/
|
||||
} else if (next.find('[name^="sp_criteria_extra"]').attr("disabled") != "disabled") {
|
||||
criteria_extra = next.find('[name^="sp_criteria_extra"]').val();
|
||||
enableAndShowExtraField(curr.find(':first-child'), index);
|
||||
curr.find('[name^="sp_criteria_extra"]').val(criteria_extra);
|
||||
}
|
||||
|
||||
curr = next;
|
||||
next = curr.next();
|
||||
}
|
||||
|
||||
/* Disable the last visible row since it holds the values the user removed
|
||||
* Reset the values to empty and resize the criteria value textbox
|
||||
* in case the row had the extra criteria textbox
|
||||
*/
|
||||
item_to_hide = list.find('div:visible:last');
|
||||
item_to_hide.children().attr('disabled', 'disabled');
|
||||
item_to_hide.find('[name^="sp_criteria_field"]').val(0).end()
|
||||
.find('[name^="sp_criteria_modifier"]').val(0).end()
|
||||
.find('[name^="sp_criteria_value"]').val('');
|
||||
|
||||
sizeTextBoxes(item_to_hide.find('[name^="sp_criteria_value"]'), 'sp_extra_input_text', 'sp_input_text');
|
||||
item_to_hide.hide();
|
||||
|
||||
list.next().show();
|
||||
|
||||
// always put '+' button on the last enabled row
|
||||
appendAddButton();
|
||||
// remove the 'x' button if only one row is enabled
|
||||
removeButtonCheck();
|
||||
});
|
||||
|
||||
form.find('button[id="save_button"]').live("click", function(event){
|
||||
var playlist_type = form.find('input:radio[name=sp_type]:checked').val(),
|
||||
data = $('form').serializeArray(),
|
||||
save_action = 'Playlist/smart-playlist-criteria-save',
|
||||
playlist_id = $('input[id="pl_id"]').val();
|
||||
|
||||
$.post(save_action, {format: "json", data: data, pl_id: playlist_id}, function(data){
|
||||
callback(data, "save");
|
||||
});
|
||||
});
|
||||
|
||||
form.find('button[id="generate_button"]').live("click", function(event){
|
||||
var playlist_type = form.find('input:radio[name=sp_type]:checked').val(),
|
||||
data = $('form').serializeArray(),
|
||||
generate_action = 'Playlist/smart-playlist-generate',
|
||||
playlist_id = $('input[id="pl_id"]').val();
|
||||
|
||||
$.post(generate_action, {format: "json", data: data, pl_id: playlist_id}, function(data){
|
||||
callback(data, "generate");
|
||||
});
|
||||
});
|
||||
|
||||
form.find('button[id="shuffle_button"]').live("click", function(event){
|
||||
var playlist_type = form.find('input:radio[name=sp_type]:checked').val(),
|
||||
data = $('form').serializeArray(),
|
||||
shuffle_action = 'Playlist/smart-playlist-shuffle',
|
||||
playlist_id = $('input[id="pl_id"]').val();
|
||||
|
||||
$.post(shuffle_action, {format: "json", data: data, pl_id: playlist_id}, function(data){
|
||||
callback(data, "shuffle");
|
||||
});
|
||||
});
|
||||
|
||||
form.find('dd[id="sp_type-element"]').live("change", function(){
|
||||
setupUI();
|
||||
});
|
||||
|
||||
form.find('select[id^="sp_criteria"]:not([id^="sp_criteria_modifier"])').live("change", function(){
|
||||
var index_name = $(this).attr('id'),
|
||||
index_num = index_name.charAt(index_name.length-1);
|
||||
|
||||
// disable extra field and hide the span
|
||||
disableAndHideExtraField($(this), index_num);
|
||||
populateModifierSelect(this);
|
||||
});
|
||||
|
||||
form.find('select[id^="sp_criteria_modifier"]').live("change", function(){
|
||||
var criteria_value = $(this).next(),
|
||||
index_name = criteria_value.attr('id'),
|
||||
index_num = index_name.charAt(index_name.length-1);
|
||||
|
||||
if ($(this).val() == 'is in the range') {
|
||||
enableAndShowExtraField(criteria_value, index_num);
|
||||
} else {
|
||||
disableAndHideExtraField(criteria_value, index_num);
|
||||
}
|
||||
});
|
||||
|
||||
setupUI();
|
||||
appendAddButton();
|
||||
removeButtonCheck();
|
||||
}
|
||||
|
||||
function setupUI() {
|
||||
var playlist_type = $('input:radio[name=sp_type]:checked').val();
|
||||
if (playlist_type == "0") {
|
||||
$('button[id="generate_button"]').show();
|
||||
$('button[id="shuffle_button"]').show();
|
||||
$('#spl_sortable').unblock();
|
||||
$('#spl_sortable').css("position", "static");
|
||||
} else {
|
||||
$('button[id="generate_button"]').hide();
|
||||
$('button[id="shuffle_button"]').hide();
|
||||
$('#spl_sortable').block({
|
||||
message: "",
|
||||
theme: true,
|
||||
applyPlatformOpacityRules: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function enableAndShowExtraField(valEle, index) {
|
||||
var spanExtra = valEle.nextAll("#extra_criteria");
|
||||
spanExtra.children('#sp_criteria_extra_'+index).removeAttr("disabled");
|
||||
spanExtra.show();
|
||||
|
||||
//make value input smaller since we have extra element now
|
||||
var criteria_val = $('#sp_criteria_value_'+index);
|
||||
sizeTextBoxes(criteria_val, 'sp_input_text', 'sp_extra_input_text');
|
||||
}
|
||||
|
||||
function disableAndHideExtraField(valEle, index) {
|
||||
var spanExtra = valEle.nextAll("#extra_criteria");
|
||||
spanExtra.children('#sp_criteria_extra_'+index).val("").attr("disabled", "disabled");
|
||||
spanExtra.hide();
|
||||
|
||||
//make value input larger since we don't have extra field now
|
||||
var criteria_value = $('#sp_criteria_value_'+index);
|
||||
sizeTextBoxes(criteria_value, 'sp_extra_input_text', 'sp_input_text');
|
||||
}
|
||||
|
||||
function sizeTextBoxes(ele, classToRemove, classToAdd) {
|
||||
var form = $('#smart-playlist-form');
|
||||
if (ele.hasClass(classToRemove)) {
|
||||
ele.removeClass(classToRemove).addClass(classToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
function populateModifierSelect(e) {
|
||||
var criteria = $(e).val(),
|
||||
criteria_type = criteriaTypes[criteria],
|
||||
div = $(e);
|
||||
|
||||
$(e).next().children().remove();
|
||||
|
||||
if (criteria_type == 's') {
|
||||
$.each(stringCriteriaOptions, function(key, value){
|
||||
div.next().append($('<option></option>')
|
||||
.attr('value', key)
|
||||
.text(value));
|
||||
});
|
||||
} else {
|
||||
$.each(numericCriteriaOptions, function(key, value){
|
||||
div.next().append($('<option></option>')
|
||||
.attr('value', key)
|
||||
.text(value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function callback(data, type) {
|
||||
var form = $('#smart-playlist-form'),
|
||||
json = $.parseJSON(data);
|
||||
|
||||
form.find('span[class="errors sp-errors"]').remove();
|
||||
|
||||
if (json.result == "1") {
|
||||
form.find('.success').hide();
|
||||
$.each(json.errors, function(index, error){
|
||||
$.each(error.msg, function(index, message){
|
||||
$('#'+error.element).parent().append("<span class='errors sp-errors'>"+message+"</span>");
|
||||
});
|
||||
});
|
||||
} else {
|
||||
if (type == 'shuffle' || type == 'generate') {
|
||||
AIRTIME.playlist.fnOpenPlaylist(json);
|
||||
form = $('#smart-playlist-form');
|
||||
if (type == 'shuffle') {
|
||||
form.find('.success').text('Playlist shuffled');
|
||||
} else {
|
||||
form.find('.success').text('Smart playlist generated');
|
||||
}
|
||||
form.find('.success').show();
|
||||
form.find('#smart_playlist_options').removeClass("closed");
|
||||
} else {
|
||||
form.find('.success').text('Criteria saved');
|
||||
form.find('.success').show();
|
||||
}
|
||||
setTimeout('removeSuccessMsg()', 5000);
|
||||
}
|
||||
}
|
||||
|
||||
function removeSuccessMsg() {
|
||||
var form = $('#smart-playlist-form');
|
||||
form.find('.success').text('');
|
||||
form.find('.success').hide();
|
||||
}
|
||||
|
||||
function appendAddButton() {
|
||||
var rows = $('#smart-playlist-form');
|
||||
var add_button = "<a class='ui-button sp-ui-button-icon-only criteria_add'>" +
|
||||
"<span class='ui-icon ui-icon-plusthick'></span></a>";
|
||||
|
||||
rows.find('.criteria_add').remove();
|
||||
|
||||
if (rows.find('select[name^="sp_criteria_field"]:enabled').length > 1) {
|
||||
rows.find('select[name^="sp_criteria_field"]:enabled:last')
|
||||
.siblings('a[id^="criteria_remove"]')
|
||||
.after(add_button);
|
||||
} else {
|
||||
rows.find('select[name^="sp_criteria_field"]:enabled')
|
||||
.siblings('span[id="extra_criteria"]')
|
||||
.after(add_button);
|
||||
}
|
||||
}
|
||||
|
||||
function removeButtonCheck() {
|
||||
var rows = $('#smart-playlist-form');
|
||||
|
||||
if (rows.find('select[name^="sp_criteria_field"]:enabled').length == 1) {
|
||||
rows.find('a[id="criteria_remove_0"]').attr('disabled', 'disabled');
|
||||
rows.find('a[id="criteria_remove_0"]').hide();
|
||||
} else {
|
||||
rows.find('a[id="criteria_remove_0"]').removeAttr('disabled');
|
||||
rows.find('a[id="criteria_remove_0"]').show();
|
||||
}
|
||||
}
|
||||
|
||||
var criteriaTypes = {
|
||||
0 : "",
|
||||
"album_title" : "s",
|
||||
"artist_name" : "s",
|
||||
"bit_rate" : "n",
|
||||
"bpm" : "n",
|
||||
"comments" : "s",
|
||||
"composer" : "s",
|
||||
"conductor" : "s",
|
||||
"utime" : "n",
|
||||
"mtime" : "n",
|
||||
"disc_number" : "n",
|
||||
"genre" : "s",
|
||||
"isrc_number" : "s",
|
||||
"label" : "s",
|
||||
"language" : "s",
|
||||
"length" : "n",
|
||||
"lyricist" : "s",
|
||||
"mood" : "s",
|
||||
"name" : "s",
|
||||
"orchestra" : "s",
|
||||
"radio_station_name" : "s",
|
||||
"rating" : "n",
|
||||
"sample_rate" : "n",
|
||||
"soundcloud_id" : "n",
|
||||
"track_title" : "s",
|
||||
"track_num" : "n",
|
||||
"year" : "n"
|
||||
};
|
||||
|
||||
var stringCriteriaOptions = {
|
||||
"0" : "Select modifier",
|
||||
"contains" : "contains",
|
||||
"does not contain" : "does not contain",
|
||||
"is" : "is",
|
||||
"is not" : "is not",
|
||||
"starts with" : "starts with",
|
||||
"ends with" : "ends with"
|
||||
};
|
||||
|
||||
var numericCriteriaOptions = {
|
||||
"0" : "Select modifier",
|
||||
"is" : "is",
|
||||
"is not" : "is not",
|
||||
"is greater than" : "is greater than",
|
||||
"is less than" : "is less than",
|
||||
"is in the range" : "is in the range"
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue