PDA

View Full Version : Calendar Picker/Chooser



ed.canas
2 Feb 2011, 11:01 PM
For those looking for a calendar picker instead of using default date picker. This is my first shot at creating a custom control so I'm sure there will be better ways of doing things, any additions are welcome since it still needs a little bit of work, fixing up the style on the form field display. Anybody with more experience on styling let me know on how to fix the gray box and text alignment.

Git - https://github.com/ecanas/Ext.form.ux.touch.CalendarPicker
Demo - http://www.ordersinseconds.com/calendarpicker/


Here are some pics of how it looks iphone:

http://ordersinseconds.com/calendarpicker/iphone.png

and ipad:
http://ordersinseconds.com/calendarpicker/ipad.png

eladgel
4 Feb 2011, 11:09 PM
the ability to choose the year

ed.canas
5 Feb 2011, 7:17 AM
Choose a year? Currently it allows you to set a preselected date month/year by setting the value property to any date/year you need. So in the sample instead of value: new Date() you could do instead do new Date('2012/1/1')

You can also set the date via setValue(new Date())

Not sure if that's what you meant by choose year?

ed.canas
5 Feb 2011, 7:45 AM
I think I know what you mean .. To choose a year from the calendar instead of having to page by months to get to a different year. This can be easily added will see if in future version can add.

eladgel
5 Feb 2011, 8:10 AM
you got my point exactly :)

here are two more questions: 1. is there any API? or should I just look through the JS file?
2. Say I have a startingDate field and endingDate field of an event,
a. I create them both successfully.
b. I click on startingDate field and start looking for my desired date
c. I accidentally click outside the container- on the endingDate field - it also opens up at the moment.

what would you suggest me to do in order to prevent clicking outside the container while it is open?
(I'm new at this, so cut me some slack )
10X again
Elad

ed.canas
5 Feb 2011, 9:24 AM
Sorry no API, its basically a panel and added option for setting the date and a fire an event when a date is chosen.

As for the other issue I did notice that as well on my testing I will add a mask so that it will prevent tapping outside.

ed.canas
6 Feb 2011, 1:28 PM
Elad, fixed the modal window it will now not let you tap outside the window until it's closed. you can get the latest .js from GitHub

eladgel
6 Feb 2011, 1:29 PM
10x a Bunch!

eladgel
6 Feb 2011, 2:00 PM
I was thinking about the year changing saga- what do you think about this:
1. instead of 6 weeks currently displayed - it will display 5 weeks(the 6th is irrelevant)
2. adding another bar(fixed under the title bar) that has to buttons and displays the year
3. adding a to the swipe event up and down so that the year would change

1- was easy: changed 42 to 35,
2- I need to play with this framework more to get it right.
3- likewise

ed.canas
6 Feb 2011, 2:13 PM
I was going as well limit it to 5 weeks but take a look at July and October of this year it uses all 6 weeks.

I like the swipe for months but I guess it can be made a configuration swipe for years or months. The other options are to use double tap to indicate a year change, single tap would be month.

let me know which of those sounds better and can do a quick update to add either one.

eladgel
6 Feb 2011, 2:29 PM
What do you think about the attached image?

ed.canas
6 Feb 2011, 3:33 PM
Take a look at the latest sample.. and GitHub.. I've added fast fordward and rewind buttons for the year.

http://www.ordersinseconds.com/calendarpicker/

http://ordersinseconds.com/calendarpicker/yearff.png

eladgel
6 Feb 2011, 3:39 PM
LIKE, only problem I spot is that I don't think the month field and the year would be visible on my Android phone- thats why I suggested the year tab.
I will run this tomorrow and check to see how it goes
Elad

ed.canas
6 Feb 2011, 3:47 PM
Then you can resize the title by adding something like into your css

.smallTitle .x-toolbar-title{
font-size: 12px;
}

and in the calendar titleBar object set cls: 'smallTitle'

ed.canas
6 Feb 2011, 3:52 PM
Actually I had the same problem on the iPhone, for which I do have a second bar which displays the Prev Next Year and the name of the Label as well, since in there it does not point to what you've clicked on. this is how it looks now on Phone devices
http://ordersinseconds.com/calendarpicker/iphone2.png

eladgel
7 Feb 2011, 1:07 PM
Awesome! Im going to check it on my Android :)

