Issue 290: Altering display for 'active' day
Status:  Done
Owner: ----
Closed:  Feb 2010
Reported by jagthedr...@gmail.com, Jan 13, 2010
I'm trying to find a way to highlight a day based on a user click.  It 
would look much like the 'today' highlighting that is already being done, 
but it would move around the calendar based on user clicks.

I've found that I can make this happen in the day view by doing this in my 
calendar init code:

...
dayClick : function(date,allDay, jsEvent, view){
  jQuery('#calendar').fullCalendar('gotoDate', date);
  if(oldActiveDay){
     jQuery(oldActiveDay).removeClass("activeDay");
  }
  if(view.name=='month'){
     jQuery(this).addClass("activeDay");
  }
  oldActiveDay = this
  return false;
}
...


Then I have a CSS rule like this:

.activeDay{
background:#eee;
}

In the agenda views, the code above will highlight the entire row 
representing the time that was clicked.  It seems like this would be a 
pretty common thing to do, but I can find any pointers.  Can anybody help?

Thanks,
Jeremy

Jan 13, 2010
#1 travisco...@gmail.com
Below is what I have.  curSel is init as "var curSel = '';" before I define the 
below.							

eventClick: function(event, jsEvent, view){
								if(curSel != ''){									
									
curSel.className = 'pl-event';
									
cal.fullCalendar('updateEvent', curSel);
									if(curSel.id 
!= event.id){																			
										
event.className = 'pl-event-selected';								
										
cal.fullCalendar('updateEvent', event);																				
										
curSel = event;
									}else{
										
curSel = '';
									}								
								}else{
									
event.className = 'pl-event-selected';								
									
cal.fullCalendar('updateEvent', event);																				
									curSel = 
event;								
								}							
							}
Jan 13, 2010
#2 travisco...@gmail.com
WOW poor formatting on my part.  Here's something better.  

I defined a new style called "pl-event-selected", and "pl-event" is the default one I 
use. 

CSS
...
.pl-event-selected,
.pl-agenda .pl-event-selected .pl-event-time,
.pl-event-selected a {
	border-style: solid; 
	border-color: #9533CD;
	background-color: #9533CD;
	color: #fff;
	}
...

JS Code
...
eventClick: function(event, jsEvent, view){
	if(curSel != ''){									
		curSel.className = 'pl-event';
		cal.fullCalendar('updateEvent', curSel);
		if(curSel.id != event.id){																			
			event.className = 'pl-event-selected';								
			cal.fullCalendar('updateEvent', event);																				
			curSel = event;
		}else{
			curSel = '';
		}								
	}else{
		event.className = 'pl-event-selected';								
		cal.fullCalendar('updateEvent', event);																				
		curSel = event;								
	}							
},
...

enjoy
Jan 13, 2010
#3 jagthedr...@gmail.com
Hey Travis, thanks for the code.  I've been working on highlighting the entire day 
cell (or cells in agenda view), not just the event itself.  

I've actually just committed some code to GitHub.  My branch can be found here:

http://github.com/jagthedrummer/fullcalendar

I've added a 'highlightDate' event that will take care of highlighting the containing 
cell or cells for any given date.  

I've submitted a pull request to Adam, so hopefully this will make it into the main 
code base.

Thanks,
Jeremy

Jan 19, 2010
Project Member #4 adamrs...@gmail.com
hi jag,
thanks for coding things up. however, im always trying to think of the right(tm) way
to do things in order to keep fullcalendar as small and efficient as possible. i
don't think this feature would be super common, its the first time i've heard of such
a request. i'd prefer if it were done purely through callbacks, to keep it out of the
core (and make it possible as a separate file add-on later... add-on architecture in 1.5)

