Tycoon Talk
Become a Big fish!
The number 1 forum for online business!
Post topics, ask questions, share your knowledge.
Tycoon Talk is part of Freelancer.com - find skilled workers online at a fraction of the cost.

JavaScript Forum


You are currently viewing our JavaScript Forum as a guest. Please register to participate.
Login



Reply
Calendar alteration; Month and Year selected by dropdown box
Old 05-21-2010, 08:54 PM Calendar alteration; Month and Year selected by dropdown box
Experienced Talker

Posts: 37
Trades: 0
I'm using the calender as found by http://www.softcomplex.com/products/tigra_calendar/ for inputting of birthdate; However I'm trying to convert it so that a drop down box is used for the month and year rather than clicking the arrows. I'm fairly new to Javascript and learning a lot but I can't seem to find a way to do this. There are some theories used that I don't understand yet.

Anyone have the time to convert this script for a drop down box? I'm sure I would learn a lesson or two from the code you come up with because I've been trying for hours.

Here is the .js files with my modifications so far:
PHP Code:
// Tigra Calendar v4.0.3 (01/12/2009) American (mm/dd/yyyy)
// http://www.softcomplex.com/products/tigra_calendar/
// Public Domain Software... You're welcome.

// default settins
var A_TCALDEF = {
    
'months' : ['January''February''March''April''May''June''July''August''September''October''November''December'],
    
'weekdays' : ['Su''Mo''Tu''We''Th''Fr''Sa'],
    
'yearscroll'true// show year scroller
    
'weekstart'0// first day of week: 0-Su or 1-Mo
    
'centyear'  70// 2 digit years less than 'centyear' are in 20xx, othewise in 19xx.
    
'imgpath' '_images/cal/' // directory with calendar images
}
// date parsing function
function f_tcalParseDate (s_date) {

    var 
re_date = /^\s*(\d{1,2})\/(\d{1,2})\/(\d{2,4})\s*$/;
    if (!
re_date.exec(s_date))
        return 
alert ("Invalid date: '" s_date "'.\nAccepted format is mm/dd/yyyy.")
    var 
n_day Number(RegExp.$2),
        
n_month Number(RegExp.$1),
        
n_year Number(RegExp.$3);
    
    if (
n_year 100)
        
n_year += (n_year this.a_tpl.centyear 2000 1900);
    if (
n_month || n_month 12)
        return 
alert ("Invalid month value: '" n_month "'.\nAllowed range is 01-12.");
    var 
d_numdays = new Date(n_yearn_month0);
    if (
n_day d_numdays.getDate())
        return 
alert("Invalid day of month value: '" n_day "'.\nAllowed range for selected month is 01 - " d_numdays.getDate() + "."); 
    
    return new 
Date (n_yearn_month 1n_day);
}
// date generating function
function f_tcalGenerDate (d_date) {
//Set Birthdate field to green and good before returning value
setRegisterField ("birthdate""valid"); // Set birthdate to valid
checkFormSubmittable(); // Enable submit button if all is good
    
return (
         (
d_date.getMonth() < '0' '') + (d_date.getMonth() + 1) + "/"
        
+ (d_date.getDate() < 10 '0' '') + d_date.getDate() + "/"
        
d_date.getFullYear()
    );
}

// implementation
function tcal (a_cfga_tpl) {
    
// apply default template if not specified
    
if (!a_tpl)
        
a_tpl A_TCALDEF;

    
// register in global collections
    
if (!window.A_TCALS)
        
window.A_TCALS = [];
    if (!
window.A_TCALSIDX)
        
window.A_TCALSIDX = [];
    
    
this.s_id a_cfg.id a_cfg.id A_TCALS.length;
    
window.A_TCALS[this.s_id] = this;
    
window.A_TCALSIDX[window.A_TCALSIDX.length] = this;
    
    
// assign methods
    
this.f_show f_tcalShow;
    
this.f_hide f_tcalHide;
    
this.f_toggle f_tcalToggle;
    
this.f_update f_tcalUpdate;
    
this.f_relDate f_tcalRelDate;
    
this.f_parseDate f_tcalParseDate;
    
this.f_generDate f_tcalGenerDate;
    
    
// create calendar icon
    
this.s_iconId 'tcalico_' this.s_id;
    
this.e_icon f_getElement(this.s_iconId);
    if (!
this.e_icon) {
        
document.write('<img src="' a_tpl.imgpath 'cal.gif" id="' this.s_iconId '" onclick="A_TCALS[\'' this.s_id '\'].f_toggle()" class="tcalIcon" alt="Open Calendar" />');
        
this.e_icon f_getElement(this.s_iconId);
    }
    
// save received parameters
    
this.a_cfg a_cfg;
    
this.a_tpl a_tpl;
}

