title: How do I make the element UI time picker set value only after the ok button is clicked?
body: <p>Currently, the Element Timepicker triggers the <code>input</code> event (and, interestingly - not the <code>change</code> event as <a href="https://element.eleme.io/#/en-US/component/time-picker#events" rel="nofollow noreferrer">mentioned in the docs</a> ) every time the hours, minutes or seconds are changed. For my use case, I need it to allow the user to pick a value but not actually set the model (I'm using v-model but essentially, trigger an <code>input</code> event which <code>v-model</code> uses) until the user clicks the <code>ok</code> button.</p>
  
  <p>I'm thinking a wrapper component which manages the state internally is one way to do it. (Sample implementation below)</p>
  
  <p>Is there a cleaner way (ideally, built into Element and not involving hacks like below) to do this?</p>
  
  <p>EDIT: It appears that I was wrong about change not being fired - as explained in @Roy J's answer below, it does fire when the button is clicked but crucially ALSO when the user just clicks out of the time picker after it is in focus which is not the behavior which is required - The model should update <strong>only</strong> when the ok button is clicked.</p>
  
  <pre><code>&lt;template&gt;
    &lt;el-time-picker
      v-bind="_passthrough"
      :value="_displayValue"
      @blur="handleBlur"
      @focus="handleFocus"
      @input="handleInput"
    &gt;
    &lt;/el-time-picker&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
    import { TimePicker } from "element-ui";
  
    /**
     * A list of props accepted by the element time picker component
     * @private
     */
    const _elTimePickerProps = [
      "isRange",
      "readonly",
      "disabled",
      "editable",
      "clearable",
      "size",
      "placeholder",
      "startPlaceholder",
      "endPlaceholder",
      "arrowControl",
      "align",
      "popperClass",
      "pickerOptions",
      "rangeSeparator",
      "defaultValue",
      "valueFormat",
      "name",
      "unlinkPanels",
      "prefixIcon",
      "clearIcon",
      "value"
    ];
  
    /**
     * A wrapper on the element time picker to trigger the 'input' event only when the 'ok' button is clicked - lazily.
     * The actual element timepicker fires the input event every time an internal control is changed which is
     * undesirable in some cases.
     */
    export default {
      name: "LazyTimePicker",
      props: [..._elTimePickerProps], // Accept the same props as element time picker
      components: {
        ElTimePicker: TimePicker
      },
      data() {
        return {
          /**
           * Shadow to the value prop - used to update the value while the user is selecting without affecting the
           * globally bound value
           */
          currentValue: "",
          /**
           * Tracks if the element currently has focus
           */
          hasFocus: false
        };
      },
      methods: {
        handleInput(value) {
          // Update the internal value every time the value is updated
          this.currentValue = value;
        },
        handleConfirm() {
          // Confirm button was clicked
  
          // Emit input event with the current value - plays nicely with v-model
          this.$emit("input", this.currentValue);
  
          // Remove the event listener on the confirm button
          this.$confirmButton.removeEventListener("click", this.handleConfirm);
  
          // Set the instance ref to the confirm button to undefined
          this.$confirmButton = undefined;
        },
        handleFocus() {
          // The time picker has gained focus, the dialogue will be open on the next tick
          // May be called multiple time (for example when switching between hours, minutes and seconds,
          // each switch triggers a focus event
  
          // Update focus state
          this.hasFocus = true;
  
          // Check if the one time setup is complete (indicated by the availability of the button ref on the
          // instance)
          if (this.$confirmButton) {
            // One time setup is complete, return early
            return;
          }
          // Initialise the instance's currentValue to the value received via props
          this.currentValue = this.value;
  
          // Wait until the time picker dialogue is open on the next tick as the confirm button will be on
          // the DOM only then
          this.$nextTick(() =&gt; {
            // Get a ref to the confirm button
            const $confirmButton = document.querySelector(
              ".el-time-range-picker button.el-time-panel__btn.confirm"
            );
  
            // If the ref is available
            if ($confirmButton) {
              // Register click handler on the `ok` button
              $confirmButton.addEventListener("click", this.handleConfirm);
  
              // Keep a ref to the button for future use - also doubles as an indicator that the one time
              // setup that is done every time this component is opened is complete
              this.$confirmButton = $confirmButton;
            }
          });
        },
        handleBlur() {
          // The time picker has lost focus, the dialogue will be closed on the next tick
          this.hasFocus = false;
  
          this.$nextTick(() =&gt; {
            // Clean up the confirm button and it's event listener in case the user clicked out or pressed
            // cancel without pressing okay
            if (this.$confirmButton) {
              // Remove the event listener on the confirm button
              //Removing the listener here will prevent the input event from being emitted - does the listener get cleaned up?
              //this.$confirmButton.removeEventListener('click', this.handleConfirm);
  
              // Set the instance ref to the confirm button to undefined
              this.$confirmButton = undefined;
            }
          });
        }
      },
      computed: {
        /**
         * Collect all props related to the actual element time picker to be `v-bind`ed to it in one shot
         * @returns {Object} Element time picker props
         * @private
         */
        _passthrough() {
          const self = this;
          return _elTimePickerProps.reduce(
            (acc, key) =&gt; ({ ...acc, [key]: self[key] }),
            {}
          );
        },
        /**
         * The value to be displayed. When the element is not in focus (the dialogue is closed) the value in
         * the inputs should reflect the value bound to the time picker. When the element is in focus, the dialogue
         * will be open and the user will be in the process ofmaking their new selection. At this time, the inputs
         * should not show the value as it is currently being selected
         * @returns {string}
         * @private
         */
        _displayValue() {
          return this.hasFocus &amp;&amp; this.currentValue
            ? this.currentValue
            : this.value;
        }
      }
    };
  &lt;/script&gt;
  </code></pre>