File uploading issue in Angularjs - angularjs

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 = "";

Related

AngularJS ng-upload reset file selection

I am using a simple file upload as below:
<button type="file" ngf-select ng-model="fileData"
ng-change="fileChanged(fileData)" name="file" required >
Select File
</button>
And I have another button which when clicked I want to clear out the file that was selected.
<button type="button" class="btn btn-primary" ng-click="clearFile()">
Clear
</button>
I have the Controller code for button click as:
$scope.fileChanged = function(fileData) {
if (fileData != undefined) {
$scope.selectedFileName = fileData.name;
}
}
$scope.clearFile = function () {
//None of these works
//angular.element("input[type='file']").val(null);
// $scope.fileData = [];
}
I have tried couple of options as I searched through previous posts but none of it works. What am I missing here.
Here is my jsfiddle: http://jsfiddle.net/abco2Lp0/
Try this:
$scope.clearFile = function () {
$scope.fileData = [];
$scope.selectedFileName = null;
$scope.uploadedFile = [];
}
Hope this helps.

Vue.js read input file type .txt [duplicate]

I want to show contents of uploaded file in html, I can just upload a text file.
My example.html:
<html xmlns="http://www.w3.org/1999/xhtml" >
<p>
Please specify a file, or a set of files:<br>
<input type="file" name="datafile" size="40">
</p>
<textarea id="2" name="y" style="width:400px;height:150px;"></textarea>
</html>
How can I show contents of any uploaded text file in textarea shown below?
I've came here from google and was surprised to see no working example.
You can read files with FileReader API with good cross-browser support.
const reader = new FileReader()
reader.onload = event => console.log(event.target.result) // desired file content
reader.onerror = error => reject(error)
reader.readAsText(file) // you could also read images and other binaries
See fully working example below.
document.getElementById('input-file')
.addEventListener('change', getFile)
function getFile(event) {
const input = event.target
if ('files' in input && input.files.length > 0) {
placeFileContent(
document.getElementById('content-target'),
input.files[0])
}
}
function placeFileContent(target, file) {
readFileContent(file).then(content => {
target.value = content
}).catch(error => console.log(error))
}
function readFileContent(file) {
const reader = new FileReader()
return new Promise((resolve, reject) => {
reader.onload = event => resolve(event.target.result)
reader.onerror = error => reject(error)
reader.readAsText(file)
})
}
label {
cursor: pointer;
}
textarea {
width: 400px;
height: 150px;
}
<div>
<label for="input-file">Specify a file:</label><br>
<input type="file" id="input-file">
</div>
<textarea id="content-target"></textarea>
Here's one way:
HTML
<tr>
<td>Select a File to Load:</td>
<td><input type="file" id="fileToLoad"></td>
<td><button onclick="loadFileAsText()">Load Selected File</button><td>
</tr>
JavaScript
function loadFileAsText(){
var fileToLoad = document.getElementById("fileToLoad").files[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent){
var textFromFileLoaded = fileLoadedEvent.target.result;
document.getElementById("inputTextToSave").value = textFromFileLoaded;
};
fileReader.readAsText(fileToLoad, "UTF-8");
}
Try this.
HTML
<p>
Please specify a file, or a set of files:<br>
<input type="file" id="myFile" multiple size="50" onchange="myFunction()">
</p>
<textarea id="demo" style="width:400px;height:150px;"></textarea>
JS
function myFunction(){
var x = document.getElementById("myFile");
var txt = "";
if ('files' in x) {
if (x.files.length == 0) {
txt = "Select one or more files.";
} else {
for (var i = 0; i < x.files.length; i++) {
txt += (i+1) + ". file";
var file = x.files[i];
if ('name' in file) {
txt += "name: " + file.name + "";
}
if ('size' in file) {
txt += "size: " + file.size + " bytes ";
}
}
}
}
else {
if (x.value == "") {
txt += "Select one or more files.";
} else {
txt += "The files property is not supported by your browser!";
txt += "The path of the selected file: " + x.value; // If the browser does not support the files property, it will return the path of the selected file instead.
}
}
document.getElementById("demo").innerHTML = txt;
}
Demo

