@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Time control typeaheads.

Summary: Ref T8031, Time control typeaheads

Test Plan: Edit an event, type '3', typeahead should suggest, '3:00 AM', '3:30 AM', '3:00 PM', '3:30 PM'.

Reviewers: chad, epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin, epriestley

Maniphest Tasks: T8031

Differential Revision: https://secure.phabricator.com/D12953

+110 -15
+19 -9
resources/celerity/map.php
··· 7 7 */ 8 8 return array( 9 9 'names' => array( 10 - 'core.pkg.css' => 'e3ba62e8', 10 + 'core.pkg.css' => '36142bff', 11 11 'core.pkg.js' => '328799d0', 12 12 'darkconsole.pkg.js' => 'e7393ebb', 13 13 'differential.pkg.css' => 'bb338e4b', ··· 134 134 'rsrc/css/phui/phui-document.css' => '94d5dcd8', 135 135 'rsrc/css/phui/phui-feed-story.css' => 'c9f3a0b5', 136 136 'rsrc/css/phui/phui-fontkit.css' => 'dd8ddf27', 137 - 'rsrc/css/phui/phui-form-view.css' => '94ae3032', 137 + 'rsrc/css/phui/phui-form-view.css' => '79793450', 138 138 'rsrc/css/phui/phui-form.css' => 'f535f938', 139 139 'rsrc/css/phui/phui-header-view.css' => '75aaf372', 140 140 'rsrc/css/phui/phui-icon.css' => 'bc766998', ··· 231 231 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js' => '8b3fd187', 232 232 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '54f314a0', 233 233 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '2818f5ce', 234 - 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '316b8fa1', 234 + 'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '6c0e62fa', 235 235 'rsrc/externals/raphael/g.raphael.js' => '40dde778', 236 236 'rsrc/externals/raphael/g.raphael.line.js' => '40da039e', 237 237 'rsrc/externals/raphael/raphael.js' => '51ee6b43', ··· 466 466 'rsrc/js/core/behavior-scrollbar.js' => '834a1173', 467 467 'rsrc/js/core/behavior-search-typeahead.js' => '048330fa', 468 468 'rsrc/js/core/behavior-select-on-click.js' => '4e3e79a6', 469 + 'rsrc/js/core/behavior-time-typeahead.js' => '8cf340fd', 469 470 'rsrc/js/core/behavior-toggle-class.js' => '5d7c9f33', 470 471 'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884', 471 472 'rsrc/js/core/behavior-tooltip.js' => '3ee3408b', ··· 640 641 'javelin-behavior-slowvote-embed' => '887ad43f', 641 642 'javelin-behavior-stripe-payment-form' => '3f5d6dbf', 642 643 'javelin-behavior-test-payment-form' => 'fc91ab6c', 644 + 'javelin-behavior-time-typeahead' => '8cf340fd', 643 645 'javelin-behavior-toggle-class' => '5d7c9f33', 644 646 'javelin-behavior-typeahead-browse' => '635de1ec', 645 647 'javelin-behavior-typeahead-search' => '93d0c9e3', ··· 677 679 'javelin-typeahead-ondemand-source' => '8b3fd187', 678 680 'javelin-typeahead-preloaded-source' => '54f314a0', 679 681 'javelin-typeahead-source' => '2818f5ce', 680 - 'javelin-typeahead-static-source' => '316b8fa1', 682 + 'javelin-typeahead-static-source' => '6c0e62fa', 681 683 'javelin-uri' => '6eff08aa', 682 684 'javelin-util' => '93cc50d6', 683 685 'javelin-vector' => '2caa8fb8', ··· 772 774 'phui-font-icon-base-css' => '3dad2ae3', 773 775 'phui-fontkit-css' => 'dd8ddf27', 774 776 'phui-form-css' => 'f535f938', 775 - 'phui-form-view-css' => '94ae3032', 777 + 'phui-form-view-css' => '79793450', 776 778 'phui-header-view-css' => '75aaf372', 777 779 'phui-icon-view-css' => 'bc766998', 778 780 'phui-image-mask-css' => '5a8b09c8', ··· 1036 1038 'javelin-install', 1037 1039 'javelin-event', 1038 1040 ), 1039 - '316b8fa1' => array( 1040 - 'javelin-install', 1041 - 'javelin-typeahead-source', 1042 - ), 1043 1041 '331b1611' => array( 1044 1042 'javelin-install', 1045 1043 ), ··· 1307 1305 '69adf288' => array( 1308 1306 'javelin-install', 1309 1307 ), 1308 + '6c0e62fa' => array( 1309 + 'javelin-install', 1310 + 'javelin-typeahead-source', 1311 + ), 1310 1312 '6c2b09a2' => array( 1311 1313 'javelin-install', 1312 1314 'javelin-util', ··· 1481 1483 'phabricator-notification', 1482 1484 'javelin-stratcom', 1483 1485 'javelin-behavior', 1486 + ), 1487 + '8cf340fd' => array( 1488 + 'javelin-behavior', 1489 + 'javelin-util', 1490 + 'javelin-dom', 1491 + 'javelin-stratcom', 1492 + 'javelin-vector', 1493 + 'javelin-typeahead-static-source', 1484 1494 ), 1485 1495 '8cf6d262' => array( 1486 1496 'javelin-install',
+37 -1
src/view/form/control/AphrontFormDateControl.php
··· 270 270 ), 271 271 $cicon); 272 272 273 + $values = $this->getTimeTypeaheadValues(); 274 + 275 + $time_id = celerity_generate_unique_node_id(); 276 + Javelin::initBehavior('time-typeahead', array( 277 + 'timeID' => $time_id, 278 + 'timeValues' => $values, 279 + )); 280 + 281 + 273 282 $time_sel = javelin_tag( 274 283 'input', 275 284 array( 285 + 'autocomplete' => 'off', 276 286 'name' => $this->getTimeInputName(), 277 287 'sigil' => 'time-input', 278 288 'value' => $this->getTimeInputValue(), ··· 280 290 'class' => 'aphront-form-date-time-input', 281 291 ), 282 292 ''); 293 + 294 + $time_div = javelin_tag( 295 + 'div', 296 + array( 297 + 'id' => $time_id, 298 + 'class' => 'aphront-form-date-time-input-container', 299 + ), 300 + $time_sel); 283 301 284 302 Javelin::initBehavior('fancy-datepicker', array()); 285 303 ··· 308 326 $months_sel, 309 327 $years_sel, 310 328 $cal_icon, 311 - $time_sel, 329 + $time_div, 312 330 )); 313 331 } 314 332 ··· 357 375 } 358 376 359 377 return $value; 378 + } 379 + 380 + private function getTimeTypeaheadValues() { 381 + $times = array(); 382 + $am_pm_list = array('AM', 'PM'); 383 + 384 + foreach ($am_pm_list as $am_pm) { 385 + for ($hour = 0; $hour < 12; $hour++) { 386 + $actual_hour = ($hour == 0) ? 12 : $hour; 387 + $times[] = $actual_hour.':00 '.$am_pm; 388 + $times[] = $actual_hour.':30 '.$am_pm; 389 + } 390 + } 391 + 392 + foreach ($times as $key => $time) { 393 + $times[$key] = array($key, $time); 394 + } 395 + return $times; 360 396 } 361 397 362 398 }
+14 -1
webroot/rsrc/css/phui/phui-form-view.css
··· 334 334 font-size: 16px; 335 335 } 336 336 337 + .aphront-form-date-container .aphront-form-date-time-input-container { 338 + position: relative; 339 + display: inline-block; 340 + width: 7em; 341 + } 342 + 337 343 .aphront-form-date-container input.aphront-form-date-time-input { 338 344 width: 7em; 339 - display: inline; 345 + } 346 + 347 + .aphront-form-date-time-input-container div.jx-typeahead-results a.jx-result { 348 + border: none; 349 + } 350 + 351 + .phui-time-typeahead-value { 352 + padding: 4px; 340 353 } 341 354 342 355 .fancy-datepicker {
+4 -4
webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js
··· 16 16 17 17 construct : function(data) { 18 18 JX.TypeaheadSource.call(this); 19 - this._data = data; 19 + this.data = data; 20 20 }, 21 21 22 22 members : { 23 - _data : null, 23 + data : null, 24 24 25 25 didChange : function(value) { 26 26 this.matchResults(value); 27 27 }, 28 28 29 29 didStart : function() { 30 - for (var ii = 0; ii < this._data.length; ii++) { 31 - this.addResult(this._data[ii]); 30 + for (var ii = 0; ii < this.data.length; ii++) { 31 + this.addResult(this.data[ii]); 32 32 } 33 33 } 34 34 }
+36
webroot/rsrc/js/core/behavior-time-typeahead.js
··· 1 + /** 2 + * @provides javelin-behavior-time-typeahead 3 + * @requires javelin-behavior 4 + * javelin-util 5 + * javelin-dom 6 + * javelin-stratcom 7 + * javelin-vector 8 + * javelin-typeahead-static-source 9 + */ 10 + 11 + JX.behavior('time-typeahead', function(config) { 12 + var root = JX.$(config.timeID); 13 + var datasource = new JX.TypeaheadStaticSource(config.timeValues); 14 + datasource.setTransformer(function(v) { 15 + var attributes = {'className' : 'phui-time-typeahead-value'}; 16 + var display = JX.$N('div', attributes, v[1]); 17 + var object = { 18 + 'id' : v[0], 19 + 'name' : v[1], 20 + 'display' : display, 21 + 'uri' : null 22 + }; 23 + return object; 24 + }); 25 + datasource.setSortHandler(function(value, list) { 26 + list.sort(function(u,v){ 27 + return (u.id > v.id) ? 1 : -1; 28 + }); 29 + }); 30 + datasource.setMaximumResultCount(24); 31 + var typeahead = new JX.Typeahead( 32 + root, 33 + JX.DOM.find(root, 'input', null)); 34 + typeahead.setDatasource(datasource); 35 + typeahead.start(); 36 + });