vuejs how do I change input value from components - javascript

I have a form which is have hidden input. There is a small list of my data. Just has title and id. This list created by vue component. I want to click this list items then change to hidden input value. Here is my structure.
HTML
<div id="v-account-select">
<form method="post">
{!! csrf_field() !!}
<input type="hidden" name="id" v-model="account_id">
</form>
<account-select :datalist="{{ json_encode($list) }}"></account-select>
</div>
APP.JS
Vue.component("account-select", {
datalist: {
type: Array,
required: true,
},
methods: {
item_id_bind(id) {
this.$emit("#account_id", id);
},
},
template:
'<table class="table table-responsive table-striped table-bordered">' +
"<tbody>" +
'<tr v-for="item in datalist"><td>' +
'<button type="button" class="btn-link" v-on:click="item_id_bind(item.id)">{{item.title}}</button>' +
"</td></tr>" +
"</tbody>" +
"</table>",
});
This is my codes.

Add an event handler.
<account-select #account-change="onAccountChange" :datalist="{{ json_encode($list) }}"></account-select>
In your parent Vue add
methods:{
onAccountChange(id){
this.account_id = id
}
}
And update your component to
methods: {
item_id_bind(id) {
this.$emit("account_change", id)
}
},
Here is a working example.
console.clear()
Vue.component('account-select', {
props: {
datalist: {
type: Array,
required: true
}
},
methods: {
item_id_bind(id) {
this.$emit("account-change", id)
}
},
template:`
<table class="table table-responsive table-striped table-bordered">
<tbody>
<tr v-for="item in datalist" :key="item.id">
<td>
<button type="button"
class="btn-link"
v-on:click="item_id_bind(item.id)">
{{item.title}}
</button>
</td>
</tr>
</tbody>
</table>
`
});
new Vue({
el: "#app",
data: {
datalist: [{
id: 1,
title: "item1"
}, {
id: 2,
title: "item2"
}],
account_id: null
},
methods: {
onAccountChange(id) {
this.account_id = id
}
}
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="app">
<div id="v-account-select">
<form method="post">
Current Account id: {{account_id}}
<input type="hidden" name="id" v-model="account_id">
</form>
<account-select #account-change="onAccountChange" :datalist="datalist"></account-select>
</div>
</div>

Related

Vee validate v3 ValidationObserver not working with dynamic validation provider added using v-for

I am using Vee Validate v3 for validating dynamic input generated using V-FOR, which is added or removed input elements based on user actions.
My issue was only the last input gets validated other inputs not getting validated. In the documentation, they had mentioned this issue while using V-IF & V-FOR
documentation link
They told to use VueJS keep-alive component. but not working with V-FOR.
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<form method="POST" action="{{ route('app.store') }}" #submit.prevent="handleSubmit(onSubmit)" class="form" enctype="multipart/form-data">
<table class="table">
<thead>
<tr>
<th>SI No</th>
<th>input 1</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in items" :key="item.id">
<td>#{{ index + 1 }}</td>
<td>
<keep-alive>
<validation-provider rules="required" v-slot="{ errors }" name="attribute">
<div class="form-group">
<input :name="'attribute' + item.id" class="form-control" v-model="item.attribute">
<span class="error" role="alert">
#{{ errors[0] }}
</span>
</div>
</validation-provider>
</keep-alive>
</td>
<td>
<button type="button" class="btn btn-md btn-danger mt-4" #click="remove(index)">
<span class="ion-trash-a"></span>
</button>
</td>
</tr>
</tbody>
</table>
<x-form-submit>Save</x-form-submit>
</form>
My js code
<script type="application/javascript">
Vue.component('dynamic-form-wrapper', {
template: '#dynamic-form-template',
data() {
return {
items: [
{
id: 1,
attribute: null,
},
{
id: 2,
attribute: null,
}
],
id: 3
}
},
methods: {
async onSubmit() {
const valid = await this.$refs.observer.validate();
if (valid) {
document.getElementById("category-form").submit();
}
},
add() {
this.items.push({
id: this.id,
attribute: null,
});
this.id ++;
},
remove(index) {
if (this.items.length != 1) {
this.items.splice(index, 1);
}
}
}
})
</script>
Thanks in advance
Each ValdationProvider needs a unique id. set :vid for each validation providers
<keep-alive>
<validation-provider :vid="'attribute' + item.id" rules="required"
v-slot="{ errors }" name="attribute">
<x-v-form-input type="text" v-model="item.attribute" field="attribute">
</x-v-form-input>
</validation-provider>
</keep-alive>
Refer API docs for vid here: https://vee-validate.logaretm.com/v3/api/validation-provider.html#props

bind multiple inputs to each other in vuejs to change together

i want multiple text inputs that when i change one of them i want others to change with the same value too . my inputs are generating in a loop of v-for like below :
<tbody>
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index" :index="index" "></variant-item>
</tbody>
and here the input is getting generated :
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[price]') ? 'has-error' : '']">
<input type="number" v-model="variant.price" :name="[variantInputName + '[price]']" />
<span class="control-error" v-if="errors.has(variantInputName + '[price]')">#{{ errors.first(variantInputName + '[price]') }}</span></div>
</td>
so with this code if i have 2 products for example the result would be like below :
<td><div class="control-group"><input type="number" name="variants[4344][price]" data-vv-as=""price"" step="any" class="control"> <!----></div></td>
.
.
.
.
<td><div class="control-group"><input type="number" name="variants[4345][price]" data-vv-as=""[price"" > <!----></div></td>
now I want this 2 or multiple inputs change together .
#section('css')
#parent
<style>
.table th.price, .table th.weight {
width: 100px;
}
.table th.actions {
width: 85px;
}
.table td.actions .icon {
margin-top: 8px;
}
.table td.actions .icon.pencil-lg-icon {
margin-right: 10px;
}
</style>
#stop
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.before', ['product' => $product]) !!}
<accordian :title="'{{ __('admin::app.catalog.products.variations') }}'" :active="true">
<div slot="body">
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.controls.before', ['product' => $product]) !!}
<button type="button" class="btn btn-md btn-primary" #click="showModal('addVariant')">
{{ __('admin::app.catalog.products.add-variant-btn-title') }}
</button>
<variant-list></variant-list>
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.controls.after', ['product' => $product]) !!}
</div>
</accordian>
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.after', ['product' => $product]) !!}
<modal id="addVariant" :is-open="modalIds.addVariant">
<h3 slot="header">{{ __('admin::app.catalog.products.add-variant-title') }}</h3>
<div slot="body">
<variant-form></variant-form>
</div>
</modal>
#push('scripts')
#parent
<script type="text/x-template" id="variant-form-template">
<form method="POST" action="{{ route('admin.catalog.products.store') }}" data-vv-scope="add-variant-form" #submit.prevent="addVariant('add-variant-form')">
<div class="page-content">
<div class="form-container">
<div v-for='(attribute, index) in super_attributes' class="control-group" :class="[errors.has('add-variant-form.' + attribute.code) ? 'has-error' : '']">
<label :for="attribute.code" class="required">#{{ attribute.admin_name }}</label>
<select v-validate="'required'" v-model="variant[attribute.code]" class="control" :id="attribute.code" :name="attribute.code" :data-vv-as="'"' + attribute.admin_name + '"'">
<option v-for='(option, index) in attribute.options' :value="option.id">#{{ option.admin_name }}</option>
</select>
<span class="control-error" v-if="errors.has('add-variant-form.' + attribute.code)">#{{ errors.first('add-variant-form.' + attribute.code) }}</span>
</div>
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.catalog.products.add-variant-title') }}
</button>
</div>
</div>
</form>
</script>
<script type="text/x-template" id="variant-list-template">
<div class="table" style="margin-top: 20px; overflow-x: auto;">
<table>
<thead>
<tr>
<th class="sku">{{ __('admin::app.catalog.products.sku') }}</th>
<th>{{ __('admin::app.catalog.products.name') }}</th>
#foreach ($product->super_attributes as $attribute)
<th class="{{ $attribute->code }}" style="width: 150px">{{ $attribute->admin_name }}</th>
#endforeach
<th class="qty">{{ __('admin::app.catalog.products.qty') }}</th>
<th class="price">{{ __('admin::app.catalog.products.price') }}</th>
<th class="weight">{{ __('admin::app.catalog.products.weight') }}</th>
<th class="status">{{ __('admin::app.catalog.products.status') }}</th>
<th class="actions"></th>
</tr>
</thead>
<tbody>
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index" :index="index" :variant-price.sync="variantPrice" #onRemoveVariant="removeVariant($event)"></variant-item>
</tbody>
</table>
</div>
</script>
<script type="text/x-template" id="variant-item-template">
<tr>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[sku]') ? 'has-error' : '']">
<input type="text" v-validate="'required'" v-model="variant.sku" :name="[variantInputName + '[sku]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.sku') }}"" v-slugify/>
<span class="control-error" v-if="errors.has(variantInputName + '[sku]')">#{{ errors.first(variantInputName + '[sku]') }}</span>
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[name]') ? 'has-error' : '']">
<input type="text" v-validate="'required'" v-model="variant.name" :name="[variantInputName + '[name]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.name') }}""/>
<span class="control-error" v-if="errors.has(variantInputName + '[name]')">#{{ errors.first(variantInputName + '[name]') }}</span>
</div>
</td>
<td v-for='(attribute, index) in superAttributes'>
<div class="control-group">
<input type="hidden" :name="[variantInputName + '[' + attribute.code + ']']" :value="variant[attribute.code]"/>
<input type="text" class="control" :value="optionName(variant[attribute.code])" readonly/>
</div>
</td>
<td>
<button style="width: 100%;" type="button" class="dropdown-btn dropdown-toggle">
#{{ totalQty }}
<i class="icon arrow-down-icon"></i>
</button>
<div class="dropdown-list">
<div class="dropdown-container">
<ul>
<li v-for='(inventorySource, index) in inventorySources'>
<div class="control-group" :class="[errors.has(variantInputName + '[inventories][' + inventorySource.id + ']') ? 'has-error' : '']">
<label>#{{ inventorySource.name }}</label>
<input type="text" v-validate="'numeric|min:0'" :name="[variantInputName + '[inventories][' + inventorySource.id + ']']" v-model="inventories[inventorySource.id]" class="control" v-on:keyup="updateTotalQty()" :data-vv-as="'"' + inventorySource.name + '"'"/>
<span class="control-error" v-if="errors.has(variantInputName + '[inventories][' + inventorySource.id + ']')">#{{ errors.first(variantInputName + '[inventories][' + inventorySource.id + ']') }}</span>
</div>
</li>
</ul>
</div>
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[price]') ? 'has-error' : '']">
<input type="number" v-validate="'required|min_value:0.0001'" v-model="variant.price" :name="[variantInputName + '[price]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.price') }}"" step="any"/>
<span class="control-error" v-if="errors.has(variantInputName + '[price]')">#{{ errors.first(variantInputName + '[price]') }}</span>
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[weight]') ? 'has-error' : '']">
<input type="number" v-validate="'required|min_value:0.0001'" v-model="variant.weight" :name="[variantInputName + '[weight]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.weight') }}"" step="any"/>
<span class="control-error" v-if="errors.has(variantInputName + '[weight]')">#{{ errors.first(variantInputName + '[weight]') }}</span>
</div>
</td>
<td>
<div class="control-group">
<select type="text" v-model="variant.status" :name="[variantInputName + '[status]']" class="control">
<option value="1" :selected="variant.status">{{ __('admin::app.catalog.products.enabled') }}</option>
<option value="0" :selected="!variant.status">{{ __('admin::app.catalog.products.disabled') }}</option>
</select>
</div>
</td>
<td class="actions">
<a :href="['{{ route('admin.catalog.products.index') }}/edit/' + variant.id]"><i class="icon pencil-lg-icon"></i></a>
<i class="icon remove-icon" #click="removeVariant()"></i>
</td>
</tr>
</script>
<script>
$(document).ready(function () {
Vue.config.ignoredElements = [
'variant-form',
'variant-list',
'variant-item'
];
});
var super_attributes = #json(app('\Webkul\Product\Repositories\ProductRepository')->getSuperAttributes($product));
var variants = #json($product->variants);
Vue.component('variant-form', {
data: function() {
return {
variant: {},
super_attributes: super_attributes
}
},
template: '#variant-form-template',
created: function () {
this.resetModel();
},
methods: {
addVariant: function (formScope) {
this.$validator.validateAll(formScope).then((result) => {
if (result) {
var this_this = this;
var filteredVariants = variants.filter(function(variant) {
var matchCount = 0;
for (var key in this_this.variant) {
if (variant[key] == this_this.variant[key]) {
matchCount++;
}
}
return matchCount == this_this.super_attributes.length;
})
if (filteredVariants.length) {
this.$parent.closeModal();
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.catalog.products.variant-already-exist-message') }}" }];
this.$root.addFlashMessages()
} else {
var optionIds = [];
for (var key in this_this.variant) {
optionIds.push(this_this.variant[key]);
}
variants.push(Object.assign({
sku: '{{ $product->sku }}' + '-variant-' + optionIds.join('-'),
name: '',
price: 0,
weight: 0,
status: 1
}, this.variant));
this.resetModel();
this.$parent.closeModal();
}
}
});
},
resetModel: function () {
var this_this = this;
this.super_attributes.forEach(function(attribute) {
this_this.variant[attribute.code] = '';
})
}
}
});
Vue.component('variant-list', {
template: '#variant-list-template',
inject: ['$validator'],
data: function() {
return {
variants: variants,
variantPrice:0,
old_variants: #json(old('variants')),
superAttributes: super_attributes
}
},
created: function () {
var index = 0;
for (var key in this.old_variants) {
var variant = this.old_variants[key];
if (key.indexOf('variant_') !== -1) {
var inventories = [];
for (var inventorySourceId in variant['inventories']) {
inventories.push({'qty': variant['inventories'][inventorySourceId], 'inventory_source_id': inventorySourceId})
}
variant['inventories'] = inventories;
variants.push(variant);
} else {
for (var code in variant) {
if (code != 'inventories') {
variants[index][code] = variant[code];
} else {
variants[index][code] = [];
for (var inventorySourceId in variant[code]) {
variants[index][code].push({'qty': variant[code][inventorySourceId], 'inventory_source_id': inventorySourceId})
}
}
}
}
index++;
}
},
methods: {
removeVariant: function(variant) {
let index = this.variants.indexOf(variant)
this.variants.splice(index, 1)
},
}
});
Vue.component('variant-item', {
template: '#variant-item-template',
props: ['variantPrice','index', 'variant'],
inject: ['$validator'],
data: function() {
return {
inventorySources: #json($inventorySources),
inventories: {},
totalQty: 0,
superAttributes: super_attributes
}
},
created: function () {
var this_this = this;
this.inventorySources.forEach(function(inventorySource) {
this_this.inventories[inventorySource.id] = this_this.sourceInventoryQty(inventorySource.id)
this_this.totalQty += parseInt(this_this.inventories[inventorySource.id]);
})
},
computed: {
variantInputName: function () {
if (this.variant.id)
return "variants[" + this.variant.id + "]";
return "variants[variant_" + this.index + "]";
}
},
methods: {
removeVariant: function () {
this.$emit('onRemoveVariant', this.variant)
},
onVariantPriceInput(event) {
this.$emit('update:variantPrice', Number(event.target.value));
},
optionName: function (optionId) {
var optionName = '';
this.superAttributes.forEach(function(attribute) {
attribute.options.forEach(function(option) {
if (optionId == option.id) {
optionName = option.admin_name;
}
});
})
return optionName;
},
sourceInventoryQty: function (inventorySourceId) {
if (! Array.isArray(this.variant.inventories))
return 0;
var inventories = this.variant.inventories.filter(function(inventory) {
return inventorySourceId === parseInt(inventory.inventory_source_id);
})
if (inventories.length)
return inventories[0]['qty'];
return 0;
},
updateTotalQty: function () {
this.totalQty = 0;
for (var key in this.inventories) {
this.totalQty += parseInt(this.inventories[key]);
}
}
}
});
</script>
#endpush
If it is your objective to have a single price which is shared by all variants, then I would advise against having a price property per variant Object. variant.price suggests a price per variant. I would create a separate data property, say variantPrice that would be passed to each instance of the variant-item component.
(As an aside: If there is a single price that is to be shared by all variant-item components then it may be confusing to your users that you render a price input field per variant-item instead of having a single input field.)
One way to synchronize a value with multiple child components, and assuming you are using a version of Vue >= 2.3 and < 3, is to use the .sync modifier.
Your parent component - the one that references the variants Array - would have a new data property for variantPrice. Here is an example where the parent is the root Vue component:
new Vue({
components: {
variantItem: VariantItem
},
data() {
return {
variantPrice: 0,
variants: [
{
inputName: 'VariantOne'
},
{
inputName: 'VariantTwo'
}
]
};
},
el: "#App"
});
The template of the parent (root) would pass variantPrice as a prop to each variant-item instance using the .sync modifier which will bind the value of variantPrice to the update:variantPrice event emitted by the child. The template would look like:
<div id="App">
<variant-item v-for="(variant, index) in variants" :key="index" :variant="variant" :variant-price.sync="variantPrice"></variant-item>
</div>
Next, we must ensure that our VariantItem component takes a variantPrice as a prop and emits the update:variantPrice event when the input field is modified by the user:
const VariantItem = Vue.component('variant-item', {
methods: {
onVariantPriceInput(event) {
this.$emit('update:variantPrice', Number(event.target.value));
}
},
props: {
variant: {
required: true,
type: Object
},
variantPrice: {
required: true,
type: Number
}
},
template: '#VariantItemTemplate'
});
The template for this component would become:
<div>
<label :for="variant.inputName">{{ variant.inputName }}</label>
<input :id="variant.inputName" :name="variant.inputName" :value="variantPrice" #input="onVariantPriceInput" type="number">
</div>
I have created a fiddle for your reference.

How to use data or methods across different components

I have a HTML table in which in one component I have table head and other stuff and in other component I have tbody so in every row of tbody I am adding a delete row button which I want to delete but the data is in theadcomponent there is no parent-child relation here so how can I do this.
My code
Vue.component("form-row", {
template: "#row-template",
props: {
itemname: String,
quantity: Number,
sellingprice: Number,
amount: Number
},
methods: {
delete() {
alert("tedt")
}
},
computed: {
quantitySynced: {
get() {
return this.quantity;
},
set(v) {
this.$emit("update:quantity", +v);
}
},
sellingpriceSynced: {
get() {
return this.sellingprice;
},
set(v) {
this.$emit("update:sellingprice", +v);
}
},
amountSynced() {
this.$emit("update:amount", parseFloat(this.quantity) * parseFloat(this.sellingprice));
return this.amount
}
}
});
new Vue({
el: "#app",
data() {
return {
tableDatas: []
};
},
methods: {
btnOnClick(v) {
this.tableDatas.push({
itemname: "item",
quantity: 1,
sellingprice: 55,
amount: 55
});
}
},
computed: {
calculate() {
return (
this.tableDatas.reduce((total, {
amount
}) => total + amount, 0) || 0
);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button type="button" #click="btnOnClick">Add</button>
<table class="table table-striped table-hover table-bordered mainTable" id="Table">
<thead>
<tr>
<th class="itemName">Item Name</th>
<th>Quantity</th>
<th>Selling Price</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<form-row v-for="(row, key) in tableDatas" :key="key" v-bind.sync="row"></form-row>
</tbody>
</table>
<div>
<label>Total Row's Amount</label>
<input type="text" disabled :value="calculate">
</div>
</div>
<script type="text/x-template" id="row-template">
<tr>
<td>
<input class="form-control" readonly :value="itemname" />
</td>
<td>
<input class="form-control text-right" type="number" min="0" step="1" v-model="quantitySynced" />
</td>
<td>
<input class="form-control text-right" type="number" min="0" step=".5" v-model="sellingpriceSynced" />
</td>
<td>
<input readonly class="form-control text-right" type="number" min="0" step="1" :value="amountSynced" />
</td>
<td>
<button>Delete</button>
</td>
</tr>
</script>
Here I have two components In one component delete button is the I know how to delete the row in same component by using this:
delete(index) {
console.log("Removing", index);
this.tableDatas.splice(index, 1);
}
Vue Mixins will work for your problem.
Mixins are a flexible way to distribute reusable functionalities for Vue components. A mixin object can contain any component options. When a component uses a mixin, all options in the mixin will be “mixed” into the component’s own options.
Here is an example;
// define a mixin object
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// define a component that uses this mixin
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
Use the Shared events to catch between parent to component
var sharedEvents = new Vue();---declare on top of the vue instance
//parent
new Vue({
el: "#app",
---code--
methods:
getData(){
//emit the data in parent like this
sharedEvents.$emit('forceInjectGridData', {id: "billing-grid", data: data});
}
});
And catch the data in component like below wherever you want:
methods:{
forceInjectGridData(v) {
if (this.id === v.id) {
this.gridData = v.data;
//do your coding here
}
},
} ,
mounted(){
sharedEvents.$on('forceInjectGridData', this.forceInjectGridData);
}

Add comma separated value to separate lines in VUE JS

Hi guys I have the following code where I look over a json file and add the data to a table.
I want the data from product.refrencing_category_ids to be output in on separate lines instead being in one line like this:
bc-men,bc-men-fashion,bc-men-underwear
I would like it to look like:
bc-men,
bc-men-fashion,
bc-men-underwear
How would i go about doing that? Would I need another for loop for the product.refrencing_category_ids?
My code look like this:
<template>
<div>
<h1>Category Assignment</h1>
<table class="table">
<tr class="table-header">
<th>ID</th>
<th>Name</th>
<th>Primary category</th>
<th>Refrencing categories</th>
<th>Add</th>
<tr>
<tr class="product" v-for="product in products">
<td class="product__item"><input required type="text" v-model="product.id"></td>
<td class="product__item"><input required type="text" name="fname" v-model="product.name"></td>
<td class="product__item">
<input required type="text" name="fname" v-model="product.primary_category_id">
</td>
<td class="product__item">
<input required type="text" name="fname" v-model="product.refrencing_category_ids">
</td>
<td class="product__item">
<button v-on:click="product.quantity += 1">
Add
</button>
</td>
</tr>
</table>
<h2>Total inventory: {{ totalProducts }}</h2>
</div>
</template>
<script>
export default {
name: 'ProductEnrichment',
data () {
return {
products: [],
productHeadline: 'Product Flow Tool'
}
},
computed: {
totalProducts () {
return this.products.reduce((sum, product) => {
return sum + product.quantity
}, 0)
}
},
created () {
fetch('https://www.fennefoss.dk/product-request.json')
//fetch('./sample.json')
.then(response => response.json())
.then(json => {
this.products = json.products
})
}
}
</script>
Yes to another loop with v-for. To make the list item reactive, you need to update the original data and not the computed one. Something like this:
new Vue({
el: '#app',
data() {
return {
product: {
refrencing_category_ids: 'bc-men,bc-men-fashion,bc-men-underwear'
}
}
},
methods: {
remove(idx) {
let items = this.product.refrencing_category_ids.split(',');
let removed = items.splice(idx, 1);
this.product.refrencing_category_ids = items.join(',');
}
},
computed: {
refCatIds() {
return this.product.refrencing_category_ids.split(',');
}
}
})
ul {
list-style: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul>
<li v-for="(id, index) in refCatIds" :key="index">
{{id}}
</li>
</ul>
</div>
Replace all of the commas with \n (newline character)
let string = "bc-men,bc-men-fashion,bc-men-underwear"
console.log(string.replace(/,/g, '\n'))

Vue js 2 & Axios Post Request - Form

I am trying to post my form using axios, but I am not able to get the data to my backend using expressjs
This is what I am doing:
<template>
<form class="" method="post" #submit.prevent="postNow">
<input type="text" name="" value="" v-model="name">
<button type="submit" name="button">Submit</button>
</form>
</template>
export default {
name: 'formPost',
data() {
return {
name: '',
show: false,
};
},
methods: {
postNow() {
axios.post('http://localhost:3030/api/new/post', {
headers: {
'Content-type': 'application/x-www-form-urlencoded',
},
body: this.name,
});
},
components: {
Headers,
Footers,
},
};
backend file:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
router.post('/new/post', (req, res) => {
res.json(console.log("this is working" + ' ' + req.body.name));
});
The error I am receiving is:
this is working undefined
Axios post format:
axios.post(url[, data[, config]])
Your request should be:
axios.post('http://localhost:3030/api/new/post',
this.name, // the data to post
{ headers: {
'Content-type': 'application/x-www-form-urlencoded',
}
}).then(response => ....);
Fiddle: https://jsfiddle.net/wostex/jsrr4v1k/3/
<template>
<div id="content">
<h1>...</h1>
<div>
<label>Product Name</label> : <input type="text" id="txt1" v-model="model.productName" />
</div>
<div>
<label>Desciription</label> : <input type="text" id="txt2" v-model="model.descrption" />
</div>
<div>
<button type="button" v-on:click="saveClick">Save</button>
</div>
</div>
<hr />
<hr />
<h1>...</h1>
<table border="1" style="margin:auto">
<thead>
<tr>
<th style="width: 100px">ID</th>
<th style="width: 100px">Product Name</th>
<th style="width: 100px">Desciription</th>
<th style="width: 100px"></th>
</tr>
</thead>
<tbody>
<tr v-for="item in model.list" v-bind:key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.productName }}</td>
<td>{{ item.descrption }}</td>
<td><button type="button" v-on:click="deleteClick(item.id)">Delete</button></td>
</tr>
</tbody>
</table>
</template>
<script>
import axios from "axios";
export default {
name: "Product",
data: function () {
return {
model: {
productName: "",
descrption: "",
},
list: [],
};
},
methods: {
saveClick() {
axios
.post("http://example.com", this.model)
.then((resp) => {
this.getList();
alert("success" + resp.data.id);
});
},
getList() {
axios.get("http://example.com").then((resp) => {
this.model.list = resp.data;
});
},
deleteClick(id) {
axios.delete("http://example.com" + id).then(() => {
this.getList();
alert("success");
});
}
},
mounted: function () {
this.getList();
},
};
</script>

Categories

Resources