Updated 2015-02-25 to version 3.0, with the new subclassing code.

Updated 2015-02-16 to document changes in default URL and need for separate CSS file.

Updated 2015-02-13 to document additional parameters.

Updated 2015-01-28 to link to github.

Just what the world needs—another date picker

Download the code from github. You need jquery.ui.subclass.js, jquery.textpopup.js, /inc/jquery.flexcal.js and flexcal.css.

The current incarnation of the jQuery UI datepicker works fine, but I needed something that could handle the Jewish calendar. This is not the same as localizing datepicker to use Hebrew;that just translates the month and day names but uses the same Gregorian calendar as everyone uses. I needed a calendar that could switch between multiple, completely different calendar systems.

The algorithms for converting dates from Jewish to Gregorian are readily available open-source, so that was easy. textpopup is exactly what I need to create the pop-up box for the calendar, and I had already created my own date picker for my old bililite site (don't look at it too closely; it's ugly and I used an old version of Prototype. I was still learning! It works, though). So the pieces were all there.

And so was born flexcal. In its simplest form, it looks like datepicker:

<span>Using <code>datepicker</code>: </span><input id="date1"/>
<br/>
<span>Using <code>flexcal</code>: </span><input id="date2"/>
$('#date1').datepicker();$('#date2').flexcal();

But it can show multiple calendars and allows localization to different calendar systems:

<span>Jewish/civil calendar: </span><input id="date3"/>
$('#date3').flexcal({
  position: 'bl',
  calendars: ['en', 'jewish', 'he-jewish'],
  'class': 'multicalendar'
});

And it allows animated transitions (which I think is in the works for datepicker as well):

<span>Fading transition: </span><input id="date3-1"/>
$('#date3-1').flexcal({
  position: 'bl',
  transition: function(o){
    o.elements.eq(o.currSlide).fadeOut(o.duration);
    o.elements.eq(1-o.currSlide).fadeIn(o.duration);
  },
  transitionOptions: {duration: 'slow'}	
});

Options

It's a subclass of textpopup, so all the options from textpopup and ajaxpopup are available. The url defaults to a data URL (so no waiting for AJAX loading), which contains:

Note that all the required CSS is the flexcal.css file, and that it uses the themeable jQuery classes. Setting the 'class' option to multicalendar makes the date rectangles longer, giving more room for the tab bar. Setting 'class' to fontawesome makes the calendar use Font Awesome icons rather than the jQuery UI ones.

The flexcal options themselves are:

