I'm a little new in Vue.js and currently I am having a problem with radios.
I have a form with different inputs. When I'm submiting the form I create a JSON file with all the form answers:
Instead of this output I want the value of the selected radio to be 'Checked'.
{
"pos_r_1":"Radio 1"
"pos_r_2":"",
"pos_r_3":"",
"pos_r_4":"",
"pos_t_5":"this a test",
}
LIKE THAT:
{
"pos_r_1":"Checked"
"pos_r_2":"",
"pos_r_3":"",
"pos_r_4":"",
"pos_t_5":"this a test",
}
How can I change the value of the radio to 'checked'?
HTML
<v-form class="text-left" name="form" id="form">
<v-radio-group
v-model="checked"
hide-details="auto"
row
>
<v-radio
v-for="radio in group"
:key="radio.id"
:id="radio.id"
:name="radio.id"
:label="radio.text"
:value="radio.text"
/>
</v-radio-group>
<v-text-field
id="pos_t_5"
name="pos_t_5"
label="Text"
v-model="textfield"
/>
<v-btn
class="p-2"
color="primary"
elevation="11"
#click="onSubmit"
>click me</v-btn>
</v-form>
Script
export default Vue.extend({
name: 'Test',
data: function () {
return {
checked: '',
textfield: '',
group: [
{id: 'pos_r_1', text: 'Radio 1'},
{id: 'pos_r_2', text: 'Radio 2'},
{id: 'pos_r_3', text: 'Radio 3'},
{id: 'pos_r_4', text: 'Radio 4'},
],
}
},
onSubmit() {
this.loading = true
const form = document.querySelector('form');
const data = new FormData(form);
let currentObj = this;
let url = '/report/form/store';
axios({
url,
method: 'post',
data,
}) .then(function (response) {
currentObj.output = response.data;
}) .catch( (error) => {
if (error.response && error.response.status === 422){
this.errors = error.response.data.errors;
}
});
}
}
})
I've tried to change the value of the Radios to 'checked' but that doesn't work because then when I click one radio all getting checked.
This is only an example of the form. The form will be big with more that 20 different questions.
Update
This is not the way to do it. I have to manipulate the value of the radios buttons inside a Form Model, where I will save all the form answers. Then I can change the value of the radio to 'checked' easier.
So, radio buttons works as it should to https://developer.mozilla.org/ru/docs/Web/HTML/Element/Input/radio.
If you need to send a request like pos_r_3: Radio 3, you have to do some transformation on it. I'd suggest the code like:
export default Vue.extend({
name: 'Test',
data: function () {
return {
checked: '',
group: [
{id: 'pos_r_1', text: 'Radio 1'},
{id: 'pos_r_2', text: 'Radio 2'},
{id: 'pos_r_3', text: 'Radio 3'},
{id: 'pos_r_4', text: 'Radio 4'},
],
}
},
onSubmit() {
this.loading = true
const form = document.querySelector('form');
const data = new FormData(form);
for (let i = 0; i < this.group.length; i++){
const currentGroup = this.group[i];
data.set(currentGroup.id, currentGroup.text === this.checked ? 'Checked' : '');
}
let currentObj = this;
let url = '/report/form/store';
axios({
url,
method: 'post',
data,
}) .then(function (response) {
currentObj.output = response.data;
}) .catch( (error) => {
if (error.response && error.response.status === 422){
this.errors = error.response.data.errors;
}
});
}
}
Related
I'm a new web developer. I need help getting all of the titles from all of the objects in an array. I get an array of products from an axios request. In the next step I need to process this array in a Vue component and record a single value to data. Next I need to display this data value in a multiselect's options.
Here is the axios code:
async getOrders(ctx, data)
{
return new Promise((resolve, reject) => {
axios({
url: '/orders',
data: data,
method: 'GET'
})
.then((resp) => {
ctx.commit('setOrders', resp.data.orders)
ctx.commit('setUsers', resp.data.users)
ctx.commit('setProducts', resp.data.products)
ctx.commit('updatePagination', resp.data.pagination)
resolve(resp)
})
.catch((error) => {
console.log(error)
reject(error)
})
})
},
This is my array of products recorded in Vuex store
0: {id: 6, category_id: 2, title: "Test", brand: "Тест", serial_number: "2165412315864",…}
1: {id: 7, category_id: 3, title: "Климат", brand: "Климат", serial_number: "2165412315864",…}
2: {id: 8, category_id: 5, title: "New", brand: "New", serial_number: "2165412315864",…}
This is my code to proccessing this array
computed:{
...mapGetters('order', ['users', 'products', 'orders']),
},
methods:{
getProducts(products)
{
const arr = products.map(c => c.title)
console.log('titles: ', arr); //Debug
this.options = arr
}
},
And here is the code for the multiselect
<multiselect v-model="formData.product" :options="options" :value="values" :multiple="true" :close-on-select="false" :clear-on-select="false" :preserve-search="true" placeholder="Pick some" label="name" track-by="name" :preselect-first="true">
<template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">{{ values.length }} options selected</span></template>
</multiselect>
mounted() {
this.getProducts();
},
It looks like you're not sending your args by calling just this.getProducts(). You don't need to, just write this. in front of the computed value inside the method.
methods: {
getProducts () {
const arr = this.products.map(c => c.title)
this.options = arr
}
}
When passing params from a select, the usual syntax would be something like this.
<v-select
v-model="item_id"
items="items"
item-text="item_name"
item-value="id"
#change='itemDescription()'
/>
export default {
data: ()=> ({
item_id: '',
items: [],
itemDescription '',
}),
method: {
itemDescription() {
axios.get('/api/item', {
params: { id: this.item_id }
})
.then(response => this.itemDescription = response.data )
}
}
}
Now the problem comes when the select is inside an array.push. I can't simply pass the value to this.item_id since the structure would be object[0][1]. Here is an example syntax below.
<v-btn #click="addItem()">Add</v-btn>
<template v-for="item in items" :key="item.id>
<v-select
v-model="item.item_id"
items="item_all"
item-text="item_name"
item-value="id"
#change='itemDescription()'
/>
</template>
export default {
data: ()=> ({
items: [],
item_all: '',
}),
method: {
addItem() {
this.items.push({
item_id: '',
description: '',
}),
itemDescription() {
axios.get('/api/item', {
params: { id: this.items.item_id } // <-- this doesn't work
})
.then(response => this.items.description = response.data )
}
}
}
How do I pass id of each row every time I select each one of them?
I made it work now. I just used index, this was my savior.
Please see code below for those interested
<v-btn #click="addItem()">Add</v-btn>
<template v-for="(item, index) in items" :key="item.id>
<v-select
v-model="item.item_id"
items="item_all"
item-text="item_name"
item-value="id"
#change='itemDescription(index)'
/>
</template>
export default {
data: ()=> ({
items: [],
item_all: '',
itemDescription '',
}),
method: {
addItem() {
this.items.push({
item_id: '',
description: '',
}),
itemDescription(index) {
axios.get('/api/item', {
params: { id: this.items[index].item_id } // <-- this doesn't work
})
.then(response => this.items[index].description = response.data )
}
}
}
The 'this' in itemDescription method isn't same as 'this' in 'method:'.
so it will not work.
use another variable to keep this, and use it in itemDescription.
method: {
var that = this;
addItem() {
this.items.push({
item_id: '',
description: '',
}),
itemDescription() {
axios.get('/api/item', {
params: { id: that.items.item_id } // 'this' ain't work
})
.then(response => this.items.description = response.data )
}
Here is my problem : I have a parent component Edit that makes several axios requests, the results of these requests are passed down to a child component (Menu in my example).
<template>
<div>
<p>
Order Id : {{ this.$route.params.id }}
</p>
<head-fields :menu="menu"></head-fields>
<div>
<b-tabs content-class="mt-3">
<b-tab title="Menu" active>
<Menu :menuItems="items" :nutritionalValues="nutritionalValues"></Menu>
</b-tab>
<b-tab title="Specifications">
<specifications :specifications="specifications">
</specifications>
</b-tab>
<b-tab title="Redundancies"><p>I'm the redundancies tab!</p></b-tab>
</b-tabs>
</div>
</div>
</template>
<script>
import HeadFields from "./HeadFields";
import Menu from "./Menu";
import Specifications from "./Specifications";
export default {
name: "Edit",
components: {HeadFields, Menu, Specifications},
data(){
return{
menu: {},
loaded: false,
items: {},
nutritionalValues: {},
specifications: {},
error:{}
}
},
created(){
this.find(this.$route.params.id);
},
methods:{
find(id){
axios.get('/menusV2/'+id)
.then(response => {
this.loading = false;
this.menu = response.data[0];
this.fetchMenu(this.menu.orderId);
this.fetchSpecifications(this.menu.orderId);
});
return this.menu;
},
fetchMenu(orderId){
// console.log(orderId);
axios
.get('/menusV2/'+orderId+'/menu')
.then(response => {
this.loading = false;
this.items = response.data.items;
this.nutritionalValues = response.data.nutritionalValues;
})
.catch(error => {
this.loading = false;
this.error = error.response.data.message || error.message;
})
},
fetchSpecifications(orderId){
axios
.get('/menusV2/'+orderId+'/specifications')
.then(response => {
this.loading = false;
this.specifications = response.data;
// this.checkSpecifications();
})
.catch(error => {
this.loading = false;
// this.error = error.response.data.message || error.message;
})
}
}
}
</script>
The data is passed down to the child component "Menu" as a prop :
<template>
<div class="panel panel-default">
<b-table
striped hover
:items="menuItems"
:fields="fields"
:primary-key="menuItems.pivotId"
>
</b-table>
</div>
</template>
<script>
export default {
name: "Menu",
props: ['menuItems', 'nutritionalValues'],
data() {
return {
loading: true,
perPage: ['10', '25', '50'],
rowSelected: true,
fields: [
{key: "meal", label: "Meal", sortable: true},
{key: "category", label: "Category", sortable: true},
{key: "itemName", label: "Name", sortable: true},
{key: "noOfServing", label: "Serving", sortable: true},
{key: "weight", label: "Weight", sortable: true},
{key: "calories", label: "Calories", sortable: true},
{key: "carbs", label: "Carbs", sortable: true},
{key: "proteins", label: "Proteins", sortable: true},
{key: "fats", label: "Fats", sortable: true},
]
}
},
mounted(){
this.checkSpecifications();
},
methods:{
searchIngredientSpecification(itemId, itemName, specifications){
//Checking of the ingredients name
for (var i=0; i < specifications.length; i++) {
if (specifications[i].itemName === itemName) {
console.log("Specification ! "+itemName);
}
}
//Checking of the nutritional properties
var ingredientNutritionalProperties = {};
axios
.get('/menusV2/'+itemId+'/ingredient/nutritionalProperties')
.then(response => {
ingredientNutritionalProperties = response.data;
});
console.log("Ingredient : " + itemName);
console.log(ingredientNutritionalProperties);
},
searchDishSpecification(itemId, itemName, specifications){
//Checking of the ingredients name
for (var i=0; i < specifications.length; i++) {
if (specifications[i].itemName === itemName) {
console.log("Specification ! "+itemName);
}
}
//Checking of the nutritional properties
var dishNutritionalProperties = {};
axios
.get('/menusV2/'+itemId+'/dish/nutritionalProperties')
.then(response => {
dishNutritionalProperties = response.data;
});
console.log("Dish : " + itemName);
console.log(dishNutritionalProperties);
var ingredientsDish = {};
var ingredientsNutritionalProperties = {};
axios
.get('/menusV2/'+itemId+'/getIngredients')
.then(response => {
ingredientsDish = response.data.ingredients;
ingredientsNutritionalProperties = response.data.nutritionalProperties;
});
console.log("Dish : " + itemName);
console.log(ingredientsDish);
console.log(ingredientsNutritionalProperties);
},
checkSpecifications(){
console.log("Check Specifications launched !");
console.log(this.menuItems);
var items = this.menuItems;
items.forEach(
element => {
switch(element.type){
case 'Ingredient':
this.searchIngredientSpecification(element.itemId,element.itemName,this.specifications);
break;
case 'Dish':
this.searchDishSpecification(element.itemId,element.itemName,this.specifications);
break;
}
}
);
},
}
}
</script>
The problem I have is around the methods in the child component that are fired before the menuItems prop is filled with data from the axios request.
I think that a possible fix to this problem would be to use computed properties or watchers but I don't really know if it will help me..
Here is the error that is thrown :
Thanks for your help !
You are getting the error because when the checkSpecifications method is run on mount, this.menuItems is not an array and forEach must only be used on arrays.
One option is to add a watcher to menuItems and only once it has been filled with a value (making sure it's an array) then run the checkSpecifications method.
Alternatively, you could define menuItems as an array and provide a default value.
props: {
menuItems: {
type: Array,
default: []
},
nutritionalValues: {
type: Array,
default: []
}
It's always good practice to define the type of your props.
I want to create a form where in which the input data is added to a table that is on the next page. With VueJS.
The form has only a name and a dropdown menu.
I just want to input a name and a selected option to the table from the form.
The data from the dropmenu is - I'm unsure how to pull it into the dropdown.
Here is the JSON and my code:
Vue.js:
new Vue({
el: "#app",
data () {
return {
loading: false,
todos: [],
users_todos:[]
}
},
data:
{
currentstep: 1,
steps: [
{
id: 1,
title: "Personal",
icon_class: "fa fa-user-circle-o"
},
{
id: 2,
title: "Details",
icon_class: "fa fa-th-list"
},
{
id: 3,
title: "Send",
icon_class: "fa fa-paper-plane"
}
]
},
methods: {
stepChanged(step) {
this.currentstep = step;
}
},
mounted () {
this.loading = true;
axios.get('https://jsonplaceholder.typicode.com/users/1/todos?page=1')
.then(response => {this.users_todos = response.data})
.catch(error => console.log(error))
.finally(() => this.loading = false)
}
});
i have one form that form is open in popup..so i have only 2 fields in that form..after i submit the form i want to display the form values on the same popup(below the form).how can i do that..can any one help me..
here is my vue page:
<el-form :model="ScheduleInterviewForm" :rules="rules" ref="ScheduleInterviewForm" :inline="true">
<el-form-item prop="schedule_datetime">
<el-date-picker
v-model="ScheduleInterviewForm.schedule_datetime"
type="datetime"
size="small"
placeholder="Select Interview date">
</el-date-picker>
</el-form-item>
<el-form-item prop="interview_type_id">
<el-select size="small" v-model="ScheduleInterviewForm.interview_type_id" placeholder="Select Interview Type">
<el-option
v-for="it in interview_types"
:label="it.type"
:value="it.id">
</el-option>
</el-select>
</el-form-item>
<ElButton
type="success"
size="small"
#click="ScheduleInterview('ScheduleInterviewForm', c.hrc_id)">
SCHEDULE INTERVIEW
</ElButton>
</el-form>
<el-alert
v-show="interviewScheduled"
title="INTERVIEW SCHEDULED!"
type="success">
</el-alert>
<el-form :model="ScheduleInterviewForm" :rules="rules" ref="ScheduleInterviewForm" :inline="true">
<el-form-item prop="schedule_datetime">
</el-form-item>
</el-form>
export default {
props: ['c', 'interview_types'],
data() {
return {
ResumeDialog: false,
ScheduleInterviewForm: {
schedule_datetime: null,
interview_type_id: null,
},
rules: {
schedule_datetime: [
{ type: 'date', required: true, message: 'Select Schedule time', trigger: 'blur' },
{ validator: isDateFuture, trigger: 'blur' },
],
interview_type_id: [
{ type: 'number', required: true, message: 'Select Interview type', trigger: 'blur' }
],
},
interviewScheduled: null,
}
},
methods: {
ScheduleInterview(form, hrcId) {
var that = this;
this.$refs[form].validate((valid) => {
if (valid) {
// AJAX: Create HrRequest
axios.post('/ajax/schedule_interview', {
interviewTypeId: this.ScheduleInterviewForm.interview_type_id,
scheduleDatetime: this.ScheduleInterviewForm.schedule_datetime,
hrcId
})
.then(function(res) {
that.interviewScheduled = true;
setTimeout(() => that.interviewScheduled = false, 3000);
console.log(res);
// that.candidates = res.data.candidates;
})
.catch(function(err) {
console.log(err);
});
} else {
return false;
}
});
},
},
components: { ElButton, ElDialog, ElCard },
}
here is my js page:
const app = new Vue({
el: '#app',
data: () => ({
hr_request: window.data.hr_request,
candidates: window.data.candidates,
interview_types: window.data.interview_types,
}),
methods: {
ScheduleInterview(requestCandidateId, interviewTime) {
console.log(requestCandidateId, interviewTime);
},
},
components: {
Candidate,
Schedule,
}
});
Please can any one help me..
Thanks in advance..
Since you want the inputed values in the form show up af
ter the form is successfully submitted
Add a property in your data property as below:
data(){
return{
showFormValues = false;
}
}
Add a div with the inputed values in paragraph tags below the form and show the div only if form is sucessfully sunbmitted usimg v-show as below:
<div v-show="showFormValues">
<p>date: {{ScheduleInterviewForm.schedule_datetime}}</p>
<p>type: {{ScheduleInterviewForm.interview_type_id}}</p>
</div>
Now in the success part then block of your form submittion click method set the value of showFormValues = true like this:
ScheduleInterview(form, hrcId) {
var that = this;
this.$refs[form].validate((valid) => {
if (valid) {
// AJAX: Create HrRequest
axios.post('/ajax/schedule_interview', {
interviewTypeId: this.ScheduleInterviewForm.interview_type_id,
scheduleDatetime: this.ScheduleInterviewForm.schedule_datetime,
hrcId
})
.then(function(res) {
that.interviewScheduled = true;
//show the input form values on succesful form submission
that.showFormValues = true;
setTimeout(() => that.interviewScheduled = false, 3000);
console.log(res);
// that.candidates = res.data.candidates;
})
.catch(function(err) {
console.log(err);
});
} else {
return false;
}
});
},