bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

[datepicker] active state on every first day of the month

Open marco-gagliardi opened this issue 9 years ago • 21 comments

Don't know if that's the intended behavior anyway it seems weird to me that while navigating on and back through the months, day one is always marked as active (and couldn't find an option to disable this behavior). To see it open this page: http://plnkr.co/edit/F3cu3Fed6DhgjxJnxT0J?p=preview and click on the right arrow over and over...

marco-gagliardi avatar Jun 30 '15 15:06 marco-gagliardi

I would say this is a minor UX bug since if you select any other date and then navigate, the active behavior does not trigger. PRs fixing this are welcome.

wesleycho avatar Jul 02 '15 02:07 wesleycho

Found next code: $scope.move = function( direction ) { var year = self.activeDate.getFullYear() + direction * (self.step.years || 0), month = self.activeDate.getMonth() + direction * (self.step.months || 0); self.activeDate.setFullYear(year, month, 1); self.refreshView(); }; It's really weird, why it's needed at all?

viros avatar Jul 07 '15 13:07 viros

I think part of the problem is that if it is to remain on the currently selected day when changing months/years, there is the possibility of certain days not existing on the new month, such as 31.

The activeDate code looks like it keeps it simple - I would be fine with a PR changing this behavior though, it should be pretty easy to fix if someone wants to file a PR with the appropriate test to cover all edge case dates.

wesleycho avatar Aug 04 '15 02:08 wesleycho

TL;DR Both current implementation and the suggested PR don't seem right. The highlight (a.ka. active day which != selected day) should be scrapped altogether (with the exception of 'today'). All the problems with it are listed below.


@wesleycho It took me a while to realise what was the problem you were referring to. I think I know now but I don't understand why anyone would want the active day to follow you as you switch between months. What is the thinking behind this idea?

I can see that some other pickers try to do it like that, e.g. pickadate, while some don't, e.g. jQuery datepicker. From an end user perspective who uses a datepicker for a few seconds and moves on I find the pickadate (and current angular ui) behaviour confusing - why when I select 13th February does it highlight 13th March for me? Has the selection changed? Is it broken? And then if I indeed want to select 13th March I have to click on the cell that appears to have already been clicked.

Also with the current implementation you get strangeness like this. If you select 1st February 2017 and then go back to January both 1st Jan and 1st Feb appear selected. You could argue that normally styling solves the problem (for clarity - I don't think so at any rate) but here it actually is part of the problem as clearly 1st January looks selected but it isn't.

Personally I think it should work like this (jQuery way). Initially the current day is selected. As you move through months nothing happens. Then you select a different date. As you move through the months nothing happens still. This removes the potential confusion in folks like me, the need for some complex edge case logic/testing, and strange workaround solutions like selecting the first day of the month (current implementation) or in the case of the suggested PR inconsistency whereas sometimes you get a day selected (or is it highlighted?) and sometimes you don't (e.g. when the previous month had more days than the next).

johnnybaloney avatar Nov 14 '15 14:11 johnnybaloney

I will talk with a UX professional next week to gather thoughts.

I'm all for simplifying the datepicker naturally :) - I do agree that there likely is complication when it comes to the logic, I need to do some investigation.

wesleycho avatar Nov 14 '15 16:11 wesleycho

The bug is still there? Any updates? there are 3 issues:

  • navigate days: first day the current month is selected
  • navigate months: current month is selected
  • navigate years:
    • for forward navigation: current year + 10xN (where N is number of the page forward)
    • for backward navigation: current year - 10xN (where N is number of the page backward)

rsangiovanni avatar Mar 09 '16 11:03 rsangiovanni

Navigating to another month should not have an active class attached to any day by default.

The active class should be applied to a day a user has clicked.

Today's date should have a class that describes that state: today

jasonhargrove avatar Apr 16 '16 17:04 jasonhargrove

I tried to work around this problem using customClass to not resort to manipulating the DOM directly. That function doesn't offer anything particular to activeDate which seems like another issue.

For that I opened up PR #5812 where you can see the change I made to the module. With this change you can work around the design issues, while that discussion unfolds.

An example that doesn't cover all use-cases:

<!-- html directive -->
custom-class="vm.calendar.getDayClass(date, mode, activeDate)"
// controller
vm.calendar.getDayClass = function (date, mode, activeDate) {
  // Custom active class fix
  var activeMonth = new Date(activeDate).getMonth();
  var currentMonth = new Date().getMonth();
  if (activeMonth !== currentMonth) {
    return 'non-current-month';
  }

  // default
  return '';
};

On td.non-current-month button.active, disable the styling. Expand the custom class logic per your own needs. In this case, the enhancement is used to override a design flaw where there is no today class, and active is attached to today, as well as the 1st of every non current month.

jasonhargrove avatar Apr 16 '16 19:04 jasonhargrove

On PR #5812, @icfantv added an idea to this conversation. I'd hope to see this area redesigned a bit in general, while separately also having more ability to override these items via customClass, which is the idea that my above workaround is built on.

jasonhargrove avatar Apr 17 '16 15:04 jasonhargrove

Another solution for those who do not need active state, would be to disable the active styles entirely and use customClass to attach today to today's td element, styling that.

<!-- html directive -->
custom-class="vm.calendar.getDayClass(date, mode)"
// customClass active vs today fix
vm.calendar.getDayClass = function (date, mode) {
  var todaysDate = new Date().setHours(0, 0, 0, 0);
  var calendarDate = new Date(date).setHours(0, 0, 0, 0);

  if (calendarDate === todaysDate) {
    return 'today';
  }

  // default
  return '';
};

This solution doesn't require changes to the module, but you will lose the active functionality. (The attached styling when user clicks a date.)

jasonhargrove avatar Apr 17 '16 16:04 jasonhargrove

^^ For those who arrived here because they were relying on .active for today's date, I've opened a PR for today's date which solves the issue directly without relying on customClass workarounds.

I also took at look at the 1st day .active issue. A lot of the code is relying on it, and there are also unresolved thoughts about how it should eventually work, so I left it for now but willing to take a closer look later.

jasonhargrove avatar Apr 17 '16 20:04 jasonhargrove

Anyone found the solution?

onlinerahul avatar Apr 27 '16 05:04 onlinerahul

Is anyone who can help, i am struggling around to fix active state on every first day of the month How i can remove by default .active class from (01) date? http://plnkr.co/YwsIriYa1Vmmo33TgfFQ

onlinerahul avatar Apr 28 '16 06:04 onlinerahul

@onlinerahul, we set the selected day in code - there is no way to override this short of forking the library. You may be able to override the template and or controller code. the activeDt property on $scope is responsible for dictating the actively selected day. I haven't looked into whether or not this is going to be possible within the confines of the repo and I do not have the time to do so.

icfantv avatar Apr 28 '16 15:04 icfantv

@icfantv the links above give you a blueprint for "solving" this problem. If you check out this PR you can see a change that you can make which will then allow you to use the customClass feature to work around it. https://github.com/angular-ui/bootstrap/pull/5812/files (The customClass code is shown on this thread above.)

Note that there is now discussion (on my PR) about removing the active feature completely.

jasonhargrove avatar Apr 28 '16 15:04 jasonhargrove

@jasonhargrove, As this issue is currently in progress in master build, can you guys please provide me any temporary solution so that i'll fix it at my .js file?

onlinerahul avatar Apr 29 '16 06:04 onlinerahul

@onlinerahul sure, I gave it to you in my last comment. If you read up the thread there's enough info to be able to sort it out 🍀

jasonhargrove avatar Apr 29 '16 08:04 jasonhargrove

I was having the same issues as others when using .active for selected date. For some reason, the .active class is being applied to the first of the month when you advance the calendar.

What worked for me is using the .btn-info class on the button for the selected day. That seems to be unique.

I wish this datepicker had markup like the jQuery datepicker. The latter has custom classes for today and selected day.

dfw avatar Dec 13 '16 14:12 dfw

Thanks @dfw. That is a pretty quick fix. I turned off the box-shadows and set the color back to #333 for buttons, then instead of styling buttons with .active I am styling buttons with .btn-info.active.

adamjhickey avatar Apr 11 '17 00:04 adamjhickey

Using the .btn-info class works for the selected day. However, you will lose the functionality to highlight the current date.

To highlight the current date you could use .active, but then it will show as Day 1 when you switch months as it did before.

sdeering avatar Oct 31 '17 04:10 sdeering

Did you resolve this ticket? I have the same issue.

fjoalland avatar Jan 09 '19 06:01 fjoalland