[Vuejs]-Vue: How to switch between displaying input and label with v-if

1👍

The template had a few compilation errors:

  • The <label> needs a closing tag (and text content to be useful)
  • The <div class="big"> needs a closing tag
  • The v-if was bound to inputFieldInfo, but that variable was declared as InputFieldInfo (note the uppercase I), but based on your behavior description, this field should be unique per location container, so a single data property like this wouldn’t work (if I understood your description correctly).

Each location container should have a variable to contain the location name (e.g., locationName) and another variable to contain the show/hide Boolean for the <input> and <label> (i.e., inputFieldInfo):

createDiv: function() {
  this.divs.push({
          // ...
          inputFieldInfo: true,
          locationName: ''
        });
}

Then, we could bind div.inputFieldInfo and div.locationName to the <input>. We bind to v-model so that the user’s text is automatically reflected to the div.locationName variable:

<input v-if="div.inputFieldInfo" v-model="div.locationName">

The <label>‘s content should be div.locationName so that it contains the text from the <input> when shown:

<label class="propertyLabel" v-else>{{div.locationName}}</label>

To switch the <input> with the <label> when the expand-button is clicked, we update expand() to set div.inputFieldInfo to false but only when div.locationName is not empty (this gives the user a chance to revisit/re-expand the container to fill in the location later if needed):

expand: function(div) {
  if (div.expanded) {
    div.expanded = false
    if (div.locationName) {
      div.inputFieldInfo = false
    }
    // ...

updated jsfiddle

👤tony19

1👍

You had some missing closing tags and an error with InputFieldInfo, it should have a lowercase i.

var gate = 0;

Vue.component('addingdivs', {
  template: `
<div>
    <div id="header">
        <button class="addDiv" type="button" @click="createDiv">ADD LOCATION</button>
    </div>
    <div class="parent" v-for="div in divs" :style=" div.height ? { 'height': div.height }: null">
        <div class="big" v-if="div.expanded" :key="'expanded' + div.id">
          <div class="switch">
              <input type="text" v-if="inputFieldInfo">
              <label class="propertyLabel" v-else>Label</label>

              <div class="firstChild">
                  <button class="done" @click="increaseLimit">INCREASE</button>
              </div>
              <div class="secondChild">
                  <button class="done" @click="expand(div)">EXPAND</button>
              </div>
          </div>
        </div>

        <div class="small" v-else :key="'collapsed' + div.id">
            <button class="done" @click="expand(div)">EXPAND</button>
        </div>
    </div>
</div>
    `,
  data: function() {
    return {
      gate: gate,
      height: "",
      count: 0,
      locationsArr: ["one", "two", "three"],
      divs: [],
      inputFieldInfo: true
    }
  },
  methods: {
    expand: function(div) {
        this.inputFieldInfo = false
      if (div.expanded) {
        div.expanded = false
        this.height = ''
      } else {
        div.expanded = true
        this.height = '7vh'
      }
    },
    createDiv: function() {
                this.inputFieldInfo = true
      if (this.count <= gate) { // Here you can decide how many divs that will be generated
        // this.count++;
        this.divs.push({
          id: this.count,
          expanded: true,
          inputFieldInfo: true,
          height: '',
        });
        this.count++
      }
    },

    increaseLimit: function() {
      // Here you can increase the number of divs that it's possible to generate
      gate++;
    }
  }
});

new Vue({

  el: '#lotsOfDivs',
});

You just basically toggle the inputFieldInfo data, whenever each button is pressed.

0👍

You can do that by using toggle variable like this

Vue.component('addingdivs', {
    template: `
    <div>
       <div>
        <input type="text" v-if="takeinput">
        <label v-if="!takeinput">
        <button @click="toggleInput()">
        </div>
    </div>
    `,

 data: function() {
        return {
            takeinput:true,           
        }
    },

    methods: {
        toggleInput: function(){
            let vm = this;
            vm.takeinput = ( vm.takeinput == true) ? false : true
            }
        }
});

new Vue({

    el: '#lotsOfDivs',
});

In this example, we are just toggeling value of takeinput on click , so according the value either label or input will be showed.

This is very basic exmpale. But you can extend it as your need

Leave a comment