VueJS - Element UI : How to enable edit one row el-table-column - vuejs2

I want in a row table can be edited with enable and disable parameters, if edit button action in click then one row table is enable but if save button action in click then disable. and for the default table value is disabled.
It's my code:
<el-table :data="tableData" :key="index" style="width: 100%" stripe>
<el-table-column label="Name">
<template slot-scope="scope">
<el-input v-model="scope.row.name" :disabled="isEdit"></el-input>
</template>
</el-table-column>
<el-table-column label="Address">
<template slot-scope="scope">
<el-input v-model="scope.row.address" :disabled="isEdit"></el-input>
</template>
</el-table-column>
<el-table-column>
<template slot-scope="scope">
<el-button type="default" #click="handleSaveRow">Save</el-button>
<el-button type="primary" #click="handleEditRow">Edit</el-button>
</template>
</el-table-column>
</el-table>
but when I click edit button all rows of columns becomes enabled.
expected: edit click can change one row of table to enable
fiddle: https://jsfiddle.net/dede402/otxahoev/

It's normal as you use the same boolean for all rows. You must find a way to have one boolean per row indicating the edit mode.
Here is a working solution : https://jsfiddle.net/budgw/d3fxw5wq/1/
If you want to separate your data from the UI logic (generally a good idea) you should use a computed property in order to create a list with the edited field.

#budgw answers is correct - i would like to add to his answer. Rather than disabling the input you can make it a readonly attribute. I think its better that way and also makes your table look cleaner.
<el-input v-model="scope.row.name" :readonly="!scope.row.edited"></el-input>
Visit https://jsfiddle.net/noted/0atjsrnw/4/ for the full code.

Related

How to show default string in v-autocomplete field?

Here's my v-autocomplete component.
<v-autocomplete
v-model="selectedPlace"
:items="locationList"
:search-input.sync="query"
color="#e1b753"
clearable
item-text="title"
item-value="id"
label="Address"
return-object
required
close-on-content-click
class="pt-3 pb-0"
item-width="200"
:filter="v => v"
#change="setPlace()"
#blur="setPlace()"
>
<template v-slot:item="data">
<template>
<v-list-item-content>
<v-list-item-title v-html="data.item.title" />
</v-list-item-content>
</template>
</template>
</v-autocomplete>
When it's empty and the user first sets their address it works just fine but if they reload the page the autocomplete field is empty. I want to set its value according to user's information I get from the server but I can't figure out how.
What I've tried so far:
Set locationList[0] to the item I need and used auto-select-fist on autocomplete. It shows the needed location in the dropdown but doesn't display the value in the input.
Same as first but also set v-model to "locationList[0]". It displays the value in the input but doesn't let me change or clear it. When I select and remove the text it just jumps back in.
I guess auto-select-first should do the job, but it doesn't, am I trying to use it wrong?

How do I center the text in the header row of an element-ui table?

I tried centering the text in the header of my element-ui table via:
<el-table :data="myTable" header-row-style="text-align: center;">
Unfortunately, that doesn't have the desired effect. How do I center the names of the columns?
header-row-style takes an object or a function as an attribute value. it does not take a string.
So you can try it
<el-table :data="myTable" :header-row-style="{textAlign: 'center'}">
For centering only header text, use header-align="center" in <el-table-column /> as a property, for align all row + header. You can use align="center":
<el-table >
<el-table-column
label="ID"
prop="id"
header-align="center"
align="right">
</el-table-column>
</el-table>
References
Element UI - Table-Column Attributes
An example of using the Table-Column attribute
to centering the text in the header of element-ui table you can use :header-cell-style="{textAlign: 'center'} .
you can try:
<el-table :data="myTable" :header-cell-style="{textAlign: 'center'}">

Element UI Table Column that uses slot-scope Issue "Cannot read property 'column_name' of undefined"

