Replacing files in input using Vue.js - javascript

I have Vue.js template file with data that contains documents. My page has table. Table has rows with input buttons upload file, like this
<tr v-for="(doc, index) in documents">
<td :id="'doc-' + doc.id" v-show="doc.visible">
<div class="row">
<div class="col-md-9">
<a v-if="doc.document" :href="doc.document.file" v-text="doc.name"></a>
<div v-else v-text="doc.name"></div>
</div>
<div class="col-md-3">
<div class="row">
<div v-if="doc.document" class="col-md-8">
<label :for="'upload_doc_' + doc.id">
<span class="glyphicon glyphicon-upload text-primary" role="button"> Upload</span>
<input type="file"
:id="'upload_doc_' + doc.id"
class="hidden"
#change="replaceDoc($event, index)"
/>
</label>
</div>
</div>
</div>
</div>
</td>
So, some rows may contain some files and some not. But button should replace or add file to the row. So i wrote method:
methods: {
replaceDoc (event, index) {
this.documents[index] = event.target.files[0]
},
But it seems that it does not contain any data, when I'm trying to send it to server it sends empty dictionary.

Have you tried using Vue.set or this.$set
Instead of:
this.documents[index] = event.target.files[0]
Try this:
this.$set(this.documents, index, event.target.files[0]);
OR
Vue.set(this.documents, index, event.target.files[0]);
You can refer to this API.

Related

Uploading multiple dynamic files to laravel from vue

I'm trying to upload multiple files with it's respective data from vue to laravel. I'm getting the files in vue (on vue console) but when submitting the form and doing dd($request['new_members']); on the laravel controller, it returns the result below:
The other data is available but the file value is gone.
Vue
<div class="row mt-2" v-for="(new_member,index) in new_members" :key="index">
<div class="col-md-4">
<label>NAME</label>
<input class="form-control" type="text" v-model="new_member.name" required/>
</div>
<div class="col-md-4">
<label>POSITION</label>
<input class="form-control" type="text" v-model="new_member.position" required/>
</div>
<div class="col-md-4">
<label>IMAGE</label>
<input type="file" #change="onFileChange(index,$event)" name="file" ref="fileInput" required/>
</div>
</div>
<button class="btn btn-primary col-md-2 col-12 rounded-0 float-right" #click.prevent="addMoreMember()">ADD MORE</button>
<script>
data(){
return{
new_members:[{
name:'',
position:'',
file:''
}]
}
},
methods:{
addMoreMember(){
this.new_members.push({name:'',position:'',file:''})
},
onFileChange(index,$event) {
this.new_members[index].file = $event.target.files[0]
},
submit(){
let form = new FormData()
form.append('new_members',JSON.stringify(this.new_members));
form.append('content_team', this.content_team);
axios.post('/api/mainpage/addNewMember',form).then(res=>{
})
},
}
</script>
For multiple file uploading concepts,
You need to create an API service for upload files only and returning that response return string for accessing uploaded file path,
For every file uploading, You need to call this API services that you created.
And the final page submission you just send the file path string where you got from the file uploading API services
I hope you are getting my points ❤

keep properties after jquery.load

I'm learning javascript/jquery on the go, I'm trying to reload a form but keeping its js properties (required and masked inputs), code and pictures attached.
First image: Masked inputs works like a charm
Second image: The form its fully filled, still working
Third image: The form it reloaded, but no properties applied
The html form (minmized, just the first field)
<div class="card-body" id="clientsAddFormContainer">
<form method="post" action="main/clients/addController.php">
<div class="form-group row" id="clientRutDiv">
<div class="col-lg-6">
<div class="form-group" id="clientRutInnerDiv">
<label class="col-form-label" for="clientRut">RUT <span class="required">*</span></label>
<input type="text" name="clientRut" id="clientRut" class="form-control" placeholder="Ej. 11.111.111-1" required="" data-plugin-masked-input="" data-input-mask="99.999.999-*" autofocus>
</div>
</div>
</div>
</div>
</form>
<footer class="card-footer">
<div class="switch switch-sm switch-primary">
<input type="checkbox" name="wannaStay" id="wannaStay" data-plugin-ios-switch checked="checked" />
</div> Mantenerme en esta página
<button type="button" style="float: right;" class="btn btn-primary" onclick="realizaProceso();">Enviar</button>
</footer>
The JS for realizaProceso()
function realizaProceso(){
var validator =0;
validator += validateRequiredField('clientRut');
if(validator == 0){
var parametros = {
"clientRut" : document.getElementById('clientRut').value,
"tableName" : 'clients'
};
$.ajax({
data: parametros,
url: 'route/to/addController.php',
type: 'post',
success: function (respText) {
if(respText == 1){
if(document.getElementById('wannaStay').checked){
$("#clientsAddFormContainer").load(location.href + " #clientsAddFormContainer");
}else{
window.location = "linkToOtherLocation";
}
}else{
showNotyErrorMsg();
}
},
error: function () {
showNotyErrorMsg();
}
});
}else{
showNotyValidationErrorMsg();
}
}
So my JS check all fields are validated, then prepare the array, and wait for the php binary response, 1 means the data has been inserted to db, if wannaStay is checked reload the div "clientsAddFormContainer" but as I said, it loose the properties.
Please sorry for my grammar or any other related english trouble, not a native english speaker.
Ps. I've removed some code so it could go different than the images.
Thanks in advance!
EDIT!
The original code is
<div class="card-body" id="clientsAddFormContainer">
<form method="post" action="main/clients/addController.php">
</form>
</div>
one the js exec I got
<div class="card-body" id="clientsAddFormContainer">
<div class="card-body" id="clientsAddFormContainer">
<form method="post" action="main/clients/addController.php">
</form>
</div>
</div>
2nd EDIT
I found the answer in other stackoverflow question

Getting updated values in ng-repeat Angular JS

I am using ng-repeat, which is getting values from my db and putting it. Now i insert these values into input text which i update. Now i have a save button, which saves the updated values. I am not getting the updated values when i press the save button. Please guide me through this.
<div ng-controller="education" ng-init="getEducationDetails();">
<div class="col-md-12">
<div class="row" ng-repeat="values in education"
style="margin-left: 20px; margin-right: 20px; margin-top: 10px;">
<div class="col-md-6">
<h4>
<small>Degree</small>
</h4>
<input type="text" id="educationDegree" name="educationDegree"
value="{{values.education_degree}}" style="width: 90%;" />
</div>
<div class="col-md-6">
<h4>
<small>Year</small>
</h4>
<input type="text" id="educationYear" name="educationYear"
value="{{values.education_year}}" style="width: 100%;" />
</div>
<div class="col-md-12" style="margin-top: 10px;">
<h4>
<small>University</small>
</h4>
<input type="text" id="educationUniversity"
name="educationUniversity"
value="{{values.education_university}}" style="width: 100%;" />
</div>
</div>
</div>
<div class="col-md-12" style="margin: 20px;">
<button ng-click="educationSave();" class="btn btn-default">Save</button>
</div>
</div>
on educationSave() i save the values. But when i get the education array in the educationSave() method, i get the old array. How can i get the updated array, after i adjust some of the input types
Here is how i get the values:
$scope.getEducationDetails = function()
{
$http({
method : 'GET',
url : '/getEducationDetails'
}).success(function(data, status, headers, config) {
$scope.education = data.resultSet;
alert($scope.education);
}).error(function(data, status, headers, config) {
});
};
Here is my controller method:
$scope.educationSave = function() {
var educationArray = JSON.stringify($scope.education);
//I then save this educationArray
};
The problem is that you are not using ng-model to bind your actual input value to controller. From documentation:
HTML input element control. When used together with ngModel, it provides data-binding, input state control, and validation.
Try something like this in your markup for each input:
<input type="text" id="educationDegree" name="educationDegree"
ng-model="values.education_degree" style="width: 90%;" />
See little Demo

Write .each data to two different classes with same div id

I have a jQuery .each that loops through div id's and writes JSON data from an AJAX call to inputs assigned a class.
Most div's only have one row of inputs to populate, but some have two rows of input classes.
All divs and classes are created dynamically, but each dynamic div does get its own unique ID.
When the .each hits the div with two rows with the same class it does not write to both rows but writes to the second row of classes with the second row from the database.
When users write to the db with the data from both rows it creates a separate row in the db.
One for badge1, and one for badge2.
Here is my .each that writes one row of inputs great
$.each(data, function(i, item) {
$("#" + item.full_op_id).find('.badge1').val(item.badge1);
$("#" + item.full_op_id).find('.badge2').val(item.badge2);
$("#" + item.full_op_id).find('.op_date').val(item.op_date);
$("#" + item.full_op_id).find('.op_qty').val(item.op_qty);
});
I have tried several things including an if/else statement on just those id's with two rows of classes.
I understand that when the .each sees the two rows it basically sees it as one row since they have the same class names except for badge1/badge2.
Should I run another loop inside the .each to loop through and write both rows for that div id and same input classes? If so, how should I do this?
Background on app: Created with Foundation 5, dynamically creates each panel row with data from one DB (MSSQL), then using AJAX/JSON users write to a separate DB (MYSQL) their input data.
The user should then be able to pull up the job again and see what they have done by pulling their data from the MYSQL db of their inputs.
That is the db I am pulling the data from when trying to insert the JSON data to the inputs for each div row and inputs.
Here is the HTML that creates these two rows:
<div class="row" id="op_div_id">
<div class="large-3 columns badge_div">
<label>
Operator 1 <span class="badge_required" style="font-size: 0.7em;">*required</span>
<div class="row collapse">
<div class="small-3 columns">
<button class="button prefix radius badge_scan_button" onclick="badgeButton1($(this));">
Scan
</button>
</div>
<div class="small-9 columns">
<input type="text" class="badge1" name="badge1" onchange="badgeColor1($(this));" placeholder="Badge Number">
<input type="hidden" class="time_assigned" name="time_assigned" value="">
</div>
</div>
</label>
</div>
<div class="large-3 columns date_div">
<label>Today's Date <span class="date_required" style="font-size: 0.7em;">*required</span>
<input type="text" class="op_date" name="op_date" onclick="popDate($(this));" placeholder="Today's Date">
</label>
</div>
<div class="large-3 columns qty_div">
<label>Quantity <span class="qty_required" style="font-size: 0.7em;">*required</span>
<input type="text" class="op_qty" name="op_qty" onblur="opQtyColor($(this));" placeholder="Quantity">
</label>
</div>
<div class="large-3 columns">
<label>Complete Operation</label>
<button class="button postfix save_op1" onclick="saveOp1($(this));">
Save
</button>
</div>
</div>
<div class="row" id="op_div_id2">
<div class="large-3 columns badge_div">
<label>
Operator 2 <span class="badge_required" style="font-size: 0.7em;">*required</span>
<div class="row collapse">
<div class="small-3 columns">
<button class="button prefix radius badge_scan_button" onclick="badgeButton2($(this));">
Scan
</button>
</div>
<div class="small-9 columns">
<input type="text" class="badge2" name="badge2" onchange="badgeColor2($(this));" placeholder="Badge Number">
<input type="hidden" class="time_assigned" name="time_assigned" value="">
</div>
</div>
</label>
</div>
<div class="large-3 columns date_div">
<label>Today's Date <span class="date_required" style="font-size: 0.7em;">*required</span>
<input type="text" class="op_date" name="op_date" onclick="popDate($(this));" placeholder="Today's Date">
</label>
</div>
<div class="large-3 columns qty_div">
<label>Quantity <span class="qty_required" style="font-size: 0.7em;">*required</span>
<input type="text" class="op_qty" name="op_qty" onblur="opQtyColor($(this));" placeholder="Quantity">
</label>
</div>
<div class="large-3 columns">
<label>Complete Operation</label>
<button class="button postfix save_op2" onclick="saveOp2($(this));">
Save
</button>
</div>
</div>
Thanks everyone for your support and help on this. I have come up with a solution that works pretty well. Thank you #Jason for the tip to only select the ID once.
success: function (data) {
var el;
var done_row1 = false;
$.each(data, function (i, item) {
el = $("#" + item.full_op_id);
if (item.full_op_id == "210-SUTB015" || item.full_op_id == "210-PICKA" || item.full_op_id == "44-SUTB015") {
if (done_row1 === false) {
el.find('div#op_div_id input.badge1').val(item.badge1);
el.find('div#op_div_id input.op_date').val(item.op_date);
el.find('div#op_div_id input.op_qty').val(item.op_qty);
done_row1 = true;
} else {
el.find('div#op_div_id2 input.badge2').val(item.badge2);
el.find('div#op_div_id2 input.op_date').val(item.op_date);
el.find('div#op_div_id2 input.op_qty').val(item.op_qty);
// reset row1 test
done_row1 = false;
}
} else {
el.find('div#op_div_id input.badge1').val(item.badge1);
el.find('div#op_div_id input.op_date').val(item.op_date);
el.find('div#op_div_id input.op_qty').val(item.op_qty);
}
});
}
Another developer at my work helped me with this solution, so I am not 100% sure what it is doing to make it work but it is. We just separated out the writing of the rows between badge1 and badge2 using another if/else statement and true/false statements. Thanks again everyone!
I'm not sure I understand correctly, but try changing
$("#" + item.full_op_id).find('.badge1').val(item.badge1);
to
$("#" + item.full_op_id).find('.badge1').each(function() {
$(this).val(item.badge1);
});

Sorting Input Text inside multiple div's using javascript / jquery?

There are three fields(first name, Last name & age) displayed in text boxes. Each field is displayed in separate div's. There are 4 records. On clicking a sort button above each field the div records should be sorted based on the data type of the field and should displayed in the HTML page.
I tried the solution in this link
I can't use this because the records are displayed in text box within the div.
<div id="content">
<div>
<div class="price"><input type="text" class="pri" value="120"/></div>
<div class="dateDiv">2012-05-09 20:39:38.0</div>
<div class="distance">20 mile</div>
</div>
<div>
<div class="price"><input type="text" class="pri" value="123"/></div>
<div class="dateDiv">2012-05-10 20:39:38.0</div>
<div class="distance">30 mile</div>
</div>
<div>
<div class="price"><input type="text" class="pri" value="100" /></div>
<div class="dateDiv">2012-05-11 20:39:38.0</div>
<div class="distance">50 mile</div>
</div>
<div>
<div class="price"><input type="text" class="pri" value="124"/></div>
<div class="dateDiv">2012-05-12 20:39:38.0</div>
<div class="distance">60 mile</div>
</div>
</div>
How can I do this in javascript?
see this demo using jquery.tinysort.min.js
see also this one
You can use knockoutjs to do something like that.
For example, the html:
<div id="content" data-bind="foreach: lines">
<div class="fname"><input type="text class="pri" data-bind="value: fname"/></div>
<div class="lname" data-bind="text: lname"/>
<div class="age" data-bind="text: age"/>
</div>
Javascript:
function EachDivViewModel(line)
{
this.fname = line.fname;
this.lname = line.lname;
this.age = line.age;
}
function YourViewModel()
{
var self = this;
self.lines = ko.observableArray([]); // this array will contain elements of EachDivViewModel type
self.handlerForYourSortButtongs = function() {
// Code here to sort the array based on the button clicked
// The UI will automatically get updated as you reorder the elements in the lines array
}
}
$(document).ready(function() {
var yourViewModelInstance = new YourViewModel();
// Code to get the lines here
ko.applyBindings(yourViewModelInstance);
});
It can be done using tablesorter.
Hope that will help you out.

Categories

Resources