Increase amount of showed v-for items on click

Hello, im creating an app for email building right now, but i get stuck in if i want to add some more rows.

so im basically gernerating my rows with an variable count which starts at 0 and if you push a button the variable count will increase by one and then it should generate an new row. im using also the v-for loop mechanic from vue. i already created an other app where it works perfectly fine.

So the counter increases also their spawns a new row, but the contents in that row are all toggled hidden and i don’t have that as initial class. Its a bit weird how that is working and im pretty much stuck. i would appreciate any help :slight_smile:.

For the look inside the code… ↓

<template>
  <div id="zone-field" class="zone-field">
    <div class="placeholder-section-row mb-1"
         v-for="(i, index) of placeholderCounter"
         :key="i"
         @click="activateAdjustments($event)">
      <div class="placeholder-section-selectable"
           @mouseover="hoverPlaceholder('in', $event)"
           @mouseout="hoverPlaceholder('out', $event)">
        <div class="placeholder-adjustment-menu hidden">
          <div class="select-deselect absolute cursor-pointer"
               @click="activateAdjustments($event)">
            <font-awesome-icon :icon="['fas', 'x']"/>
          </div>
          <div class="select-add-row-bottom"></div>
          <div class="select-add-row-top"></div>
        </div>
        <div class="placeholder-section-content"
             @drop="dropEvent"
             @dragleave="setDragZoneInactive"
             @dragover="draggingOptions(index, $event)">
          <div v-show="contentActive.top && contentActive.index === index"
               class="select-add-content-top"></div>
          <div v-show="contentActive.bottom && contentActive.index === index"
               class="select-add-content-bottom"></div>
          <button :id="`button_${index}`" @click="addNewPlaceholder">Hallo</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {insertAfter} from "../../main";
export default {
  name: "ZoneField",
  data() {
    return {
      active:false,
      placeholderCounter: 1,
      contentActive: {
        top: false,
        bottom: false,
        index: 0,
      }
    }
  },
  methods: {
    addNewPlaceholder() {
        this.placeholderCounter += 1
        let allContents = [...document.querySelectorAll('.placeholder-section-content')]
      console.log(allContents)
    },
    hoverPlaceholder(hoverState, e) {
      if (!this.active) {
        if (hoverState === 'in') {
          if (e.target.matches('.placeholder-section-selectable')) {
            e.target.classList.add('placeholder-section-selectable-active')
            e.target.firstChild.classList.remove('hidden')
          }
        }
        else if (hoverState === 'out') {
          if (e.target.matches('.placeholder-section-selectable')) {
            e.target.firstChild.classList.add('hidden')
            e.target.classList.remove('placeholder-section-selectable-active')
          }
        }
      }
    },
    activateAdjustments(e) {
      if (e.target.matches('.placeholder-section-selectable')) {
        this.active = true
      } else {
        e.target.parentElement.parentElement.classList.remove('placeholder-section-selectable-active')
        e.target.parentElement.classList.add('hidden')
        this.active = false
      }
    },
    draggingOptions(index,e) {
      this.contentActive.index = index
      let height = e.target.offsetHeight - 50
      if (e.layerY < 50 && e.layerY >= 0) {
        this.contentActive.top = true
        this.contentActive.bottom = false
      } else if(e.layerY > height && e.layerY <= e.target.offsetHeight) {
        this.contentActive.bottom = true
        this.contentActive.top = false
      }
    },
    setDragZoneInactive() {
      this.contentActive.bottom = false
      this.contentActive.top = false
    },
    dropEvent(e) {
      let zoneField = document.getElementById('zone-field')
      let div = document.createElement('div')
      if (this.contentActive.top) {
        div.innerText = 'top'
        let type = e.dataTransfer.getData('text/html')
        zoneField.insertBefore(div, e.target.offsetParent)
      } else if(this.contentActive.bottom) {
        div.innerText = 'bottom'
        insertAfter(div, e.target.offsetParent)
      }
    }
  },
  mounted() {
    document.addEventListener('drop', (e) => {
      this.contentActive.bottom = false
      this.contentActive.top = false
    })
  }

}
</script>

<style scoped lang="scss">

.zone-field {
  background-color: #fff;
  width: 85%;
  margin: 20px auto 0 auto;
  min-height: 100%;
}

.placeholder-section-row {
  position: relative;
  width: 100%;
  min-height: 100px;
  .placeholder-section-selectable {
    width: 100%;
    height: 100px;
    .placeholder-adjustment-menu {
      .select-deselect {
        top: 10px;
        right: 10px;
        svg, path {
          pointer-events: none;
        }
      }
    }
  }
  .placeholder-section-selectable-active {
    visibility: visible;
    border: 2px solid red;
  }
  .placeholder-section-content {
    position: relative;
    z-index: 3;
    background-color: #fc6f6f;
    width: 50%;
    min-height: 100px;
    margin: 0 auto;
    border: 2px dashed #da4848;
  }
}

.select- {
  &add-content- {
    &top {
      position: absolute;
      top: -3px;
      height: 3px;
      width: 100%;
      background-color: black;
    }
    &bottom {
      position: absolute;
      bottom: -3px;
      height: 3px;
      width: 100%;
      background-color: black;
    }
  }
}

Don’t understand this line:

placeholderCounter is a number, not an array.
So as written makes no sense.

Was just an tryout, its already normal again v-for="(i, index) in placeholderCounter". in there should be no problem or what do you mean?

This is your problem and what @crystalfp is alluding to.

Don’t use an integer to track your rows, use an array of objects. That way you can track each row’s active state, etc.

See this example.

1 Like

Hey, thanks for that idea, that makes the future work a bit easier, but it doesnt solve the problem. still it adds rows but makes the content hidden.

Nevermind i found the problem was just a problem on the event which was fired. Needed to specify the target element and now it works but thanks for sure for the tip with the object.