ymeiner
11 Feb 2011, 9:41 AM
ed.canas,
Great feature! i am already adding it to my list of great sencha features to have.

One little thing that I would ask you to add is classes to all parts in order to be able to add css defs to the date picker.

thanks,
yaron

ymeiner
20 Feb 2011, 1:16 PM
Hey ed,

Like your calendar picker but having problems with it when it comes to orientation changes:
1. landscape mode is all distorted when you press on one of the dates
2. when moving from portrait to landscape its going out of shape

trying to find some solutions by myself but would love to have your input about it :-)

Thanks,

Yaron

ed.canas
21 Feb 2011, 5:52 AM
On what platform? from the sounds of it looks like an iPhone, since it works fine on iPad but I never tested it the orientation change on the iPhone, since never intended to use it landscape mode on the iphone. To make it work in landscape in the iphone scrolling needs to be enabled back in the this.calendar panel. And to the listers of this.calendar add orientationchange listener.. so will look something like this.


listeners: {
scope: this,
orientationchange: function(pn, orientation, w, h) {
pn.setSize(w, h);
},
render: function() {
this.calendar.mon(this.calendar.el, {
swipe: function(directiion) {
if (directiion.direction == "left") {
this.nextMonth();
} else if (directiion.direction == "right") {
this.prevMonth();
}
},
tap: function(obj, e) {
var currSelection;
if ((e.className.search('date') != -1)) {
dateTap = true;
currSelection = e.getAttribute("date").split(',');
}
else {
if ((e.className.search('day') != -1)) {
dateTap = true;
currSelection = e.parentNode.getAttribute("date").split(',');
}
}
if (currSelection) {
var d = new Date(currSelection[0], currSelection[1], currSelection[2]);
this.onPickerChange(this, d);
this.calendar.hide();
}
},
scope: this
});
}
}

jaredgreener
2 Apr 2011, 2:40 PM
Hey - great work on this! It looks awesome. Just wondering if there was an option for getting rid of the year arrows. At least in my application it is a little confusing which arrows control months and which ones control the year and I don't need to navigate through years.

Thanks!

Jared

ed.canas
2 Apr 2011, 6:11 PM
There is currently no option to remove the arrows for the year, however you can easily hide them or remove the code. To hide just a new line after 52 and make it hidden: true, do the same after line 62 and hide that one as well

It would look something like this


this.pYear = new Ext.Button({
ui: 'action',
iconMask: true,
hidden: true,

iconCls: "rewind",
scope: this,
handler: function() {
this.prevYear();
}
});

this.nYear = new Ext.Button({
ui: 'action',
iconMask: true,
hidden: true,
iconCls: "fforward",
scope: this,
handler: function() {
this.nextYear();
}
});

jep
3 Jun 2011, 7:48 AM
FANTASTIC component. I've been wanting one of these since day one and just haven't had the time (and, lets be honest, probably the skill) to add one yet. The native iPhone picker style is okay, but not great. And it's outrageously stupid when you're on an iPad. This one solves all that.

My suggestion: add a 'beforeselect' event. Should be pretty easy. Only wrinkle might be making it where you can cancel the select if you want. I also feel that 'select' should probably be 'change'. This seems more standard, though I admit some fields like checkbox use 'check' or spinner uses 'cycle'. Of course, I've always thought that was counter-intuitive, too and they should just stick to a predictable event. Edit: On second thought, I realized that simply calling setValue() won't fire this event. So maybe 'select' makes more sense than 'change'. See, that's why I didn't write this component.

