4

Lots of panels (product) are showing in a page in multiple row and multiple column. I'm using Vue 2 and panels are components. Now, on clicking a panel, I want to show details of that panel below the row of that. This is similar to Google image search.

enter image description here

For example, in the above image, if I click any of the s1, s2 or s3, the big panel will appear after s3 (last element of that row). Similarly, for clicking s4 or s5, the big panel appear after s5.

** Number of items in a row will vary based on the screen size.

How to find the last element of the row and insert a component after that element?

2
  • Is it always going to be three items per row? Commented Jan 1, 2017 at 13:09
  • No, it'll vary based on screen size. Commented Jan 1, 2017 at 13:13

2 Answers 2

0

This does not answer your question directly, but should implement the expected behavior. Here is a jsfiddle

Template:

<div id="vue-instance">
  <ul class="item-list">
    <li class="item" v-for="item in inventory" @click="dispalyDetails(item)">
      <div class="header">{{ item.name }} - ${{ item.price }}</div>
      <div v-if="item.displayed" class="details">
        <div class="details__inner">
          {{ item.details }}
        </div>
      </div>
    </li>
  </ul>
</div>

Vue:

var vm = new Vue({
  el: '#vue-instance',
  data: {
    inventory: [
      {name: 'MacBook Air', price: 1000, details: 'Lorem ipsum', displayed: false},
      {name: 'MacBook Pro', price: 1800, details: 'Lorem ipsum', displayed: false},
      {name: 'Lenovo W530', price: 1400, details: 'Lorem ipsum', displayed: false},
      {name: 'Acer Aspire One', price: 300, details: 'Lorem ipsum', displayed: false},
      {name: 'Aspire One', price: 700, details: 'Lorem ipsum', displayed: false}
    ]
  },
  methods: {
    deselectItems() {
        this.inventory.forEach((item) => {
        item.displayed = false;
      });
    },
    dispalyDetails(item) {
        if (!item.displayed) {
        this.deselectItems();
      }

        item.displayed = !item.displayed;
    }
  }
});

Scss:

.item-list {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  width: 80%;
  margin: 0 auto;
}

.item {
  width: 33.33%; // adjust accordingly in mq
  box-sizing: border-box;
}

.header {
  box-sizing: border-box;
  padding: 10px;
}

.details {
  border: 1px solid red;
  min-height: 200px;
}

.details__inner {
  position: absolute;
  left: 0;
  width: 100%;
  min-height: 200px;
  border: 1px solid green;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer, but this doesn't solve my issue. Here is the jquery version of what I needed: jsfiddle.net/sovon/zmp10wtq
@Sovon This seems close enough. You should link this in the new question you asked and describe what else you want.
0

If you want to arrange the components: one will appear after another. Let me assume I have all those components in an array and you can re-arrange those in the array as par your logic, and you can use special attribute: is to render those component.

Here in sample I have an array of components and I use v-for to render those one after another:

See fiddle here.

HTML:

<div id="app">
  <h1>
  Following are the components
  </h1>
  <div v-for="comp in compArray" :is="comp"></div>
  <br>
  <button @click="resuffle">
     Resuffle
  </button>
</div>

<template id="comp1">
  <div>
    <span>This is component 1</span>
  </div>
</template>

<template id="comp2">
  <div>
    <span>This is component 2</span>
  </div>
</template>

<template id="comp3">
  <div>
    <span>This is component 3</span>
  </div>
</template>

JS:

Vue.component('comp1', {
  template: '#comp1', 
})

Vue.component('comp2', {
  template: '#comp2', 
})
Vue.component('comp3', {
  template: '#comp3', 
})

new Vue({
    el: '#app',
  data: {
    compArray: ['comp1', 'comp2', 'comp3']
  },
  methods: {
    resuffle: function() {
       this.compArray.push(this.compArray[1])
       this.compArray.splice(1,1)
    }
  },
})

1 Comment

is there a beautiful way to acheieve tihs?

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.