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
$.extend
ed 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 useoptions.l10n.isRTL
to determine if "next month" should be animated right-to-left or left-to-right
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 returnnew Date(undefined)
or do some error correcting the waynew 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()))
});
});
Erik says:
Great Widget!
April 3, 2009, 2:28 amsravan says:
i need the code for the clip notes widget.
May 16, 2009, 3:07 amcould you please mai it to my email id.
Danny says:
@sravan:
May 17, 2009, 2:16 pmWhat clip notes widget? I don’t think I ever wrote anything called that.
–Danny
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
August 14, 2009, 6:59 amDanny says:
@Axel:
August 14, 2009, 3:55 pmI 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
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.
September 10, 2009, 3:08 amDanny says:
@Ed:
September 10, 2009, 8:36 amUsing 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 overridesetdate
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)
Alexandr says:
Hi, Examples don`t work
December 29, 2009, 1:22 amDanny says:
@Alexandr:
December 31, 2009, 9:39 pmWhat system are you using? They work for me in IE8 and FF3.5.
–Danny
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
April 17, 2011, 5:00 amwhen i use datepicker instead, it does work, but flexcal not.
can u please try to help me?
am i missing some file? link? thanks
yisman says:
oh i see all the html markup got deleted
here it is encoded
<html >
April 17, 2011, 5:02 am<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>
Danny says:
@yisman:
April 17, 2011, 3:11 pmSounds 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
Ronny says:
hi , i’m having the same problem as yisman , do you mind putting all the needed files in a .zip file
June 27, 2011, 11:16 amcause that will be just wonderful
Danny says:
@Ronny:
June 27, 2011, 2:03 pmI’m not going to have the time to keep it updated if I update the originals, but I put
jquery.flexcal.js
, the templateflexcal.html
, and the dependency filesjquery.textpopup.js
andjquery.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.ronny says:
still at lost ,
this is my super-basic code :
$(document).ready(function() {
$('#date1').datepicker();
$('#date2').flexcal();
});
Using
datepicker
:Using
June 28, 2011, 5:48 amflexcal
:Danny says:
@Ronny:
July 1, 2011, 6:04 amThat looks right. Can you put up a page with your code and I’ll try to take a look at it?
–Danny
chanan says:
Hi,
October 21, 2011, 2:06 amI 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
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
October 22, 2011, 10:08 amchanan
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:
or use the
setDate
function after the calendar is created: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 aDate
and returnstrue
to enable that date andfalse
to disable it:Hope this helps,
October 23, 2011, 9:40 pmDanny
Danny says:
@Chanan:
The big change for version 2.0 (which you inspired) is the addition of the ‘current’ option, so now
works.
However, the value of the input element overrides that, so you can change the option after the fact to force it:
.
October 26, 2011, 1:38 pmsetDate
no longer works.–Danny
Chanan says:
@Danny:
Thanks for adding this new current property to the options.
October 28, 2011, 2:11 amI 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.
Danny says:
@Chanan:
October 28, 2011, 3:06 amArrgh! That’s what I get for not testing thoroughly. It should work now. Please let me know.
Danny
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
October 28, 2011, 3:26 amDanny says:
@Chanan:
October 28, 2011, 12:34 pmSee 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
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!
May 1, 2012, 3:37 pmAdrian
Adrian says:
noticed the stuff in the code blocks didn’t work. heheh. sorry. Trying again:
May 1, 2012, 3:43 pmDanny says:
@Adrian:
May 1, 2012, 3:54 pmI 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
Adrian says:
On the second one I did just that… I typed it in.. *sigh*
May 1, 2012, 3:56 pmAdrian 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!
May 1, 2012, 4:01 pmInbar 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?
January 20, 2014, 10:09 pmDanny 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
included in that order, in addition to jQuery and jQuery UI.
January 21, 2014, 9:17 amI 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
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
February 26, 2014, 1:34 amDanny says:
Tova:
February 26, 2014, 6:50 amIt’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
Danny says:
Tova:
February 26, 2014, 11:24 amFor the Today button, I wrote a new post: http://bililite.com/blog/2014/02/26/flexcal-with-today-button/
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!!
February 27, 2014, 5:03 amTova 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?
February 28, 2014, 2:33 amDanny says:
@Tova:
February 28, 2014, 4:11 amWithout 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 withflexcal
. Those end up internally being different things (even thoughfancyflexcal
is a subclass offlexcal
), so try adding the “after
” code withfancyflexcal
.–Danny
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?
March 6, 2014, 2:24 pmDanny says:
@Tova:
March 6, 2014, 3:41 pmUsing 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. Ifd
is a string, the function should return a Date created by that string. As the function is set up now, it just usesnew 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 dated
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
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
March 6, 2014, 9:22 pmTova 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 כ”ה אדר תשע”ד
March 7, 2014, 1:35 amSo I created a server side function that returns a string according to the culture I want, do you have any better solution then that?
Danny says:
@Tova:
March 7, 2014, 5:28 pmThe 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
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
January 25, 2015, 2:00 amDanny says:
Tova:
January 28, 2015, 9:06 amI 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 includingjquery.flexcal.js
, includeflexcaltemplate.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
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
January 28, 2015, 4:12 pmTova says:
Thank you for your time!
When adding
January 29, 2015, 1:07 am$(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?
Danny says:
Tova:
January 29, 2015, 8:51 amI’m not having that problem: http://bililite.com/blog/blogfiles/flexcal.html
Do you have a website set up showing your problem?
–Danny
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)
January 29, 2015, 2:27 pmTova 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.
February 11, 2015, 1:50 amThanks
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
February 11, 2015, 6:53 am