mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 12:52:42 +01:00
Make the "All Day Event" control use a checkbox instead of a dropdown
Summary: This feels a little cleaner: - Clean up transaction log a bit. - Use a checkbox instead of a two-option dropdown. This is a little messy because the browser doesn't send anything if the user submits a form with an un-clicked checkbox. We now send a dummy value ("Hey, there's definitely a checkbox in this form!") so the server can figure out what to do. Test Plan: - Edited all-dayness of an event. - Viewed transaction log. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D16776
This commit is contained in:
parent
182611ef7e
commit
f7b0c09ac4
8 changed files with 86 additions and 10 deletions
|
@ -382,7 +382,7 @@ return array(
|
||||||
'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'edd1ba66',
|
'rsrc/js/application/aphlict/behavior-desktop-notifications-control.js' => 'edd1ba66',
|
||||||
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
|
'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18',
|
||||||
'rsrc/js/application/calendar/behavior-day-view.js' => '4b3c4443',
|
'rsrc/js/application/calendar/behavior-day-view.js' => '4b3c4443',
|
||||||
'rsrc/js/application/calendar/behavior-event-all-day.js' => '937bb700',
|
'rsrc/js/application/calendar/behavior-event-all-day.js' => 'b41537c9',
|
||||||
'rsrc/js/application/calendar/behavior-month-view.js' => 'fe33e256',
|
'rsrc/js/application/calendar/behavior-month-view.js' => 'fe33e256',
|
||||||
'rsrc/js/application/calendar/behavior-recurring-edit.js' => '5f1c4d5f',
|
'rsrc/js/application/calendar/behavior-recurring-edit.js' => '5f1c4d5f',
|
||||||
'rsrc/js/application/config/behavior-reorder-fields.js' => 'b6993408',
|
'rsrc/js/application/config/behavior-reorder-fields.js' => 'b6993408',
|
||||||
|
@ -651,7 +651,7 @@ return array(
|
||||||
'javelin-behavior-editengine-reorder-configs' => 'd7a74243',
|
'javelin-behavior-editengine-reorder-configs' => 'd7a74243',
|
||||||
'javelin-behavior-editengine-reorder-fields' => 'b59e1e96',
|
'javelin-behavior-editengine-reorder-fields' => 'b59e1e96',
|
||||||
'javelin-behavior-error-log' => '6882e80a',
|
'javelin-behavior-error-log' => '6882e80a',
|
||||||
'javelin-behavior-event-all-day' => '937bb700',
|
'javelin-behavior-event-all-day' => 'b41537c9',
|
||||||
'javelin-behavior-fancy-datepicker' => '568931f3',
|
'javelin-behavior-fancy-datepicker' => '568931f3',
|
||||||
'javelin-behavior-global-drag-and-drop' => '960f6a39',
|
'javelin-behavior-global-drag-and-drop' => '960f6a39',
|
||||||
'javelin-behavior-herald-rule-editor' => '7ebaeed3',
|
'javelin-behavior-herald-rule-editor' => '7ebaeed3',
|
||||||
|
|
|
@ -3,8 +3,21 @@
|
||||||
final class AphrontBoolHTTPParameterType
|
final class AphrontBoolHTTPParameterType
|
||||||
extends AphrontHTTPParameterType {
|
extends AphrontHTTPParameterType {
|
||||||
|
|
||||||
|
protected function getParameterExists(AphrontRequest $request, $key) {
|
||||||
|
if ($request->getExists($key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$checkbox_key = $this->getCheckboxKey($key);
|
||||||
|
if ($request->getExists($checkbox_key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getParameterValue(AphrontRequest $request, $key) {
|
protected function getParameterValue(AphrontRequest $request, $key) {
|
||||||
return $request->getBool($key);
|
return (bool)$request->getBool($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getParameterTypeName() {
|
protected function getParameterTypeName() {
|
||||||
|
@ -26,4 +39,8 @@ final class AphrontBoolHTTPParameterType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCheckboxKey($key) {
|
||||||
|
return "{$key}.exists";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,8 +90,8 @@ final class PhabricatorCalendarEventEditEngine
|
||||||
->setValue($object->getName()),
|
->setValue($object->getName()),
|
||||||
id(new PhabricatorBoolEditField())
|
id(new PhabricatorBoolEditField())
|
||||||
->setKey('isAllDay')
|
->setKey('isAllDay')
|
||||||
->setLabel(pht('All Day'))
|
|
||||||
->setOptions(pht('Normal Event'), pht('All Day Event'))
|
->setOptions(pht('Normal Event'), pht('All Day Event'))
|
||||||
|
->setAsCheckbox(true)
|
||||||
->setTransactionType(
|
->setTransactionType(
|
||||||
PhabricatorCalendarEventAllDayTransaction::TRANSACTIONTYPE)
|
PhabricatorCalendarEventAllDayTransaction::TRANSACTIONTYPE)
|
||||||
->setDescription(pht('Marks this as an all day event.'))
|
->setDescription(pht('Marks this as an all day event.'))
|
||||||
|
|
|
@ -39,7 +39,7 @@ final class PhabricatorCalendarEventAllDayTransaction
|
||||||
public function getTitle() {
|
public function getTitle() {
|
||||||
if ($this->getNewValue()) {
|
if ($this->getNewValue()) {
|
||||||
return pht(
|
return pht(
|
||||||
'%s changed this as an all day event.',
|
'%s changed this to an all day event.',
|
||||||
$this->renderAuthor());
|
$this->renderAuthor());
|
||||||
} else {
|
} else {
|
||||||
return pht(
|
return pht(
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class PhabricatorBoolEditField
|
||||||
extends PhabricatorEditField {
|
extends PhabricatorEditField {
|
||||||
|
|
||||||
private $options;
|
private $options;
|
||||||
|
private $asCheckbox;
|
||||||
|
|
||||||
public function setOptions($off_label, $on_label) {
|
public function setOptions($off_label, $on_label) {
|
||||||
$this->options = array(
|
$this->options = array(
|
||||||
|
@ -17,6 +18,15 @@ final class PhabricatorBoolEditField
|
||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setAsCheckbox($as_checkbox) {
|
||||||
|
$this->asCheckbox = $as_checkbox;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAsCheckbox() {
|
||||||
|
return $this->asCheckbox;
|
||||||
|
}
|
||||||
|
|
||||||
protected function newControl() {
|
protected function newControl() {
|
||||||
$options = $this->getOptions();
|
$options = $this->getOptions();
|
||||||
|
|
||||||
|
@ -27,10 +37,24 @@ final class PhabricatorBoolEditField
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return id(new AphrontFormSelectControl())
|
if ($this->getAsCheckbox()) {
|
||||||
|
$key = $this->getKey();
|
||||||
|
$value = $this->getValueForControl();
|
||||||
|
$checkbox_key = $this->newHTTPParameterType()
|
||||||
|
->getCheckboxKey($key);
|
||||||
|
$id = $this->getControlID();
|
||||||
|
|
||||||
|
$control = id(new AphrontFormCheckboxControl())
|
||||||
|
->setCheckboxKey($checkbox_key)
|
||||||
|
->addCheckbox($key, '1', $options['1'], $value, $id);
|
||||||
|
} else {
|
||||||
|
$control = id(new AphrontFormSelectControl())
|
||||||
->setOptions($options);
|
->setOptions($options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $control;
|
||||||
|
}
|
||||||
|
|
||||||
protected function newHTTPParameterType() {
|
protected function newHTTPParameterType() {
|
||||||
return new AphrontBoolHTTPParameterType();
|
return new AphrontBoolHTTPParameterType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -553,10 +553,18 @@ abstract class PhabricatorApplicationTransaction
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($old) && !strlen($old)) {
|
if (!is_array($old)) {
|
||||||
|
if (!strlen($old)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The integer 0 is also uninteresting by default; this is often
|
||||||
|
// an "off" flag for something like "All Day Event".
|
||||||
|
if ($old === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,16 @@
|
||||||
final class AphrontFormCheckboxControl extends AphrontFormControl {
|
final class AphrontFormCheckboxControl extends AphrontFormControl {
|
||||||
|
|
||||||
private $boxes = array();
|
private $boxes = array();
|
||||||
|
private $checkboxKey;
|
||||||
|
|
||||||
|
public function setCheckboxKey($checkbox_key) {
|
||||||
|
$this->checkboxKey = $checkbox_key;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCheckboxKey() {
|
||||||
|
return $this->checkboxKey;
|
||||||
|
}
|
||||||
|
|
||||||
public function addCheckbox(
|
public function addCheckbox(
|
||||||
$name,
|
$name,
|
||||||
|
@ -52,6 +62,23 @@ final class AphrontFormCheckboxControl extends AphrontFormControl {
|
||||||
phutil_tag('th', array(), $label),
|
phutil_tag('th', array(), $label),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When a user submits a form with a checkbox unchecked, the browser
|
||||||
|
// doesn't submit anything to the server. This hidden key lets the server
|
||||||
|
// know that the checkboxes were present on the client, the user just did
|
||||||
|
// not select any of them.
|
||||||
|
|
||||||
|
$checkbox_key = $this->getCheckboxKey();
|
||||||
|
if ($checkbox_key) {
|
||||||
|
$rows[] = phutil_tag(
|
||||||
|
'input',
|
||||||
|
array(
|
||||||
|
'type' => 'hidden',
|
||||||
|
'name' => $checkbox_key,
|
||||||
|
'value' => 1,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return phutil_tag(
|
return phutil_tag(
|
||||||
'table',
|
'table',
|
||||||
array('class' => 'aphront-form-control-checkbox-layout'),
|
array('class' => 'aphront-form-control-checkbox-layout'),
|
||||||
|
|
|
@ -6,7 +6,7 @@ JX.behavior('event-all-day', function(config) {
|
||||||
var all_day = JX.$(config.allDayID);
|
var all_day = JX.$(config.allDayID);
|
||||||
|
|
||||||
JX.DOM.listen(all_day, 'change', null, function() {
|
JX.DOM.listen(all_day, 'change', null, function() {
|
||||||
var is_all_day = !!parseInt(all_day.value, 10);
|
var is_all_day = !!all_day.checked;
|
||||||
|
|
||||||
for (var ii = 0; ii < config.controlIDs.length; ii++) {
|
for (var ii = 0; ii < config.controlIDs.length; ii++) {
|
||||||
var control = JX.$(config.controlIDs[ii]);
|
var control = JX.$(config.controlIDs[ii]);
|
||||||
|
|
Loading…
Reference in a new issue