diff --git src/wp-admin/js/customize-controls.js src/wp-admin/js/customize-controls.js
index 0504891969..6e1f513ef5 100644
|
|
|
5552 | 5552 | var input = $( this ), component, element; |
5553 | 5553 | component = input.data( 'component' ); |
5554 | 5554 | element = new api.Element( input ); |
5555 | | if ( 'meridian' === component ) { |
5556 | | element.validate = function( value ) { |
5557 | | if ( 'am' !== value && 'pm' !== value ) { |
5558 | | return null; |
5559 | | } |
5560 | | return value; |
5561 | | }; |
5562 | | } else { |
5563 | | element.validate = function( value ) { |
5564 | | var val = parseInt( value, 10 ); |
5565 | | if ( isNaN( val ) ) { |
5566 | | return null; |
5567 | | } |
5568 | | return val; |
5569 | | }; |
5570 | | } |
5571 | | element.bind( control.populateSetting ); |
5572 | 5555 | control.inputElements[ component ] = element; |
5573 | 5556 | control.elements.push( element ); |
| 5557 | |
| 5558 | // Add invalid date error once user changes (and has blured |
| 5559 | input.on( 'change', function() { |
| 5560 | if ( control.invalidDate ) { |
| 5561 | control.notifications.add( new api.Notification( 'invalid_date', { |
| 5562 | message: api.l10n.invalidDate |
| 5563 | } ) ); |
| 5564 | } |
| 5565 | } ); |
| 5566 | input.on( 'input', _.debounce( function() { |
| 5567 | if ( ! control.invalidDate ) { |
| 5568 | control.notifications.remove( 'invalid_date' ); |
| 5569 | } |
| 5570 | } ) ); |
5574 | 5571 | } ); |
5575 | 5572 | |
5576 | 5573 | control.inputElements.month.bind( control.updateDaysForMonth ); |
… |
… |
|
5580 | 5577 | } |
5581 | 5578 | control.populateDateInputs(); |
5582 | 5579 | control.setting.bind( control.populateDateInputs ); |
| 5580 | |
| 5581 | // Start populating setting after it has been populated. |
| 5582 | _.each( control.inputElements, function( element ) { |
| 5583 | element.bind( control.populateSetting ); |
| 5584 | } ); |
5583 | 5585 | }, |
5584 | 5586 | |
5585 | 5587 | /** |
… |
… |
|
5629 | 5631 | * @return {boolean} If date input fields has error. |
5630 | 5632 | */ |
5631 | 5633 | validateInputs: function validateInputs() { |
5632 | | var control = this, errorMessage, components; |
| 5634 | var control = this, components, validityInput; |
5633 | 5635 | |
5634 | 5636 | control.invalidDate = false; |
5635 | 5637 | |
… |
… |
|
5638 | 5640 | components.push( 'hour', 'minute' ); |
5639 | 5641 | } |
5640 | 5642 | |
5641 | | _.each( components, function( component ) { |
5642 | | var element, el, max, min, value; |
| 5643 | _.find( components, function( component ) { |
| 5644 | var element, max, min, value; |
| 5645 | |
| 5646 | element = control.inputElements[ component ]; |
| 5647 | validityInput = element.element.get( 0 ); |
| 5648 | max = parseInt( element.element.attr( 'max' ), 10 ); |
| 5649 | min = parseInt( element.element.attr( 'min' ), 10 ); |
| 5650 | value = parseInt( element(), 10 ); |
| 5651 | control.invalidDate = isNaN( value ) || value > max || value < min; |
5643 | 5652 | |
5644 | 5653 | if ( ! control.invalidDate ) { |
5645 | | element = control.inputElements[ component ]; |
5646 | | el = element.element.get( 0 ); |
5647 | | max = parseInt( element.element.attr( 'max' ), 10 ); |
5648 | | min = parseInt( element.element.attr( 'min' ), 10 ); |
5649 | | value = element(); |
5650 | | control.invalidDate = value > max || value < min; |
5651 | | errorMessage = control.invalidDate ? api.l10n.invalid + ' ' + component : ''; |
5652 | | |
5653 | | el.setCustomValidity( errorMessage ); |
5654 | | if ( ! control.section() || api.section.has( control.section() ) && api.section( control.section() ).expanded() ) { |
5655 | | _.result( el, 'reportValidity' ); |
5656 | | } |
| 5654 | validityInput.setCustomValidity( '' ); |
5657 | 5655 | } |
| 5656 | |
| 5657 | return control.invalidDate; |
5658 | 5658 | } ); |
5659 | 5659 | |
| 5660 | if ( control.inputElements.meridian && ! control.invalidDate ) { |
| 5661 | validityInput = control.inputElements.meridian.element.get( 0 ); |
| 5662 | if ( 'am' !== control.inputElements.meridian.get() && 'pm' !== control.inputElements.meridian.get() ) { |
| 5663 | control.invalidDate = true; |
| 5664 | } else { |
| 5665 | validityInput.setCustomValidity( '' ); |
| 5666 | } |
| 5667 | } |
| 5668 | |
| 5669 | if ( control.invalidDate ) { |
| 5670 | validityInput.setCustomValidity( api.l10n.invalidValue ); |
| 5671 | } else { |
| 5672 | validityInput.setCustomValidity( '' ); |
| 5673 | } |
| 5674 | if ( ! control.section() || api.section.has( control.section() ) && api.section( control.section() ).expanded() ) { |
| 5675 | _.result( validityInput, 'reportValidity' ); |
| 5676 | } |
| 5677 | |
5660 | 5678 | return control.invalidDate; |
5661 | 5679 | }, |
5662 | 5680 | |
… |
… |
|
5669 | 5687 | updateDaysForMonth: function updateDaysForMonth() { |
5670 | 5688 | var control = this, daysInMonth, year, month, day; |
5671 | 5689 | |
5672 | | month = control.inputElements.month(); |
5673 | | year = control.inputElements.year(); |
5674 | | day = control.inputElements.day(); |
| 5690 | month = parseInt( control.inputElements.month(), 10 ); |
| 5691 | year = parseInt( control.inputElements.year(), 10 ); |
| 5692 | day = parseInt( control.inputElements.day(), 10 ); |
5675 | 5693 | |
5676 | 5694 | if ( month && year ) { |
5677 | 5695 | daysInMonth = new Date( year, month, 0 ).getDate(); |
5678 | 5696 | control.inputElements.day.element.attr( 'max', daysInMonth ); |
5679 | 5697 | |
5680 | 5698 | if ( day > daysInMonth ) { |
5681 | | control.inputElements.day( daysInMonth ); |
| 5699 | control.inputElements.day( String( daysInMonth ) ); |
5682 | 5700 | } |
5683 | 5701 | } |
5684 | 5702 | }, |
… |
… |
|
5698 | 5716 | |
5699 | 5717 | minuteEl = control.inputElements.minute.element; |
5700 | 5718 | |
5701 | | if ( maxHours === control.inputElements.hour() ) { |
5702 | | control.inputElements.minute( 0 ); |
| 5719 | if ( String( maxHours ) === String( control.inputElements.hour() ) ) { |
| 5720 | control.inputElements.minute( '0' ); |
5703 | 5721 | minuteEl.data( 'default-max', minuteEl.attr( 'max' ) ); |
5704 | 5722 | minuteEl.attr( 'max', '0' ); |
5705 | 5723 | } else if ( minuteEl.data( 'default-max' ) ) { |
… |
… |
|
5745 | 5763 | }; |
5746 | 5764 | |
5747 | 5765 | getElementValue = function( component ) { |
5748 | | var value = control.inputElements[ component ].get(); |
| 5766 | var value = parseInt( control.inputElements[ component ].get(), 10 ); |
5749 | 5767 | |
5750 | 5768 | if ( _.contains( [ 'month', 'day', 'hour', 'minute' ], component ) ) { |
5751 | 5769 | value = pad( value, 2 ); |
… |
… |
|
5822 | 5840 | } |
5823 | 5841 | |
5824 | 5842 | _.each( control.inputElements, function( element, component ) { |
5825 | | element.set( parsed[ component ] ); |
| 5843 | if ( 'meridian' === component || parseInt( parsed[ component ], 10 ) !== parseInt( element() ) ) { |
| 5844 | element.set( parsed[ component ] ); |
| 5845 | } |
5826 | 5846 | } ); |
5827 | 5847 | |
5828 | 5848 | return true; |
diff --git src/wp-includes/customize/class-wp-customize-date-time-control.php src/wp-includes/customize/class-wp-customize-date-time-control.php
index 0506910b61..d1e8d12500 100644
|
|
class WP_Customize_Date_Time_Control extends WP_Customize_Control { |
141 | 141 | <legend class="title-time"><?php esc_html_e( 'Time' ); ?></legend> |
142 | 142 | <div class="time-fields clear"> |
143 | 143 | <label for="{{ idPrefix }}date-time-hour" class="screen-reader-text"><?php esc_html_e( 'Hour' ); ?></label> |
144 | | <# var maxHour = data.twelveHourFormat ? 12 : 24; #> |
145 | | <input id="{{ idPrefix }}date-time-hour" type="number" size="2" autocomplete="off" class="date-input hour" data-component="hour" min="1" max="{{ maxHour }}"> |
| 144 | <# var maxHour = data.twelveHourFormat ? 12 : 23; #> |
| 145 | <# var minHour = data.twelveHourFormat ? 1 : 0; #> |
| 146 | <input id="{{ idPrefix }}date-time-hour" type="number" size="2" autocomplete="off" class="date-input hour" data-component="hour" min="{{ minHour }}" max="{{ maxHour }}"> |
146 | 147 | <span class="time-special-char date-time-separator">:</span> |
147 | 148 | <label for="{{ idPrefix }}date-time-minute" class="screen-reader-text"><?php esc_html_e( 'Minute' ); ?></label> |
148 | 149 | <input id="{{ idPrefix }}date-time-minute" type="number" size="2" autocomplete="off" class="date-input minute" data-component="minute" min="0" max="59"> |
diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php
index c43659379d..e5204a7aa0 100644
|
|
function wp_default_scripts( &$scripts ) { |
599 | 599 | esc_url( admin_url( 'theme-install.php' ) ) |
600 | 600 | ), |
601 | 601 | 'publishSettings' => __( 'Publish Settings' ), |
| 602 | 'invalidDate' => __( 'Invalid date.' ), |
| 603 | 'invalidValue' => __( 'Invalid value.' ), |
602 | 604 | ) ); |
603 | 605 | $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 ); |
604 | 606 | |