Reading of text file without using any server in JS - javascript

I want to read a text file which is in my local directory,I found many examples they have used httprequest()I don't want to use any of the servers like xampp,wampp etc
I am using JS!!

Best partice is always us php,nodeJS or backend langaugae to do such things, but in your case you might use angularJS .
Add the below in your JS
var myapp = angular.module('myapp', []);
myapp.controller('MainCtrl', function ($scope) {
$scope.showContent = function($fileContent){
$scope.content = $fileContent;
};
});
myapp.directive('onReadFile', function ($parse) {
return {
restrict: 'A',
scope: false,
link: function(scope, element, attrs) {
var fn = $parse(attrs.onReadFile);
element.on('change', function(onChangeEvent) {
var reader = new FileReader();
reader.onload = function(onLoadEvent) {
scope.$apply(function() {
fn(scope, {$fileContent:onLoadEvent.target.result});
});
};
reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
});
}
};
});
The below is the HTML body:
<div ng-controller="MainCtrl" class="container">
<h1>Select text file</h1>
<input type="file" on-read-file="showContent($fileContent)" />
<div ng-if="content">
<h2>File content is:</h2>
<pre>{{ content }}</pre>
</div>
</div>
Keep in mind that read, write and save function should always be done in back-end side.

Related

AngularJS Calling the controller method from directive

