Remember chosen file and reload it in Filedropjs - javascript

I'm using FileDropJS to allow users to choose a local file and upload its content to the application.
I'm looking for a way to "choose" the same file automatically for the user, when the user comes back, without him having to drag & drop the file again every time he uses the application.
Is there an easy way to do it with FileDropJS? I looked into the docs but didn't find anything related.
Current code to allow to choose the file and assign its content to a JavaScript variable:
var file_zone = new FileDrop('file_file', file_options);
file_zone.event('send', function (files) {
files.each(function (file) {
file.readData(
function (str) {
file_content = str;
document.getElementById("file_file_label").innerHTML = '<i style="color:green;" class="fa fa-check-circle"></i> Thank you!';
},
function () { alert('Problem reading this file.'); },
'text'
);
});
});
Thanks!

Related

copying Javascript working on a laravel view to another site not working

So on similar sites with different themes, same core functions for laravel there is a view that has
<div class="footer__item footer__item--right"> <div class="footer__item-search"> <span class="search-wrap"><input type="text" placeholder="Search" class="search"></span> </div>
in scripts the only relative javascript code which is also already on the other site
$(document).on('keyup', '.search', function() {
var query = $(this).val().toLowerCase();
doSearch(query);
});
function OnSearch(input) {
var query = input.value.toLowerCase();
doSearch(query);
}
function doSearch(query){
$.getJSON('{{ route('frontend.game.search') }}?category1={{ $category1 }}&q=' + query, function(data) {
$('#games').html(data.data);
});
}```
so copying those makes a box appear but searches nothing
What possibly the javascript is missing to actually be called and call the laravel template view mentioned ?

Uploading images using aurelia to asp.net core backend

I have been searching for a solution for this but none of the guides are updated or suited for my intention. I need a user uploaded image to be loaded into javascript/aurelia which then sends it to the asp.net core backend using its http fetch client so the image is saved on disk(not in a database). I'm currently using the following code but I'm getting the following error and no images are being saved.
extract from html code being used to upload image
<input class="hiddenButton" id="images" type="file" accept=".jpeg" file.bind="image">
<button class="upload" onclick="document.getElementById('images').click()">
<i class="fa fa-pencil" style="color:green"></i>
</button>
extract of javascript code used to invoke saving
save() {
this.api.saveEmployee(this.employee).then(employee => this.employee = employee);
this.ea.publish(new EmployeeAdded(this.employee));
this.api.saveImage(this.image);
return this.employee;
}
Javascript/aurelia code
saveImage(image) {
var form = new FormData()
form.append('image', image)
this.http.fetch('/api/Images', {
method: 'POST',
//headers: { 'Content-Type': image.type },
body: form
})
.then(response => {
return response
})
.catch(error => {
console.log("Some Failure...");
throw error.content;
})
return true;
}
Asp.net core MVC code(backend)
[HttpPost]
public async Task<IActionResult> SaveImage(IFormFile file)
{
Console.WriteLine("Images controller");
var filePath = Path.Combine(Directory.GetCurrentDirectory(),"Image");
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return Ok();
}
error message
The HTML element <input type="file" /> does not have a property file, the correct property is files, so it sounds like the problem is with aurelia/javascript and binding.
Since the property files is a FileList (collection) you will need to access the first file in the collection. Even though you haven't used multiple I think files will still be a collection.
You could try this:
// html
<input class="hiddenButton" id="images" type="file" accept=".jpeg" files.bind="image">
// ^ files
// jss/aurelia
saveImage(image) {
var form = new FormData();
form.append('image', image[0]); // access the first image in collection image[0]
// the other code remains the same
//...
}
PS I haven't used aurelia so can't be 100% sure this is the issue but hopefully points you in the correct direction.
PPS: since files is a collection, technically image in your view model is a collection too, so you could consider renaming it to images to make it clearer (even if you're only using one image). It should still work using image[0] but images[0] would be clearer.

Binding data into localStorage with ngStorage - what's wrong here?

I started this journey trying to get some settings to persist with localStorage, has some problems and posted about it here (without a solution): Why won't this data bind? An odd case in Angularjs
I've abandoned that method as I learnt about ngStorage. In theory ngStorage lets you 2-way bind into and out of Angular models. It's a great, great theory.
I'm having problems with it though. It half works.
The ideas is this:
Test for permission selection (true or false).
If no selection (first time use) pop-up a choice.
Store the choice.
On restart use the stored choice to set the permission true or false.
Allow user to change the permission from within the app.
It works up to number 4.
Testing shows that although on first use I can set $storage.analytics to true or false subsequent changes are not being stored and retrieved from local storage.
Here is the code:
permissionCallback = function(permission){
if(permission===1){
console.log("analytics allowed");
analytics.startTrackerWithId('UA-45544004-1');
$scope.$storage.analytics=true;
navigator.notification.alert('You can turn analytics off in the Data Tracking section at any time.', null, 'Analytics On', 'OK');
}else{
console.log("analytics denied");
$scope.$storage.analytics=false;
navigator.notification.alert('You can turn analytics on in the Data Tracking section at any time.',null , 'Analytics Off', 'OK');
}
}
if(typeof $scope.$storage.analytics === 'undefined'){
navigator.notification.confirm('This app would like your permission to collect data on how you use the app. No personal or user identifiable data will be collected.', permissionCallback, 'Attention', ['Allow','Deny']);
}
else{
console.log('start analytics are', $scope.$storage.analytics);
if(typeof analytics !== 'undefined'){
console.log("analytics functioning");
analytics.startTrackerWithId('UA-45544004-1');
$scope.trackClick = function(category, action){
analytics.trackEvent(category, action);
console.log('Tracking category: ' + category + ', Section: ' + action + '.');
}
}
}
$scope.counter = 0;
$scope.change = function(){
$scope.counter++;
console.log('analytics are ' + $scope.$storage.analytics);
}
And here is the html.
<li class="item item-toggle">
<i class="icon ion-cloud"></i> Data Tracking is {{$storage.analytics}} {{counter}}
<label class="toggle toggle-balanced">
<input type="checkbox" ng-model="$storage.analytics" ng-change="change()">
<div class="track">
<div class="handle"></div>
</div>
</label>
</li>
It's either a fault with my logic or, and I think this more likely, a misunderstanding about the scope of the data.
The odd thing is the console log in the change() function (which is purely for tracking these things) is always correct. So using $storage.analytics in the html is the correct way to do it (using $scope.storage.analytics causes all sorts of errors) and it is indeed binding from the html into $scope.storage.analytics.
So why isn't it saving it to local storage when using the toggle?
I ran into a similar problem with ng-storage. When the page was loaded/reloaded anything bound to a value in $sessionStorage was updated correctly. However any changes to $sessionStorage afterwards were not reflected in my view. What I ended up doing was creating a service for storing changes and using $sessionStorage as a temporary data store.
app.controller('TestController', funciton($scope, $sessionStorage, Service) {
// if we have session data set our service
if($sessionStorage.data) {
Service.data = $sessionStorage.data;
} else {
$sessionStorage.data = {};
}
// now bind scope to service
scope.data = Service.data;
// on update we set both Service and $sessionStorage
// scope.data will be automatically updated
scope.update = function(val) {
Service.data.value = val;
$sessionStorage.data.value = val;
}
});
app.service('TestService', function() {
var service = {
data: {
value: 'Hello World'
}
};
return service;
});
<div ng-controller="TestController">{{data.value}}</div>
<button ng-click-"update('Hello Universe')">Update</button>
This is a very rudimentary example of how my solution works but hopefully it gets anyone else stuck in the same situation on the right track.

filepicker.io -- easy implementation

I have a site, btstats.com, that provides the following service:
"It imports a JSON file from 'Bluescan 4.0 Scanner for Android' and generates graphs and stats".
I implemented Dropbox Chooser on my site with this simple and elegant code to provide the functionality, provided by Dropbox:
<script type="text/javascript">
document.getElementById('dropbox-bt').onclick = function()
{
Dropbox.choose
({
linkType: 'direct',
extensions: ['.json'],
multiselect: false,
success: function (files)
{
var dbSelected = "File selected: ";
var filenamePanel = document.getElementById('filenamePanel');
filenamePanel.textContent = dbSelected + files[0].name;
var postLink = files[0].link;
document.getElementById('postLink').value = postLink;
var postName = files[0].name;
document.getElementById('postName').value = postName;
}
});
};
</script>
What I like about the code above is that it is small and provides me the file link and file name.
I'm thinking about implementing filepicker.io, so I can provide to users more cloud storage options.
I couldn't find an easy way to add filepicker.io's window to my site that offers these options. First, I would like to implement it using a button, and I can't find on their documentation an example with getElementById.
Would it be possible for someone to guide me or write a small filepicker.io example based on my Dropbox implementation that provides the file link and file name? I'm not a Javascript expert.
Thanks in advance.
The filepicker code is quite similar:
filepicker.setKey('yourApikey');
document.getElementById('filepickerBtn').onclick = selectFile;
function selectFile(){
filepicker.pick(
// picker options
{
extension: '.json',
},
onSuccessCallback
);
};
function onSuccessCallback(Blob){
document.getElementById('postName').textContent = Blob.filename;
document.getElementById('postlink').textContent = Blob.url;
document.getElementById('results').textContent = JSON.stringify(Blob);
};
Sample html code:
<div class="container">
<h3>Filepicker example</h3>
<p>
<button id="filepickerBtn" class="btn btn-primary">
Select json file
</button>
</p>
<p>Filename: <span id="postName"></span></p>
<p>Filelink: <span id="postlink"></span></p>
<p>Results: <pre id="results">Upload file to see results</pre></p>
</div>
And working example here

Having issues tying together basic javascript chat page

I have the skeleton of a chat page but am having issues tying it all together. What I'm trying to do is have messages sent to the server whenever the user clicks send, and also, for the messages shown to update every 3 seconds. Any insights, tips, or general comments would be much appreciated.
Issues right now:
When I fetch, I append the <ul class="messages"></ul> but don't want to reappend messages I've already fetched.
Make sure my chatSend is working correctly but if I run chatSend, then chatFetch, I don't retrieve the message I sent.
var input1 = document.getElementById('input1'), sendbutton = document.getElementById('sendbutton');
function IsEmpty(){
if (input1.value){
sendbutton.removeAttribute('disabled');
} else {
sendbutton.setAttribute('disabled', '');
}
}
input1.onkeyup = IsEmpty;
function chatFetch(){
$.ajax({
url: "https://api.parse.com/1/classes/chats",
dataType: "json",
method: "GET",
success: function(data){
$(".messages").clear();
for(var key in data) {
for(var i in data[key]){
console.log(data[key][i])
$(".messages").append("<li>"+data[key][i].text+"</li>");
}
}
}
})
}
function chatSend(){
$.ajax({
type: "POST",
url: "https://api.parse.com/1/classes/chats",
data: JSON.stringify({text: $('input1.draft').val()}),
success:function(message){
}
})
}
chatFetch();
$("#sendbutton").on('click',chatSend());
This seems like a pretty good project for Knockout.js, especially if you want to make sure you're not re-appending messages you've already sent. Since the library was meant in no small part for that sort of thing, I think it would make sense to leverage it to its full potential. So let's say that your API already takes care of limiting how many messages have come back, searching for the right messages, etc., and focus strictly on the UI. We can start with our Javascript view model of a chat message...
function IM(msg) {
var self = this;
self.username = ko.observable();
self.message = ko.observable();
self.timestamp = ko.observable();
}
This is taking a few liberties and assuming that you get back an IM object which has the name of the user sending the message, and the content, as well as a timestamp for the message. Probably not too far fetched to hope you have access to these data elements, right? Moving on to the large view model encapsulating your IMs...
function vm() {
var self = this;
self.messages = ko.observableArray([]);
self.message = ko.observable(new IM());
self.setup = function () {
self.chatFetch();
self.message().username([user current username] || '');
};
self.chatFetch = function () {
$.getJSON("https://api.parse.com/1/classes/chats", function(results){
for(var key in data) {
// parse your incoming data to get whatever elements you
// can matching the IM view model here then assign it as
// per these examples as closely as possible
var im = new IM();
im.username(data[key][i].username || '');
im.message(data[key][i].message || '');
im.timestamp(data[key][i].message || '');
// the ([JSON data] || '') defaults the property to an
// empty strings so it fails gracefully when no data is
// available to assign to it
self.messages.push(im);
}
});
};
}
All right, so we have out Javascript models which will update the screen via bindings (more on that in a bit) and we're getting and populating data. But how do we update and send IMs? Well, remember that self.message object? We get to use it now.
function vm() {
// ... our setup and initial get code
self.chatSend = function () {
var data = {
'user': self.message().username(),
'text': self.message().message(),
'time': new Date()
};
$.post("https://api.parse.com/1/classes/chats", data, function(result) {
// do whatever you want with the results, if anything
});
// now we update our current messages and load new ones
self.chatFetch();
};
}
All right, so how do we keep track of all of this? Through the magic of bindings. Well, it's not magic, it's pretty intense Javascript inside Knockout.js that listens for changes and the updates the elements accordingly, but you don't have to worry about that. You can just worry about your HTML which should look like this...
<div id="chat">
<ul data-bind="foreach: messages">
<li>
<span data-bind="text: username"></span> :
<span data-bind="text: message"></span> [
<span data-bind="text: timestamp"></span> ]
</li>
</ul>
</div>
<div id="chatInput">
<input data-bind="value: message" type="text" placeholder="message..." />
<button data-bind="click: $root.chatSend()">Send</button>
<div>
Now for the final step to populate your bindings and keep them updated, is to call your view model and its methods...
$(document).ready(function () {
var imVM = new vm();
// perform your initial search and setup
imVM.setup();
// apply the bindings and hook it all together
ko.applyBindings(imVM.messages, $('#chat')[0]);
ko.applyBindings(imVM.message, $('#chatInput')[0]);
// and now update the form every three seconds
setInterval(function() { imVM.chatFetch(); }, 3000);
});
So this should give you a pretty decent start on a chat system in an HTML page. I'll leave the validation, styling, and prettifying as an exercise to the programmer...

Categories