I am trying to implement a feature so that the user will be able to upload a profile photo for our company page. I am using ng-file-upload plugin in angular: https://github.com/danialfarid/ng-file-upload
I followed one example in the documentation for uploading a photo:
function uploadPic ( file ) {
file.upload = Upload.upload( {
url: 'api/companyprofile/upload_logo',
method: 'POST',
sendFieldsAs: 'form',
headers: {
'my-header': 'my-header-value'
},
file: file,
fileFormDataName: 'myLogo.png'
} );
file.upload.then( function ( response ) {
$timeout( function () {
file.result = response.data;
} );
}, function ( response ) {
if ( response.status > 0 )
logger.error( response )
} );
file.upload.progress( function ( evt ) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min( 100, parseInt( 100.0 * evt.loaded / evt.total ) );
} );
}
and this is it's html
<form name="myForm" enctype="multipart/form-data">
<fieldset>
<legend>Upload on form submit</legend>
<br>Photo:
<input type="file" ngf-select ng-model="picFile" name="cp_logo" accept="image/*" ngf-max-size="2MB" required>
<i ng-show="myForm.file.$error.required">*required</i>
<br>
<i ng-show="myForm.file.$error.maxSize">File too large
{{picFile.size / 1000000|number:1}}MB: max {{picFile.$errorParam}}</i>
<img ng-show="myForm.file.$valid" ngf-src="!picFile.$error && picFile" class="thumb">
<br>
<button ng-click="vm.uploadPic(picFile)">Submit</button>
<span class="progress" ng-show="picFile.progress >= 0">
<div style="width:{{picFile.progress}}%"
ng-bind="picFile.progress + '%'"></div>
</span>
<span ng-show="picFile.result">Upload Successful</span>
<span class="err" ng-show="errorMsg">{{errorMsg}}</span>
</fieldset>
<br>
</form>
The problem is that I get a status code of 200 telling me that it had uploaded the photo successfully but in reality it did not. Giving me an empty response. What am I doing wrong?
Disclaimer: I don't know php but this is the backend code from our backend developer. This might help
/**
* Upload a Company Logo (Synchronous).
* #route GET - prefix/companyprofile/upload_logo
*
* #return json
*/
public function uploadLogo()
{
// get the company profile object
$cProfile = CompanyProfile::first();
// get all inputs from the form
$input = Input::all();
// needs validation
$validator = Validator::make(Input::all(), ['cp_logo' => 'image|max:'.$this->max_filesize]);
if ($validator->fails()) {
return array('error' => $validator->messages());
}
// if there is a cp_logo store in $file variable
if($file = array_get($input,'cp_logo')) {
// delete old company logo
$this->deleteOldCompanyLogo($cProfile);
// concatenate the filename and extension
$input['filename'] = $this->generateFileName($file);
// save the company logo filename in the database
$this->saveCompanyLogo($cProfile, $input['filename']);
try {
// upload the files to the file server
Storage::disk(env('FILE_STORAGE'))->put($input['filename'], File::get($file));
return response()->json(['status' => 'Upload successful', 'filename' => $input['filename']]);
} catch(\Exception $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
}
}
your backend expecting input named "cp_logo"
function uploadPic(file) {
if (!file || file.$error) {
logger.error(file);
return;
}
file.upload = Upload.upload({
url: 'api/companyprofile/upload_logo',
method: 'POST',
sendFieldsAs: 'form',
headers: {
'my-header': 'my-header-value'
},
file: file,
fileFormDataName: 'cp_logo' //<-- here is your POST data key send to server
});
and since in your html input named "cp_logo"
<input type="file" ngf-select ng-model="picFile" name="cp_logo" accept="image/*" ngf-max-size="2MB" required>
your validation expression should be.. myForm.cp_logo.$error or myForm.cp_logo.$valid
also double check upload input before send
HTML
<img ng-show="myForm.cp_logo.$valid" ngf-src="!picFile.$error && picFile" class="thumb">
<br>
<button ng-click="vm.uploadPic(picFile)" ng-disabled="!myForm.$valid" >Submit</button>
^ if this button is disabled obviously something wrong with inputs
BTW: the backend could return a status 200 (OK) when validation failed
you could check json response
file.upload.then(function(response) {
$timeout(function() {
logger.log(response.data);
if(response.data.error){
//something went wrong?
}
file.result = response.data;
});
}, function(response) {
if (response.status > 0)
logger.error(response)
});
Related
this.row is Generating form input into JSON Array which I'm trying to post via submit function using Axios but unable to the value please help what's wrong ??
Axios postcode
axios.post('/submit', this.rows).then(response => {
this.rows; //Clear input fields.
this.loaded = true;
Here is my complete code
<template>
<form #submit.prevent="submit">
{{ /* These are 3 buttons which are calling 3 different function to create input boxes */ }}
<div class="d-flex mt-5"><div>
<label>Add A</label>
<button type="button" #click="addRow">01</button>
</div>
<div> <label>Add B</label>
<button type="button" #click="addRow1">02</button>
</div>
<div> <label>Add c</label>
<button type="button" #click="addRow3">03</button>
</div>
</div>
{{ /* this section calls button-counter template from script code */ }}
<div v-for="row in rows" :key="row.id">
<button-counter :name ="row.name" :id="row.id" :value.sync="row.value"></button-counter>
</div>
<div>
<button type="submit" class="btn btn-primary">Add Points</button>
</div>
<div v-if="success" class="alert alert-success mt-3">
Message sent!
</div>
</form>
</template>
<script>
Vue.component("button-counter", {
props: {
value: {
default: "",
}
},
/* This is my template which gets called fro the addition of new inputs ...guess here I need to add v-model so that dynamically generated fields will be posted but I'm unable to get it posted */
template: '<input class="form-control" id= id.row name=row.name type="number" style="margin-top: 10px;" :value="value" #change="$emit(\'update:value\', $event.target.value)">'
});
export default {
props: ['gameId','userId'],
mounted() {
console.log('Component mounted.')
},
data() {
return {
gamex: this.gameId,
rows: [],
count: 0,
fields: {},
errors: {},
success: false,
loaded: true,
};
},
computed: {
total() {
if (this.rows.length) {
return this.rows.reduce((acc, row) => acc += parseInt(row.value), 0);
}
return 0;
}
},
methods: {
addRow: function() {
var txtCount = 1;
let id = "txt_" + txtCount;
this.rows.push({ name:'zero',value:100, description: "textbox1", id });
},
addRow1: function() {
var txtCount = 1;
let id = "txt2_" + txtCount;
this.rows.push({name:'one',value:200, description: "textbox2", id });
},
addRow3: function() {
var txtCount = 1;
let id = "txt3_" + txtCount;
this.rows.push({name:'two',value:300, description: "textbox3", id });
},
submit: function() {
if (this.loaded) {
this.loaded = false;
this.success = false;
this.errors = {};
axios.post('/submit', this.rows).then(response => {
this.rows; //Clear input fields.
this.loaded = true;
this.success = true;
}).catch(error => {
this.loaded = true;
if (error.response.status === 422) {
this.errors = error.response.data.errors || {};
}
});
}
},
followUser() {
axios.post('/chklet/' + this.userId)
.then(response => {
return response.data ;
});
}
},
mounted () {
this.followUser();
}
};
</script>
You can use JSON.stringify(array_to_convert_in_string_to_send_in_ajax) but you will have to json_decode it also in backend server
In server section for example laravel:
$result = json_decode($request->your_array);
Can you guys tell me what i'm doing wrong here in my code? I tried to post the data inside these checkboxes to database
here is the view.php
(more code)
<div class="form-group">
<label class="control-label col-md-3">Infection</label>
<div class="col-md-9">
<input type="checkbox" name="infectionType[]" value="vap"> VAP
<input type="checkbox" name="infectionType[]" value="hap"> HAP
<input type="checkbox" name="infectionType[]" value="isk"> ISK
<input type="checkbox" name="infectionType[]" value="iad"> IAD
</div>
</div>
and this is my controller.php
public function insert_surveilance(){
$data=array(
(more code)
'vap' => $this->input->post('vap'),
'hap' => $this->input->post('hap'),
'isk' => $this->input->post('isk'),
'iad' => $this->input->post('iad'),
(more code)
);
$data[]=
$insert = $this->surveilance_model->insert_surveilance($data);
echo json_encode(array("status"=>TRUE));
}
then this is my model.php
public function insert_surveilance($data){
$this->db->insert($this->table, $data);
return $this->db->insert_id();
}
this is the save function
...
function save(){
var url;
if(save_method == 'add'){
url="<?php echo site_url('surveilance/insert_surveilance')?>";
} else {
url="<?php echo site_url('surveilance/edit_surveilance')?>";
}
$.ajax({
url : url,
type: "POST",
data: $('#form').serialize(),
dataType: "JSON",
success: function(data)
{
//if success close modal and reload ajax table
$('#modal_form').modal('hide');
location.reload();// for reload a page
},
error: function (jqXHR, textStatus, errorThrown)
{
alert('Failed adding data');
}
});
}
First of all var_dump($this->input->post()) in your controller, if it shows post data then try replacing below code.
public function insert_surveilance(){
$request_params = $this->input->post('infectionType');
$data=array(
(more code)
'vap' => $request_params[0],
'hap' => $request_params[1],
'isk' => $request_params[2],
'iad' => $request_params[3],
(more code)
);
$data[]=
$insert = $this->surveilance_model->insert_surveilance($data);
echo json_encode(array("status"=>TRUE));
}
I am uploading an .csv file using below code and it works perfectly. But I am facing one issue during the upload. When I the choose the .csv for the first time, submit button will get enabled, but when I choose the wrong file instead of .csv, button is not getting disabled. If I want to clear the selected file the clear button is not working. I am not to figure it out what is wrong.
Below is the code of controller where upload file functionality take place:
Html:
<div class="col-md-2" >
<input type="file" id="file1" name="file" ng-model="searchData" ng-files="getFiles($files)" multiple/>
</div>
<div class="col-md-2" style="padding:17px 0px 0px 55px">
<button type="button" ng-click="uploadFile()" ng-disabled="!flag">SUBMIT</button>
<button type="button" ng-click="clearFile()">CLEAR</button>
</div>
Angularjs:
var formData = new FormData();
$scope.getFiles = function ($files) {
var data = $files;
if (data.length > 0) {
formData.append('file1',data[0]);
var allData = formData.get('file1');
var filename = allData.name; // Here we will get file name with type
csvCheck = filename.substr(-4); // Here I am selecting the last four char, i.e (.csv)
if (csvCheck === ".csv") {
$scope.flag = true;
}
} else {
$scope.flag = false;
}
$timeout($scope.time(), 500);
};
Here is the plunker
Use this code to accept only CSV files :
In your HTML Use :
<input type="file" id="file1" name="file" onchange="angular.element(this).scope().getFiles(this)" multiple/>
Then in your controller use:
$scope.getFiles = function ($files) {
var validExts = new Array(".csv");
var fileExt = $files.value;
fileExt = fileExt.substring(fileExt.lastIndexOf('.'));
if (validExts.indexOf(fileExt) < 0) {
alert("Invalid file selected");
$scope.flag=false;
}
else $scope.flag=true;
}
Use this code to clear the selected file :
document.getElementById("file1").value = "";
I am using md auto complete for Auto Segessions. while I am entering text I want to make a server call to get the results. but I want to abort the previous server call, when I have to control that in controller script or in service script.?
<md-autocomplete flex required flex-gt-sm="25
md-selected-item="school.college_name"
md-clear-button="true"
md-input-name="school.college"
md-input-minlength="3"
md-input-maxlength="40"
md-no-cache="noCache"
md-search-text="searchText"
md-items="item in ctrl.academyschoolsList"
md-search-text-change = "ctrl.searchAcademySchools(searchText)"
md-item-text="item.name">
<md-item-template>
<span class="item-title">
<span> {{item.name}}, {{item.city}}, {{item.state}}, {{item.zip}}
</span>
</span>
</md-item-template>
<div ng-messages="ctrl.leadEntryForm.school.college.$error">
<div ng-message="required">This field is required</div>
</div>
</md-autocomplete>
function searchAcademySchools(query) {
ctrl.academyschoolsList = [];
if (query.length > 3) {
C2Services.getAcademySchools(query).then(function (data) {
angular.forEach(data, function (value, key) {
ctrl.academyschoolsList.push(value);
});
});
}
}
An XHR can't be aborted once it starts, but new results can replace old results:
function searchAcademySchools(query) {
if (query.length > 3) {
C2Services.getAcademySchools(query).then(function (data) {
ctrl.academyschoolsList = data;
});
} else {
ctrl.academyschoolsList = [];
};
}
In this example each XHR will replace the old results.
Updated question with fiddle.
Original is here: https://stackoverflow.com/questions/31874313/angularjs-clean-remote-validation-error-after-change-input
In my form I have two validations. First is local, second is remote.
So this is my example
<form ng-controller="MyCtrl" name="Form">
<div class="form-group">
<label class="control-label">
First Name
</label>
<input type="text" class="form-control" name="firstName" ng-model="myModel.firstName" required />
<span class="error" ng-if="Form.firstName.$dirty && Form.firstName.$invalid" ng-repeat="(e, b) in Form.firstName.$error">{{e}}</span>
</div>
<input type="submit" ng-click="submit(Form)">
</form>
Here is Controller
function MyCtrl($scope, $element) {
$scope.submit = function (form) {
if (form.$invalid) {
renderErrors(form);
return;
}
console.log('local validation passed');
// imitation of remote error
// send, then data
if($scope.myModel.firstName === 'Tom')
renderServerErrors({firstName: ['Already in use']}, form);
else
alert('Success');
}
/**
* Errors will appear below each wrong input
*/
var renderErrors = function(form){
var field = null;
for (field in form) {
if (field[0] != '$') {
if (form[field].$pristine) {
form[field].$dirty = true;
}
}
}
};
/**
* Server errors will appear below each wrong input
*/
var renderServerErrors = function(err, form){
var field = null;
_.each(err, function(errors, key) {
_.each(errors, function(e) {
form[key].$dirty = true;
form[key].$setValidity(e, false);
});
});
}
}
http://jsfiddle.net/uwozaof9/6/
If you type 'Tom' into input - you will never submit form more..
And I want to delete server errors from input's error stack on it's change.
Please help!
It seems you only set invalid but don't set valid after it was corrected. IF you are doing yourself you also have to implement setting $valid if the imput is valid.