I'm creating vue js spa and what i trying to create is when i click on table row, it will show a modals with/showing data from the row that i clicked on.
here i have created my table
<tr class="cursor-pointer" #click="modalContextMenu">
<td>
<img :src="'/images/artikel/' + props.item.images + 'n.jpg'" class="img-rounded img-sm" v-if="props.item.images">
<img :src="'/images/image-articlen.jpg'" class="img-rounded img-sm" v-else>
</td>
<td>{{props.item.name}}</td>
<td>{{props.item.category.name}}</td>
<td>{{props.item.writter}}</td>
<td v-html="$options.filters.checkStatus(props.item.publish)"></td>
<td v-html="$options.filters.checkStatus(props.item.featured)"></td>
<td>{{props.item.created_at | publishDate}}</td>
</tr>
at <tr> i put #click methods that make modal show and data that i want to show into modals is data from each <td> for that row / <tr>
right now my modalContextMenu methods is basically make modals visible/appear like this
modalContextMenu(){
this.modalShow= true;
}
You can create a data property for the data you want to show in the modal.
data () {
modalData: ''
}
Then you can set that property in onClick function.
HTML
<tr class="cursor-pointer" #click="modalContextMenu(data)">
<td>
<img :src="'/images/artikel/' + props.item.images + 'n.jpg'" class="img-rounded img-sm" v-if="props.item.images">
<img :src="'/images/image-articlen.jpg'" class="img-rounded img-sm" v-else>
</td>
<td>{{props.item.name}}</td>
<td>{{props.item.category.name}}</td>
<td>{{props.item.writter}}</td>
<td v-html="$options.filters.checkStatus(props.item.publish)"></td>
<td v-html="$options.filters.checkStatus(props.item.featured)"></td>
<td>{{props.item.created_at | publishDate}}</td>
</tr>
JS:
modalContextMenu(data) {
this.modalData = data;
this.modalShow= true;
}
Then access the data in modal using {{ modalData }}.
Related
Okay so I have a table and the table has a number display and an Input for the user to increase the number up and down.
<tr v-for="(obj, index) in OBJECTARRAY" :key="obj.key">
<td>{{OBJOTHERNUMBER- OBJNUMBER}}</td>
<td>
<input v-model="OBJNUMBER" type="number">
</td>
</tr>
I don't want this change to show dynamically with a v-model but with a button click that updates the change?
What you could do is use 2 variables.
DiscountPriceTemp
DiscountPrice
And when you click on the button, you update DiscountPrice with DiscountPriceTemp.
<tbody>
<tr v-for="(obj, index) in OBJECTARRAY" :key="obj.key">
<td>{{ obj.SalePrice - obj.DiscountPrice }}</td>
<td>
<input v-model="obj.DiscountPriceTemp" type="number">
</td>
</tr>
</tbody>
export default {
methods: {
onButtonClick (obj) {
obj.DiscountPrice = obj.DiscountPriceTemp
}
}
}
You can use a ref to access the input value and set the discountPrice when the update button is clicked. In Vue it's best practice to not access the document directly. Not sure if you want a button for each row or a bulk update so I've included both. Here's the codepen if you want to see it in action https://codepen.io/madison_at_vrume/pen/mdWNrMy
<div>
<tbody>
<tr v-for="(obj, index) in prices" :key="obj.key">
<td>{{ obj.salePrice - obj.discountPrice }}</td>
<td>
<input
:ref="`discountInput-${index}"
:value="obj.discountPrice"
type="number"
>
</td>
<td>
<button #click="updatePrice(index)">Update Price</button>
</td>
</tr>
</tbody>
<button #click="updateAllPrices()">Update Prices</button>
</div>
methods: {
updatePrice(index) {
const newDiscountPrice = this.$refs[`discountInput-${index}`].value;
this.prices[index].discountPrice = newDiscountPrice;
},
updateAllPrices() {
this.prices.forEach((obj, index) => {
this.updatePrice(index);
})
},
}
I'm having a problem with my table when I scroll to the right
this is my code
TableComponent.vue
<div id="main-container">
<table class="maint-table">
<thead id="table-header">
<tr>
<th class="dates"> </th>
<th v-for="data in dateHeader">{{data}}</th>
</tr>
<tr>
<th class="title"> </th>
<th v-for="data in dayOfWeek">{{data}}</th>
</tr>
</thead>
<tbody id="table-body" #scroll="fixedScroll">
<table_block :table_data="dataHeader"></table_block>
<table_block :table_data="allData"></table_block>
</tbody>
</table>
</div>
...
...
...
<script>
components: {
table_block
},
methods: {
fixedScroll() {
fixedScroll(event) {
var thead = document.getElementById("table-header");
var tbodyScroll = document.getElementById("table-body").scrollLeft;
thead.scrollLeft = tbodyScroll;
}
</script>
I made a props to pass the data to my TableBlock to loop through the data and display it on the table. This is my TableBlock Code.
TableBlock.vue
<template>
<div>
<tr v-for="row in table_data">
<td>
<div class="drop-down-container"><span class="drop-down-controller"">{{ row.title }}</span></div>
</td>
<td v-for="cel in row.data" class="group-header">{{ cel }}</td>
</tr>
</div>
</template>
When I scroll it to the right, the first column must freeze but it's not.
I tried to create a dummy data inside TableComponent.vue with a normal HTML Table without passing the data to another component using props, it works perfectly. But when I use these codes, it doesn't work correctly.
Scenario
Let say I have 10 columns in the table, when I scroll it to the right, the 1st column will stick which is normal but when the 10th column reach to 1st column, the 1st column will scroll away together with the 10th column.
I'm trying my best to illustrate the scenario but this is the best that I can do. If someone can help, please help me.
I had a table row that was like this:
<tr v-for="(pricing, idx) in pricings"">
<td>{{pricing.description}}</td>
<td>$ {{pricing.unconfirmed_price_formatted}}
</tr>
I wanted to migrate this table row to a component. However, when I change the underlying data (this.pricings), the child component doesn't update. I am calling it like this:
<pricing-row v-for="(pricing, idx) in pricings" :key="pricing.id + pricing.description" :pricing=pricing v-on:updateAfterSave="savedData" v-on:showModal="showAddEditModal"></pricing-row>
The strange thing is that the underlying array is changing - just this component is not properly updating.
It's also clear that if we use as a key the value that changes (unconfirmed_price_formatted in this case), it does update.
I'm a bit baffled by this behavior. Any ideas on what is wrong?
edit 1
here is the component:
<template>
<tr>
<td>{{localPricing.description}}</td>
<td v-if="localPricing.price">$ {{localPricing.price_formatted}} {{localPricing.units_display}}</td>
<td v-else> </td>
<td v-if="localPricing.unconfirmed_price">$ {{localPricing.unconfirmed_price_formatted}} {{localPricing.unconfirmed_units_display}}</td>
<td v-else> </td>
<td v-if="localPricing.state != 'deleted'">
<!-- button class="btn btn-outline-secondary" #click="willShowModalWithBattery(pricing)">edit</button -->
<button class="btn btn-outline-secondary" #click="showModal(pricing)">edit</button>
</td>
<td v-else> </td>
</tr>
</template>
<script>
export default {
props: ['pricing'],
data: function(){
return {
localPricing: this.pricing
}
},
methods:{
showModal: function(pricing){
this.$emit('showModal', pricing);
}
}
}
</script>
I’m very new to VUE and trying loop through dynamically created tables from unique arrays. I have the table creation complete and dynamic table id’s based off a value from the array. I’m trying to validate that either cell[0] in each row contains a specific string or if the last cell[?] which has a select dropdown has been selected and is said string.
I’ve done something similar before in JS like this.
$("#" + t_node + " :selected").each(function (i,sel) { .....///code }
and like this
$("table#"+t_node+" > tbody > tr").each(function(row, tr) { .....///code }
I don’t know how to replicate with VUE.
I have a onclick event that I want to loop through the table and for any row that has p2vg01 already created sum its size along with any select option of p2vg01. In the below table I’d want to find that SDB was selected at 107GB. Not shown but it could be that SDB was already p2vg01 but if I selected SDC as well as p2vg01 I’d sum 32GB + 107GB.
<div v-for="storageResult in storageValidationResults" >
<h3 class="panel-title">{{ storageResult.node_name }}</h3>
<table :ref="storageResult.node_name" v-bind:id="storageResult.node_name" class="table table-bordered table-striped table-hover" >
<thead>
<th v-for="(value, key, index) in storageResult.table_head">
{{ value }}
</th>
<th>Select</th>
</thead>
<tbody>
<tr v-for="(value, key, index) in storageResult.disk_data">
<td v-for="v in value">
{{ v }}
</td>
<td v-if="checkAvailable(value)">
<select>
<option value="">--Select VG--</option>
<option value="p2vg00">p2vg00</option>
</select>
</td>
<td v-else=""></td>
</tr>
</tbody>
</table>
</div>
After reading docs & forums for hours... still have no answer.
Have the following JS/HTML:
Vue.component("my-component", {
props: ["id"],
render: function(h) {
return h("tr", this.$slots.default);
}
});
var vapp = new Vue();
<script src="https://unpkg.com/vue#2.4.2/dist/vue.js"></script>
<table>
<tr is="my-component" :name="yo">
<td>
<span v-text="name"></span>
</td>
</tr>
</table>
Use tr + "is" attribute to specify component within the table otherwise browser will hoist it out as invalid content. Done
Use render + h("tr"...) because vuejs doesn't render tr element, but instead table > td and again browser hoist it out.Done
Now I have table > tr > td rendered well but how can I add children bound to the props/data, so I will see "yo" on the screen.
Thanks a lot!
If the elements in the slot need access to data inside the component, then you need to use a scoped slot.
Since you are using a render function, the scoped slot is available as a function through this.$scopedSlots.default() and you pass it an object with the data you want to be made available to the scoped slot.
You also need to define the scoped slot in the template. Here is an example.
Vue.component("my-component", {
props: ["id", "name"],
render: function(h) {
return h("tr", this.$scopedSlots.default({name: this.name}));
}
});
var vapp = new Vue({ el:"#app"});
<script src="https://unpkg.com/vue#2.4.2/dist/vue.js"></script>
<div id="app">
<table>
<tr is="my-component" :name="'yo'">
<template scope="{name}">
<td>
<span v-text="name"></span>
</td>
</template>
</tr>
</table>
</div>
If you are using .vue files you can have the table row component defined like this:
<template>
<tr>{{ name }}</tr>
</template>
<script>
export default {
name: 'table-row',
props: ['name'],
};
</script>
Then use it like this:
<table>
<tr is="TableRow" name="Some name here"></tr>
</table>
<table>
<thead>
<!-- ...some th -->
</thead>
<tbody>
<tr>
<td>..</rd>
</tr>
<template> <row-component my-param="blabla"></row-component> <!-- component return full row <tr>...</tr> -->
<some-other-recomponent my-par="blabla"></some-other-recomponent> <!-- component return full row <tr>...</tr> -->
</template>
</tbody>
</table>
If your're interested in returning multiple rows from your component, you can do like this.
In your main component.
<table width="90%">
<thead>
<tr>
<th width="1%">#</th>
<th>header description</th>
</tr>
</thead>
<template>
<your-child-component
:prop="prop-data"
v-for="(lancamento, index) in lancamentos"
:key="lancamento.id">
</your-child-component
</template>
</table>
And inside your child component
<template>
<tbody> <!-- dont forget this tag -->
<tr>
<td rowspan="2" v-html="prop.id"></td>
<td><td>
</tr>
<tr>
<td colspan="2" class="text-center"></td>
</tr>
</tbody>
</template>