Prompt as from a directive to cause a method of the controller.
Directive
app.directive('scroll', function($location){
return{
restrict: 'A',
link: function(scope, element, attrs){
element.on('scroll', function(){
let fh = $('#ngview').height();
let nh = Math.round($(element).height() + $(element).scrollTop());
if(fh == nh){
//Here we do what we need
}
})
}
}
});
HTML markup
<div class="col-md-12 middle-body" scroll>
<div ng-show="showUserModal" ng-include="'partial/loginModal.html'"></div>
<div class="user-loader" ng-show="loading">
<div class="spinner"></div>
</div>
<div ng-view id="ngview">
</div>
</div>
app is the main application module
var app = angular.module('app',
[
'ngRoute',
'lastUpdateModule',
'selectedByGenreModule',
'currentFilmModule',
'httpFactory',
'userModule',
'accountModule'
]);
The controller from which you want to call the method is described in a separate file
and connects via require
const SelectedByGenreModule = require('../controllers/selectedByGenre.controller.js')
and passed as a dependency to the main module
So it is from this controller that I need to call the method in the directive.
Tell me how to do it correctly. I left through $rootScope but it did not work out
As far as I know, the directive has the same scope as the controller in which it is located. That is, the directive is in the controller which is the parent for the controller from which you need to call the method.
It sounds like you want your directive to trigger an action defined by your controller. I'd recommend passing the function to the directive via the scope property. See the example below.
var app = angular.module('ExampleApp', []);
app.directive('scroll', function($location) {
return {
restrict: 'A',
scope: {
scroll: '='
},
link: function(scope, element, attrs) {
element.on('scroll', function() {
let fh = $('#ngview').height();
let nh = Math.round($(element).height() + $(element).scrollTop());
if (fh == nh) {
scope.scroll();
}
})
}
}
});
app.controller('ExampleCtrl', function($scope) {
$scope.onScroll = function() {
console.log('Scrolled!')
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="ExampleApp" ng-controller="ExampleCtrl">
<div class="col-md-12 middle-body" scroll="onScroll">
<div ng-show="showUserModal" ng-include="'partial/loginModal.html'"></div>
<div class="user-loader" ng-show="loading">
<div class="spinner"></div>
</div>
<div ng-view id="ngview">
</div>
</div>
</div>
You can require parent controllers using the require property when defining the directive, the ^^ tells angular to look up the DOM for a parent, otherwise it will only look on the local element.
app.directive('scroll', function($location){
return{
restrict: 'A',
require: '^^selectedByGenreCtrl', // Use the correct controller name here
link: function(scope, element, attrs, selectedByGenreCtrl){
element.on('scroll', function(){
let fh = $('#ngview').height();
let nh = Math.round($(element).height() + $(element).scrollTop());
if(fh == nh){
//Here we do what we need
}
})
}
}
});

Using AngularJS for two-way binding of XML display to form fields

Have a requirement where the user should be able to display and update an XML using form fields.
To be able to display the XML and bind the XML elements to from fields, I did the following:
Retrieve XML, convert to JSON (using xml2json) and put it in scope (name='domObject').
Use angular directive on the HTML to get the domObject from scope and beatify it and display it (using vkbeautify)
Also, on the same html, bind the form fields to the domObject from scope.
The binding from the domObject to the XML & form fields is working fine. But, when I make update the value in the field, the same is NOT reflected in the XML displayed (although the changes can be seen in the domObject) i.e 2 way binding is not happening when using the directive.
Please help.
Link to plunker here
Code Snippets
Main script:
var App = angular.module('myApp', []);
App.controller('myCtrl', function($scope, $http, $window) {
$http.get("sample.xml")
.then(function(response) {
var x2js = new $window.X2JS();
var jsonDocument = x2js.xml_str2json( response.data );
$scope.domObject = jsonDocument;
$scope.dataLoaded = true;
});
})
App.directive('prettyprint', function($window) {
return {
restrict: 'C',
replace: true,
link: function postLink(scope, element, attrs) {
var x2js = new $window.X2JS();
var xmlString = x2js.json2xml_str(scope.domObject);
element.text(vkbeautify.xml(xmlString, 4));
}
};
});
HTML Snippet:
<body ng-app="myApp">
<section class="container">
<div class="form-style-3" ng-controller="myCtrl">
<form novalidate ng-if="dataLoaded">
<fieldset><legend>Fields</legend>
Catalog Name
<input type="text" ng-model="domObject.catalog.name" />
</fieldset>
</form>
<br />
<div>
<br />
XML Display:
<pre class="prettyprint lang-xml" ng-if="dataLoaded"></pre>
DOM Object: <br /><br />
{{domObject}}
</div>
</div>
</section>
</body>
Your prettyprint directive takes scope.domObject initially and doesn't reflect to its changes.
One of the ways to do this is to setup a watcher like:
App.directive('prettyprint', function($window) {
return {
restrict: 'AC',
replace: true,
scope: {
obj: '='
},
link: function postLink(scope, element, attrs) {
scope.$watch('obj', function(val) {
var x2js = new $window.X2JS();
var xmlString = x2js.json2xml_str(val);
element.text(vkbeautify.xml(xmlString, 4));
}, true)
}
};
});
Here is working plnkr.

How to upload multiple files(each file contains max 1 file) on clicking on submit button?

Hi i am developing file upload module using Angularjs and api. I am following https://jsfiddle.net/JeJenny/vtqavfhf/. I have one list which contains document names such as passport,visa etc and so on. I am binding this list to array and looping inside ng-repeat. So based on the number of documents it generates file upload controls as below.
<div class="upload-button" ng-repeat="file in files">
<div class="upload-button-icon">
<img src="images/folder-small.png">
<div class="upload-text">{{file}}</div>
<input type="file" id="file1" name="file1" file-model="{{file}}" />
</div>
</div>
Note: we can upload obly one document on one upload.
So clearly if i have 4 documents in files array then 4 file upload controls will generate.
Finally i have one button which should save all the above files on click.
<input type="submit" value="{{ 'NEXT' | translate }}" class="blue-button" ng-click="uploadFile(files)">
I have this function to save file(Taken from fiddler)
$scope.uploadFile = function(filename){
//Here i want to save all the files. For example if there are three documents in array files then 3 documents at a time i want to send it to server.
};
As you can see, fiddler will be having separate functions to save each file individually. I am trying to send all the files at a time.
May i get some help here? I am not sure what should be written inside $scope.uploadFile function? How can i collect here all files data? Thank you.
Here is a working example, hope it helps
var myApp = angular.module('myApp', []);
myApp.directive('fileModel', ['fileUpload', function(fileUpload) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind("change", function(evt) {
fileUpload.pendingFiles[attrs.fileModel] = evt.target.files[0];
});
}
};
}]);
myApp.factory('fileUpload', ['$http', function($http) {
var service = {
uploadUrl: "https://httpbin.org/post",
pendingFiles: [],
doUpload: doUpload
};
return service;
function doUpload() {
var files = new FormData();
angular.forEach(this.pendingFiles, function(value, key) {
files.append('file', value);
});
return $http.post(this.uploadUrl, files, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
})
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload) {
$scope.fileInputs = [1, 2, 3];
$scope.upload = function(filename) {
fileUpload.doUpload().success(function(success) {
$scope.result = success
});
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<div ng-repeat="fileInput in fileInputs">
<input type="file" file-data="{{fileInput}}" file-model="{{fileInput}}" />
</div>
<br />
<button ng-click="upload()">upload all</button>
<br />
<pre>{{result | json}}</pre>
</div>
</body>
add multiple attribute to your input tag file
<input type="file" multiple>
this will allow multiple select of files

using directive in angularjs for getting filepath

I am creating a web app in angularjs but i am not very familiar with directives in angularjs
i want to get the file path of the selected file by a particular user
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope, $http, $q){
$scope.uploadFile=function(){
var f = document.getElementById('file').files[0];
console.log(f);
console.log(files);
}
});
myApp.directive('customFileInput', [function () {
return {
restrict: "EA",
scope: false,
link: function (scope, element, attrs) {
element.on('change', function (evt) {
var files = evt.target.files;
scope.filename = files[0].name
});
}
}
}]);
</script>
this is my script in which i used angularjs app, controller and directive
but i am not able to call the directive on the button click
<div ng-app="myApp" ng-controller="myCtrl">
ggggg
<input id="file" type="file" ng-model="mdfile" ng-change="filepath()" class="form-control" custom-directive custom-file-input />
<button ng-click="uploadFile()">upload me</button>
</div>
this is my button and input field with file upload
when i click on the button i am getting the following error
ReferenceError: files is not defined
at b.$scope.uploadFile (image.html:22)
at fn (eval at compile (angular.js:14539), <anonymous>:4:221)
at b (angular.js:15628)
at e (angular.js:25172)
at b.$eval (angular.js:17378)
at b.$apply (angular.js:17478)
at HTMLButtonElement.<anonymous> (angular.js:25177)
at Rf (angular.js:3487)
at HTMLButtonElement.d (angular.js:3475)
what i need to do if i want to get the file path and use this directive?
See this Plunkr:
https://embed.plnkr.co/dmNRL8bj7E5ZtnArQ0sm/
I changed your directive to make it alert the url on change
app.directive('customFileInput', [function () {
return {
restrict: "EA",
scope: false,
link: function ($scope, element, attrs) {
element.on('change', function (evt) {
var files = evt.target.files;
var filename = files[0].name;
alert(URL.createObjectURL(files[0]));
});
}
}

Angular directive to add content rather than overwrite

I am trying to write a directive that will show a "loading" message over a div while the data is fetched from the server.
Thus far I've managed to get this:
.directive('dataLoadingPanel', function () {
return {
templateUrl: '/Utilities/loadingPanelBox.html',
scope: {
panelData: '=',
loadingMessage: "#"
}
};
})
loadingPanelBox.html has this:
<div class="modal-dialog" style="background-color: white;width:300px;height:46px;padding-top:16px;top:30px;padding-left:40px;border-radius: 4px;" ng-hide="panelData">
<img src="/images/BlueSpinner.gif" style="margin-top:-2px" /> {{loadingMessage}}
</div>
This actually does most of what I want, the panel is shown until the data is returned at which point it disappears.
Unfortunately it also overwrites the contents of the div it's placed on, so in this instance:
<div data-loading-panel panel-data="myData" loading-message="Loading Data">Hello There</div>
the Hello There is never seen. This seems to be a function of my using a template.
Is there a way of stopping this overwriting happening or maybe some way of adding the content other than with a template.
I use this:
BlockUI
This is a module which is very easy to use. There is a nice tutorial on the page that fills all of your needs.
Thanks to #Amiros I've made it work slightly differently.
Here's the directive and controller code:
.controller('dataLoadingPanelController', [
'$scope', '$timeout', function($scope, $timeout) {
$timeout(function() {
$scope.setBoxSize();
});
} ])
.directive('dataLoadingPanel', function () {
return {
restrict: 'EA',
scope: {
panelData: '=',
loadingMessage: "#"
},
templateUrl: '/Content/Utilities/loadingPanelBox.html',
link: function (scope, element, attr) {
var elMessage = element.find('.loading-message-area');
var elBox = element.find('.loading-dialog');
scope.setBoxSize = function() {
var messageSize = parseInt(elMessage.css('width').replace(/px$/, ""));
var parentSize = parseInt(element.parent().css('width').replace(/px$/, ""))
var newBoxSize = messageSize + 70;
elBox.css('width', newBoxSize + 'px');
var newBoxPosition = (parentSize / 2) - (newBoxSize / 2);
elBox.css('margin-left', newBoxPosition + 'px');
};
},
controller: 'dataLoadingPanelController'
};
})
The html file is:
<div style="position:absolute;color:black;font-weight:normal;">
<div class="modal-dialog loading-dialog" style="border:1px solid #1f4e6c;background-color: white;height:46px;padding-top:14px;top:30px;padding-left:20px;border-radius: 4px;" ng-hide="panelData">
<img src="/images/BlueSpinner.gif" style="margin-top:-2px" /> <span class="loading-message-area">{{loadingMessage}}</span>
</div>
</div>
which is pretty simple and means that the usage is as follows:
<div class="panel-body">
<data-loading-panel panel-data="myData" loading-message="Loading Data"></data-loading-panel>
{{myData}}
</div>

Categories

Resources