function 
f_tcalShow (d_date) {

setRegisterField ("birthdate""invalid");
    
// find input field
    
if (!this.a_cfg.controlname)
        throw(
"TC: control name is not specified");
    if (
this.a_cfg.formname) {
        var 
e_form document.forms[this.a_cfg.formname];
        if (!
e_form)
            throw(
"TC: form '" this.a_cfg.formname "' can not be found");
        
this.e_input e_form.elements[this.a_cfg.controlname];
    }
    else
        
this.e_input f_getElement(this.a_cfg.controlname);

    if (!
this.e_input || !this.e_input.tagName || this.e_input.tagName != 'INPUT')
        throw(
"TC: element '" this.a_cfg.controlname "' does not exist in "
            
+ (this.a_cfg.formname "form '" this.a_cfg.controlname "'" 'this document'));

// Ensure color status of Birthdate field is current
if (this.e_input.value) {setRegisterField ("birthdate""valid") };
if (!
this.e_input.value) {setRegisterField ("birthdate""invalid") };

//alert (this.e_input.value);

    // dynamically create HTML elements if needed
    
this.e_div f_getElement('tcal');
    if (!
this.e_div) {
        
this.e_div document.createElement("DIV");
        
this.e_div.id 'tcal';
        
document.body.appendChild(this.e_div);
    }
    
this.e_shade f_getElement('tcalShade');
    if (!
this.e_shade) {
        
this.e_shade document.createElement("DIV");
        
this.e_shade.id 'tcalShade';
        
document.body.appendChild(this.e_shade);
    }
    
this.e_iframe =  f_getElement('tcalIF')
    if (
b_ieFix && !this.e_iframe) {
        
this.e_iframe document.createElement("IFRAME");
        
this.e_iframe.style.filter 'alpha(opacity=0)';
        
this.e_iframe.id 'tcalIF';
        
this.e_iframe.src this.a_tpl.imgpath 'pixel.gif';
        
document.body.appendChild(this.e_iframe);
    }
    
    
// hide all calendars
    
f_tcalHideAll();

    
// generate HTML and show calendar
    
this.e_icon f_getElement(this.s_iconId);
    if (!
this.f_update())
        return;

    
this.e_div.style.visibility 'visible';
    
this.e_shade.style.visibility 'visible';
    if (
this.e_iframe)
        
this.e_iframe.style.visibility 'visible';

    
// change icon and status
    
this.e_icon.src this.a_tpl.imgpath 'no_cal.gif';
    
this.e_icon.title 'Close Calendar';
    
this.b_visible true;
}

function 
f_tcalHide (n_date) {
    if (
n_date)
        
this.e_input.value this.f_generDate(new Date(n_date));

    
// no action if not visible
    
if (!this.b_visible)
        return;

    
// hide elements
    
if (this.e_iframe)
        
this.e_iframe.style.visibility 'hidden';
    if (
this.e_shade)
        
this.e_shade.style.visibility 'hidden';
    
this.e_div.style.visibility 'hidden';
    
    
// change icon and status
    
this.e_icon f_getElement(this.s_iconId);
    
this.e_icon.src this.a_tpl.imgpath 'cal.gif';
    
this.e_icon.title 'Open Calendar';
    
this.b_visible false;
}

function 
f_tcalToggle () {
    return 
this.b_visible this.f_hide() : this.f_show();
}

