Add datetime picker for start date
This commit is contained in:
@@ -64,7 +64,7 @@ class Task extends Base
|
||||
'time_spent' => $task['time_spent'] ?: '',
|
||||
);
|
||||
|
||||
$this->dateParser->format($values, array('date_started'));
|
||||
$this->dateParser->format($values, array('date_started'), 'Y-m-d H:i');
|
||||
|
||||
$this->response->html($this->taskLayout('task/show', array(
|
||||
'project' => $this->project->getById($task['project_id']),
|
||||
|
||||
@@ -85,8 +85,7 @@ class DateParser extends Base
|
||||
*/
|
||||
public function getTimestamp($value)
|
||||
{
|
||||
foreach ($this->getDateFormats() as $format) {
|
||||
|
||||
foreach ($this->getAllFormats() as $format) {
|
||||
$timestamp = $this->getValidDate($value, $format);
|
||||
|
||||
if ($timestamp !== 0) {
|
||||
@@ -97,6 +96,25 @@ class DateParser extends Base
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all combinations of date/time formats
|
||||
*
|
||||
* @access public
|
||||
* @return []string
|
||||
*/
|
||||
public function getAllFormats()
|
||||
{
|
||||
$formats = array();
|
||||
|
||||
foreach ($this->getDateFormats() as $date) {
|
||||
foreach ($this->getTimeFormats() as $time) {
|
||||
$formats[] = $date.' '.$time;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($formats, $this->getDateFormats());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of supported date formats (for the parser)
|
||||
*
|
||||
@@ -112,6 +130,21 @@ class DateParser extends Base
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of supported time formats (for the parser)
|
||||
*
|
||||
* @access public
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTimeFormats()
|
||||
{
|
||||
return array(
|
||||
'H:i',
|
||||
'g:i A',
|
||||
'g:iA',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of available date formats (for the config page)
|
||||
*
|
||||
@@ -143,7 +176,7 @@ class DateParser extends Base
|
||||
* Get a timetstamp from an ISO date format
|
||||
*
|
||||
* @access public
|
||||
* @param string $date Date format
|
||||
* @param string $date
|
||||
* @return integer
|
||||
*/
|
||||
public function getTimestampFromIsoFormat($date)
|
||||
@@ -166,7 +199,6 @@ class DateParser extends Base
|
||||
}
|
||||
|
||||
foreach ($fields as $field) {
|
||||
|
||||
if (! empty($values[$field])) {
|
||||
$values[$field] = date($format, $values[$field]);
|
||||
}
|
||||
@@ -180,15 +212,16 @@ class DateParser extends Base
|
||||
* Convert date (form input data)
|
||||
*
|
||||
* @access public
|
||||
* @param array $values Database values
|
||||
* @param string[] $fields Date fields
|
||||
* @param array $values Database values
|
||||
* @param string[] $fields Date fields
|
||||
* @param boolean $keep_time Keep time or not
|
||||
*/
|
||||
public function convert(array &$values, array $fields)
|
||||
public function convert(array &$values, array $fields, $keep_time = false)
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
|
||||
if (! empty($values[$field]) && ! is_numeric($values[$field])) {
|
||||
$values[$field] = $this->removeTimeFromTimestamp($this->getTimestamp($values[$field]));
|
||||
$timestamp = $this->getTimestamp($values[$field]);
|
||||
$values[$field] = $keep_time ? $timestamp : $this->removeTimeFromTimestamp($timestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ class TaskCreation extends Base
|
||||
*/
|
||||
public function prepare(array &$values)
|
||||
{
|
||||
$this->dateParser->convert($values, array('date_due', 'date_started'));
|
||||
$this->dateParser->convert($values, array('date_due'));
|
||||
$this->dateParser->convert($values, array('date_started'), true);
|
||||
$this->removeFields($values, array('another_task'));
|
||||
$this->resetFields($values, array('owner_id', 'swimlane_id', 'date_due', 'score', 'category_id', 'time_estimated'));
|
||||
|
||||
|
||||
@@ -83,7 +83,8 @@ class TaskModification extends Base
|
||||
*/
|
||||
public function prepare(array &$values)
|
||||
{
|
||||
$this->dateParser->convert($values, array('date_due', 'date_started'));
|
||||
$this->dateParser->convert($values, array('date_due'));
|
||||
$this->dateParser->convert($values, array('date_started'), true);
|
||||
$this->removeFields($values, array('another_task', 'id'));
|
||||
$this->resetFields($values, array('date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent'));
|
||||
$this->convertIntegerFields($values, array('is_active', 'recurrence_status', 'recurrence_trigger', 'recurrence_factor', 'recurrence_timeframe', 'recurrence_basedate'));
|
||||
|
||||
@@ -39,7 +39,7 @@ class TaskValidator extends Base
|
||||
new Validators\Integer('recurrence_status', t('This value must be an integer')),
|
||||
new Validators\MaxLength('title', t('The maximum length is %d characters', 200), 200),
|
||||
new Validators\Date('date_due', t('Invalid date'), $this->dateParser->getDateFormats()),
|
||||
new Validators\Date('date_started', t('Invalid date'), $this->dateParser->getDateFormats()),
|
||||
new Validators\Date('date_started', t('Invalid date'), $this->dateParser->getAllFormats()),
|
||||
new Validators\Numeric('time_spent', t('This value must be numeric')),
|
||||
new Validators\Numeric('time_estimated', t('This value must be numeric')),
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<?= $this->form->hidden('id', $values) ?>
|
||||
|
||||
<?= $this->form->label(t('Start date'), 'date_started') ?>
|
||||
<?= $this->form->text('date_started', $values, array(), array('placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-date') ?>
|
||||
<?= $this->form->text('date_started', $values, array(), array('placeholder="'.$this->text->in($date_format, $date_formats).'"'), 'form-datetime') ?>
|
||||
|
||||
<?= $this->form->label(t('Time estimated'), 'time_estimated') ?>
|
||||
<?= $this->form->numeric('time_estimated', $values, array(), array('placeholder="'.t('hours').'"')) ?>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -52,3 +52,8 @@ hr {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* datepicker */
|
||||
#ui-datepicker-div {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
@@ -137,6 +137,7 @@ ul.form-errors li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
input.form-datetime,
|
||||
input.form-date {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
/* datepicker */
|
||||
#ui-datepicker-div {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/* pagination */
|
||||
.pagination {
|
||||
text-align: center;
|
||||
|
||||
5
assets/css/vendor/jquery-ui-timepicker-addon.min.css
vendored
Normal file
5
assets/css/vendor/jquery-ui-timepicker-addon.min.css
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/*! jQuery Timepicker Addon - v1.5.5 - 2015-05-24
|
||||
* http://trentrichardson.com/examples/timepicker
|
||||
* Copyright (c) 2015 Trent Richardson; Licensed MIT */
|
||||
|
||||
.ui-timepicker-div .ui-widget-header{margin-bottom:8px}.ui-timepicker-div dl{text-align:left}.ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.ui-timepicker-div dl dd{margin:0 10px 10px 40%}.ui-timepicker-div td{font-size:90%}.ui-tpicker-grid-label{background:0 0;border:0;margin:0;padding:0}.ui-timepicker-div .ui_tpicker_unit_hide{display:none}.ui-timepicker-rtl{direction:rtl}.ui-timepicker-rtl dl{text-align:right;padding:0 5px 0 0}.ui-timepicker-rtl dl dt{float:right;clear:right}.ui-timepicker-rtl dl dd{margin:0 40% 10px 10px}.ui-timepicker-div.ui-timepicker-oneLine{padding-right:2px}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,.ui-timepicker-div.ui-timepicker-oneLine dt{display:none}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label{display:block;padding-top:2px}.ui-timepicker-div.ui-timepicker-oneLine dl{text-align:right}.ui-timepicker-div.ui-timepicker-oneLine dl dd,.ui-timepicker-div.ui-timepicker-oneLine dl dd>div{display:inline-block;margin:0}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before{content:':';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before{content:'.';display:inline-block}.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{display:none}
|
||||
File diff suppressed because one or more lines are too long
@@ -277,6 +277,15 @@ var Kanboard = (function() {
|
||||
constrainInput: false
|
||||
});
|
||||
|
||||
// Datetime picker
|
||||
$(".form-datetime").datetimepicker({
|
||||
controlType: 'select',
|
||||
oneLine: true,
|
||||
dateFormat: 'yy-mm-dd',
|
||||
// timeFormat: 'h:mm tt',
|
||||
constrainInput: false
|
||||
});
|
||||
|
||||
// Markdown Preview for textareas
|
||||
$("#markdown-preview").click(Kanboard.MarkdownPreview);
|
||||
$("#markdown-write").click(Kanboard.MarkdownWriter);
|
||||
|
||||
5
assets/js/vendor/jquery-ui-timepicker-addon.min.js
vendored
Normal file
5
assets/js/vendor/jquery-ui-timepicker-addon.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -2,10 +2,10 @@
|
||||
|
||||
print_css="print links table board task comment subtask markdown"
|
||||
app_css="base links title table form button alert tooltip header board task comment subtask markdown listing activity dashboard pagination popover confirm sidebar responsive dropdown screenshot filters"
|
||||
vendor_css="jquery-ui.min chosen.min fullcalendar.min font-awesome.min c3.min"
|
||||
vendor_css="jquery-ui.min jquery-ui-timepicker-addon.min chosen.min fullcalendar.min font-awesome.min c3.min"
|
||||
|
||||
app_js="base board calendar analytic swimlane screenshot"
|
||||
vendor_js="jquery-1.11.1.min jquery-ui.min jquery.ui.touch-punch.min chosen.jquery.min dropit.min moment.min fullcalendar.min mousetrap.min mousetrap-global-bind.min app.min"
|
||||
vendor_js="jquery-1.11.1.min jquery-ui.min jquery-ui-timepicker-addon.min jquery.ui.touch-punch.min chosen.jquery.min dropit.min moment.min fullcalendar.min mousetrap.min mousetrap-global-bind.min app.min"
|
||||
lang_js="da de es fi fr hu it ja nl pl pt-br ru sv sr th tr zh-cn"
|
||||
|
||||
function merge_css {
|
||||
|
||||
@@ -56,6 +56,12 @@ class DateParserTest extends Base
|
||||
$this->assertEquals('2014-03-05', date('Y-m-d', $d->getTimestamp('2014-03-05')));
|
||||
$this->assertEquals('2014-03-05', date('Y-m-d', $d->getTimestamp('2014_03_05')));
|
||||
$this->assertEquals('2014-03-05', date('Y-m-d', $d->getTimestamp('03/05/2014')));
|
||||
$this->assertEquals('2014-03-25 17:18', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 5:18 pm')));
|
||||
$this->assertEquals('2014-03-25 05:18', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 5:18 am')));
|
||||
$this->assertEquals('2014-03-25 05:18', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 5:18am')));
|
||||
$this->assertEquals('2014-03-25 23:14', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 23:14')));
|
||||
$this->assertEquals('2014-03-29 23:14', date('Y-m-d H:i', $d->getTimestamp('2014_03_29 23:14')));
|
||||
$this->assertEquals('2014-03-29 23:14', date('Y-m-d H:i', $d->getTimestamp('2014-03-29 23:14')));
|
||||
}
|
||||
|
||||
public function testConvert()
|
||||
|
||||
@@ -284,29 +284,35 @@ class TaskCreationTest extends Base
|
||||
|
||||
public function testDateStarted()
|
||||
{
|
||||
$date = '2014-11-23';
|
||||
$timestamp = strtotime('+2days');
|
||||
$p = new Project($this->container);
|
||||
$tc = new TaskCreation($this->container);
|
||||
$tf = new TaskFinder($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test', 'date_started' => $date)));
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 1, 'title' => 'test', 'date_started' => $timestamp)));
|
||||
|
||||
// Set only a date
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'test', 'date_started' => '2014-11-24')));
|
||||
|
||||
$task = $tf->getById(1);
|
||||
$this->assertNotEmpty($task);
|
||||
$this->assertNotFalse($task);
|
||||
$this->assertEquals('2014-11-24 '.date('H:i'), date('Y-m-d H:i', $task['date_started']));
|
||||
|
||||
$this->assertEquals(1, $task['id']);
|
||||
$this->assertEquals($date, date('Y-m-d', $task['date_started']));
|
||||
// Set a datetime
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 1, 'title' => 'test', 'date_started' => '2014-11-24 16:25')));
|
||||
|
||||
$task = $tf->getById(2);
|
||||
$this->assertNotEmpty($task);
|
||||
$this->assertNotFalse($task);
|
||||
$this->assertEquals('2014-11-24 16:25', date('Y-m-d H:i', $task['date_started']));
|
||||
|
||||
$this->assertEquals(2, $task['id']);
|
||||
$this->assertEquals($timestamp, $task['date_started']);
|
||||
// Set a datetime
|
||||
$this->assertEquals(3, $tc->create(array('project_id' => 1, 'title' => 'test', 'date_started' => '2014-11-24 6:25pm')));
|
||||
|
||||
$task = $tf->getById(3);
|
||||
$this->assertEquals('2014-11-24 18:25', date('Y-m-d H:i', $task['date_started']));
|
||||
|
||||
// Set a timestamp
|
||||
$this->assertEquals(4, $tc->create(array('project_id' => 1, 'title' => 'test', 'date_started' => time())));
|
||||
|
||||
$task = $tf->getById(4);
|
||||
$this->assertEquals(time(), $task['date_started'], '', 1);
|
||||
}
|
||||
|
||||
public function testTime()
|
||||
|
||||
@@ -202,15 +202,29 @@ class TaskModificationTest extends Base
|
||||
$task = $tf->getById(1);
|
||||
$this->assertEquals(0, $task['date_started']);
|
||||
|
||||
// Set only a date
|
||||
$this->assertTrue($tm->update(array('id' => 1, 'date_started' => '2014-11-24')));
|
||||
|
||||
$task = $tf->getById(1);
|
||||
$this->assertEquals('2014-11-24', date('Y-m-d', $task['date_started']));
|
||||
$this->assertEquals('2014-11-24 '.date('H:i'), date('Y-m-d H:i', $task['date_started']));
|
||||
|
||||
// Set a datetime
|
||||
$this->assertTrue($tm->update(array('id' => 1, 'date_started' => '2014-11-24 16:25')));
|
||||
|
||||
$task = $tf->getById(1);
|
||||
$this->assertEquals('2014-11-24 16:25', date('Y-m-d H:i', $task['date_started']));
|
||||
|
||||
// Set a datetime
|
||||
$this->assertTrue($tm->update(array('id' => 1, 'date_started' => '2014-11-24 6:25pm')));
|
||||
|
||||
$task = $tf->getById(1);
|
||||
$this->assertEquals('2014-11-24 18:25', date('Y-m-d H:i', $task['date_started']));
|
||||
|
||||
// Set a timestamp
|
||||
$this->assertTrue($tm->update(array('id' => 1, 'date_started' => time())));
|
||||
|
||||
$task = $tf->getById(1);
|
||||
$this->assertEquals(date('Y-m-d'), date('Y-m-d', $task['date_started']));
|
||||
$this->assertEquals(time(), $task['date_started'], '', 1);
|
||||
}
|
||||
|
||||
public function testChangeTimeEstimated()
|
||||
|
||||
Reference in New Issue
Block a user