Remove select options based on button click in angular js

In my app i have a select html which has following options
"Addition","Deletion","Duplicate","Member Duplicate"
Above drop down page is common for both add and edit screen. As of now if we come from any addition click or edit click drop-down has all options. (Note: drop-down binds at the time of loading page itself. we will show/hide depending on click)
As per new requirement I need to remove all other options except "Addition" in addition click and remove "Addition" option in edit click.
select html:
<select name="ReasonID" required ng-model="member.ReasonID" class="form-control" ng-options="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description"></select>
Js
$scope.manageMember = function (member) {
$scope.showGrid = false;
$scope.showForm = true;
reset();
$scope.memberTemp = member;
angular.extend($scope.member, member); };
Please let me know if you need more details from my end.
Update :
Here the full sample code and working demo with dummy data.
HTML
<div ng-app>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<select name="ReasonID" required ng-model="member.ReasonID" class="form-control" ng-options="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description"></select>
<br/>
<input type="button" ng-click="manageMember(undefined)" value="add"/>
<input type="button" ng-click="manageMember('bla bla bla')" value="edit"/>
</div>
</div>
JS
function TodoCtrl($scope) {
$scope.reasons = [{ID:1,Description :"Addition"}, {ID:2,Description :"Deletion"},{ID:3,Description :"Duplicate"},{ID:4,Description :"Member Duplicate"}];
var reasonsTemp =angular.copy($scope.reasons);
$scope.manageMember = function (member) {
console.log(reasonsTemp)
$scope.reasons=reasonsTemp;// assign global object to model
$scope.showGrid = false;
$scope.showForm = true;
$scope.memberTemp = member;
var EditArray=[];
for(var i = 0 ; $scope.reasons.length>i;i++)
{
if($scope.reasons[i].Description === ($scope.memberTemp == undefined ? "Addition" : "bla bla bla"))// condition for is this addition or not
{
EditArray = $scope.reasons[i];
break;
}
else // if is it not addition, then addition only offect that object. because we were already assigned original value globally
{
if($scope.reasons[i].Description!=="Addition")
{
EditArray.push($scope.reasons[i])
}
}
}
$scope.reasons=EditArray;
console.log($scope.reasons);
}
}
Working Demo On console window
Try this,
HTML
<select ng-model="selectedOption">
<option ng-show="reason.show" ng-repeat="reason.ID as reason.Description for reason in reasons |orderBy: reason.Description">{{reason.ID}}</option>
</select>
JS
$scope.manageMember = function (member) {
$scope.showGrid = false;
$scope.showForm = true;
reset();
$scope.memberTemp = member;
angular.extend($scope.member, member);
if(member){
for(var i = 0 ; $scope.reasons.length>i;i++)
{
$scope.reasons[i].show = true;
if($scope.reasons[i].ID == "Addition"){$scope.reasons[i].show = false;}
}
}else{
for(var i = 0 ; $scope.reasons.length>i;i++)
{
$scope.reasons[i].show = false;
if($scope.reasons[i].ID == "Addition"){$scope.reasons[i].show = true;}
}
}
}
Suppose you have two buttons as,
<input type="button" ng-click="toAdd=true">Add</input>
<input type="button" ng-click="toAdd=false">Edit</input>
And the select box code should be like,
<select ng-model="selectedOption">
<option ng-show="toAdd">Addition</option>
<option ng-show="!toAdd">Deletion</option>
<option ng-show="!toAdd">Duplicate</option>
<option ng-show="!toAdd">Member Duplicate</option>
</select>
Hope this helps.

could not upload properly using ng-file-upload and laravel

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)
});

AngularJS clear validation $error after input's changing

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.

Resources