Luis Rodriguez
Luis Rodriguez

Reputation: 277

V-if doesn't react to state change

So I've got two columns, where first is inputs and second outputs the user input in a box. The functionality is that I can add with a click of a button, which works fine, but I also want to be able to delete selected boxes with an X icon as currently displayed. When I click the X icon to delete the box I expect the previous box's input form to appear but it won't until I click the box.

I originally had the delect function on a button outside of the for loop and it worked fine but need it to be with an X icon and I'm having these issues now. I've got a codepen set up with the code

  <div id="app">  
    <div class="columns is-v-centered">
    <div class="column is-5">
    <h2 class="help">Use <span class="tag">_keyword</span> tag to dynamically replace your keyword</h2>
    <div v-for="(ad, index) in ads" :key="index">
    <div v-if="ads[index]['boolean'] == true">
      <div class="form-inputs">
        <label class="label is-capitalized">Headline One</label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.headline1" placeholder="Leave empty to skip this!">
          </div>
        </div>
      </div>
      <div class="form-inputs">
        <label class="label is-capitalized">Headline Two </label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.headline2" placeholder="headline 2">
          </div>
        </div>
      </div>
      <div class="form-inputs">
        <label class="label is-capitalized">Headline Three </label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.headline3" placeholder="healdine 3">
          </div>
        </div>
      </div>
      <div class="form-inputs">
        <label class="label is-capitalized">Description One </label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.desc1" placeholder="description one">
          </div>
        </div>
      </div>
      <div class="form-inputs">
        <label class="label is-capitalized">Description Two </label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.desc2" placeholder="description two">
          </div>
        </div>
      </div>
      <div class="form-inputs">
        <label class="label is-capitalized">Final URL </label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.finalurl" placeholder="www.books.com">
          </div>
        </div>
      </div>
      <div class="form-inputs">
        <label class="label is-capitalized">Path One </label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.path1" placeholder="path1">
          </div>
        </div>
      </div>
      <div class="form-inputs">
        <label class="label is-capitalized">Path Two </label>
        <div class="field">
          <div class="control is-expanded">
            <input type="text" class="input" v-model="ad.path2" placeholder="path2">
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
<div class="column is-2">

</div>
<div class="column is-5">
  <div class="field is-grouped is-grouped-right has-addons">
    <a id="blue-button-theme" class="button is-fullwidth" @click="newAd()">Create new ad</a>


  </div>
  <p class="help">Click on an ad and edit the values in the form. Your changes will be applied to all ad sets automatically.</p>
  <br>
  <div class="box ad-box" v-for="(ad, index) in ads" :key="index"@click="hideInput(index)">
    <div>
      <span> text| </span>
      <span class="icon is-pulled-right has-text-grey-light has-text-weight-light" @click="deleteAd()">
        <span v-if="ad.boolean">
          <p class="">X</p>
        </span>
      </span>
      <br>
      <span class="is-size-7 is-grey">{{ad.headline1}} </span>
    </div>
    <br>
  </div>
</div>

https://codepen.io/luis4flames/pen/KJzrjb?editors=1010

Upvotes: 1

Views: 108

Answers (1)

tao
tao

Reputation: 90247

Here's a version that seems to work. I've done two things:

  • dumped the for - there's no need to go through all your ads. You're only interested in the one you're deleting
  • and set boolean to true on $nextTick().
deleteAd(){
  let index = this.ads.findIndex(_a => _a.boolean);
  this.ads.splice(index, 1);
  this.$nextTick().then(() => {
    if (this.ads.length) {
      this.ads[Math.min(index, this.ads.length - 1)]["boolean"] = true;
    }
  });
},

Updated pen.

By the way, another problem you have is your newAd() function currently requires your component to have at least 1 ad. I haven't fixed it. You probably want to implement an ad interface that can create new ads from scratch.

Upvotes: 2

Related Questions