calendars {Array(String || Object)}
Array of calendars to display. Each string is a key into the $.bililite.flexcal.l10n object. Default is ['en'], which means that the default is one calendar, using the localization of $.bililite.flexcal.l10n.en. Calendar names are always of the form lowercase two-letter language code, then optionally an upper case two letter country code, then optionally a lower case calendar system name (default: 'gregorian'), all delimited by hyphens. Thus, 'zh-TW-islamic'. The code will try to find a localization in the jQuery UI datepicker or in Keith Woods's calendarspicker if available. If the string cannot be recognized as a calendar name, it is assumed to mean {name: name}, a localization object where everything is the default except the displayed name of the calendar.
If the item is an object then it is the localization object itself. If the item is itself an array, then each item is recursively evaluated and all the resulting localization objects are $.extended together.
Thus, calendars: ['en', 'he-jewish', ['ar-islamic', 'Arabic']] displays three calendars, an English Gregorian calendar, a Hebrew Jewish calendar (both with their default names) and an Arabic Islamic calendar named 'Arabic' (the string is not a calendar name, so it is interpreted as {name: 'Arabic'} which modifies the $.bililite.flexcal.l10n['ar-islamic'] object.
tab {Number}
Index into the calendars array of the one to display when initially shown
current {Date|String}
If the element value is not set to a valid date, then use this as the initial display date.
filter {undefined|Function}
Function to filter dates. Function is of the form f(d) where d is a Date object; it should return true enable that date or false to disable it. this is set to the <a> element that contains the date number. See the examples below.
transitionOptions
Options to pass to the transition function, below
transition {Function}
Function to handle the transition from one calendar or month to another. Signature is function(options), where options is copied from transitionOptions, augmented by the following fields:
options.$cont
jQuery object that is the container for the calendars
options.elements
jQuery object that has two elements, each an absolutely-positioned <div> one on top of the other, that are the calendars to be transitioned
options.currSlide
The index of the current calendar. Thus, options.elements.eq(options.currSlide) is the currently-showing calendar and options.elements.eq(1-options.currSlide) is the currently hidden calendar that needs to be shown
options.rev
Boolean to indicate that the animation should show a "reverse" transition, going to a previous month.
options.l10n
Localization object for the calendar to be displayed (options.elements.eq(1-options.currSlide)). The transition function can use options.l10n.isRTL to determine if "next month" should be animated right-to-left or left-to-right
The default is function(o){ o.elements.eq(o.currSlide).hide(); o.elements.eq(1-o.currSlide).show(); }
hidetabs {true|false|'conditional'}
True to hide the tab bar, false to show it and 'conditional' to hide it if there is only one calendar to display. Default is 'conditional'.
reposition {true|false}
True to reposition the calendar with every transition; useful if the calendar is above the text element and transitions to months with more weeks obscures the box. Default is True.
l10n {Object (see below)}
Localization object to use if one of the fields in the calendar array item is undefined

The localization (l10n for short) object is the key to the whole thing. $.flexcal.l10n contains objects, each of which is a localization object with the following fields (named to match the corresponding fields in $.datepicker.regional):

name {String}
Default display name
calendar {Function}
Calendar generating function, defaults to Gregorian calendar. Takes a Date object, d, and returns an object with the following fields:
first {Date}
First date of the month containing d
last {Date}
Last date of the month containing d
prev {Date}
Date one month before d
next {Date}
Date one month after d
prevYear {Date}
Date one year before d
nextYear {Date}
Date one year after d
y {Number}
Number of the year of d
m {Number}
0-indexed number of the month of d
d {Number}
Date of the month of d
dow {Number}
0-indexed number of the day of the week of the first day of the month. Note that this is not necessarily just first.getDay(), since this calendar system may use some other "week" system.
toDate {Function}
Function that takes an object {y: y, m: m, d: d} representing the date in this calendar and returns the corresponding Javascript Date. Not currently used; I plan on implementing some sort of date parsing (Issue #4) that will use this. It is optional; if not present, will use a binary search to find the right date. If the values given are invalid, should either return new Date(undefined) or do some error correcting the way new Date(y, m, d) does, e.g. turning 0 dates into the last day of the previous month.
monthNames {Array(String)}
Names of the months
dayNamesMin {Array(String)}
Names of the days of the week
isRTL {Boolean}
True if the calendar should display right-to-left
firstDay {Number}
Day of the week (0-indexed) that the calendar should start. Not currently implemented (Issue #5), always assumes 0.
prevText {String}
Wording on the "previous month" button. The CSS for jQuery UI replaces this with an icon but still uses the text for the title. By the jQuery UI guidelines, it should not include an arrow or chevron
nextText {String}
Wording on the "next month" button
years {Function}
Function to convert a year number to the displayed string. Default is function(n) {return n}
fromYears {Function}
Inverse of years, above. Function to convert a string into a number. If undefined, will not parse year strings but only allow numbers. Not currently used; I plan on implementing some sort of date parsing (Issue #4) that will use this.
dates{Function}
Function to convert a date number to the displayed string. Default is function(n) {return n}
fromDates {Function}
Inverse of years, above. Function to convert a string into a number. If undefined, will not parse date strings but only allow numbers.. Not currently used; I plan on implementing some sort of date parsing (Issue #4) that will use this.

// default l10n calendar
$.bililite.flexcal.prototype.options.l10n = {
	name: 'flexcal',
	calendar: function(d){
		var m = d.getMonth(), y = d.getFullYear(), date = d.getDate(), first = new Date (y, m, 1);
		var prev = new Date (y, m-1, date), next = new Date (y, m+1, date);
		if (prev.getDate() != date) prev = new Date (y, m, 0); // adjust for too-short months
		if (next.getDate() != date) next = new Date (y, m+2, 0);
		return {
			first: first,
			last: new Date (y, m+1, 0),
			prev: prev,
			next: next,
			m: m,
			y: y,
			dow: first.getDay()
		};
	},
	monthNames: ['January','February','March','April','May','June',
		'July','August','September','October','November','December'],
	dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
	isRTL: false,
	prevText: 'Previous',
	nextText: 'Next',
	years: function(n) {return n},
	days: function(n) {return n}
};

The API (publicly accessible methods) is documented in a later post.

The plugin comes with three localizations defined (the ones I wanted): $.bililite.flexcal.l10n.en (English-language civil calendar), $.bililite.flexcal.l10n.jewish (Jewish calendar with English names) and $.bililite.flexcal.l10n['he-jewish'] (Jewish calendar with Hebrew names), and two calendar-generating functions: $.bililite.flexcal.calendars.gregorian and $.bililite.flexcal.calendars.jewish.

The options object that is passed to the transition function was designed to allow drop-in use of Mike Alsup's excellent cycle plugin, with $(selector).flexcal({transition: $.fn.cycle.next}), though it doesn't work that easily.

Examples

French/English calendar. We grab the French localization from the datepicker svn.

<input id="date4"/>
$.getScript('https://rawgit.com/jquery/jquery-ui/master/ui/i18n/datepicker-fr.js', function(){
  $.datepicker.setDefaults($.datepicker.regional['']);
  $.bililite.flexcal.l10n.fr = $.datepicker.regional.fr;
  $('#date4').flexcal({
    position: 'rt',
    calendars: [['fr', 'Français'], ['en','Anglais']]
  });
});

The French Revolutionary calendar. This is just to show off how flexible the widget is; 10-day weeks and 5-day months are no problem. View source to see the calendar algorithms.

<input id="date5"/>
$('#date5').flexcal({
  position: 'rt',
  calendars: ['en', 'jacobin']
});

flexcal with fancier transitions and using my scrollIntoView plugin (put the input box at the bottom of the window to see the scrolling effect)

<input id="date6"/>
$('#date6').flexcal({
	position: 'bl',
	calendars: ['en', 'jewish'],
	transition: function(o){
		var dir = o.rev ^ o.l10n.isRTL;
		var first = o.elements.eq(o.currSlide), second = o.elements.eq(1-o.currSlide);
		var h = o.$cont.height(), w = o.$cont.width();
		first.css({zIndex: 1});
		second.css({zIndex: 0}).show();
		first.animate({foo: 0}, { // the {foo:0} seems necessary because we need to animate some property, even if it isn't real
			duration: o.speed,
			step: function(now, fx){
				if (fx.state == 0){
					fx.start = now = dir ? 0 : w;
					fx.end = dir ? w : 0;
				}
				if (dir){
					first.css('clip', 'rect(0px '+w+'px '+h+'px '+now+'px)');
					second.css('clip', 'rect(0px '+now+'px '+h+'px 0px)');
				}else{
					first.css('clip', 'rect(0px '+now+'px '+h+'px 0px)');
					second.css('clip', 'rect(0px '+w+'px '+h+'px '+now+'px)');
				}
			},
			complete: function() {
				// clip is so inconsistently implemented. This way works in FF3, Opera 9, Safari 3,  IE7
				first.hide().css('clip', 'rect(auto)');
				second.css('clip', 'rect(auto)');
			}
		});
	},
	transitionOptions: {speed: 'slow'},
	shown: function() {$(this).flexcal('box').scrollIntoView()}
});

Using draggable. The option cancel: '.ui-state-default' makes sure that clickable elements aren't used as drag handles. A real draggable calendar probably should have the cursor change on hover also.

<input id="date7"/>
<input id="date8"/>
$('#date7').flexcal({
  position: 'rt',
  calendars: ['en', ['fr', 'French']],
  reposition: false
}).flexcal('box').draggable({cancel: '.ui-state-default', cursor: 'move'});

$('#date8').flexcal({
  position: 'lt',
  calendars: ['en',  ['fr', 'French']],
  reposition: false
}).flexcal('box').draggable({
  cancel: '.ui-state-default',
  cursor: 'move',
  start: function(){
    $(this).css({right: 'auto', bottom: 'auto'});
  }
});

Differences from datepicker

I intentionally gave this widget fewer options than datepicker; I just included what I thought I would need. Since it uses my subclass-able widget framework, it can easily be extended to be more capable. One thing that is still definitely lacking is keyboard accessibility; I don't know anything about that and have to start experimenting. To be added in some later version, for sure.

The power of Extending Widgets

Some examples of extending flexcal to be more datepicker-like.

Date formatting

The format for the date that is inserted into the text box is very simple; mm/dd/yyyy. You can subclass flexcal to use datepicker's formatting (as with any subclassing, you should look at the source code to figure out what the code is doing):

<input id="date9"/>
<input id="date10"/>

$.widget('bililite.fancyflexcal', $.bililite.flexcal, {
  format: function(d){
    return $.datepicker.formatDate (this.options.dateFormat, d);
  },
  options: {
    dateFormat: $.datepicker.W3C
  }
});

$('#date9').fancyflexcal();
$('#date10').fancyflexcal({dateFormat: 'D, M d, yy'});
Filtering dates

Filter dates with the filter option:

<input id="date11"/>
// allow weekdays only
$('#date11').flexcal({
  filter: function(d){ return d.getDay() != 0 && d.getDay() != 6; }
});

Using the filter option to manipulate the css of the calendar:

<input id="date12"/>
// Put a border around every other Thursday (it's payday!)
$('#date12').flexcal({
  filter: function(d){
    // is it Thursday and is it an even numbered week since the epoch?
    if (d.getDay() == 4 && Math.floor(d.getTime()/(1000*60*60*24*7)) %2 == 0){
      $(this).css('border', '2px solid purple'); // put a nice border on it
    }
    return true; // don't disable anything
  }
});
Drop-down menus

Creating drop-down menus is a bit more complicated, because we can't assume that all the month names in the monthNames array are present in every year, and the definition of the localization calendar routine does not provide with us with a way to get the alternate calendar date for a given Date. The following routines help:


function option(d, l10n, cal, isMonth, selected){
  return [
    '<option',
    selected ? ' selected="selected"' : '',
    ' value="', d.toString(), '">',
    isMonth ? l10n.monthNames[cal.m] : l10n.years(cal.y), 
    '</option>'
  ].join('');
}
window.monthSelect = function(currentdate, l10n){
  var f = l10n.calendar;
  var currentcal = f(currentdate), ret = [option(currentdate, l10n, currentcal , true, true)], d = currentdate;
  for (var cal = currentcal; d = cal.prev, cal = f(d), cal.y == currentcal.y; ){
    ret.unshift(option(d, l10n, cal, true, false));
  }
  for (cal = currentcal; d = cal.next, cal = f(d), cal.y == currentcal.y; ){
    ret.push(option(d, l10n, cal, true, false));
  }
  return $('<select>').html(ret.join(''));
};
window.yearSelect = function(currentdate, l10n, n){
  var f = l10n.calendar;
  var currentcal = f(currentdate), ret = [option(currentdate, l10n, currentcal , false, true)], d = currentdate;
  for (var i = 0, cal = currentcal; d = cal.prevYear, cal = f(d), i < n; ++i){
    ret.unshift(option(d, l10n, cal, false, false));
  }
  for (var i = 0, cal = currentcal; d = cal.nextYear, cal = f(d), i < n; ++i){
    ret.push(option(d, l10n, cal, false, false));
  }
  return $('<select>').html(ret.join(''));
};
<input id="date13"/>

$('#date13').flexcal({'class': 'multicalendar', calendars: ['en','he-jewish']}).flexcal('after', '_adjustHTML', function (cal){
  cal.find('.ui-datepicker-month').html(monthSelect(this.options.current, this.o.l10n));
  cal.find('.ui-datepicker-year').html(yearSelect(this.options.current, this.o.l10n, 5));
  var self = this;
  cal.find('select').bind('change', function(){
    self._setDate(new Date($(this).val()))
  }); 
});

51 Comments

  1. Erik says:

    Great Widget!

  2. sravan says:

    i need the code for the clip notes widget.
    could you please mai it to my email id.

  3. Danny says:

    @sravan:
    What clip notes widget? I don’t think I ever wrote anything called that.
    –Danny

  4. Axel says:

    I have a problem with your code. I cannot make my example page run well.

    Could you please give me an email address where I could write to you ?
    I would like to send you my test.html page to check what is missing.

    Regards

  5. Danny says:

    @Axel:
    I unfortunately don’t have a lot of free time for support, but I can try to help. It would be easier if you posted a link to your website rather than emailing me code; most problems come from the interaction of little things that are hard to track down without looking at the whole thing in its “natural habitat”.
    –Danny

  6. Ed says:

    Hi Danny, firstly thanks so much for creating this datepicker – incredibly useful!

    I am having a minor issue with it…I have set it up to use Joda time (http://joda-time.sourceforge.net/) supplied calendar information – so that any calendar system it supports, is supported by flexcal.

    My problem is that AJAX requests are sent off to a JSP file that returns information (using Joda time) about months for a particular system, to then determine what the calendar object returned should be. If the request is too slow, the calendar object falls back to the gregorian object you implemented. What I want to do is that as soon as that request has been processed, refresh the date picker to display the calendar using the correct calendar system.

    I have been trying to do this by literally invoking setDate(the last d) once the request is complete but it keeps flicking back to the date that it first opened with (today’s date). Any ideas? Is there another method I should be invoking to refresh the calendar?

    Thanks in advance.

  7. Danny says:

    @Ed:
    Using AJAX to get the calendar from the server sounds cool. flexcal as it stands isn’t set up to deal with asynchronous changes, but it ought to be possible to override setdate to do that. Can you send me your Javascript code and I can try to think about it? I’m real busy, so no promises, but I’m intrigued enough to ignore my real responsibilities to look at it.
    At worst, you could do the AJAX synchronously, but that would mean a seriously unresponsive page.
    –Danny (d.wachss@prodigy.net)

  8. Alexandr says:

    Hi, Examples don`t work

  9. Danny says:

    @Alexandr:
    What system are you using? They work for me in IE8 and FF3.5.
    –Danny

  10. yisman says:

    hi
    looks like an excellent widget
    i appreciate
    but i cant get it to work
    i made a super-simple website with one page like this

    $(function () { $(‘#date3’).flexcal(); });

    but when i put focus in the textbox i just get a loading spinner and nothing shows up
    when i use datepicker instead, it does work, but flexcal not.
    can u please try to help me?
    am i missing some file? link? thanks

  11. yisman says:

    oh i see all the html markup got deleted
    here it is encoded

    <html >
    <head>
    <title></title>
    <script type="text/javascript" src="Scripts/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery-ui.min.js"></script>
    <script type="text/javascript" src="Scripts/jquery.ui.subclass.js"></script>
    <script type="text/javascript" src="Scripts/jquery.textpopup.js"></script>
    <script type="text/javascript" src="Scripts/jquery.flexcal.js"></script>
    </head>
    <body>
    <script type="text/javascript">
    $(function () { $('#date3').flexcal(); });
    </script>
    <input id="date3" type="text" />
    </body>
    </html>

  12. Danny says:

    @yisman:
    Sounds like you’re missing the template HTML file that is pulled in with AJAX, so it needs to be on the same server as your page. You have to set the url parameter to the file name (it defaults to /inc/flexcal.html); you can copy http://bililite.com/inc/flexcal.html.
    Hope this makes sense.
    –Danny

  13. Ronny says:

    hi , i’m having the same problem as yisman , do you mind putting all the needed files in a .zip file
    cause that will be just wonderful

  14. Danny says:

    @Ronny:
    I’m not going to have the time to keep it updated if I update the originals, but I put jquery.flexcal.js, the template flexcal.html, and the dependency files jquery.textpopup.js and jquery.ui.subclass.js into a ZIP file: flexcal-archive.zip
    –Danny
    Update 2011-11-07: flexcal-archive.zip no longer exists. The new archive is jquery.flexcal-package.js.

  15. ronny says:

    still at lost ,
    this is my super-basic code :

    $(document).ready(function() {
    $('#date1').datepicker();
    $('#date2').flexcal();
    });

    Using datepicker:

    Using flexcal:

  16. Danny says:

    @Ronny:
    That looks right. Can you put up a page with your code and I’ll try to take a look at it?
    –Danny

  17. chanan says:

    Hi,
    I found this plugin very useful, but I could’nt find out how to set the starting date (in the jquery UI there is a `current` option)
    Can you give a hint how can I modify this?
    10x

  18. Chanan says:

    Hi Danny,

    I found this a great datepicker, but I looking for a way to set the starting date (the jquery UI datepicker has a `current` property in its settings), or even allow only a range of dates. can you point me out how can this be done?

    10x
    chanan

  19. Danny says:

    @Chanan:
    First, make sure you have the most recent version (1.3); the previous version had a bug that I only found when I was trying to answer your comment (thanks!).
    To set the starting date, either set the value of the input before creating the calendar:

    $('input.date').val('10/1/2001').flexcal();

    or use the setDate function after the calendar is created:

    $('input.date').flexcal().flexcal('setDate','10/1/2011');

    As I write this, I realize that setDate and the rest of the public API isn’t documented; I’ll try to get to that as soon as possible.
    For allowing a range of dates, it was possible in the previous version but kind of complicated, so I created a new option, filter, that can be set to a function that takes a Date and returns true to enable that date and false to disable it:

    $('input.date').flexcal({
    	filter: function(d) {return d >= startDate && d <= endDate}
    });

    Hope this helps,
    Danny

  20. Danny says:

    @Chanan:
    The big change for version 2.0 (which you inspired) is the addition of the ‘current’ option, so now

    $('input.date').flexcal({current:  '10/1/2011'});

    works.
    However, the value of the input element overrides that, so you can change the option after the fact to force it:

    $('input.date').flexcal().flexcal('option','current','10/1/2011');

    .
    setDate no longer works.
    –Danny

  21. Chanan says:

    @Danny:

    Thanks for adding this new current property to the options.
    I just tried using it but it does’nt really work for me. I might miss some thing, but I’ve looked into the code and it looks as the _setOption function is never called, so also if I set current hardcoded in the default options it does’nt work.

  22. Danny says:

    @Chanan:
    Arrgh! That’s what I get for not testing thoroughly. It should work now. Please let me know.
    Danny

  23. Chanan says:

    @Danny:

    One more question, Is there any easy way to format date format (‘d/m/y’ instead of ‘m/d/y’ for exampe)?

    10x

  24. Danny says:

    @Chanan:
    See the section on “date formatting” in the post. You can subclass the widget to use the jQuery UI datepicker formatting code, or just override the format method to return d.getDay()+’/’+d.getMonth()+’/’+d.getFullYear()
    –Danny

  25. Adrian says:

    Hello Danny,

    Excellent work here, and write-up. I’m looking to see if there is a way to make the calendar appear for multiple inputs with the same id/name. For example, I’m working on a project where the application is required to display the initial form with one calendar input. Then the user can duplicate the input within the form, to have a second set of, say, computer inventory information. Thus, the form data is passed to the server as an array.
    Can I have something like:
    [code]

    [/code]
    Then when the user clicks on the two input fields, two separate calendars appear. And the date would go through as an array as expected (ex: date=01/01/2010,02/02/2012).

    I tried the datepicker supplied by JQuery’s core ui, but couldn’t get it to work (or maybe I’m not understanding JQuery enough to make it generate a new calendar for each input with matching id/name). So, I’m checking you JQuery plug-in to see if it can do what I’m looking for.

    If your plug-in can do this, would you be so kind to provide a mini example, or explain how I can make this work?

    Thank you!
    Adrian

  26. Adrian says:

    noticed the stuff in the code blocks didn’t work. heheh. sorry. Trying again:

  27. Danny says:

    @Adrian:
    I don’t understand what you are trying to do without the sample code. Don’t try to format it or anything, just type it in.
    –Danny

  28. Adrian says:

    On the second one I did just that… I typed it in.. *sigh*

  29. Adrian says:

    I think I answered my own question just now… I meant multiple inputs with the same name. Not ID, sorry. But I believe I figured out how to make this work. Sorry to have wasted your time there. :)

    Thanks!

  30. Inbar Gross says:

    I am trying to get flexcal to work on my site.. but i am not having much luck… you you please include a list of all classes i have to include to get it to work?

    and maybe some instructions?

  31. Danny says:

    @Inbar Gross:
    It looks like jQuery UI 1.10 changed their CSS a bit, so the flexcaltemplate.js file had to be updated. Thanks for noticing this!
    You can get all the code on github at https://github.com/dwachss/flexcal; you need the files

    jquery.ui.subclass.js
    jquery.textpopup.js
    jquery.flexcal.js
    flexcaltemplate.js

    included in that order, in addition to jQuery and jQuery UI.
    I have a single file that packages them all together, at
    http://bililite.com/inc/package.php/jquery.flexcal-package.js
    Please copy that, don’t hotlink!
    You can see a minimal example at
    http://bililite.com/blog/blogfiles/flexcal.html
    Hope this helps,
    –Danny

  32. Tova says:

    Hi,

    Thank you for the post! its great!

    I am trying to get the year and month combo boxes to work in my calendar (example 13 by you) I copied the code you wrote in the example but when it tries to call ‘aftre’ I get an error

    Uncaught Error: cannot call methods on flexcal prior to initialization; attempted to call method ‘after’

    What am I doing wrong.

    Also how can I add a Today button that will give me Today’s Date?

    thanks

  33. Danny says:

    Tova:
    It’s hard to figure out what’s wrong without a complete code sample. Do you have a public page that generates the error?
    I will try to look at the code later today to show how to add a Today button.
    –Danny

  34. Danny says:

    Tova:
    For the Today button, I wrote a new post: http://bililite.com/blog/2014/02/26/flexcal-with-today-button/

  35. Tova says:

    Hi,

    Regarding the error I had I got it to work, I added a ‘:visible’ jquery selector.

    $(“#:visible”).flexcal({….

    Thanks for the post for the Today button!!

  36. Tova says:

    Hi,

    I still get that error I told you about the other day, my code is like this:

    $(“#:visible”).fancyflexcal({
    dateFormat: ‘dd/mm/yy’,
    position: ‘bl’,
    changeYear: true,
    calendars: [‘en’, ‘he-jewish’, ‘hebrew’],
    ‘class’: ‘multicalendar’
    });

    This works fine, but when I add the code for the combo box for the year and month I get the error

    Uncaught Error: cannot call methods on flexcal prior to initialization; attempted to call method ‘after’

    I try doing this:

    $(“#:visible”).flexcal(‘after’, ‘_adjustHTML’, function (cal) {
    cal.find(‘.ui-datepicker-month’).html(monthSelect(this.options.current, this.o.l10n));
    cal.find(‘.ui-datepicker-year’).html(yearSelect(this.options.current, this.o.l10n, 5));
    var self = this;
    cal.find(‘select’).bind(‘change’, function () {
    self._setDate(new Date($(this).val()))
    });
    });

    Can you help me with this?

  37. Danny says:

    @Tova:
    Without seeing the whole code with the details of the error, its hard to say what’s wrong, but it looks like you are initializing the element with fancyflexcal but adding the “after” code with flexcal. Those end up internally being different things (even though fancyflexcal is a subclass of flexcal), so try adding the “after” code with fancyflexcal.
    –Danny

  38. Tova says:

    I have a problem…

    I create the flexcal like this:

    function addDatePicker(id) {
    $(“#”+id).flexcal({
    dateFormat: ‘dd/mm/yy’,
    position: ‘bl’,
    changeYear: true,
    calendars: [‘en’, ‘he-jewish’, ‘hebrew’],
    ‘class’: ‘multicalendar’
    }).flexcal(‘after’, ‘_adjustHTML’, function (cal) {
    cal.find(‘.ui-datepicker-month’).html(monthSelect(this.options.current, this.o.l10n));
    cal.find(‘.ui-datepicker-year’).html(yearSelect(this.options.current, this.o.l10n, 5));
    var self = this;
    cal.find(‘select’).bind(‘change’, function () {
    self._setDate(new Date($(this).val()))
    });
    });
    }

    with the dateFormat dd/mm/yy

    But then when I have a date in my input box let say 3/5/2014 instead of it being May 3 2014 it opens the calendar as if its March 5 2014.

    I also have this in my code:

    var currInputId = “”;
    $.ui.flexcal.subclass(‘ui.flexcal’, {
    format: function (d) {
    var newDate = new Date(d);
    currInputId = this.element[0].id;
    var parameters = { date: d };

    $.ajax({
    type: “POST”,
    url: “../WebService1.asmx/GetFormattedDate”,
    data: JSON.stringify(parameters),// parameters,
    contentType: “application/json; charset=utf-8”,
    dataType: “json”,
    success: function (msg) {
    returnFormatedDate(msg.d);
    },
    error: function (err) {
    alert(err.toString());

    }
    });

    },
    options: {
    dateFormat: “dd/mm/yy”
    }
    });

    function returnFormatedDate(str) {
    $(‘#’ + currInputId + ”).val(str);
    }

    Every thing else is like the original code.

    Is there any way you can help me with this?

  39. Danny says:

    @Tova:
    Using a web service to format your code seems like overkill, but if it works, it works. Your problem now is converting a string (the input element value) into a Date object (the reverse of the format(d) function, which converts a Date into a string). That is done by the _createDate(d, oldd) function. If d is a string, the function should return a Date created by that string. As the function is set up now, it just uses new Date(d). It looks like your browser is using American dates (month/day/year) rather than European (day/month/year).
    Writing a date parser to correct that can be complicated, and you have to replace the _date2string(d) as well. this._createDate(this._date2string(d)) has to return the original date d in order for the calendar to work. I unfortunately don’t have time to do this for you.
    But I will keep it in mind and comment again if I come up with a solution.
    –Danny

  40. Danny says:

    @Tova:
    OK, I was challenged enough to write a flexcal subclass that handles European dates (and does it locally rather than using a web service). See the post at http://bililite.com/blog/2014/03/06/flexcal-with-european-date-formatting/

    –Danny

  41. Tova says:

    Hi,

    Thank you so much for your help!!

    The reason I did a webservice is because I wanted to display the Jewish date in the Jewish format for example כ”ה אדר תשע”ד
    So I created a server side function that returns a string according to the culture I want, do you have any better solution then that?

  42. Danny says:

    @Tova:
    The problem with using a webservice is that it is likely going to be noticeably slow. You’re probably better off doing the formatting/parsing on the client. Anything you can do with ASP you could do in Javascript.
    -Danny

  43. Tova says:

    Hi,
    Im back with another question.

    I am trying to position the date picker that it should open on the buttom right of text box and it should open to the left (RTL web site)
    I did position: ‘br’, but then the first time I open the datepicker the calander is not on the right side of the text box (it moves to much to the right of the text box) and only if I click again the text box or go to another tab and then come back it positions in the right place.

    Any idea on what can be done?

    (If its not clear I can send you screens shots)

    Thanks

  44. Danny says:

    Tova:
    I am aware of the problem, that the position of the calendar overlaps the text box until you click back in it or change it in some way. This may be due to the delay in loading flexcal.html. Try using the data URL option for the template: after including jquery.flexcal.js, include flexcaltemplate.js (get both of them from the github site).
    On some playing, it still does not solve the problem.
    I have added this as an issue (https://github.com/dwachss/flexcal/issues/1). If you would like to add your comments, screen shots or solutions, please comment there.
    I will play with this more when I get a chance, since I now know that it bothers some one else.
    –Danny

  45. Danny says:

    Tova:
    The problem is that when the textbox is being positioned it is still slowly being shown, so the calculated position is wrong. A workaround is to use the speed option, with $(input).flexcal({speed: 0}).

    Setting speed to zero means no animation when displaying, so the final size is set immediately.

    –Danny

  46. Tova says:

    Thank you for your time!

    When adding
    $(input).flexcal({speed: 0}).
    It really positions the datepicker in the right place, but now when I choose a date the date picker doesnt automaticly close.
    How can we fix that?

  47. Danny says:

    Tova:
    I’m not having that problem: http://bililite.com/blog/blogfiles/flexcal.html
    Do you have a website set up showing your problem?
    –Danny

  48. Danny says:

    I think I’ve fixed the problem with the animated display positioning wrong. Please get the most recent commit for jquery.textpopup.js and jquery.flexcal.js from github (https://github.com/dwachss/flexcal)

  49. Tova says:

    Since i did some changes in my flexcal.js can you please tell me what changes you did? if is only a few changes.
    Thanks

  50. Danny says:

    Tova:
    Have you used github? It makes comparing versions much easier. Look at:
    https://github.com/dwachss/flexcal/commit/d0ec314ef401dc971d9ee10f4c7f73225276c7be?diff=split
    The lines in green are the ones that were added; the ones in red are the ones removed. Basically I changed the _setDate routine from having a dontAnimate parameter to having a forceAnimate parameter, so all the calls to _setDate had to be modified.

    –Danny

Leave a Reply


Warning: Undefined variable $user_ID in /home/public/blog/wp-content/themes/evanescence/comments.php on line 75