Clear form after submit image in Meteor - javascript

I’m using CFS for files upload in my Meteor App, almost everything works fine, except because when I try to upload another image, I see my previous sended image in the form, so I need to clear that form after submit the image. I've tried with .reset but it doesn't work. This is my code right now. Thanks for the help.
NewImage.html
<template name="newImage">
<div align="center">
<form align="center">
<div>
<div>
<span class="btn btn-success btn-file">
<input type="file" accept=".gif,.jpg,.png" class="myFileInputimagepub" id="image"/>
</span>
</div>
<div>
<img src="{{currentUser.profile.image}}" alt="Image" width="60px" height="60px" class="img-circle avatar-upload" value=''/>
</div>
</div>
</form>
</div>
</template>
NewImage.js
import './newImage.html';
Template.NewImage.events({
'change .myFileInputimagepub':function(evt,tmpl){
FS.Utility.eachFile(event,function(file){
fileImagespub.insert(file,function(err,fileObj){
if(!err){
var userId = Meteor.userId();
var imageurl = {
'profile.image':'/cfs/files/fileimages/' + fileObj._id
};
setTimeout(function(){
Meteor.users.update(userId,{$set:imageurl});
},2000);
}
})
})
},
'submit form':function(event,template){
event.preventDefault();
template.find("form").reset();
}
});

If the image in question is the one with class .img-circle, the issue is that its src attribute is being dynamically provided. Currently it is currentUser.profile.image. This won't clear just by resetting the form and manually clearing the image's src value would be fighting the framework.
Option 1 (Not Ideal):
If you don't want to keep the image, unset the database change made after the file upload by running something like this:
Meteor.users.update(userId, { $set: { 'profile.image': null }});
This is not ideal as it enables you to continue modifying the database with an image which may not be needed long-term.
Additionally, I'm assuming you're currently using the autopublish/insecure packages. You'll want to remove these before going public with your app as they allow any user to change the database without restriction.
Option 2:
You could save the returned value from your 'change .myFileInputimagepub' event as a ReactiveVar, then only actually run Meteor.users.update (preferably on the server using a Method) when your user submits the form. At that point you could clear the reactive variable.
Using a ReactiveVar will allow you to provide the saved URL to the src attribute via a helper, and then change the ReactiveVar's value when you wish to clear the form.
There's a simple example of manipulating ReactiveVars here: https://gist.github.com/ahoereth/a75d2d6528b1844ad503

Related

Changing Profile Picture, and then Saving new one

I am writing a program that has a profile page and I want to be able to switch the profile picture. I am able to change it but I am not sure how to go about saving the new picture from the files.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="profile-container">
<image id="profileImage" src="https://t3.ftcdn.net/jpg/03/46/83/96/360_F_346839683_6nAPzbhpSkIpb8pmAwufkC7c5eD7wYws.jpg" />
</div>
<input id="imageUpload" type="file" name="profile_photo" placeholder="Photo" required="" capture>
<script>
$("#profileImage").click(function(e) {
$("#imageUpload").click();
});
function fasterPreview( uploader ) {
if ( uploader.files && uploader.files[0] ){
$('#profileImage').attr('src',
window.URL.createObjectURL(uploader.files[0]) );
}
}
$("#imageUpload").change(function(){
fasterPreview( this );
});
</script>
This is my code to change the picture, but I don't know how to save the new one. Every time I refresh the page, the picture goes back to the default.
If using local storage is an option, I think it would solve your issue. I am not very comfortable in jquery but I think you are trying to change the src attribute if a new image is provided.
You could initially store the path to the image in local storage.
localstorage.setItem('imgPath', 'https://path-to-image-here');
Then, when a new image is uploaded, just change the path in local storage. You can show this image in your profile like this:
localstorage.getItem('imgPath');

Image taken from camera not saved to gallery