instead of it being a method, i would envision is as an option called "selectDays"
(unrelated to the "selectDate" method you wrote) that automatically selects a day
when clicked, in effect... adds a new class, and removes a class from any old day,
calls gotoDate (but doesn't refetch events :)

i think developers could hit the ground running faster with this 'option' form versus
the 'method' form.

in fact, i also think there should be a callback that goes along with it. it would be
called "daySelect" and would be fired *after* dayClick is fired. it can return
true/undefined to go ahead w/ the select, or false to cancel it. so...

$('#calendar').fullCalendar({
    selectDays: true,
    daySelect: function(date) {
        return confirm("are you sure you want to select this date?")
    }
});


what do you think?

if you like my ideas, and like the idea of it being an "add-on", unfortunately the
add-on architecture is not built yet, so it couldn't be in a redistributable form,
but you should be able to achieve all this through callbacks and have it working on
your setup. the add-on architecture will most be a way to hook in "global" callbacks,
so making it official wouldn't take much work after that.

(you would use the dayClick click callback and inspect the 'view' parameter to see
what view you're in)
Jan 20, 2010
#5 jagthedr...@gmail.com
Hey Adam, I really like your idea about it being an option instead of a method.  I'd actually thought of that after coding the method based solution.  
Actually I had decided that it was probably common enough that it should be turned on by default and that the user/developer could turn it off if they 
don't want it for some reason.  I'm very surprised to hear that you've never heard of anybody wanting to do this and that you don't want to include it in 
the core.

I've got two arguments to try to change your mind:

1.  UI principals
2.  Ease of use for developers


*UI principals*

It seems to me that from a UI perspective the calendar should give the user a clue about it's internal state.  As it stands now it's kind of a mystery to 
the user as to what behavior they should expect when changing views.  Try this to demonstrate:

1.  Load a page with fullcalendar
2.  Go forward 2 months
3.  Switch to week view
4.  Go forward 4 to 6 weeks
5.  Switch to month view
6.  Try to predict which day you'll get when you switch to day veiw
7.  Switch to day view and see if you're right

My point with this is that fullcalendar is a rich GUI widget and is already tracking the concept of 'active' day.  Leaving out any indication to the user 
of which is the 'active' day in an effort to keep things lean and mean seems strange.  If keeping things lean is really the goal, shouldn't you leave out 
all of the control generating code (next month/week, today, etc...) and leave it to the developer to implement that stuff by using the gotoDate function?  
I think fullcalendar is past "only the basics" and well into "slick as hell" territory.  I can't see how one clue for the end user is too much. 

*Ease of use for developers*

I saw your new doc that mentions doing something like this in a dayClick callback:

$(this).css('background-color', 'red');

The main problem with that method is that for the agenda views, the 'this' object does not represent the day in question.  Rather it represents the hour 
across all days shown in the calendar.  Here's a branch with a new test page that demonstrates the problem:

http://github.com/jagthedrummer/fullcalendar/tree/show-active-day

Load up test/show_active_day.html and click on a day.  This method works OK for the month view and the week grid and day grid views.  Now switch to 
agendaWeek view and click on something and you'll see the problem.

I have a few gripes about this approach.  

1.  The developer that's integrating fullcalendar must keep track of the current day and the previously current day on their own even though fullcalendar 
already tracks this information.  Shouldn't this be part of fullcalendar's job?
2.  Even setting aside my first gripe, the agenda views simply don't work with this approach.  So, now the developer must come up with a separate way to 
handle the agenda views.
3.  There is no good way (at least that I can find) for a developer to get a hold of the cell (or cells) that represent a given day.  

Maybe I'm missing something about how to implement this through callbacks, but it just seems hacky to implement that way.  I'd love to hear any 
suggestions.  It just seems like functionality that should be encapsulated by the calendar itself (object orientation and what not).

Also, I realize that the code I contributed to do this wasn't really very pretty.  It was just enough to get it to work for me.  I'll probably work on 
refactoring it to work with the option format you suggested then post a link to a repo to let you check it out.

Thanks again for the great library, I hope I'm not out of line in arguing to have this feature accepted.

Thanks,
Jeremy

Jan 21, 2010
#6 jagthedr...@gmail.com
I've been thinking some more about this problem and I think I have an idea for how to do this in a more general way that could have 
other uses.

I'm thinking we could introduce a 'specialDay' object.  It would be something like this.

myDay = new SpecialDay({ 
  day: new Date(),
  class: 'myDay',
  exclusive : true  
})

$('#calendar').fullCalendar('addSpecialDay',myDay)

Then the list of special days would be passed to the Grid and Agenda classes to allow them to insert the class name into the code 
for the cell representing that day.  I'm thinking that adding an exclusive specialDay with a given class name would automatically 
remove any other specialDays with the same class name.

Possible applications for this:

*Marking weekend days differently than week days
*Marking the days a business is closed
*Current day indicator

Basically any time that you might want to change the background of a day for any reason.

I would think that specialDays could be delivered with events.

Anyway, I know it would be a good bit of coding.  I just wanted to throw it out there and see what you guys think before I do 
anything.

Thanks,
Jeremy
Jan 23, 2010
Project Member #7 adamrs...@gmail.com
Hey Jeremy. I appreciate the pushback and agree with most of what you've said.

The confusing UI scenario is definitely true (i guessed the wrong date). However, I feel that 
other solutions would be better at solving it, like having clickable day titles that bring you 
to day view (https://code.google.com/p/fullcalendar/issues/detail?id=153) or having a mini-
calendar that controls the main one (https://code.google.com/p/fullcalendar/issues/detail
id=167). Google calendar employs both and is very usable. Both seem better than denoting an 
'active' day, because not only can the user see which day they will be taken to, they can also 
control which one.

Also, i would be afraid the user would confuse the 'active' day with the 'current' day.

I want to find a way to build the active day feature through callbacks. however, as you 
pointed out, the developer doesn't have adequate access to the day cell in agenda view. i 
think we should just change the way fullcalendar behaves and have `this` be the (vertical) 
cell. the only reason it has been the horizontal slot cell is because that is where the mouse 
click is generated. but this doesn't matter. makes much more sense to change it.

the adding and removing of classes [on the old/new active day] is the next hurdle as you point 
out. i'm not really sure i like the specialday approach, seems a little to abstract, and also 
not flexible enough (what if you wanted to change the id instead of the class?). A better 
approach would be through a callback, analogous to eventRender, called dayRender 
(https://code.google.com/p/fullcalendar/issues/detail?id=191) that gets invoked on every 
rerender for every day cell...

   dayRender: function(date, element) {
      if (date == $('#calendar').fullCalendar('getDate')) {
          element.addClass('active');
      }else{
          element.removeClass('active');
      }
   }

you could come up with some optimizations by saving the previous date (in the viewDisplay 
callback) so you don't have to `removeClass` from every old cell.

for the agenda views, this would be called only on the vertical day cells.

let me know what you think,
adam

Jan 26, 2010
#8 jagthedr...@gmail.com
Hey Adam, I think that fixing the agenda views to return the vertical cell would be a
pretty good overall solution.  As far as the other issues you mention, they both
sound like good ideas, but I think you may have misunderstood what I'm trying to get
at as the whole point of this feature is to allow the user to control the 'active'
day by simply clicking on the day itself without introducing new external controls.

Here's an example based on my first ugly hacking at the code:

http://chamber.webapeel.com/calendars/chamber_events

'Today" is alway highlighted in gold, and the 'active' day gets a grey background. 
Click around from day to day to see it follow you around.  It also stays in place
between view changes.  In month view, you can click on any day, then change to day
view, and you're taken to the view for the day you just clicked on.  This is the type
of functionality I'm shooting for.  

I can see what you mean about the special day feature.  There would be so many
different use cases that I think it's probably better handled externally as part of
calendar implementation.  The 'dayRender' function you suggest would be excellent in
letting a developer implement this.

I do think that some built in functionality for 'active' day indicator and changing
like I have demonstrated in my example would be very useful in the core.  What do you
think?  

Thanks,
Jeremy

Feb 5, 2010
#9 yowza...@gmail.com
Adam,

When you're considering the right(tm) way to do this, please consider supporting the 
selection and toggling on/off of multiple days.  This feature would allow many days to be 
selected rather than just one day.  Perhaps a simple example use case will explain my 
request best.

Users of my application need a quick way to specify when they are available. Creating 
these events one at a time is too tedious. The interface includes a fullcalendar, a UI 
Slider with 2 handles ranging between 12am and 11:59pm, and an Add button.  

1. User clicks a day in the calendar and it becomes selected with a highlight color.
2. User clicks the same day again which deselects the day and removes the color.
3. User clicks onto several different days, calendar highlights all selected days.
4. User slides left handle of slider to 8am
5. User slides right handle of slider to 8pm
6. User clicks the Add button
7. System creates events on each of the selected days from 8am to 8pm.

I'm writing code to do just this right now.  If multiple day selection was built into 
fullcalendar, this process would certainly be simplified.
Feb 5, 2010
Project Member #10 adamrs...@gmail.com
yowzator, i can see this being similar behavior to what this issue proposes 
https://code.google.com/p/fullcalendar/issues/detail?id=215 (but in month view). google 
calendar does this and it might be cool if fullcalendar did this too.

jeremy, i understand what you are trying achieve. but your intent of the feature seems 
to be to improve navigation, and the solutions i listed seem a lot better from a 
usability and user understanding perspective. the notion of an "active" day that serves 
as a pivot point when switching views is something i don't think people will get. 
granted, its better than the current state of the fullcalendar, but i still feel 
clicking on a day's title to be brought to it's day view (one step) is more straightforward than making it active, then click the "day" button at the top (two 
steps).

maybe i'm being anal, but i am reluctant to put anything into fullcalendar doesn't have 
proven usability to end users. that is why i often look to google calendar / icalendar 
for design cues.

i will think about it more if other people approach me with the same suggestion though. 
i still think this should eventually packaged as a plugin
Status: Done
Feb 6, 2010
#11 yowza...@gmail.com
Adam,

I think you're right -- the pivot point idea would be hard for people to grasp.  My 
suggestion was only meant for you to consider if you did implement something like day 
selections. I just figured it wouldn't be that much harder to track an array of day 
selections rather than just a single day selection.

If you don't add this, it isn't a big deal.  I already have day selections working like 
this:

dayClick: function(date, allDay, jsEvent, view) {
	if (view.name == "month") {
		// Allow selection of multiple days on the calendar
		if ($(this).data('selected')) {
			$(this).data('selected', false);
			$(this).css('background-color', $(this).data('prev-background-
color'));
			if ($(this).data('isToday')) {
				$(this).addClass('ui-state-highlight');
			}
		}
		else {
			$(this).data('selected', true);
			$(this).data('prev-background-color', $(this).css('background-
color'));
			var isToday = $(this).hasClass('ui-state-highlight');
			if (isToday) {
				$(this).data('isToday', isToday);
				$(this).removeClass('ui-state-highlight');
			}
			$(this).css('background-color', '#7EB0C8');
		}
	}
},

Feb 6, 2010
Project Member #12 adamrs...@gmail.com
yowzator, cool, glad you were able to make your own solution. what i meant in response 
to your last comment is that i think the feature would be useful for creating new 
events
Feb 6, 2010
#13 yowza...@gmail.com
Thanks for clarifying.  I didn't understand why you thought my suggestion was related 
to  issue 215  or your comment that google calendar does it.  But now I get your point!  

Although it would be nice for me if this was a provided method of creating events, my 
needs are probably not too common.  All of my events are created with a title of 
"Available".  Most people probably want different titles and information for each 
event.  I'm not sure how often most people would really need to create a bunch of 
events at once.


Feb 22, 2011
#14 victor.a...@gmail.com
Hi Yowza,
   Presently i'm working on full calendar in asp.net c#,i've a issue please help me...

my issue is:
   when the client add a new event i have given a option in dropdownlist on add event window to change the color of a cell,when select the color that color will apply to the event cell ..
Is it possible ...? if it is possible please help me.........