Anyone here uses element ui framework? https://element.eleme.io/#/en-US/
I'm using its table component and using slot-scope on its columns. It's working fine until I ran npm update which of course updates the packages. Now, console has a lot of errors. And later I discovered that this slot-scope of the table column causes the issue.
Any help would be very much appreciated. Here is a fiddle of the issue.
https://jsfiddle.net/japhfortin/jkzma0v8/3/
<el-table :data=list>
<el-table-column label="First Name">
<template slot-scope="scope">{{ scope.row.first_name }}</template>
</el-table-column>
<el-table-column prop="last_name" label="Last Name">
</el-table-column>
</el-table>
data() {
return {
input: '',
list: [
{
first_name: 'Foo',
last_name: 'Bar'
}
]
}
},
The error is thrown because the value scope is an empty object on the first render. It means that the object row is undefined an it throws. You have to check that the row value is defined before accessing it. You can also use their alternative form to bind the value to the column. It depends of your use case.
<el-table :data="list">
<el-table-column prop="first_name" label="First Name"> </el-table-column>
<el-table-column prop="last_name" label="Last Name"> </el-table-column>
</el-table>
You can also use a v-if on the scope.row to ensure that the value is present at render time.
<el-table :data="list">
<el-table-column label="First Name">
<template slot-scope="scope" v-if="scope.row">
{{ scope.row.first_name }}
</template>
</el-table-column>
<el-table-column prop="last_name" label="Last Name"> </el-table-column>
</el-table>
The problem occurs because of new slot syntax in Vue.
More information at https://github.com/vuejs/rfcs/blob/master/active-rfcs/0001-new-slot-syntax.md
Default slot with text
<!-- old -->
<foo>
<template slot-scope="scope">
{{ scope}}
</template>
</foo>
<!-- new -->
<foo v-slot="scope">
{{ scope}}
</foo>
Another example using the Table component of the UI element.
Note: Upgrade the Vue to the latest version, currently it is 2.6.3.
<el-table :data="list">
<el-table-column label="First Name" v-slot="scope">
{{ scope.row.first_name }}
</el-table-column>
<el-table-column prop="last_name" label="Last Name">
</el-table-column>
</el-table>
The issue is fixed on Vue#2.6.3

How to combine props arithmetically in Vue.js?

I have a table that looks like this:
<el-table
:data="info"
class="myform"
stripe
style="width: 100%">
<el-table-column
prop="location_name"
label="Name"
width="180">
</el-table-column>
<el-table-column
v-if="promoActive"
prop="original_price"
label="Original Price"
width="180">
</el-table-column>
<el-table-column
prop="spaces_available"
label="Spaces"
width="180">
</el-table-column>
<el-table-column
v-if="promoActive"
prop="discount_value"
label="Discount Value"
width="180">
</el-table-column>
</el-table-column>
<el-table-column
v-if="promoActive"
label="Final Price"
width="180">
</el-table-column>
</el-table>
I'm trying to make the prop value of the last table column equal to the the final price which is the original price minus the discount price. However, when I put the prop like this, it doesn't work:
<el-table-column
v-if="promoActive"
prop="(original_price - discount_value)"
label="Final Price"
width="180">
</el-table-column>
What's the best way to go about this?
you can use computed property like
computed:{
calculate(){
return this.prop1 - this.prop2;
}
}
And then called the prop
Have you considered computed properties in Vue JS ?
refer : [https://v2.vuejs.org/v2/guide/computed.html#Computed-Properties]
these properties are derived from the data and change whenever the source data is modified. This could be the recommended approach.
example :
computed:{
finalPrize : function () {
return this.original_price - this.discount_value;
}
}
First and foremost, the reason why your prop="(original_price - discount_value)" did not work is because prop attribute is evaluated as text unless you use the v-bind syntax. So this should work:
v-bind:prop="(original_price - discount_value)"
However, this is what computed properties in VueJS can be used for, to abstract all these calculation logic away from your template: you can perform the calculations in there, and simply use the v-bind directive to bind the computed value to the element. Let's name your computed property finalPrice. In your VueJS app/component code, you can do this:
computed: {
finalPrice() {
return this.original_price - this.discount_value;
}
}
Then, update your markup to use v-bind:prop="finalPrice":
<el-table-column
v-if="promoActive"
v-bind:prop="finalPrice"
label="Final Price"
width="180">
</el-table-column>
p/s: If you prefer to use shorthands, fret not: :prop="finalPrice" (note the : prefix) is syntactically identical to v-bind:prop="finalPrice".
Not recommended, but still workable: if you want to pass the arguments to perform calculations instead, you can use a method instead:
method: {
calculateFinalPrice(original, discount) {
return original- discount;
}
}
And your markup will be:
<el-table-column
v-if="promoActive"
v-bind:prop="calculateFinalPrice(original_price, discount_value)"
label="Final Price"
width="180">
</el-table-column>
You can use computed property for this type of arithmetic calculations. where you can define a function and have full control over all properties of component.
follow this link. you will get idea how you can do it.

Vue Js Form Validation with Components and Element UI

I am trying to find a way using vue js, components, and element ui to validate a form that is within a table and has data pushed into it from a template.
At the moment this is a snippet of the code that I have written, where if el-input is empty the message “hi” should appear as a blur event.
However, it shows up even when there is a value in the input field, and seems like the validation cannot read the value that is inserted from the template.
Any ideas on how to connect the two?
<el-form ref=“formA”>
<el-table :data=“data_list” border class=“my-table" size="mini" row-key="id">
<el-table-column property=“my_name":label='$t("attributes.person_name")' width="200">
<template slot-scope="scope">
<el-form-item :prop=“’data_list.' + scope.$index + ‘.my_name'"
:rules="{
required: true,
message: 'hi',
trigger: 'blur'
}">
<el-input v-model="scope.row.my_name" />
</el-form-item>
</template>
</el-table-column>
</el-table>