QUESTION UPDATED WITH CURRENT STATUS
I'm using Laravel 5.7 & VueJs 2.5.* ...
I want to autofill my form textboxes with the values in database when i select dropdown option. i've been finding solution since days but didn't get any success. I'm very new at this.
WHAT I WANT TO DO:
I have two invoices VendorInvoice and CustomerInvoice…
I created my VendorInvoice, fill all data and store in DB…
But when i want to create CustomerInvoice, i need to fetch & autofill the same data which i filled and stored in DB for VendorInvoice.
So when i create CustomerInvoice, I have a <select> options of VendorInvoice _no, by selecting any option CustomerInvoice form fields should auto fill with the VendorInvoice & VendorInvoiceItems data.
So i don’t have to fill same data by myself again in CustomerInvoice…
In my code:
VendorInvoice = ticketInvoice && VendorInvoiceItems = ticketInvoiceItems
CustomerInvoice = ctInvoice && CustomerInvoiceItems = ctInvoiceItems
If anyone could help to get me out from this issue i'll be very grateful. Thank You.
Here Is my HTML <select> & some ctInvoice & ctInvoiceItems fields which i want to autofill:
<form #submit.prevent="editmode ? updateCtInvoice() : createCtInvoice()">
<div class="modal-body">
<div class="row">
<!-- =====VENDOR INVOICE SELECTION===== -->
<select id="ticket_invoice_no" v-model="selectedTicketInvoiceId" #change="getRecord" name="ticket_invoice_no" type="text" class="form-control">
<option v-for="ticketInvoice in ticketInvoices" :key="ticketInvoice.id" :value="ticketInvoice.id">{{ ticketInvoice.ticket_invoice_no }}</option>
</select>
<!-- =====CUSTOMER TICKET INVOICE NUMBER===== -->
<input v-model="form.ct_invoice_no" type="text" name="ct_invoice_no" class="form-control">
<!-- =====CUSTOMER TICKET INVOICE ITEMS===== -->
<tbody>
<tr v-for="(ctInvoiceItem, key) in form.ctInvoiceItems" :key="key">
<!--Passenger Name-->
<td>
<input v-model="ctInvoiceItem.ct_passenger_name" size="40" type="text" name="ct_passenger_name" class="table-control form-control">
</td>
<!--Ticket No.-->
<td>
<input v-model="ctInvoiceItem.ct_ticket_no" size="24" type="text" name="ct_ticket_no" class="table-control form-control">
</td>
<!--Flight No.-->
<td>
<input v-model="ctInvoiceItem.ct_flight_no" size="7" type="text" name="ct_flight_no" class="table-control form-control">
</td>
</tbody>
My #change="getRecord" method:
getRecord: function(e) {
axios
.get("api/ticket-invoice/fetch/" + this.selectedTicketInvoiceId)
.then(({
data
}) => {
console.log(data);
this.form = data; // assumes the data keys maps directly to the form properties!!
})
.catch(error => {
console.log(error.response);
});
}
Route:
Route::get('ticket-invoice/fetch/{ticket_invoice}', 'API\TicketInvoiceController#fetch')->name('ticket-invoice.fetch');
My fetch(){} method:
public function fetch($id) {
$ticketInvoices = TicketInvoice::findOrFail($id);
return response() ->json([
'id' => '',
'customer_id' => '',
'ct_invoice_no' => $ticketInvoices->ticket_invoice_no,
'ct_invoice_date' => $ticketInvoices->ticket_invoice_date,
'ct_invoice_fares_total' => $ticketInvoices->ticket_invoice_fares_total,
'ct_invoice_grand_total' => $ticketInvoices->ticket_invoice_grand_total,
'ctInvoiceItems' => $ticketInvoices->ticketInvoiceItems->map(function($item) {
return [
// get the relevant $item->property for each key below
'id' => "",
'ct_invoice_id' => "",
'ct_passenger_name' => $item->passenger_name,
'ct_fares' => $item->fares,
'ct_sub_total' => $item->sub_total
];
}) ->all()
]);
}
My data() in Vue Component:
data() {
return {
editmode: true,
selectedTicketInvoiceId: false,
ticketInvoices: {},
ctInvoices: {},
customers: null,
form: new Form({
id: "",
customer_id: "",
ct_invoice_no: "",
ct_invoice_date: "",
ct_invoice_fares_total: 0,
ct_invoice_grand_total: 0,
ctInvoiceItems: [{
id: "",
ct_invoice_id: "",
ct_passenger_name: "",
ct_fares: 0,
ct_sub_total: 0
}]
})
};
},
When i select option i see in my Vue Component that specific id data fill in my form:. but its not actually fill my input fields with that data, so i could do some changes in the data and finally store it in DB as a customerInvoice.
Vue Dev Tool BEFORE SELECTING OPTION:
Vue Dev Tool AFTER SELECTING OPTION:
BUT NOT FILLING FIELDS:
I don't know Laravel 5.7 or vue but the concept remains the same
1- I would give an example of what I would do, I'll make a php file that has a select * from database and echo the result in json
2- Then use ajax, fetch to the php file and get that json, I will use the data retrieved in the javascript file
3 - I will have a function like on Dropdown Option onclick fetch or ajax, make the dropdown options equal to to the json fetched.
Related
I'm doing a view where the customer is able to edit items, it comes with a filter so he/she can select between the options given. Everytime I edit it and save it works, however, if I return to the edit section the text box is empty and even though it was saved. If i use the inspect tool, the Console shows this:
impuestos_compra: Array [ {…} ]
If I open it, this is the information displayed:
impuestos_compra: (1) […]
"$$hashKey": "object:87"
0: Object { id: 2, empresa_id: 6, nombre: "IVA", … }
length: 1
<prototype>: Array []
This is the <DIV> label where I display this:
<div class="form-group col-md-6">
<label>
Impuestos de Mario
</label>
<select ng-model="articulo.impuestos_compra" name="impuestos_compra" class="form-control input-lg" required>
<option value="">Seleccione impuesto de compra</option>
<option ng-repeat="item in impuestos_compra" value="#{{ item.abreviacion }}">#{{ item.abreviacion }}</option>
</select>
</div>
In my try to iterate it, I did this code:
impuestos_compra = ['IVA' , 'IVAT0' ];
impuestos_compra.forEach(function(impuestos_compra) {
console.log(impuestos_compra);
});
And, finally, the controller from Laravel with the edit function looks like this:
public function edit($id)
{
$articulo = Articulo::with('sat_producto:clave,descripcion', 'sat_unidad:clave,descripcion')->findOrFail($id);
return view('panel.configuracion.articulo', [
'id' => $id,
'presentaciones' => Presentacion::select('nombre')->get()->toArray(),
'impuestos_compra' => Impuesto::select('abreviacion')->where('tipo' , 'compra')->get(),
]);
What am'I doing wrong? I tried ->get()->toArray() and it works neither.
Thanks in advance.
I think the problem is in your impuestos_compra initialization. You can try pluck instead of select. Pluck returns the value of the column as a collection. Try the following code.
public function edit($id)
{
$articulo = Articulo::with('sat_producto:clave,descripcion', 'sat_unidad:clave,descripcion')->findOrFail($id);
return view('panel.configuracion.articulo', [
'id' => $id,
'presentaciones' => Presentacion::select('nombre')->get()->toArray(),
'impuestos_compra' => Impuesto::where('tipo' , 'compra')->pluck('abreviacion')->toArray(),
]);
}
Objective: I have a form interface that is being loaded with an object's current data for editing. The user opens this modal with the form that is loaded with the current info so they an either edit it or leave it
Currently working: The form loads with the data from my three objects (details, editSubEvents, instructions) and shows properly without issue
My problem: When I edit the fields and hit submit, I'm only currently dumping the submitted data object to make sure I have what I need. I get the eventID fine becasue it won't change and I get it from the original object. However, I need to store the new title, instruction, and subEvents (as an array) in order to submit them because they're obviously different from the origin ones
How can I properly store the new info from these input fields, including storing the new subEvent title and instructions as an array?
<div class="modal-body">
<div class="form-group row" v-for="detail in details">
<p class="modal-title">Title</p>
<input v-model="detail.title" type="text" class="form-control" id="EventTitle" name="EventTitle">
</div>
<div class="form-group row" v-for="subEvent in editSubEvents">
<p class="modal-title">SubEvent Title</p>
<input v-model="subEvent.title" type="text" class="form-control" id="newSubTitle" name="newSubTitle">
<p class="modal-title">SubEvent Instructions</p>
<textarea v-model="subEvent.instructions" type="text" class="form-control" id="newSubInstructions" name="newSubInstructions"></textarea>
</div>
</div>
data() {
return {
details: [],
instructions:[],
editSubEvents:[],
}
},
methods: {
updateEvent() {
let data = {
EventID: this.details[0].event_id,
title:
origin:
instructions:
subEvents: //needs to be an array
};
console.dir(data);
}
}
All of the properties of your data object can be bound to the UI elements (and most of them are, going by your template example code). The properties of the data object are accessible through the Vue component's this.
new Vue({
el: '#vueApp',
data() {
return {
details: [],
instructions:[],
editSubEvents:[],
}
},
methods: {
updateEvent() {
const data = {
EventID: this.details[0].event_id,
title: this.details[0].title,
origin: this.details[0].origin,
instructions: this.instructions,
subEvents: this.subEvents,
};
console.dir(data);
}
}
}
Yes me again!
This is my project
I want to pull the data from the json file when I fill in the required fields and press the button.
For example, let's write the developer part to the jobs section. then select istanbul as an option and click Find!.
var app = new Vue({
el: "#app",
data: {
founded: [],
search: ""
},
created() {
fetch("job.json")
.then(res => {
return res.json();
})
.then(res => {
this.founded = res.items;
});
},
computed:{
filteredFounded: function(){
return this.founded.filter((items)=> {
return items.positionName.match(this.search)
});
}
}
});
<div class="header">
<h4>Get Job</h4>
</div>
<div id="app" class="nested">
<div class="card w-50">
<div class="search">
<input type="text" class="job" v-model="search" placeholder="Job...">
<select name="" class="city" id="">
<option value="Seçiniz">Seçiniz</option>
<option value="İstanbul">İstanbul</option>
<option value="Ankara">Ankara</option>
<option value="İzmir">İzmir</option>
<option value="Çanakkale">Çanakkale</option>
</select>
</div>
<div class="find">
<button>Find!</button>
</div>
<div class="card-body" v-for="items in filteredFounded">
<h5 class="card-title">{{items.companyName}}</h5>
<p class="card-text">{{items.positionName | to-uppercase}}</p>
<p class="card-text">{{items.cityName}}</p>
<p class="card-text">{{items.townName}}</p>
<p class="card-text">{{items.distance}}</p>
Go!
</div>
</div>
</div>
<script src="script.js"></script>
If I understand your issue:
the view updates on each form change since you bound the card-body repeating div directly to the filtering process, so the "Find!" button isn't used
you don't consider the city selection
To fix these, bind a model to the city selector, and declare separate variables for the JSON data and for the selected data:
<select name="" class="city" id="" v-model="city">
and:
data: {
search: "",
sourceJobs: [],
selectedJobs: [],
city: ""
}
Then put you JSON data in sourceJobs on creation:
fetch("job.json").then(function (res) {
this.sourceJobs = res.json();
});
Side note: this architecture will not be viable for large JSON data, maybe you should consider filtering data through a call to your back-end API... but that's not the current question.
Now that your form data is bound to data.search and data.city, and that your pool of jobs is stored in data.sourceJobs, you want to have a method (no more computed) to filter data.sourceJobs and copy the resulting subset in data.selectedJobs:
methods: {
selectJobs: function () {
this.selectedJobs = this.sourceJobs
.filter((job) => {
return job.cityName === this.city && job.positionName.match(this.search);
})
}
}
Finally, call this method when the "Find!" button is clicked:
<button v-on:click="selectJobs">Find!</button>
In case you change you architecture to go for an API call to do the filtering, then you just need to remove that created part and do the API call from within the selectJobs method.
Side, unrelated note: find/found/found (successful result of searching) vs. found/founded/founded (create, build, set a base for something - a city, a company...).
I'm new to Vue and I would like some help getting a value from an input field:
In my form I have:
<input type="hidden" id="groupId" value="1">
If I was using jQuery I would do:
var group_id = $('#groupId').val();
However, in Vue I don't know how to bind the hidden field:
<div id="app">
<input type="text" v-model="groupId"> //Where do I put the value?
</div>
new Vue({
el: '#app',
data: {
groupId: //What do I put here to get the field's value?
}
How can I achieve this?
Update to the update: See this answer. Previously updated answer was wrong.
Original answer:
In Vue, you don't get things from the view and put things into the view. Vue does that. You do all manipulations in the viewmodel, and make bindings in the view so that Vue knows how to synchronize it. So you'd bind the input to your model data item:
<input type="hidden" id="groupId" v-model="groupId">
and set its value in your viewmodel:
data: {
groupId: 1
}
I had the same question. I'm working with Vue + Laravel.
For me, the solution was simple after searching and not finding a concrete solution in the Vue documentation.
Simply:
document.getElementById('MyId').value;
Details in → https://www.w3schools.com/jsref/prop_text_value.asp
It is not the most efficient solution, but it works for now!
Greetings.
Working sample of getting value from input field in this case it is hidden type:
<input type="hidden" name="test">
<script>
new Vue ({
created () {
const field = document.querySelector("input[name=test]").value
console.log(field)
}
})
</script>
this code helped me
i hope that this work with you
define the input
<div class="root">
<input type="hidden" ref="groupId" value="1">
<button type="button" v-on:click="get_id()">test</button>
</div>
define the method
new Vue({
el: ".root",
data: {
id: null,
}
methods: {
get_id() {
this.id = this.$refs.groupId.value;
}
}
});
// if you want it displayed on your page, use {{ groupId }}
/* you can get the value by using #change.enter=".." #keypress.enter="getInputValue",
or #input="getInputValue" or #click="getInputValue" using button,
or if it is with a form element, #submit.prevent="getInputValue" */
/* #keypress.enter tracks input but only calls the function when the Enter key
is pressed, #input track changes as it's being entered */
// it is important to use event.preventDefault() when using #change or #keypress
<div id="app">
<input type="text" v-model="groupId">
<p> {{ groupId }} </p>
<button #click="getInputValue">Get Input</button>
</div>
new Vue({
el: '#app',
data: {
groupId: //What do I put here to get the field's value?
// for what to put there, you can use an empty string or null
groupId: "",
},
// to get the value from input field
methods: {
getInputValue: function() {
if(this.groupId !== "") {
console.log(this.groupId);
}
},
}
})
look at this I did it in laravel, vuejs, vuetable2 and children's row, and don't use the v-model:
this.$refs['est_'+id_det].localValue
en VUE:
<div class="col-md-3">
<b-form-select class="form-control selectpicker" :ref="'est_'+props.row.id_detalle_oc"
:value="props.row.id_est_ven" v-on:change="save_estado(props.row.id_detalle_oc)">
<option value="0">Sin estado</option>
<option value="1">Pendiente</option>
<option value="2">Impresa</option>
<option value="3">Lista</option>
</b-form-select>
in methods
methods: {
save_estado:function (id_det){
var url= 'ordenes-compra/guardar_est_ven'
var id_estado = this.$refs['est_'+id_det].localValue
axios.post(url,{
id_det: id_det,
id_est_ven: id_estado,
est_ven: est_ve
}).then(function (response) {
var respuesta= response.data;
if(respuesta == "OK"){
swal({
type: 'success',
title: '¡Éxito!',
text: 'Estado modificado',
confirmButtonText: 'Entendido',
})
}
})
.catch(function (error) {
console.log(error);
});
},
I hope it helps, I've been hanging around for a while.
Regards
Hi you can also try the following:
const input = this.$el.firstElementChild;
in case you are using TypeScript, declare input as:
: HTMLInputElement
Then, you can simply get the value if you do:
input.value
Hope it helps!
Ok, this does the job: document.querySelector('#groupId').getAttribute('value');
I have to add/post data form. But the form dynamically can increase as user 'click' on a button. I've already browse about it and there some answer i get like using $request->all() to fetch all data from input forms.
And then my problem is, my app using VueJS as front-end. Is there any some configuration on VueJS script to post all data from that dynamic form??
My Blade template that will be increase dynamically:
<div id="form-message">
{!! Form::text('rows[0][DestinationNumber]', null, [
'id' => 'recipient',
'class' => 'form-control',
'v-model' => 'newMessage.DestinationNumber'
])
!!}
{!! Form::textarea('rows[0][TextDecoded]', null, [
'rows' => '3',
'id' => 'recipient',
'class' => 'form-control',
'v-model' => 'newMessage.TextDecoded'
])
!!}
</div>
That zero number will increase depends on how much user click add button.
And then here my VueJS script
var newSingleMessage = new Vue({
el: '#newsinglemsg',
data: {
newMessage: {
DestinationNumber: '',
TextDecoded: ''
},
},
methods: {
onSubmitForm: function(e) {
e.preventDefault();
var message = this.newMessage;
this.$http.post('api/outbox', message);
message = { DestinationNumber: '', TextDecoded: '' };
this.submitted = true;
}
}
});
On laravel controller, i have simple logic to test result how data passed.
$input = $request->all();
$output = dd($input);
return $output;
And, I test it using 2 additional form. So, the data should be 3 rows. The result (checked from FireBug) to be like this
{"DestinationNumber":"1234567890","TextDecoded":"qwertyuio"}
Data passed just one, and then the type is JSON. Even I use return $output->toArray(), type still JSON.
Oh yeah, once more. Idk how to make the zero number increase dynamically using javascript. When testing, i just manual add the form. Here my add click function javascript
var i = 0,
clone = $('#form-message').clone(),
recipient = document.getElementById('recipient');
recipient.setAttribute('name', 'rows['+ i +'][DestinationNumber]');
clone.appendTo('.form-message:last');
i++;
For second and next rows, name attribute not added on the input elements.
Thanks
You're mixing blade and jquery and vue in a way that is pretty confusing. Check out this JS fiddle that accomplishes all of this with Vue:
https://jsfiddle.net/cr8vfgrz/10/
You basically have an array of messages that are automatically mapped to inputs using v-for. As those inputs change, your messages array changes. Then when submit is pressed, you just post this.messages and the array of messages is sent to server. Then you can clear the array to reset the form.
Template code:
<div id="form-message">
<button class="btn btn-default" #click="addNewMessage">New Message</button>
<template v-for="message in messages">
<input type="text" v-model="message.DestinationNumber" class="form-control">
<textarea rows="3" v-model="message.TextDecoded" class="form-control"></textarea>
</template>
<button class="btn btn-success" #click.prevent="submitForm">Submit</button>
</div>
Vue code:
var newSingleMessage = new Vue({
el: '#form-message',
data: {
messages: [
{
DestinationNumber: '',
TextDecoded: ''
}
],
submitted:false
},
methods: {
addNewMessage: function(){
this.messages.push({
DestinationNumber: '',
TextDecoded: ''
});
},
submitForm: function(e) {
console.log(this.messages);
this.$http.post('api/outbox', {messages:this.messages})
.then(function(response){
//handle success
console.log(response);
}).error(function(response){
//handle error
console.log(response)
});
this.messages = [{ DestinationNumber: '', TextDecoded: '' }];
this.submitted = true;
}
}
});
Edit:
In the controller you can use $request->input('messages'); which will be the array of messages. You can insert multiple new Outbox model using:
Outbox::insert($request->input('messages'));
or
foreach($request->input('messages') as $message){
Outbox::create($message);
}