4

I'm attempting to conditionally render form elements based on user input in Vue, and it is not going well. I know how to do this using VanillaJS or jQuery, but I'm struggling to translate that knowledge into using Vue's built-in conditional directives. I'm using single-file components with the webpack template from vue-cli.

From my <template>:

<form autocomplete="off" name="loadDeets" id="loadDeets" class="loadDeets">
    <div class="form-group row">
       <label>Date</label>
       <flat-pickr v-model="date"
              :config="{dateFormat: 'l, F j'}"
                class="form-control" 
                placeholder="Select date"               
                name="date"></flat-pickr>
    </div>

    <div class="row">
        <div class="form-group col left">
           <label>Time</label>
           <flat-pickr v-model="time"
                :config="config"
                class="form-control" 
                placeholder="Select time"               
                name="time1"></flat-pickr>
        </div>

        <div class="form-group col right">
            <label>Time</label>
            <flat-pickr
                :config="config"
                class="form-control" 
                placeholder="Select time"               
                name="time2" v-show="document.getElementById('apptCheck').checked"></flat-pickr>
        </div>
    </div>

    <div class="form-check">
        <input class="form-check-input" type="checkbox" id="apptCheck">
        <label class="form-check-label" for="apptCheck">
           Appointment?
        </label>
    </div>
 </form>

This breaks the page's component rendering altogether. So then I tried using v-model based on this page from the Vue documentation. https://v2.vuejs.org/v2/guide/forms.html#v-model-with-Components

<div class="row">
   <div class="form-group col left">
      <label>Time</label>
      <flat-pickr v-model="time"
           :config="config"
            class="form-control" 
            placeholder="Select time"               
            name="time1"></flat-pickr>
    </div>

    <div class="form-group col right">
       <label>Time</label>
       <flat-pickr
           :config="config"
            class="form-control" 
            placeholder="Select time"               
            name="time2" v-show="vm.checked == true"></flat-pickr>
    </div>
 </div>

 <div class="form-check">
    <input class="form-check-input" type="checkbox" value="checked" id="apptCheck" v-model="checked">
    <label class="form-check-label" for="apptCheck">
        Appointment?
    </label>
 </div>

Unfortunately, that also breaks the page.

I'm not entirely sure how to proceed from here. Am I not thinking about this correctly? Is v-if/v-show not meant to be used with input from other elements?

6
  • Lose the vm in vm.checked and just use v-show="checked" Commented Jun 26, 2018 at 18:36
  • 1
    codesandbox.io/s/xo8q7w9w7p Commented Jun 26, 2018 at 19:05
  • Thank you for the example, it helped me fix what would have been another struggle on Jeff's answer! Commented Jun 26, 2018 at 19:42
  • You're welcome Amanda! Feel free to keep asking questions if you have any doubts. Commented Jun 26, 2018 at 20:08
  • 1
    Are you using the same data property for both checkboxes? If that's the case, v-model is pointing to the same property checked when you should have two different ones, one for each checkbox. For example, data() { return { pickupChecked: false, deliveryChecked: false } }. One should have v-model="pickupChecked" and the other v-model="deliveryChecked". Commented Jun 27, 2018 at 16:48

1 Answer 1

5

Your second example is the correct way to do this, you should never need to access an element by ID in Vue. You have access to all the variables in your component, so you don't need vm., just v-show="checked":

   <flat-pickr
       :config="config"
        class="form-control" 
        placeholder="Select time"               
        name="time2" v-show="checked"></flat-pickr>

Make sure you instantiate checked in your data function as well. Rather than put value="checked" on that element to start, you can set it equal to true in your starting data and v-model="checked" will automatically check it.

Sign up to request clarification or add additional context in comments.

2 Comments

Is there an easy way to do this, but instead of hiding the button, grey it out and make it unclickable? Seems like something simple but I'm having trouble finding it.
@BigGuy <button :disabled="checked"> would be disabled if the checked variable is true.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.