But anyway, I love it! Thanks for all the work you put into it.

Edit: For clarification on the suggested beforeselect event, I'd suggest parameters of the sort:
function (picker, oldValue, newValue). I already added this to the code for myself because I have two linked date boxes (start/end dates). I need to update the end date to move forward/backwards the appropriate amount when the start box changes. A beforeselect provides a very clean way to do that:


endDateBox.setValue(endDateBox.getValue().add(Date.MILLI, newValue.valueOf() - oldValue.valueOf()));

jep
3 Jun 2011, 8:11 AM
Oh, and one other suggestion if I may be so bold: when you click on a date, have that date box get colored right before the calendar disappears. I think it's a good visual cue that just makes the app feel much more responsive. Otherwise, it's like a button that doesn't depress when you click it.

jep
3 Jun 2011, 8:38 AM
Dang, just noticed a potential showstopper. I see you've released this as GPL. Any chance you'd consider changing it to another less restrictive license like MIT, Mozilla, etc. (or just charge for it - it'd be worth it!)? Otherwise, I think I'm going to have to go back to the drawing board.

ed.canas
3 Jun 2011, 9:24 AM
Jep, I just copied that header from somewhere else, I updated to MIT. Also I've added a minor change/option for showYearArrows, this way if you can hide the year arrows. I'll see if I can add some of the other suggestions.

Thanks

ed.canas
3 Jun 2011, 9:26 AM
If you already added the beforeselect event send me any of the code changes so I can include in the project.

jep
3 Jun 2011, 9:27 AM
Awesome! Thanks so much for that. Here's the changes I made for the beforeselect. Like I said, pretty simple:



Ext.jep.CalendarPickerField = Ext.extend(Ext.form.ux.touch.CalendarPickerField, {
initComponent: function() {
this.addEvents('beforeselect');

Ext.jep.CalendarPickerField.superclass.initComponent.apply(this, arguments);
},

onPickerChange: function(picker, value) {
this.fireEvent('beforeselect', this, this.getValue(), value);

Ext.jep.CalendarPickerField.superclass.onPickerChange.apply(this, arguments);
}
});


You could just back that code into the original class and I could get rid of my extension.

If I come up with a good way to do the highlighting, I'll post it, too.

(Funny, I posted this while you were posting asking me to post it!)

jep
3 Jun 2011, 9:28 AM
Though my beforeselect doesn't allow you to cancel the select. That might be something some people would find useful for validation purposes, maybe. But it might be too complicated because it'd probably require you to not hide the picker if the beforeselect canceled the change going through...

jep
3 Jun 2011, 9:30 AM
Sorry for spewing out post after post, but in retrospect I realized you could probably just add oldValue onto the list of parameters and that would eliminate the need for beforeselect for most of the stuff I do. Wouldn't allow the canceling thing, but I'm not sure how important that aspect would be.

ed.canas
3 Jun 2011, 9:43 AM
Updated GIT, let me know if there are any problems.

jep
3 Jun 2011, 9:57 AM
Looks good to me and seems to work fine. Only suggestion I'd have is to eventually combine those addEvents into



this.addEvents(['select', 'beforeselect']


But you probably already thought of that and just had it the way it was because you were just pasting in my changes. No worries.

profunctional
5 Oct 2011, 2:49 PM
Just tried the demo and October only has 29 days.

jep
5 Oct 2011, 2:58 PM
Weird, says 31 here. Not even sure where to start figuring that problem out. What browser and sencha version?

profunctional
5 Oct 2011, 3:39 PM
I'm trying the link in the first post on my iPhone 4.

ed.canas
5 Oct 2011, 4:21 PM
I believe the problem is with the view, on Android it might be cutting off the last row, you might need to scroll down. However scrolling might be disabled in the plugin, enable it if that's the case or change the style so that rows are smaller.

pmahoney
1 Mar 2012, 4:46 AM
Has anyone ported this to ST2 yet?