From 852014124062af3ba7de98d658f457d6c8e7963c Mon Sep 17 00:00:00 2001 From: denise Date: Mon, 10 Sep 2012 17:17:09 -0400 Subject: [PATCH] CC-4282: Library ->"Uploaded From" -> Submitting data in wrong format causes "Processing ..." message pop up for a while -implemented advanced search validation -data only gets sent to server if all fields are valid --- .../public/js/airtime/library/library.js | 145 +++++++++++++++++- .../plugin/dataTables.columnFilter.js | 69 +++++---- 2 files changed, 181 insertions(+), 33 deletions(-) diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index ba7c0f574..321276289 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -479,14 +479,13 @@ var AIRTIME = (function(AIRTIME) { "fnServerData": function ( sSource, aoData, fnCallback ) { var type; - aoData.push( { name: "format", value: "json"} ); //push whether to search files/playlists or all. type = $("#library_display_type").find("select").val(); type = (type === undefined) ? 0 : type; aoData.push( { name: "type", value: type} ); - + $.ajax( { "dataType": 'json', "type": "POST", @@ -970,3 +969,145 @@ function addQtipToSCIcons(){ } }); } + +/* + * Called from dataTables.columnFilter.js + */ +function validateAdvancedSearch(divs) { + var valid = true, + fieldName, + fields, + searchTerm = Array(), + searchTermType, + regExpr, + timeRegEx = "\\d{2}[:]([0-5]){1}([0-9]){1}[:]([0-5]){1}([0-9]){1}([.]\\d{1,6})?", + dateRegEx = "\\d{4}[-]\\d{2}[-]\\d{2}?", + integerRegEx = "^\\d+$", + numericRegEx = "^\\d+[.]?\\d*$"; + + searchTerm[0] = ""; + searchTerm[1] = ""; + + $.each(divs, function(i, div){ + fieldName = $(div).children(':nth-child(2)').attr('id'); + fields = $(div).children().find('input'); + searchTermType = validationTypes[fieldName]; + + $.each(fields, function(i, field){ + searchTerm[i] = $(field).val(); + + if (searchTerm[i] !== "") { + + if (searchTermType === "l") { + regExpr = new RegExp("^" +timeRegEx+ "$"); + } else if (searchTermType === "t") { + var pieces = searchTerm[i].split(" "); + if (pieces.length === 2) { + regExpr = new RegExp("^" +dateRegEx+ " " +timeRegEx+ "$"); + } else if (pieces.length === 1) { + regExpr = new RegExp("^" +dateRegEx+ "$"); + } + } else if (searchTermType === "i") { + regExpr = new RegExp(integerRegEx); + } else if (searchTermType === "n") { + regExpr = new RegExp(numericRegEx); + if (searchTerm[i].charAt(0) === "-") { + searchTerm[i] = searchTerm[i].substr(1); + } + } + + //string fields do not need validation + if (searchTermType !== "s") { + valid = regExpr.test(searchTerm[i]); + } + + addRemoveValidationIcons(valid, $(field)); + + /* Empty fields should not have valid/invalid indicator + * Range values are considered valid even if only the + * 'From' value is provided. Therefore, if the 'To' value + * is empty but the 'From' value is not empty we need to + * keep the validation icon on screen. + */ + } else if (searchTerm[0] === "" && searchTerm[1] !== "" || + searchTerm[0] === "" && searchTerm[1] === ""){ + if ($(field).closest('div').children(':last-child').hasClass('checked-icon') || + $(field).closest('div').children(':last-child').hasClass('not-available-icon')) { + $(field).closest('div').children(':last-child').remove(); + } + } + + if (!valid) { + return false; + } + }); + + if (!valid) { + return false; + } + }); + + return valid; +} + +function addRemoveValidationIcons(valid, field) { + var validIndicator = "", + invalidIndicator = ""; + + if (valid) { + if (!field.closest('div').children(':last-child').hasClass('checked-icon')) { + //remove invalid icon before adding valid icon + if (field.closest('div').children(':last-child').hasClass('not-available-icon')) { + field.closest('div').children(':last-child').remove(); + } + field.closest('div').append(validIndicator); + } + } else { + if (!field.closest('div').children(':last-child').hasClass('not-available-icon')) { + //remove valid icon before adding invalid icon + if (field.closest('div').children(':last-child').hasClass('checked-icon')) { + field.closest('div').children(':last-child').remove(); + } + field.closest('div').append(invalidIndicator); + } + } +} + +/* Validation types: + * s => string + * i => integer + * n => numeric (positive/negative, whole/decimals) + * t => timestamp + * l => length + */ +var validationTypes = { + "album_title" : "s", + "artist_name" : "s", + "bit_rate" : "i", + "bpm" : "i", + "comments" : "s", + "composer" : "s", + "conductor" : "s", + "copyright" : "s", + "utime" : "t", + "mtime" : "t", + "lptime" : "t", + "disc_number" : "i", + "genre" : "s", + "isrc_number" : "s", + "label" : "s", + "language" : "s", + "length" : "l", + "lyricist" : "s", + "mood" : "s", + "name" : "s", + "orchestra" : "s", + "owner_id" : "i", + "rating" : "i", + "replay_gain" : "n", + "sample_rate" : "i", + "track_title" : "s", + "track_number" : "i", + "info_url" : "s", + "year" : "i" +}; diff --git a/airtime_mvc/public/js/datatables/plugin/dataTables.columnFilter.js b/airtime_mvc/public/js/datatables/plugin/dataTables.columnFilter.js index 4f36c9a71..d1c1122fd 100644 --- a/airtime_mvc/public/js/datatables/plugin/dataTables.columnFilter.js +++ b/airtime_mvc/public/js/datatables/plugin/dataTables.columnFilter.js @@ -103,7 +103,8 @@ label = label.replace(/(^\s*)|(\s*$)/g, ""); var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch; var search_init = 'search_init '; - var inputvalue = label; + //var inputvalue = label; + var inputvalue = ''; if (currentFilter != '' && currentFilter != '^') { if (bIsNumber && currentFilter.charAt(0) == '^') inputvalue = currentFilter.substr(1); //ignore trailing ^ @@ -133,29 +134,32 @@ }); } else { input.keyup(function () { - if (oTable.fnSettings().oFeatures.bServerSide && iFilterLength != 0) { - //If filter length is set in the server-side processing mode - //Check has the user entered at least iFilterLength new characters - - var currentFilter = oTable.fnSettings().aoPreSearchCols[index].sSearch; - var iLastFilterLength = $(this).data("dt-iLastFilterLength"); - if (typeof iLastFilterLength == "undefined") - iLastFilterLength = 0; - var iCurrentFilterLength = this.value.length; - if (Math.abs(iCurrentFilterLength - iLastFilterLength) < iFilterLength - //&& currentFilter.length == 0 //Why this? - ) { - //Cancel the filtering - return; - } - else { - //Remember the current filter length - $(this).data("dt-iLastFilterLength", iCurrentFilterLength); + var advSearchFields = $("div#advanced_search").children(':visible'); + if(validateAdvancedSearch(advSearchFields)){ + if (oTable.fnSettings().oFeatures.bServerSide && iFilterLength != 0) { + //If filter length is set in the server-side processing mode + //Check has the user entered at least iFilterLength new characters + + var currentFilter = oTable.fnSettings().aoPreSearchCols[index].sSearch; + var iLastFilterLength = $(this).data("dt-iLastFilterLength"); + if (typeof iLastFilterLength == "undefined") + iLastFilterLength = 0; + var iCurrentFilterLength = this.value.length; + if (Math.abs(iCurrentFilterLength - iLastFilterLength) < iFilterLength + //&& currentFilter.length == 0 //Why this? + ) { + //Cancel the filtering + return; + } + else { + //Remember the current filter length + $(this).data("dt-iLastFilterLength", iCurrentFilterLength); + } } + /* Filter on the column (the index) of this element */ + oTable.fnFilter(this.value, _fnColumnIndex(index), regex, smart); //Issue 37 + fnOnFiltered(); } - /* Filter on the column (the index) of this element */ - oTable.fnFilter(this.value, _fnColumnIndex(index), regex, smart); //Issue 37 - fnOnFiltered(); }); } @@ -168,7 +172,8 @@ input.blur(function () { if (this.value == "") { $(this).addClass("search_init"); - this.value = asInitVals[index]; + //this.value = asInitVals[index]; + this.value = ""; } }); } @@ -228,14 +233,16 @@ $('#' + sFromId + ',#' + sToId, th).keyup(function () { - - var iMin = document.getElementById(sFromId).value * 1; - var iMax = document.getElementById(sToId).value * 1; - if (iMin != 0 && iMax != 0 && iMin > iMax) - return; - - oTable.fnDraw(); - fnOnFiltered(); + var advSearchFields = $("div#advanced_search").children(':visible'); + if(validateAdvancedSearch(advSearchFields)){ + var iMin = document.getElementById(sFromId).value * 1; + var iMax = document.getElementById(sToId).value * 1; + if (iMin != 0 && iMax != 0 && iMin > iMax) + return; + + oTable.fnDraw(); + fnOnFiltered(); + } });