I'm doing a site that uses laravel and vue js. The error I'm getting is this
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "selected_parent"
and this
[Vue warn]: Error in v-on handler (Promise/async): "Error: Request failed with status code 404"
I can't see where I'm going wrong.
Here is my product.blade.php
#extends('layouts.public')
#section('content')
<div class="content_wrapper">
#foreach($single_product as $product)
<div class="row single_product_wrapper">
<div class="col-lg-8 col-md-12-col-sm-12 product_details">
#foreach($parent_product as $parent)
<h1>
{{ $parent->title }}
</h1>
<table style="width: 100%; height: 95px;" border="2" cellspacing="5" cellpadding="5">
<tbody>
<tr style="text-align: center;">
<td>
<strong>Code</strong>
</td>
<td>
<strong>Description</strong>
</td>
<td>
<strong>Price</strong>
</td>
</tr>
<tr style="text-align: center;">
<td>
{{ $parent->code }}
</td>
<td>
{{ $parent->description }}
</td>
<td>
{{ $parent->price }}
</td>
</tr>
</tbody>
</table>
#endforeach
<!-- BEGIN ADD TO CART FORM -->
<div id="app">
#foreach($parent_product as $parent)
<code-selection :products="{{ $parent_product }}" :children="{{ $parent->parent }}"></code-selection>
#endforeach
</div>
<!-- END ADD TO CART FORM -->
</div>
</div>
#endforeach
</div>
#stop
and this is my vue
<template>
<div>
<form #submit.prevent="submit">
<div class="row">
<div class="col-lg-12 code_select">
<select name="code" id="code" class="form-control mb-2 mt-10" v-model="selected_parent" required>
<option :value="selected_parent">Please select your code</option>
<option v-for="product in products" :value="product.id">
{{ product.code }}
</option>
<option v-for="child in children" :value="child.id">
{{ child.code }}
</option>
</select>
</div>
</div>
<input type="submit" class="btn btn-dark btn-lg btn-block" value="Add To Cart">
</form>
</div>
</template>
<script>
import axios from 'axios'
export default {
props: [
'products',
'children',
'selected_parent'
],
mounted() {
console.log('Component mounted.')
},
methods: {
submit(){
var formData = new FormData();
formData.append('code', this.selected_parent);
return axios.post('/add-to-cart/'+this.selected_parent, formData)
.then(
function(response)
{
console.log(response.data.redirect);
window.location = response.data.redirect;
}
);
},
},
}
</script>
So what I would like to happen is, when the user selects a code and hits the Add To Cart button they will then get taken to the cart page, but right now
that isn't happening when I select the code and hit the button nothing happens and I get the errors that I said in my console.
If there is anything else you need to know please let me know
The answer is simple, you should break the direct prop mutation by assigning the value to some local component variables(could be data property, computed with getters, setters, or watchers).
Here's a simple solution using the watcher.
<template>
<input
v-model="input"
#input="updateInput" />
</template>
<script>
export default {
props: {
value: {
type: String,
default: '',
},
},
data() {
return {
input: '',
};
},
watch: {
value: {
handler(after) {
this.input = after;
},
immediate: true,
},
},
methods: {
updateInput() {
this.$emit('input', this.input);
},
},
};
</script>
It's what I use to create any data input components and it works just fine. Any new variables sent by parent v-model will be watched and assigned to the input variable and once the input is received, catch that action and emit input to parent suggesting that data is input from the form element.
And for the second part, when you receive the new url from redirect, simply replace the location href like this:
return axios.post('/add-to-cart/'+this.selected_parent, formData)
.then((response) => {
window.location.href = response.data.redirect;
})
.catch((error) => {
console.log(error);
})
);
Related
I am trying to get the Decoration types according to the house area types. I got the house area types but failed to get the decoration types. In Vue dev tool the "houseTypes" are showing an array but the "decorTypes" are showing "Reactive". I am also dynamically creating rows and removing them. for that i took an array
my vue file is--
<template>
<div v-for="(tab,k) in tabs" :key="k" >
<table class="table table-borderless col-md-12">
<thead>
<th>HouseAreaType</th>
<th>DecorationType</th>
<th>Action</th>
</thead>
<tbody>
<td>
<select
v-model="tab.selectedHouseType"
class="form-control select2"
id="houseType1"
required
name="houseAreaTypeId"
>
<option
v-for="houseType in houseTypes"
:key="houseType.id"
:value="houseType.id"
>
{{ houseType.name }}
</option>
</select>
</td>
<td>
<select
v-model="selectedDecor"
#change="getDescription()"
class="form-control select2"
required
>
<option
selected
v-for="decorType in decorTypes"
:key="decorType.id"
:value="decorType.id"
>
{{ decorType.name }}
</option>
</select>
</td>
<input type="submit" class="btn btn-success" value="Save" />
</td>
<td>
<input
type="button"
class="btn btn-success"
value="Add More"
#click="addRow"
/>
</td>
<td >
<input
type="button"
class="btn btn-danger"
value="Remove"
#click="removeRow(k,tab)"
/>
</td>
</tbody>
</table>
</div>
</template>
<script type="module">
export default {
data() {
return {
tabs: [{
rate:"",
selectedHouseType: "",
selectedDecor: "",
}],
tabCounter: 0,
houseTypes: {},
decorTypes: {},
};
},
methods: {
getHouseTypes() {
axios.get("/api/houseTypes").then((response) => {
this.houseTypes = response.data;
// this.productForm.colors = response.data;
});
},
addRow() {
this.tabs.push(this.tabCounter++);
},
removeRow(index,tab) {
var idx = this.tabs.indexOf(tab);
console.log(idx, index);
this.tabs.splice(idx, 1);
},
},
watch: {
'tab.selectedHouseType': function (value){
axios.get('/api/decorTypes?houseAreaTypeId=' + value)
.then((response) => {
console.log(response.data);
this.decorTypes = response.data.data;
});
},
},
mounted() {
this.getHouseTypes();
},
};
</script>
my api.php---
Route::get('/houseTypes',[CartController::class,'getHouseTypes'])->name('houseTypes');
Route::get('/decorTypes',[CartController::class,'getDecorTypes'])->name('decorTypes');
my CartController--
public function getHouseTypes()
{
$houseTypes = HouseAreaType::all();
return response()->json($houseTypes);
}
public function getDecorTypes()
{
$houseAreaTypeId = request('houseAreaTypeId');
$decorTypes = DecorationType::where('houseAreaTypeId',$houseAreaTypeId)->get();
return response()->json($decorTypes);
}
solved iy.
created a method getDecor()..
<select
v-model="tab.selectedHouseType"
#change="getDecor()"
class="form-control select2"
id="houseType1"
required
name="houseAreaTypeId"
>
in the mthods--
getDecor(){
axios.get('/api/decorTypes', {
params: {
houseAreaTypeId: this.tabs[this.tabs.length-
1].selectedHouseType
}
}).then(function(response){
console.log(response.data);
}.bind(this));
}
I'm trying to return a specific data when Enter key is pressed. It's something like a barcodes scanner. After each scann scanner enter key code(keyCode = 13) and then app should go through each json object and return the whole json object depends on the scanned barcode.
At this momment I can get whole json... So as I don't need whole json I would like at first to get blank form and after I put barcode in the input field and press ENTER it sould return the sepcific object...
Yeah kind of a complicated task.
index.vue:
<template>
<div class="row">
<div class="card mx-auto">
<div>
<div class="row">
<div class="card w-auto mx-auto">
<div class="card-header">
<div class="row">
<div class="col">
<h3>{{ id }}</h3>
</div>
</div>
</div>
<div class="card-body">
<form >
<div class="form-row align-items-center">
<div class="col">
<input
type="number"
v-model="barcodeSearch"
name="barcode"
class="form-control"
id="inlineFormInput"
placeholder="Barkodas..."
/>
placeholder="Barkodas...">
</div>
</div>
</form>
<table class="table">
<tbody v-if="items">
<div v-for="item in items" :key="item.PrekesID" class="tItems">
<tr >{{ item.Prekes_Pavad}}</tr>
<hr>
<tr >{{ item.Prekes_Kodas}}</tr>
<hr>
<tr >{{ item.PrekesID}}</tr>
<hr>
<div class="col">
<input type="number" name="ItemsFound" class="form-control" id="inlineFormInput"
placeholder="Faktinis likutis">
</div>
<hr>
<div class="col">
<button type="submit" class="btn btn-primary mb-1">Patvirtinti</button>
</div>
</div>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['id'],
data() {
return {
items: []
};
},
mounted() {
fetch("https:**internal address which return json. Example below.**)
.then((res) => res.json())
.then((data) => (this.items = data))
.catch((err) => console.log("err.message"));
},
},
computed: {
searchedBarcode() {
const value = this.barcodeSearch;
let reactiveArray = this.items.filter(function (item) {
if (item && item.Barkodas) {
return item.Barkodas.indexOf(value) > -1;
}
return false;
});
if (reactiveArray.length > 0) {
return reactiveArray;
} else {
return this.items;
}
},
},
</script>
Json exmple:
[
{
"EilesNumeris": 1,
"EilutesNumeris": 1,
"PrekesID": 521328,
"Prekes_Kodas": "5METP000000084",
"Barkodas": "000000220136",
"Prekes_Pavad": "M6-Zn POVERŽLĖ DIN9021",
},
{
"EilesNumeris": 1,
"EilutesNumeris": 2,
"PrekesID": 68316,
"Prekes_Kodas": "5MST000057",
"Barkodas": "0000010008812",
"Prekes_Pavad": "MEDSRAIGČIAI BLT 6,0x40 grūd.D 1/200",
},
{
"EilesNumeris": 1,
"EilutesNumeris": 3,
"PrekesID": 314849,
"Prekes_Kodas": "5MSGR00023",
"Barkodas": "000003962",
"Prekes_Pavad": "%-4,2x19 SAVISRIEGIS Į MET. BE GRĄŽTELIO (AKCIJA)",
},
Use a form submit handler
As we discussed in the comments: Yes, you cannot call barcodeSearch as a method, it is a computed value. But why not create a form handler for the component?
Let's add a form submit handler. You only change this.barcodeSearch in that submit method and don't bind it to the input. This way the only time barcodeSearch is updated is when the form is submitted (pressing enter, clicking search button, clicking "OK" on mobile, etc.).
So remove v-bind="barcodeSearch" from your form first.
Add a submit method for the form:
methods: {
submitForm() {
this.barcodeSearch = this.$refs.searchForm.barcode;
}
}
Then add a submit handler to the form:
...
<form #submit.prevent="submitForm" ref="searchForm">
...
Now the computed value will only change when submitting the form.
I am trying to get data in the table code are as below
I want to autofill the table with the depending dropdownlist selected value. i’ve been finding solution since days but didn’t get any success. I’m very new at this.
If anyone could help to get me out from this issue i’ll be very grateful. Thank You.
Here Is my HTML code
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">employees Table</h3>
<div class="card-body">
<div class="md-3">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<select
name="company_id"
id="company_id"
:class="{'is-invalid':form.errors.has('company_id')}"
class="form-control"
v-model="form.company_id"
#change="getEmployeesbyCompany()"
>
<option value selected>Select Company</option>
<option
v-for="Company in Companies.data"
:key="Company.id"
>{{Company.Company}}</option>
</select>
<has-error :form="form" field="company_id"></has-error>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /.card-header -->
<div class="card-body table-responsive p-0">
<div class="col-md-12"></div>
<table class="table table-hover">
<!-- <thead>
</thead>-->
<tbody>
<tr>
<th>ID</th>
<th>Badge#</th>
<th>Company</th>
<th>BadgeType</th>
<th>Nationality</th>
<th>Last Name</th>
<th>First Name</th>
<th>Telphonenumber</th>
<th>Position</th>
<th>SupervisorName</th>
<th>SupervisorNumber</th>
<th>Issuedate</th>
<th>Tazker</th>
<th>Expiredate</th>
<th>Serialnumber</th>
<th>Modify</th>
</tr>
<tr v-for="employee in employees.data" :key="employee.id">
<td>{{employee.id}}</td>
<td>{{employee.BadgeCode|UppCaseFirstLetter}}</td>
<!-- <td>{{employee.company_id}}</td> -->
<td>{{Company.Company}}</td>
<td>
<span class="tag tag-success">{{employee.BadgeType}}</span>
</td>
<td>{{Nationality.nationality}}</td>
<td>{{employee.lastname |UppCaseFirstLetter}}</td>
<td>{{employee.firstname |UppCaseFirstLetter}}</td>
<td>{{employee.telphonenumber |UppCaseFirstLetter}}</td>
<td>{{employee.position |UppCaseFirstLetter}}</td>
<td>{{employee.supervisorname |UppCaseFirstLetter}}</td>
<td>{{employee.supervisornumber|UppCaseFirstLetter}}</td>
<td>{{employee.Issuedate|mydate}}</td>
<td>{{employee.tazker|UppCaseFirstLetter}}</td>
<td>{{employee.Expiredate |mydate}}</td>
<td>{{employee.serialnumber |UppCaseFirstLetter}}</td>
</tr>
</tbody>
</table>
</div>
<!-- /.card-body -->
<div class="card-footer">
<pagination :data="employees" #pagination-change-page="getResults"></pagination>
</div>
</div>
<!-- /.card -->
</div>
My #change="getEmployeesbyCompany" method:
methods: {
getEmployeesbyCompany: function() {
axios.get("api/getEmployees", {
params: {company_id: this.form.company_id}})
.then( function(response) {this.employees = response.data;}.bind(this)
);
}
Route:
Route::get('getEmployees','API\EmployeeController#getEmployees');
My getEmployees(){} method:
public function getEmployees(Request $request)
{
$employees = Employee::where('company_id',$request->company_id)->get();
return $employees;
}
My data() in Vue Component:
data() {
return {
editMode: false,
selectedTicketInvoiceId: false,
Companies: {},
Nationalities: {},
employees: {},
form: new Form({id: "",BadgeCode: "",BadgeType: "",company_id: "",
nationality_id: "",lastname: "",firstname: "",telphonenumber: "",
position: "",supervisorname: "", supervisornumber: "",
issuedate: "",tazker: "", expiredate: "", serialnumber: "" })};
}
The issue is that your table is using employees.data in the v-for directive. This works fine on the initial page load, because employees is a Laravel paginator, so the data property is defined, and it contains the array of employees, as expected.
However, your controller function is simply returning an array of employees. You are saving that array to your Vue instance's employees property. So now employees.data is undefined, and your table is empty.
To fix the issue, you can update your controller function like this:
public function getEmployees(Request $request)
{
$employees = Employee::where('company_id',$request->company_id)->get();
return ['data' => $employees]; // or return response()->json(['data' => employees]);
}
I want to insert multi rows checked in my data table, when I click a button valider, everyone I have a problem in a laravel framework, I want to insert line check in a data table when click on button validate, this my code
the display of the salary list
<body>
<div class="container" id="app">
<div class="list-group">
<div class="list-group-item">
<h3>Pointage Mensuel</h3>
<div class="col-md-6 col-md-offset-3">
<h3>jour : {{$data['datek']}} chantier : {{$data['chantier_name']}}</h3>
</div>
<button class="btn btn-success add-all" data-url="">Valider Pointage de mois</button>
</div>
</div>
<div class="list-group">
<div class="list-group-item">
<table class="table table-bordered">
<tr>
<th>Archive</th>
<th><input type="checkbox" id="check_all"></th>
<th>S.No.</th>
<th>matricule</th>
<th>nom & prenom</th>
<th>salaire net</th>
<th>nbre de jour </th>
<th>prime</th>
</tr>
#if($salaries->count())
#foreach($salaries as $key => $salarie)
<tr id="tr_{{$salarie->id}}">
<td>archive</td>
<td><input type="checkbox" class="checkbox" data-id="{{$salarie->id}}"></td>
<td>{{ ++$key }}</td>
<td>{{ $salarie->matricule }}</td>
<td>{{ $salarie->nom }} {{ $salarie->prenom }}</td>
<td>{{ $salarie->salairenet }}</td>
<td><input type="text" name="nbreJ" class="form-control" value="{{$data['nbr']}}"></td>
<td><input type="text" name="prime" class="form-control" value="0"></td>
</tr>
#endforeach
#endif
</table>
</div>
</div>
<!-------------------//////////////////////////------------->
</div>
</body>
code ajax for checked all /uncheck and
<script type="text/javascript">
$(document).ready(function () {
$('#check_all').on('click', function(e) {
if($(this).is(':checked',true)) {
$(".checkbox").prop('checked', true);
} else {
$(".checkbox").prop('checked',false); } });
$('.checkbox').on('click',function(){
if($('.checkbox:checked').length == $('.checkbox').length){
$('#check_all').prop('checked',true);
}else{
$('#check_all').prop('checked',false); }});
$('.add-all').on('click', function(e) {
var idsArr = [];
$(".checkbox:checked").each(function() {
idsArr.push($(this).attr('data-id'));});
if(idsArr.length <=0) {
alert("Please select atleast one record to pointer.");
} else {
var strIds = idsArr.join(",");
$.ajax({
url: "{{ route('salarie.multiple-add') }}",
type: 'POST',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
data: {
'ids' : strIds},
success: function (data) {
if (data['status']==true) {
$(".checkbox:checked").each(function() {
alert(strIds); });
alert(data['message']);
} else {
alert('Whoops Something went wrong!!');}
window.location.reload()},
error: function (data) {
alert(data.responseText);}});} }); });
</script>
function controller addMultiple
public function addMultiple(Request $request){
$pointage=new Pointage();
$pointage->datep=$request->datep;
$pointage->nbrj=$request->nbrj;
$pointage->prime=$request->prime;
$pointage->solde=$request->solde;
return response()->json(['status'=>true]);
}
Apologies for late answer laptop died on me while i was busy but one way you could do it is by using array names for example:
<td><input type="checkbox" class="checkbox" name="row[$key][salarie]" data-id="{{$salarie->id}}"></td>
baiclly if you have multiple of these inputs with the same group it will make an array of inputs on your backend which you can loop through. to test this dd(request()); in your controller function above everything else. then you should be able to see what it returns in your console.
foreach(request(inputgroup) as $value){
Pointage::create([
'some_column' => $value['actualInputName']
]);
}
Update your function to something like this:
public function addMultiple(Request $request){
dd(request());
$pointage=new Pointage();
foreach(request('row') as $row){
// this is the important line $row is your request and ['salari'] is the name of the input
$pointage->salarie = $row['salarie'];
$pointage->save();
}
return response()->json(['status'=>true]);
}
i am practicing with axios and Vue in the use of WebApi.
I have done this:
My template:
<template>
<form>
<div>
<div class="panel panel-default">
<div class="panel-heading"><h1><strong>Lista de nombres</strong></h1></div>
<div class="panel-body">
<table class="table table-hover table-bordered table-striped">
<thead>
<tr>
<th>Nombre</th>
<th>Apellido Paterno</th>
<th>Apellido Materno</th>
</tr>
</thead>
<tbody>
<tr v-for="usuario in usuarios">
<td>{{usuario.Nombre}}</td>
<td>{{usuario.Apellido_P}}</td>
<td>{{usuario.Apellido_M}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<br />
<p>Buscar usuario</p>
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" v-model="busqueda" placeholder="Buscar usuario" />
<button type="submit" class="btn btn-default" v-on:click="buscarUsuario">Buscar</button>
</div>
</div>
</div>
</form>
</template>
And My Script:
<script>
import axios from 'axios'
export default {
data() {
return {
usuarios:[],
busqueda: ''
}
},
methods: {
buscarUsuario() {
axios.get('http://localhost:50995/api/GetUsuario', {
params: {
'id' : 7
}
}).then(response => {
this.usuarios = response.data
}).catch(e => {
console.log(e)
})
},
getUsuarios() {
axios.get("http://localhost:50995/api/GetUsuarios")
.then(response => {
this.usuarios = response.data
})
.catch(e => {
this.errors.push(e)
})
}
},
created() {
this.getUsuarios(),
this.buscarUsuario()
}
}
</script>
The method getUsuarios() is working well; but the method buscarUsuario() not; only if i put in the params ‘id’ a number the log of my WebApi records a query, but if write this code: this.busqueda not working. Either way, the result in the page is not working with the method buscarUsuario().
And finally friends, how to prevent load the page everytime i push the button?
Thank you very much!
It seems kind of strange. I conclude you reading it properly on server-side. So I bet your server only wants Number(7) not String(7). You should change basic stance of busqueda to null. Then add .number modifier to v-model. Like that:
<input type="text" class="form-control" v-model.number="busqueda" placeholder="Buscar usuario" />
How to prevent load the page everytime you push button?
Add .prevent modifier.
Change:
<button type="submit" class="btn btn-default" v-on:click="buscarUsuario">Buscar</button>
To:
<button type="submit" class="btn btn-default" v-on:click.prevent="buscarUsuario">Buscar</button>
Also I recomend use # as shortcut for v-on:(in this example you could have use #click.prevent).
If it still refreshes. Add #submit.prevent="functionName" to form...
Use id without quote and click.prevent to prevent submit.
params: {
id: 7
}
<button type="submit" class="btn btn-default" v-on:click.prevent="buscarUsuario">Buscar</button>
also you can use button type="buttton"
<button type="button" class="btn btn-default" v-on:click="buscarUsuario">Buscar</button>