function 
f_tcalUpdate (d_date) {
    
    var 
d_today this.a_cfg.today this.f_parseDate(this.a_cfg.today) : f_tcalResetTime(new Date());
    var 
d_selected this.e_input.value == ''
        
? (this.a_cfg.selected this.f_parseDate(this.a_cfg.selected) : d_today)
        : 
this.f_parseDate(this.e_input.value);

    
// figure out date to display
    
if (!d_date)
        
// selected by default
        
d_date d_selected;
    else if (
typeof(d_date) == 'number')
        
// get from number
        
d_date f_tcalResetTime(new Date(d_date));
    else if (
typeof(d_date) == 'string')
        
// parse from string
        
this.f_parseDate(d_date);
        
    if (!
d_date) return false;

    
// first date to display
    
var d_firstday = new Date(d_date);
    
d_firstday.setDate(1);
    
d_firstday.setDate(- (d_firstday.getDay() - this.a_tpl.weekstart) % 7);
    
    var 
a_classs_html '<table class="ctrl"><tbody><tr><select name="monthPick" ';
//alert ("here: " + A_TCALDEF.months[1]);
for (loop 0loop<12loop++) {

    
s_html += '<option value="' loop '">' A_TCALDEF.months[loop] + '</option>'
}
    
s_html += '</select><select name = "yearPick" ' this.f_relDate(d_date1'y')

for (
loop 1900loop<2000loop++) {
    
s_html += '<option value="' loop '">' loop '</option>'
}
    
    
s_html += '</select>'




//+'<select><option>September</option><option>October</option>'
//+ '<select><option>2009</option><option>2008</option'// + d_date.getFullYear()






'</tr></tbody></table><table><tbody><tr class="wd">';


/*
    var a_class, s_html = '<table class="ctrl"><tbody><tr>'
        + (this.a_tpl.yearscroll ? '<td' + this.f_relDate(d_date, -1, 'y') + ' title="Previous Year"><img src="' + this.a_tpl.imgpath + 'prev_year.gif" /></td>' : '')
        + '<td' + this.f_relDate(d_date, -1) + ' title="Previous Month"><img src="' + this.a_tpl.imgpath + 'prev_mon.gif" /></td><th>'
        + this.a_tpl.months[d_date.getMonth()] + ' ' + d_date.getFullYear()
            + '</th><td' + this.f_relDate(d_date, 1) + ' title="Next Month"><img src="' + this.a_tpl.imgpath + 'next_mon.gif" /></td>'
        + (this.a_tpl.yearscroll ? '<td' + this.f_relDate(d_date, 1, 'y') + ' title="Next Year"><img src="' + this.a_tpl.imgpath + 'next_year.gif" /></td></td>' : '')
        + '</tr></tbody></table><table><tbody><tr class="wd">';
*/



// print weekdays titles
    
for (var 07i++)
        
s_html += '<th>' this.a_tpl.weekdays[(this.a_tpl.weekstart i) % 7] + '</th>';
    
s_html += '</tr>' ;

    
// print calendar table
    
var n_daten_monthd_current = new Date(d_firstday);
    while (
d_current.getMonth() == d_date.getMonth() ||
        
d_current.getMonth() == d_firstday.getMonth()) {
    
        
// print row heder
        
s_html +='<tr>';
        for (var 
n_wday 0n_wday 7n_wday++) {

            
a_class = [];
            
n_date  d_current.getDate();
            
n_month d_current.getMonth();

            
// other month
            
if (d_current.getMonth() != d_date.getMonth())
                
a_class[a_class.length] = 'othermonth';
            
// weekend
            
if (d_current.getDay() == || d_current.getDay() == 6)
                
a_class[a_class.length] = 'weekend';
            
// today
            
if (d_current.valueOf() == d_today.valueOf())
                
a_class[a_class.length] = 'today';
            
// selected
            
if (d_current.valueOf() == d_selected.valueOf())
                
a_class[a_class.length] = 'selected';

            
s_html += '<td onclick="A_TCALS[\'' this.s_id '\'].f_hide(' d_current.valueOf() + ')"' + (a_class.length ' class="' a_class.join(' ') + '">' '>') + n_date '</td>'

            
d_current.setDate(++n_date);
            while (
d_current.getDate() != n_date && d_current.getMonth() == n_month) {
                
d_current.setHours(d_current.getHours 1);
                
d_current f_tcalResetTime(d_current);
            }
        }
        
// print row footer
        
s_html +='</tr>';
    }
    
s_html +='</tbody></table>';
    
    
// update HTML, positions and sizes
    
this.e_div.innerHTML s_html;

    var 
n_width  this.e_div.offsetWidth;
    var 
n_height this.e_div.offsetHeight;
    var 
n_top  f_getPosition (this.e_icon'Top') + this.e_icon.offsetHeight;
    var 
n_left f_getPosition (this.e_icon'Left') - n_width this.e_icon.offsetWidth;
    if (
n_left 0n_left 0;
    
    
this.e_div.style.left n_left 'px';
    
this.e_div.style.top  n_top 'px';

    
this.e_shade.style.width = (n_width 8) + 'px';
    
this.e_shade.style.left = (n_left 1) + 'px';
    
this.e_shade.style.top = (n_top 1) + 'px';
    
this.e_shade.innerHTML b_ieFix
        
'<table><tbody><tr><td rowspan="2" colspan="2" width="6"><img src="' this.a_tpl.imgpath 'pixel.gif"></td><td width="7" height="7" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' this.a_tpl.imgpath 'shade_tr.png\', sizingMethod=\'scale\');"><img src="' this.a_tpl.imgpath 'pixel.gif"></td></tr><tr><td height="' + (n_height 7) + '" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' this.a_tpl.imgpath 'shade_mr.png\', sizingMethod=\'scale\');"><img src="' this.a_tpl.imgpath 'pixel.gif"></td></tr><tr><td width="7" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' this.a_tpl.imgpath 'shade_bl.png\', sizingMethod=\'scale\');"><img src="' this.a_tpl.imgpath 'pixel.gif"></td><td style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' this.a_tpl.imgpath 'shade_bm.png\', sizingMethod=\'scale\');" height="7" align="left"><img src="' this.a_tpl.imgpath 'pixel.gif"></td><td style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' this.a_tpl.imgpath 'shade_br.png\', sizingMethod=\'scale\');"><img src="' this.a_tpl.imgpath 'pixel.gif"></td></tr><tbody></table>'
        
'<table><tbody><tr><td rowspan="2" width="6"><img src="' this.a_tpl.imgpath 'pixel.gif"></td><td rowspan="2"><img src="' this.a_tpl.imgpath 'pixel.gif"></td><td width="7" height="7"><img src="' this.a_tpl.imgpath 'shade_tr.png"></td></tr><tr><td background="' this.a_tpl.imgpath 'shade_mr.png" height="' + (n_height 7) + '"><img src="' this.a_tpl.imgpath 'pixel.gif"></td></tr><tr><td><img src="' this.a_tpl.imgpath 'shade_bl.png"></td><td background="' this.a_tpl.imgpath 'shade_bm.png" height="7" align="left"><img src="' this.a_tpl.imgpath 'pixel.gif"></td><td><img src="' this.a_tpl.imgpath 'shade_br.png"></td></tr><tbody></table>';
    
    if (
this.e_iframe) {
        
this.e_iframe.style.left n_left 'px';
        
this.e_iframe.style.top  n_top 'px';
        
this.e_iframe.style.width = (n_width 6) + 'px';
        
this.e_iframe.style.height = (n_height 6) +'px';
    }
    return 
true;
}

function 
f_getPosition (e_elemRefs_coord) {
    var 
n_pos 0n_offset,
        
e_elem e_elemRef;

    while (
e_elem) {
        
n_offset e_elem["offset" s_coord];
        
n_pos += n_offset;
        
e_elem e_elem.offsetParent;
    }
    
// margin correction in some browsers
    
if (b_ieMac)
        
n_pos += parseInt(document.body[s_coord.toLowerCase() + 'Margin']);
    else if (
b_safari)
        
n_pos -= n_offset;
    
    
e_elem e_elemRef;
    while (
e_elem != document.body) {
        
n_offset e_elem["scroll" s_coord];
        if (
n_offset && e_elem.style.overflow == 'scroll')
            
n_pos -= n_offset;
        
e_elem e_elem.parentNode;
    }
    return 
n_pos;
}

function 
f_tcalRelDate (d_dated_diffs_units) {
    var 
s_units = (s_units == 'y' 'FullYear' 'Month');
    var 
d_result = new Date(d_date);
    
d_result['set' s_units](d_date['get' s_units]() + d_diff);
    if (
d_result.getDate() != d_date.getDate())
        
d_result.setDate(0);
    return 
' onclick="A_TCALS[\'' this.s_id '\'].f_update(' d_result.valueOf() + ')"';
}

function 
f_tcalHideAll () {
    for (var 
0window.A_TCALSIDX.lengthi++)
        
window.A_TCALSIDX[i].f_hide();
}

function 
f_tcalResetTime (d_date) {
    
d_date.setHours(0);
    
d_date.setMinutes(0);
    
d_date.setSeconds(0);
    
d_date.setMilliseconds(0);
    return 
d_date;
}

f_getElement document.all ?
    function (
s_id) { return document.all[s_id] } :
    function (
s_id) { return document.getElementById(s_id) };

if (
document.addEventListener)
    
window.addEventListener('scroll'f_tcalHideAllfalse);
if (
window.attachEvent)
    
window.attachEvent('onscroll'f_tcalHideAll);
    
// global variables
var s_userAgent navigator.userAgent.toLowerCase(),
    
re_webkit = /WebKit\/(\d+)/i;
var 
b_mac s_userAgent.indexOf('mac') != -1,
    
b_ie5 s_userAgent.indexOf('msie 5') != -1,
    
b_ie6 s_userAgent.indexOf('msie 6') != -&& s_userAgent.indexOf('opera') == -1;
var 
b_ieFix b_ie5 || b_ie6,
    
b_ieMac  b_mac && b_ie5,
    
b_safari b_mac && re_webkit.exec(s_userAgent) && Number(RegExp.$1) < 500

The CSS file and images remain the same, although the arrows are not used anymore. My notes so far from what I've figured out:

calling "this.f_relDate(d_date, -1)" will return text of a javascript command including the ONCLICK=" " tag to set the calender back a day. the "-1" can be changed to go back more than one day, likewise the - can be removed to go forward. It affects years if you call this.f_relDate(d_date, -1, "y").

My idea was to have an ONCHANGE event handler on the SELECT list box which takes the current year displayed and subtracts the current setting on the listbox and calls the above mentioned function with the correct offset to get the calender to the date selected.

The concept thats confusing me is all the use of "this". I don't understand where "this" is coming from, I know how to use "this" and that it changes with the environment and situation that you use it in. However it's not clear to me how these functions are originally being called. I've tried replacing "this" with different objects to try and hit on the origin but it doesn't work so I know I haven't got the right object that "this" represents.

Any takers? I could learn from the solution I am sure of it!
catatung is offline
Reply With Quote
View Public Profile
 
 
Register now for full access!
Old 05-21-2010, 10:52 PM Re: Calendar alteration; Month and Year selected by dropdown box
JeremyMiller's Avatar
WT Moderator

Posts: 1,712
Name: Jeremy Miller
Location: Las Vegas, NV
Trades: 0
Forgive me for ignoring your code, but I didn't want to spend the time to see what you changed and wanted to make sure that what I created would work as an extension to the base code. I downloaded the code and made a few changes which are described here.

First, if you download the code and look at sample1.html, I added a few options to the constructor to help us as can be seen here.

Code:
var current_date = new Date();
new tcal ({
  // form name
  'formname': 'testform',
  // input name
  'controlname': 'testinput',
  //Change title navigation to select boxes
  'titlenavigation': 'select',
  //When titlenavigation==select, then allow min, max years
  'titlenavigationminyear': current_date.getFullYear(),
  'titlenavigationmaxyear': current_date.getFullYear() + 5
});
I decided not to remove the left/right navigation options, but to change the title to allow users to select the month and year, while displaying the current month/year. In the code above, I use the current year as the minimum year and 5 years from this year as the maximum year (giving 6 entries total for the year dropdown).

I then went under the assign method section of the constructor and created ids for the month and year dropdowns that I planned to create and assigned a function to catch when those dropdowns changed. That's this code:

Code:
this.f_titleNavChange = f_tcalTitleNavChange;
this.f_tcalMonthId = 'tcalmonth_' + this.s_id;
this.f_tcalYearId = 'tcalyear_' + this.s_id;
You'll notice that tcal is a function, but it is treated as an object. That's something javascript does. Because of the assign method section, the other functions become members of that object, so "this" refers to the instance of the tcal object, allowing us to retain the configuration values and other variables over multiple instances.

After that, I went in to find where the title was output and found it where the "this.a_tpl.months[current_month] + ' ' + current_year" code was. Because I needed to remove that code if the titlenavigation configuration value was set as "select", I turned it into a variable and then created the dropdowns with classnames so that you can style them via the stylesheet (those classnames are tcalMonth and tcalYear, respectively). Here's the code that generates the dropdowns:

Code:
var current_month = d_date.getMonth();
var current_year = d_date.getFullYear();
var title_navigation_code = this.a_tpl.months[current_month] + ' ' + current_year;
var min_year = parseInt(this.a_cfg.titlenavigationminyear);
var max_year = parseInt(this.a_cfg.titlenavigationmaxyear);

if (this.a_cfg.titlenavigation == 'select' && min_year > 1970  && max_year > 1970 && min_year < max_year) {
  title_navigation_code = '<select class="tcalMonth" id="' + this.f_tcalMonthId + '" onChange="A_TCALS[\'' + this.s_id + '\'].f_titleNavChange();">';
  for(var i=0;i<A_TCALDEF.months.length;i++) {
    title_navigation_code += '<option value="' + i + '"' + (i == current_month?' SELECTED':'') + '>' + A_TCALDEF.months[i] + '</option>';
  }
  title_navigation_code += '</select>';
  title_navigation_code += ' <select class="tcalYear" id="' + this.f_tcalYearId + '" onChange="A_TCALS[\'' + this.s_id + '\'].f_titleNavChange();">';
  for(i=min_year;i<=max_year;i++) {
    title_navigation_code += '<option value="' + i + '"' + (i == current_year?' SELECTED':'') + '>' + i + '</option>';
  }
  title_navigation_code += '</select>';
}
The variable "title_navigation_code" then contained either just the month/year if the user did not have the configuration value set and dropdowns if it was set, the years for min and max were greater than 1970, and the max date was greater than the min date.

NOTE: I kept the methodology of the base script, but it's more prudent to use DOM methods to create HTML entities on a page -- I'll leave that to you as an exercise, but should you choose to ignore that, the script will still work.

The last step (before testing) was to create the navigation change function. Because I had assigned id vlaues
Code:
// title navigation function
function f_tcalTitleNavChange () {
  var target_date = new Date(document.getElementById(this.f_tcalYearId).options[document.getElementById(this.f_tcalYearId).options.selectedIndex].value, document.getElementById(this.f_tcalMonthId).options[document.getElementById(this.f_tcalMonthId).options.selectedIndex].value);
  this.f_update(target_date);
}
All that function does is create a new date based on the selected month and year and then call the native f_update function with the new date to update the display.

And, that was all there was to it ( ).

I've attached the 2 files (I did not update the other files that use different languages).

Enjoy and hopefully the explanation helps you (and others) learn.
Attached Files
File Type: zip tigra_calendar_dropdown_extension.zip (4.8 KB, 10 views)
__________________
Jeremy Miller

Please login or register to view this content. Registration is FREE
JeremyMiller is offline
Reply With Quote
View Public Profile Visit JeremyMiller's homepage!
 
Old 05-22-2010, 03:45 AM Re: Calendar alteration; Month and Year selected by dropdown box
Experienced Talker

Posts: 37
Trades: 0
Hi,

Thanks so much, I've implemented the code and see that it works.. Now I will have to take some time and go through it and try and grasp these concepts behind how and why.
catatung is offline
Reply With Quote
View Public Profile
 
Reply     « Reply to Calendar alteration; Month and Year selected by dropdown box
 

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off





   
RSS Feed  Feeds: RSS   JS   XML
RSS Feed  Feeds for this forum: RSS   JS   XML



Page generated in 0.14888 seconds with 13 queries