I'm implementing a simple image upload form. When on the phone the user has the option of taking a photo with the camera and uploading it.
For some reason, the picture taken this way is not saved to the gallery.
Is there anything missing in the HTML declaration to enable the picture to be saved to gallery irregardles of whether it is discarded or used?
This is my form(in Angular):
<ng-container *ngFor="let image of imageList; let i = index;">
<div class="mb-1" fxLayoutAlign.gt-xs="space-between" fxLayoutGap.xs="10px" fxLayout.xs="column">
<input type="file" accept="image/*" [disabled]="image.hasOwnProperty('Id') && image?.Id" (change)="showPreview($event, img, i)" #input/>
<img [src]="image?.url" alt="" #img class="image-limited" />
<p *ngIf="image?.url !== ''" fxLayoutAlign.xs="center center">{{ image?.hasOwnProperty('name') ? image?.name : (form.get('AssetNumber').value || '') + '_' + (i + 1) }}</p>
<button md-raised-button color="accent" class="delete-button" (click)="clearImage(input, img, $event, i)" [disabled]="image?.url === ''">
<i class="fa fa-remove"></i> {{ 'ADD_EDIT_ASSET_IMAGE_DELETE_BUTTON_TEXT' | translate }}
</button>
</div>
<hr class="mb-1" *ngIf="i !== imageList.length - 1" />
</ng-container>
This method gets called on change of the input:
showPreview(event: { target: { files: FileList, value: string } }, element: HTMLImageElement, imageIndex: number): void {
ImageCompression.compress(event.target.files[0], this.configurationService.previewQuality)
.then((res: File) => {
const imageUrl: string = URL.createObjectURL(res);
this.imageList[imageIndex].url = this.sanitizer.bypassSecurityTrustUrl(imageUrl);
this.renderer.setAttribute(element, 'src', imageUrl);
});
}
TL;DR: Is not the expected behaviour.
When you take input a file in a web page, the user doesn't expect the image to be saved. They expect the image to be upload to the page, and maybe to the server.
An installed app has permissions and memory space assigned to it. It is expected that the app would save an image. A web page is not an App installed in the phone, it has no memory assigned and doesn't have permissions. Users will get mad if a web page suddenly starts to save images in their memory without ther permission.
Having said that, you sure can take a photo and then download it to the memory of the phone. But the user will see it as it, as a download.
But there's a problem: you don't control where the photo is coming from. The user might select the file picker and input an already saved image, if you download it without asking then the user might have duplicate files in their memory. That would drive me crazy for sure.
Asking the user if they want it to be downloaded will be better.
That behaviour ensures consistency in the page seen in a desktop or mobile. But again, you don't control where the images are going to be saved or if the images will get downloaded for sure. If you need the images for later, you need the user to select those images and input them as usually.
Referring to this article i've made some code, tested and working pretty well.
Code main function is capture function, which gets 2d context, and then pushes image to array you are iterating by in view of your component. I am pretty sure you will be able to adjust this solution to your needs :D
some code from some.component.ts looks like
public capture() {
const context = this.canvas.nativeElement.getContext('2d').drawImage(this.video.nativeElement, 0, 0, 640, 480);
this.captures.push(this.canvas.nativeElement.toDataURL('image/png'));
}
and some.component.html looks like
<div id="app">
<div><video #video id="video" width="640" height="480" autoplay></video></div>
<div><button id="snap" (click)="capture()">Snap Photo</button></div>
<canvas #canvas id="canvas" width="640" height="480"></canvas>
<ul>
<li *ngFor="let c of captures">
<img src="{{ c }}" height="50" />
</li>
</ul>
</div>
Maybe it's related with the permissions, this one allows to storage, meanwhile CAMERA one probably only allows to use it:
https://developer.android.com/reference/android/Manifest.permission#WRITE_EXTERNAL_STORAGE
What is your permissions list?
(Probably it's not related, but just in case!)

Submitting a post request through Vuejs and axios to a laravel back-end

I need some help in implementing a basic ajax request through vue to my laravel back-end, I have a boolean named completed on a table called courses, and I have a view that fetches all courses assigned to a specific user and allows them to press a button to change the current status of the course, either completed or not, that's it, that's all I wanna do, right now I can do it normally through get and post requests, obviously results in a refresh of the page, I want that to be dynamic with just refreshing the dom, I am so frustrated that I couldn't figure this out on my own because I think It should be easy, turns out I know nothing when it comes to using vuejs.
Here is the significant part of my CoursesController:
public function toggling($name)
{
$course = Course::where(['name' => $name])->first();
$course->completed = !$course->completed;
$course->save();
// return redirect()->back();
return response()->json(['course' => $course], 202);
}
And here is the significant part of the view that provides the courses to the user, it's a part of a table:
<td>
<form method="POST" #submit.prevent="onSubmit" action="{{ route('course.completed', $course->name) }}" id="form-submit">
{{-- {{ method_field('PUT') }} --}}
{{ csrf_field() }}
#if ($course->completed == true)
<button type="submit" class="btn btn-sm" id="coursetogglingtrue">Done!</button>
#else
<button type="submit" class="btn btn-sm" id="coursetogglingfalse">Not Yet!</button>
#endif
</form>
</td>
For some reason the #submit.prevent method is not working, it worked a couple of times but then It just didn't, and the form kept submitting as usual.
These are the scripts inside app.blade.php, I don't know how/where should I compile this, it's just sitting there in the main layout of my project, should I transfer it to public/js/app.js? or compile it using gulp? if you have something in mind please let me know:
<!-- Scripts -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/vue#2.1.10/dist/vue.js"></script>
<script src="/js/app.js"></script>
<script>
new Vue({
el: '#app',
data: {
course: {}
},
methods: {
onSubmit() {
// course = $event.target;
axios.post('/MyCourses/{{course.name}}').then(console.log(course));
}
}
});
</script>
I want to have course be equal to whatever value of the request was, so that I can then target the value of the name of the course that was submitted and inject it to the route as I'm trying to do, but I'm not sure how to do that, I tried a few different things, all failed.
And here is routes/api.php
Route::post('/MyCourses/{name}', 'CoursesController#toggling')->name('course.completed');
ofc right now this is not working, the form is submitting, and I'm redirected to a route where I get back the json response, and that's it, I just want to refresh the dom so that the button would have the new id depending on that status of the course, and the course itself to be updated and saved in the background without refreshing the page.
I am fairly new to this, I understand that the form should probably be re-written, and I know I've done a lot of mistakes, but I just want it to work, so help would be very appreciated.
UPDATE
After a lot of hours of trial and error, I'm done with the ajax part and I'm almost there with the rest I just need to do a few things, this is what I've managed to do so far,
In the view:
<form method="POST" #click.prevent="onSubmit" action="{{ route('course.completed', $course->name) }}" id="form-submit">
{{ csrf_field() }}
#if ($course->completed == true)
<button type="button" class="btn btn-sm" id="coursetogglingtrue">Done!</button>
#else
<button type="button" class="btn btn-sm" id="coursetogglingfalse">Not Yet!</button>
#endif
Changing the type of the button from submit to button allowed the .prevent method to actually fire, now the form doesn't submit anymore, the form still needs work in order to output the proper class depending on the status of the course but regardless,
This is the script that I have now:
<script>
new Vue({
el: '#app',
data: {
course: {
name: '',
bool: false
}
},
methods: {
onSubmit: function() {
this.course.bool = !this.course.bool,
axios.post('/MyCourses/{{$course->name}}')
.then(function (response){
// {{$course->completed}} = response.course.completed;
});
}
}
});
</script>
Somehow right now, I'm actually sending the post request to the correct route, but there's a problem which has the highest priority right now, $course is referencing the latest course that was added to the page, and not the course that I chose by pressing on the button, now whichever button I press, the last course gets injected to $course, and then ofc to the route in axois, I don't know how to figure that out yet, but so far that course gets updated, and if I inspected the network tab in chrome, I see the response and that value of the completed column gets updated, I believe that there are still some mistakes in the code, but I'll keep trying, if you can point out some more things please let me know, thanks
An improvement to the answer above would be to use Template Literals introduced in ES6.
Instead of:
axios.post('/MyCourses/' + course.name).then(console.log(course));
You can do:
axios.post(`/MyCourses/${course.name}`).then(console.log(course));
More information on Template Literals functionality and syntax can be found here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
The syntax you are using is wrong in following line:
axios.post('/MyCourses/{{course.name}}').then(console.log(course));
It should be :
axios.post('/MyCourses/' + course.name).then(console.log(course));

Submitting JSP form data to servlet

I currently have this tree node which was created from http://mbraak.github.io/jqTree/. I am trying to implement this tree, so that when a user clicks on a node in the tree, it will send the data to my servlet. Is there any way to do this? I am currently using JSP. My initial solution was to add a button so that the button (with form tag) will do post action when it is being clicked(after selecting my node), but i would like to know if there is any solution without using a button. I also thought of using ajax but im new to this and am not sure if it works. Really need some help. Thanks
My Tree:
$('#tree1').tree({data: data});
$('#tree1').bind(
'tree.click',
function(event) {
if (event.node) {
// node was selected
node = event.node.name;
alert(node);
// send node value to servlet
}
else {
}});
HTML
<div id="tree1"></div>
My Initial idea
$('#saveCat').click(function(){
document.getElementById('mainCat').value = node;
document.getElementById('action').value = "savecategory";
});
<form action="TopicCloudServlet">
<button id="saveCat" class=" catbtn btn-primary">Save</button>
<input type="hidden" id="mainCat" name="mainCat" value="" />
<input type="hidden" id="action" name="action" value="" />
</form>
Assuming that you are dynamically creating the tree , you can add extra elements as attributes to each nodes of the tree when you render it.Do not worry,your custom attributes will be ignored by the browser.
Below "nodevalue" is your own attribute that you add to the div dynamically when rendering the tree to uniquely identify each node.
<div id="tree1">
<div nodevalue="node1" class="mynode">
</div>
<div nodevalue="node2" class="mynode">
</div>
</div>
Then write a jquery class selector onclick event and get the unique ID of the clicked node.
$(".mynode").on("click",function(){
alert(this.attr("nodevalue"));
});
this.attr("nodevalue")
will give the value of the node you currently clicked.
Ok i found 1 solution which is very simple( why didn't i thought of it)
Add an id to the form that is going to be submitted.
At the javascript where u want your form to be submitted,
document.forms["FormID"].submit();

Image as a post variable

I am working on a site where there is a feature for users to be able to sign directly on the webpage using a canvas free form pen tool. When users click the 'apply signature' button the signature that the user drew is converted into an image and saved on the page as an <img src=""> (as you can see in the code below). Up until this point everything works great.
The problem is, When the user submits the form, I am trying to get the newly created canvas image to submit with it as a post variable and render on the process.php page as the signature that was signed. It appears that image (toDataURL()) gets passed as a post variable, but for some reason it does not render on the process.php page. It appears like the image source is not found.
I am new to javascript and I have been trying to fix this problem for days now, I would appreciate any help with fixing this. Many thanks in advance!
Markup
<div class="signature-field">
Sign:
<span class="sketch-container">
<canvas id="simple_sketch" width="350" height="100"></canvas>
</span>
Date: <input name="signature-date" type="text"><br/>
<div class="signature-buttons">
<span class="save-signature">Apply Signature | </span>
<span class="reset-canvas">| Reset Signature</span><br/>
</div>
</div>
<form method="post" action="process.php">
<input type="text" name="fname">
<input id="signature" name="signature" type="hidden">
<input type="submit">
</form>
JavaScript
$(function () {
var sktch = $('#simple_sketch').sketch();
var cleanCanvas = $('#simple_sketch')[0];
$('.save-signature').click(function () {
/* replace canvas with image */
var canvas = document.getElementById("simple_sketch");
var img = canvas.toDataURL("image/png");
$('#simple_sketch').replaceWith('<img src="' + img + '"/>');
$('.signature-buttons').replaceWith('');
document.getElementById("signature").value = $('.sketch-container').html();
});
});
I'm not quite sure what you're doing here, but if you want to post the image data through the hidden signature field, simply do this:
document.getElementById("signature").value = document.getElementById("simple_sketch").toDataURL("image/png");
As right now, it looks like you're posting the image data including <img> tags ("<img src="<DataUrl>"/>")
How about your server-side code, is the img param output empty? Are you sure the img data is being sent through the request? Try some packet sniffing tool like Fiddler or Wireshark and analyze the contents of the request (You can also take a quick look with Firebug).
Perhaps you could try some other approach to convert the img data:
https://developer.mozilla.org/en-US/docs/HTML/Canvas/Pixel_manipulation_with_canvas

Categories