views:

117

answers:

2

I am in the process of stripping down some code I've written for a Time Frame selector function that filters search results based on a selected Time Frame (Last Month, Last Quarter & Last Year) by hiding all irrelevant results based on when they were created. The function is called by a GET variable submitted on form submit ?time_frame_query=Last+Month

Now the code as is works, which is a start. However I feel it could be greatly improved, and unfortunately I have exhausted all options trying to do this myself. The problem I am having is that by the time I get to writing the functions for the Last Year filter, I am having to write a huge amount of code which I feel isn't entirely necessary. I have toyed with the idea of putting all the month variables into an array then putting together a specific "Last Month" "Last Quarter" "Last Year" function that will do the work for me. But again given my current knowledge of JS/jQuery, I simply do not know how to go about doing this.

Below is a snippet of code that I feel is relevant to my question and also helps illustrate the problem I am facing. Please let me know if you need to see any more.

EDIT: Thanks to Doug the entire working code can be found here: http://pastie.org/private/wl2qvnyar5xpibu4ot1lig

Any help/advice would be greatly appreciated.

var timezone = "Australia/ACT";
$.getJSON("http://json-time.appspot.com/time.json?tz="+timezone+"&callback=?",
  function(data){
    var datetime = data.datetime
      var date = datetime.split(" ")
      var day = date[1]
      var month = date[2]
      var year = date[3]
      var prevYear = year - 1
      var jan = 'Jan'
      //etc etc etc
      var dec = 'Dec'
      var timeFrame = $.getUrlVar('time_frame_query');
      switch(timeFrame){
      //****************************
      // Begin Last Quarter function
      //****************************
      case 'Last+Quarter': 
        switch(month){
          case 'Jan':
            $('#searchResults div.'+oct+prevYear+',#searchResults div.'+nov+prevYear+',#searchResults div.'+dec+prevYear+',#searchResults div.'+jan+year).show();
            break;
          case 'Feb':
            $('#searchResults div.'+nov+prevYear+',#searchResults div.'+dec+prevYear+',#searchResults div.'+jan+year+',#searchResults div.'+feb+year).show();
            break;
          case 'Mar':
            $('#searchResults div.'+dec+prevYear+',#searchResults div.'+jan+year+',#searchResults div.'+feb+year+',#searchResults div.'+mar+year).show();
            break;
          case 'Apr':
            $('#searchResults div.'+jan+year+',#searchResults div.'+feb+year+',#searchResults div.'+mar+year+',#searchResults div.'+apr+year).show();
            break;
            // etc etc etc
        }
        break;

Appologies for the poorly formatted code above, first submission to this site. WYSIWYG FTL! :(

+1  A: 

Try datejs, library that parses date strings and return actual dates. It is really flexible and understand last/next concept. It doesn't know what quarter is though so you might have to tweak it, there's an API if I'm not mistaken.

vava
Looks promising. Thanks for the link Vava. However, I would like to steer away from adding additional JS library's to the site. This will be used as a last resort for sure. I appreciate your input.
JoshG
+1  A: 

OK, here is my best shot for how tired I am :) A couple things in general. You need to end each line in a semicolon, that is really important. Also, my code assumes a four digit year (2009 vs 09). Without the rest of your site, its hard to test. Please let me know if you have any questions:

$(document).ready(function(){
  $.extend({
    getUrlVars: function(){
      var vars = [], hash;
      var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
      for(var i = 0; i < hashes.length; i++)
      {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
      }
      return vars;
    },
    getUrlVar: function(name){
      return $.getUrlVars()[name];
    }
  });
  var timezone = "Australia/ACT";
  $.getJSON("http://json-time.appspot.com/time.json?callback=?",
    { tz: timezone },
    function(data) {
      var datetime   = data.datetime,
          date       = datetime.split(" "),
          month      = date[2],
          year       = date[3],
          months     = ['Jan', 'Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
          curr_month = $.inArray(month, months), // Zero based return
          curr       = new Date(year, curr_month),
          time_frame = $.getUrlVar('time_frame_query');

      $('#searchResults p.report-date').each(function(){
        var reportDate  = $(this).text(),
            dateExtract = reportDate.split(" "),
            month       = dateExtract[1],
            year        = dateExtract[2];

        $(this).parent().addClass(month + year).hide();
      });

      var buildSelector = function(date) {
          return "div." + months[date.getMonth()] + date.getFullYear();
      }

      var selectorRange = function(monthStart, monthRange, yearStart){
        var range = [];
        for(var i = monthRange; i <= 0; i++){
          range.push( buildSelector(new Date(yearStart, monthStart + i)));
        };
        return range;
      }

      var searchResults = $('#searchResults')[0];

      switch(time_frame){
        case 'Last+Month': 
          $( selectorRange( curr_month, -1, year).join(), searchResults ).show();
          break;

        case 'Last+Quarter': 
          $( selectorRange( curr_month, -3, year).join(), searchResults ).show();
          break;

        case 'Last+Year':
          $( selectorRange( curr_month, -12, year).join(), searchResults ).show();
          break;
      }
    });
});
Doug Neiner
Ok, just gave it a test then. On line 37 you forgot to update the variables `for $(this).parent().addClass(m+y).hide();`. No problems though I simply added the correct variables to fix that, unfortunately now firebug is throwing the following error: **Error: uncaught exception: [Exception... "Could not convert JavaScript argument arg 0" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js :: anonymous :: line 22" data: no]** , any ideas?Thanks a whole lot for your help, Doug! :)
JoshG
Ok, I found one error in my code in addition to the error you spotted (which I also fixed). Try this, though I fear it will still throw the same error. But at least we can narrow it down. Then let me know!
Doug Neiner
Hmmmm, yeah same error, I just tried another version of the jQuery plugin jquery-1.3.2.min, which now returns the following error **Error: this[H].style is undefined Source File: jquery-1.3.2.min.js Line: 19** I'll keep digging to see what I uncover.
JoshG
Just had an idea, http://pastie.org/private/prbdmmfyzdcbyoffkt3lg here's the entire source code of the page I am using to test this script before it's implemented into a live site. Just so you can get an idea of how it'll work. Hope it helps.
JoshG
Awesome... making some food and I'll look at it. Should be able to get it working in a few min. Thanks!
Doug Neiner
Fixed! Two changes. You need to use jQuery 1.3.2 (1.2.6 is *really* legacy :) and use my updated answer. I had messed up the `selectorRange` function.
Doug Neiner
Ah, Doug that's the trick. Very well done mate! :)
JoshG