1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-18 19:40:55 +01:00

Convert date control dropdowns to an input for date

Summary: Ref T8060, Convert date control dropdowns to an input for date

Test Plan: Create new Calendar event, use US time format to enter a date or use datepicker, confirm dates are interpreted correctly.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T8060

Differential Revision: https://secure.phabricator.com/D13010
This commit is contained in:
lkassianik 2015-05-25 14:02:33 -07:00
parent e4c9914697
commit e8dbdedbd4
5 changed files with 100 additions and 170 deletions

View file

@ -5,9 +5,7 @@ final class AphrontFormDateControl extends AphrontFormControl {
private $initialTime;
private $zone;
private $valueDay;
private $valueMonth;
private $valueYear;
private $valueDate;
private $valueTime;
private $allowNull;
private $continueOnInvalidDate = false;
@ -41,9 +39,7 @@ final class AphrontFormDateControl extends AphrontFormControl {
}
public function readValueFromRequest(AphrontRequest $request) {
$day = $request->getInt($this->getDayInputName());
$month = $request->getInt($this->getMonthInputName());
$year = $request->getInt($this->getYearInputName());
$date = $request->getStr($this->getDateInputName());
$time = $request->getStr($this->getTimeInputName());
$enabled = $request->getBool($this->getCheckboxInputName());
@ -55,10 +51,8 @@ final class AphrontFormDateControl extends AphrontFormControl {
$err = $this->getError();
if ($day || $month || $year || $time) {
$this->valueDay = $day;
$this->valueMonth = $month;
$this->valueYear = $year;
if ($date || $time) {
$this->valueDate = $date;
$this->valueTime = $time;
// Assume invalid.
@ -67,8 +61,8 @@ final class AphrontFormDateControl extends AphrontFormControl {
$zone = $this->getTimezone();
try {
$date = new DateTime("{$year}-{$month}-{$day} {$time}", $zone);
$value = $date->format('U');
$datetime = new DateTime("{$date} {$time}", $zone);
$value = $datetime->format('U');
} catch (Exception $ex) {
$value = null;
}
@ -100,9 +94,7 @@ final class AphrontFormDateControl extends AphrontFormControl {
public function setValue($epoch) {
if ($epoch instanceof AphrontFormDateControlValue) {
$this->continueOnInvalidDate = true;
$this->valueYear = $epoch->getValueYear();
$this->valueMonth = $epoch->getValueMonth();
$this->valueDay = $epoch->getValueDay();
$this->valueDate = $epoch->getValueDate();
$this->valueTime = $epoch->getValueTime();
$this->allowNull = $epoch->getOptional();
$this->isDisabled = $epoch->isDisabled();
@ -119,42 +111,18 @@ final class AphrontFormDateControl extends AphrontFormControl {
$readable = $this->formatTime($epoch, 'Y!m!d!g:i A');
$readable = explode('!', $readable, 4);
$this->valueYear = $readable[0];
$this->valueMonth = $readable[1];
$this->valueDay = $readable[2];
$year = $readable[0];
$month = $readable[1];
$day = $readable[2];
$this->valueDate = $month.'/'.$day.'/'.$year;
$this->valueTime = $readable[3];
return $result;
}
private function getMinYear() {
$cur_year = $this->formatTime(
time(),
'Y');
$val_year = $this->getYearInputValue();
return min($cur_year, $val_year) - 3;
}
private function getMaxYear() {
$cur_year = $this->formatTime(
time(),
'Y');
$val_year = $this->getYearInputValue();
return max($cur_year, $val_year) + 3;
}
private function getDayInputValue() {
return $this->valueDay;
}
private function getMonthInputValue() {
return $this->valueMonth;
}
private function getYearInputValue() {
return $this->valueYear;
private function getDateInputValue() {
return $this->valueDate;
}
private function getTimeInputValue() {
@ -168,18 +136,10 @@ final class AphrontFormDateControl extends AphrontFormControl {
$fmt);
}
private function getDayInputName() {
private function getDateInputName() {
return $this->getName().'_d';
}
private function getMonthInputName() {
return $this->getName().'_m';
}
private function getYearInputName() {
return $this->getName().'_y';
}
private function getTimeInputName() {
return $this->getName().'_t';
}
@ -202,27 +162,6 @@ final class AphrontFormDateControl extends AphrontFormControl {
$disabled = 'disabled';
}
$min_year = $this->getMinYear();
$max_year = $this->getMaxYear();
$days = range(1, 31);
$days = array_fuse($days);
$months = array(
1 => pht('Jan'),
2 => pht('Feb'),
3 => pht('Mar'),
4 => pht('Apr'),
5 => pht('May'),
6 => pht('Jun'),
7 => pht('Jul'),
8 => pht('Aug'),
9 => pht('Sep'),
10 => pht('Oct'),
11 => pht('Nov'),
12 => pht('Dec'),
);
$checkbox = null;
if ($this->allowNull) {
$checkbox = javelin_tag(
@ -237,32 +176,24 @@ final class AphrontFormDateControl extends AphrontFormControl {
));
}
$years = range($this->getMinYear(), $this->getMaxYear());
$years = array_fuse($years);
$days_sel = AphrontFormSelectControl::renderSelectTag(
$this->getDayInputValue(),
$days,
$date_sel = javelin_tag(
'input',
array(
'name' => $this->getDayInputName(),
'sigil' => 'day-input',
));
'autocomplete' => 'off',
'name' => $this->getDateInputName(),
'sigil' => 'date-input',
'value' => $this->getDateInputValue(),
'type' => 'text',
'class' => 'aphront-form-date-time-input',
),
'');
$months_sel = AphrontFormSelectControl::renderSelectTag(
$this->getMonthInputValue(),
$months,
$date_div = javelin_tag(
'div',
array(
'name' => $this->getMonthInputName(),
'sigil' => 'month-input',
));
$years_sel = AphrontFormSelectControl::renderSelectTag(
$this->getYearInputValue(),
$years,
array(
'name' => $this->getYearInputName(),
'sigil' => 'year-input',
));
'class' => 'aphront-form-date-time-input-container',
),
$date_sel);
$cicon = id(new PHUIIconView())
->setIconFont('fa-calendar');
@ -329,9 +260,7 @@ final class AphrontFormDateControl extends AphrontFormControl {
),
array(
$checkbox,
$days_sel,
$months_sel,
$years_sel,
$date_div,
$cal_icon,
$time_div,
));

View file

@ -2,9 +2,7 @@
final class AphrontFormDateControlValue extends Phobject {
private $valueDay;
private $valueMonth;
private $valueYear;
private $valueDate;
private $valueTime;
private $valueEnabled;
@ -12,16 +10,8 @@ final class AphrontFormDateControlValue extends Phobject {
private $zone;
private $optional;
public function getValueDay() {
return $this->valueDay;
}
public function getValueMonth() {
return $this->valueMonth;
}
public function getValueYear() {
return $this->valueYear;
public function getValueDate() {
return $this->valueDate;
}
public function getValueTime() {
@ -36,15 +26,7 @@ final class AphrontFormDateControlValue extends Phobject {
}
public function isEmpty() {
if ($this->valueDay) {
return false;
}
if ($this->valueMonth) {
return false;
}
if ($this->valueYear) {
if ($this->valueDate) {
return false;
}
@ -83,9 +65,7 @@ final class AphrontFormDateControlValue extends Phobject {
$value = new AphrontFormDateControlValue();
$value->viewer = $viewer;
$value->valueYear = $year;
$value->valueMonth = $month;
$value->valueDay = $day;
$value->valueDate = $month.'/'.$day.'/'.$year;
$value->valueTime = coalesce($time, '12:00 AM');
$value->valueEnabled = $enabled;
@ -95,10 +75,7 @@ final class AphrontFormDateControlValue extends Phobject {
public static function newFromRequest(AphrontRequest $request, $key) {
$value = new AphrontFormDateControlValue();
$value->viewer = $request->getViewer();
$value->valueDay = $request->getInt($key.'_d');
$value->valueMonth = $request->getInt($key.'_m');
$value->valueYear = $request->getInt($key.'_y');
$value->valueDate = $request->getStr($key.'_d');
$value->valueTime = $request->getStr($key.'_t');
$value->valueEnabled = $request->getStr($key.'_e');
@ -111,11 +88,14 @@ final class AphrontFormDateControlValue extends Phobject {
$readable = $value->formatTime($epoch, 'Y!m!d!g:i A');
$readable = explode('!', $readable, 4);
$value->valueYear = $readable[0];
$value->valueMonth = $readable[1];
$value->valueDay = $readable[2];
$year = $readable[0];
$month = $readable[1];
$day = $readable[2];
$value->valueDate = $month.'/'.$day.'/'.$year;
$value->valueTime = $readable[3];
return $value;
}
@ -125,9 +105,7 @@ final class AphrontFormDateControlValue extends Phobject {
$value = new AphrontFormDateControlValue();
$value->viewer = $viewer;
$value->valueYear = idx($dictionary, 'y');
$value->valueMonth = idx($dictionary, 'm');
$value->valueDay = idx($dictionary, 'd');
$value->valueDate = idx($dictionary, 'd');
$value->valueTime = idx($dictionary, 't');
$value->valueEnabled = idx($dictionary, 'e');
@ -149,9 +127,7 @@ final class AphrontFormDateControlValue extends Phobject {
public function getDictionary() {
return array(
'y' => $this->valueYear,
'm' => $this->valueMonth,
'd' => $this->valueDay,
'd' => $this->valueDate,
't' => $this->valueTime,
'e' => $this->valueEnabled,
);
@ -176,9 +152,7 @@ final class AphrontFormDateControlValue extends Phobject {
return null;
}
$year = $this->valueYear;
$month = $this->valueMonth;
$day = $this->valueDay;
$date = $this->valueDate;
$time = $this->valueTime;
$zone = $this->getTimezone();
@ -203,8 +177,8 @@ final class AphrontFormDateControlValue extends Phobject {
}
try {
$date = new DateTime("{$year}-{$month}-{$day} {$time}", $zone);
$value = $date->format('U');
$datetime = new DateTime("{$date} {$time}", $zone);
$value = $datetime->format('U');
} catch (Exception $ex) {
$value = null;
}

View file

@ -90,10 +90,7 @@ final class PHUICalendarDayView extends AphrontView {
}
$this->events = msort($this->events, 'getEpochStart');
if (!$this->events) {
$first_event_hour = $this->getDateTime()->setTime(8, 0, 0);
}
$first_event_hour = $this->getDateTime()->setTime(8, 0, 0);
foreach ($this->events as $event) {
if ($event->getIsAllDay()) {

View file

@ -150,8 +150,11 @@ final class PHUICalendarListView extends AphrontTagView {
$this->getUser(),
$event->getEpochEnd()));
$start_date = $start->getDateTime()->format('m d Y');
$end_date = $end->getDateTime()->format('m d Y');
if ($event->getIsAllDay()) {
if ($start->getValueDay() == $end->getValueDay()) {
if ($start_date == $end_date) {
$tip = pht('All day');
} else {
$tip = pht(
@ -160,9 +163,7 @@ final class PHUICalendarListView extends AphrontTagView {
$end->getValueAsFormat('M j, Y'));
}
} else {
if ($start->getValueDay() == $end->getValueDay() &&
$start->getValueMonth() == $end->getValueMonth() &&
$start->getValueYear() == $end->getValueYear()) {
if ($start->getValueDate() == $end->getValueDate()) {
$tip = pht(
'%s - %s',
$start->getValueAsFormat('g:i A'),

View file

@ -78,25 +78,23 @@ JX.behavior('fancy-datepicker', function() {
var get_inputs = function() {
return {
y: JX.DOM.find(root, 'select', 'year-input'),
m: JX.DOM.find(root, 'select', 'month-input'),
d: JX.DOM.find(root, 'select', 'day-input'),
d: JX.DOM.find(root, 'input', 'date-input'),
t: JX.DOM.find(root, 'input', 'time-input')
};
};
var read_date = function() {
var i = get_inputs();
value_y = +i.y.value;
value_m = +i.m.value;
value_d = +i.d.value;
var date = i.d.value;
var parts = date.split('/');
value_y = +parts[2];
value_m = +parts[0];
value_d = +parts[1];
};
var write_date = function() {
var i = get_inputs();
i.y.value = value_y;
i.m.value = value_m;
i.d.value = value_d;
i.d.value = value_m + '/' + value_d + '/' + value_y;
};
var render = function() {
@ -133,9 +131,12 @@ JX.behavior('fancy-datepicker', function() {
return JX.$N('td', {meta: {value: value}, className: class_name}, label);
};
// Render the top bar which allows you to pick a month and year.
var render_month = function() {
var valid_date = getValidDate();
var month = valid_date.getMonth();
var year = valid_date.getYear() + 1900;
var months = [
'January',
'February',
@ -152,7 +153,7 @@ JX.behavior('fancy-datepicker', function() {
var buttons = [
cell('\u25C0', 'm:-1', false, 'lrbutton'),
cell(months[value_m - 1] + ' ' + value_y, null),
cell(months[month] + ' ' + year, null),
cell('\u25B6', 'm:1', false, 'lrbutton')];
return JX.$N(
@ -161,9 +162,21 @@ JX.behavior('fancy-datepicker', function() {
JX.$N('tr', {}, buttons));
};
function getValidDate() {
var written_date = new Date(value_y, value_m-1, value_d);
if (isNaN(written_date.getTime())) {
return new Date();
} else {
return written_date;
}
}
// Render the day-of-week and calendar views.
var render_day = function() {
var today = new Date();
var valid_date = getValidDate();
var weeks = [];
// First, render the weekday names.
@ -179,16 +192,21 @@ JX.behavior('fancy-datepicker', function() {
// Render the calendar itself. NOTE: Javascript uses 0-based month indexes
// while we use 1-based month indexes, so we have to adjust for that.
var days = [];
var start = new Date(value_y, value_m - 1, 1).getDay();
var start = new Date(
valid_date.getYear() + 1900,
valid_date.getMonth(),
1).getDay();
while (start--) {
days.push(cell('', null, false, 'day-placeholder'));
}
var today = new Date();
for (ii = 1; ii <= 31; ii++) {
var date = new Date(value_y, value_m - 1, ii);
if (date.getMonth() != (value_m - 1)) {
var date = new Date(
valid_date.getYear() + 1900,
valid_date.getMonth(),
ii);
if (date.getMonth() != (valid_date.getMonth())) {
// We've spilled over into the next month, so stop rendering.
break;
}
@ -206,7 +224,11 @@ JX.behavior('fancy-datepicker', function() {
classes.push('weekend');
}
days.push(cell(ii, 'd:'+ii, value_d == ii, classes.join(' ')));
days.push(cell(
ii,
'd:'+ii,
valid_date.getDate() == ii,
classes.join(' ')));
}
// Slice the days into weeks.
@ -263,4 +285,11 @@ JX.behavior('fancy-datepicker', function() {
render();
});
JX.Stratcom.listen('click', null, function(e){
if (e.getNode('phabricator-datepicker')) {
return;
}
onclose();
});
});