Hi I was wondering if there was a way to preview images before I upload them using angularjs? I am using the this library. https://github.com/danialfarid/angular-file-upload
Thanks. Here is my code:
template.html
<div ng-controller="picUploadCtr">
<form>
<input type="text" ng-model="myModelObj">
<input type="file" ng-file-select="onFileSelect($files)" >
<input type="file" ng-file-select="onFileSelect($files)" multiple>
</form>
</div>
controller.js
.controller('picUploadCtr', function($scope, $http,$location, userSettingsService) {
$scope.onFileSelect = function($files) {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $files.length; i++) {
var $file = $files[i];
$http.uploadFile({
url: 'server/upload/url', //upload.php script, node.js route, or servlet uplaod url)
data: {myObj: $scope.myModelObj},
file: $file
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}
}
OdeToCode posted great service for this stuff. So with this simple directive you can easily preview and even see the progress bar:
.directive("ngFileSelect",function(){
return {
link: function($scope,el){
el.bind("change", function(e){
$scope.file = (e.srcElement || e.target).files[0];
$scope.getFile();
});
}
}
It is working in all modern browsers!
Example: http://plnkr.co/edit/y5n16v?p=preview
JavaScript
$scope.setFile = function(element) {
$scope.currentFile = element.files[0];
var reader = new FileReader();
reader.onload = function(event) {
$scope.image_source = event.target.result
$scope.$apply()
}
// when the file is read it triggers the onload event above.
reader.readAsDataURL(element.files[0]);
}
Html
<img ng-src="{{image_source}}">
<input type="file" id="trigger" class="ng-hide" onchange="angular.element(this).scope().setFile(this)" accept="image/*">
This worked for me.
See the Image Upload Widget from the Jasney extension of Bootstrap v3
// start Picture Preview
$scope.imageUpload = function (event) {
var files = event.target.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = $scope.imageIsLoaded;
reader.readAsDataURL(file);
}
}
$scope.imageIsLoaded = function (e) {
$scope.$apply(function () {
$scope.img = e.target.result;
});
}
<input type='file' ng-model-instant onchange="angular.element(this).scope().imageUpload(event)" />
<img class="thumb" ng-src="{{img}}" />
Related
I'm upload images in the form of Base64 into Firebase but what I've noticed is that it shows up on the uploader's interface before it's finished uploading to Firebase server.
So how would I know when it's finished uploading the image?
Alternatively, how can I postpone the image showing up on the uploader's interface until the image has been uploaded, so it displays synchronously with all users?
Any help is appreciated, thanks in advance.
Edit: March 6th
Ok so I've reduce the code to the bare minimum to demonstrate this. Though to observe this effect it's best to view the CodePen on two separate locations simultaneously.
HTML:
<script src='https://cdn.firebase.com/js/client/2.0.4/firebase.js'></script>
<ul id="messages"></ul>
<input id="upload" type="file" accept="image/*" onchange="uploadImage()">
JQuery:
var dataRef = new Firebase('https://citruso.firebaseio.com/');
var messagesRef = dataRef.child('Messages');
messagesRef.on('child_added', function(snapshot) {
var message = snapshot.val();
var text = message.text;
if (text.substring(0,11) === "data:image/") {
$('#messages').append('<img class="message-image" src="' + text + '">');
}
else {
$('#messages').append('<li>' + text + '</li>');
}
});
function uploadImage() {
var file = document.querySelector('#upload').files[0];
var reader = new FileReader();
reader.onloadend = function () {
messagesRef.push({text: reader.result});
}
if (file) {
if (file.size < 10000000) {
reader.readAsDataURL(file);
}
else {
alert('File size cannot exceed 10mb.');
}
}
}
I have this problem using dropzone.js for uploading files with drag&drop.
Lets say i have this form:
<form action=""<?php echo $_SERVER['PHP_SELF'];?>"" enctype=""multipart/form-data"" class=""dropzone"" id=""dropzone1"">
<input type=""text"" name=""somevalue"" id=""somevalue"" value=""somevalue"" />
<div class=""fallback"">
<input type=""file"" name=""file-image"" />
</div>
</form>
The javascript for the dropzone call is :
<script type=""text/javascript"">
$(document).ready(function() {
Dropzone.autoDiscover = false;
var fileList = new Array;
var i =0;
$(""#dropzone1"").dropzone({
init: function() {
var $this = this;
$(""#submit-all-1"").click(function() {
$this.processQueue();
});
var totalFiles = 0,completeFiles = 0;
this.on(""addedfile"", function (file) {
totalFiles += 1;
var numQueued=this.getQueuedFiles().length;
});
this.on(""success"", function(file, serverFileName) {
fileList[i] = {""serverFileName"" : serverFileName, ""fileName"" : file.name,""fileId"" : i };
i++;
});
this.on(""removed file"", function (file) {
totalFiles -= 1;
});
this.on(""complete"", function (file) {
completeFiles += 1;
if (completeFiles === totalFiles) {
// Do something
}
});
},
paramName: 'file-image',
acceptedFiles:'image/*',
autoProcessQueue:false,
addRemoveLinks: true,
parallelUploads: 10
});
/////////////////////////////////
});
</script>
And in php section:
<?php
if (!empty($_FILES)) {
$somevalue=$_POST['somevalue'];
$counter=1;
$image=$_FILES['file-image']['name']);
$picture_in = ""/PicsUrl/"".$somevalues.$counter.$image;
move_uploaded_file($_FILES['file-image']['tmp_name'], $picture_in);
$counter++;
}
?>
I want to do this :
With the $somevalue posted, all the files that i upload simultanously,
to be renamed like that:
$somevalue_1_imagefilename,$somevalue_2_imagefilename,$somevalue_3_imagefilename
etc....
Any help ?
Try changing your PHP script like the below :
<?php
if (!empty($_FILES)) {
$somevalue=$_POST['somevalue'];
$counter=1;
$image=$_FILES['file-image']['name']);
$picture_in = ""/PicsUrl/"".$somevalue.$counter++.$image;
move_uploaded_file($_FILES['file-image']['tmp_name'], $picture_in);
}
?>
I am about to integrate svg-edit to an ASP.NET MVC project.
Is there anyone who has a recommendation or tutorial on how to begin with?
Thank you.
I am answering my own question.
After a research, I recommend deploying the whole SVG-EDIT lib into mvc architecture, then modify the embed api as following:
This is my Partial View and JS file that call the embed api and put it into the iframe within the partial view:
document.write("<script type='text/javascript' src='~/Scripts/svg-edit/embedapi.js'></script>");
// Make sure to add the embedapi into the html file, becuase the intialization function runs actually in that file, all this call does is basically to take the iframe from html and inialize the api within that tag.
$(document).ready(function () {
// jquery selectro
$("#LoadSVG").click(function () {
$("#svg").append($('<iframe src="/Scripts/svg-edit/svg-editor.html" width="900px" height="600px" id="svgedit"></iframe>'));
});
});
#Scripts.Render("~/bundles/KSage")
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<header>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</header>
<input id="LoadSVG" type="button" value="LoadSVG" />
<input id="CloseSVG" type="button" value="CloseSVG" />
<input id="save" type="button" value="save" onclick="save()">
<input id="Add" type="button" value="AddNewTag!" onclick="AddNewElemnt()" />
<input id="LoadExample" type="button" value ="LoadExample" onclick="LoadExample()"/>
<body id ="mainBody">
<p id="svg"></p>
<p id="DivData"></p>
<p id="TestId"></p>
<p id="SavedData"></p>
</body>
</html>
Here I have a save and load functions ready for the module: There is so much work to do in order to perfect the algorithm, but since this was just a test project to figure out the possibility of integrating the module into the environment I put enough effort to understand that share the knowledge with the community:
Here is my cshtml file:
#Scripts.Render("~/bundles/KSage")
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<header>
</header>
<input id="LoadSVG" type="button" value="LoadSVG" />
<input id="CloseSVG" type="button" value="CloseSVG" />
<input id="save" type="button" value="save" onclick="save()">
<input id="Add" type="button" value="AddNewTag!" onclick="AddNewElemnt()" />
<input id="LoadExample" type="button" value ="LoadExample" onclick="LoadExample()"/>
<body id ="mainBody">
<p id="svg"></p>
<p id="DivData"></p>
<p id="TestId"></p>
<p id="SavedData"></p>
</body>
</html>
Here is the js file:
document.write("<script type='text/javascript' src='~/Scripts/svg-edit/embedapi.js'></script>");
document.write("<script src='~/Scripts/jquery-1.10.2.js'></script>");
$(document).ready(function () {
// jquery selectro
$("#LoadSVG").click(function () {
$("#svg").append($('<iframe src="/Scripts/svg-edit/svg-editor.html" width="900px" height="600px" id="svgedit"></iframe>'));
});
});
$(document).ready(function () {
// jquery selectro
$("#save1").click(function () {
$("#DivData").append("<b>Appended text</b>");
});
});
$(document).ready(function(){
$("#CloseSVG").click(function () {
$("#svg").hide();
});
});
function HandleSvgData(data,error) {
if (error) {
alert('Error:' + error);
} else {
$('#DivData').append(data);
alert(data);
}
}
function handleSvgData(data, error) {
alert("handling Data");
if (error) {
alert('error ' + error);
} else {
alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
}
}
function save1() {
alert("saving");
// svgCanvas.getSvgString()(handleSvgData);
$("#svgedit").append($('This is the test classed appended after DivDat'));
}
function AddNewElemnt()
{
var newElement = document.createElement("Test");
var newNode = document.createTextNode("This is my new node!");
newElement.appendChild(newNode);
var referenceElement = document.getElementById("mainBody");
var tagInsert = document.getElementById("TestId");
referenceElement.insertBefore(newElement, tagInsert);
// alert("added");
}
function Postt(data) {
}
function Post(data) {
var mainBody = document.getElementById("mainBody");
var SvgDataId = prompt("give me primary id");
var SvgUser = prompt("give me UserName");
var form = document.createElement("form");
form.setAttribute("id", "PostData");
form.setAttribute("action", "/SvgDatas/Create");
form.setAttribute("method", "post");
mainBody.appendChild(form);
var PostData = document.getElementById("PostData");
var InputSvgDataId = document.createElement("input");
InputSvgDataId.setAttribute("name", "SvgDataId");
InputSvgDataId.setAttribute("value", SvgDataId);
PostData.appendChild(InputSvgDataId);
var InputSvgUser = document.createElement("input");
InputSvgUser.setAttribute("name", "SvgUser");
InputSvgUser.setAttribute("value", SvgUser);
PostData.appendChild(InputSvgUser);
var InputData = document.createElement("input");
InputData.setAttribute("name", "Data");
InputData.setAttribute("value", data);
PostData.appendChild(InputData);
form.submit();
}
function save() {
var doc, mainButton,
frame = document.getElementById('svgedit');
svgCanvas = new EmbeddedSVGEdit(frame);
// Hide main button, as we will be controlling new, load, save, etc. from the host document
doc = frame.contentDocument || frame.contentWindow.document;
mainButton = doc.getElementById('main_button');
mainButton.style.display = 'none';
// get data
svgCanvas.getSvgString()(function handleSvgData(data, error) {
if (error) {
alert('error ' + error);
} else {
alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
Post(data);
}
});
}
/*
function BuidUrl(SVGUser) {
var uri = prompt("Give me url where the serach function lives, if empty then I will use Razor syntax to call within MVC architescture");
if (uri)
return uri;
else {
var urlHelper = ('http://localhost:53546/SvgDatas/Search?id='+SVGUser);
return urlHelper;
}
}
*/
function returnedData_IntializeEditor(data, status) {
if ((data != null) && (status == "success")) {
var frame = document.getElementById('svgedit');
svgCanvas = new EmbeddedSVGEdit(frame);
doc = frame.contentDocument || frame.contentWindow.document;
mainButton = doc.getElementById('main_button');
tool_Bottum = doc.getElementById("#tool_button");
mainButton.style.display = 'none';
// Open Data into the frame
// var svgexample = '<svg width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1<\/title><rect stroke-width="5" stroke="#000000" fill="#FF0000" id="svg_1" height="35" width="51" y="35" x="32"/><ellipse ry="15" rx="24" stroke-width="5" stroke="#000000" fill="#0000ff" id="svg_2" cy="60" cx="66"/><\/g><\/svg>';
svgCanvas.setSvgString(data.Data);
} else {
$("#svg").append("<li>There is not such a data available in the database!</li>");
}
}
function LoadExample() {
var SVGUser = prompt("Enter the SVG ID");
$.getJSON("http://localhost:53546/SvgDatas/Search?id=" + SVGUser, returnedData_IntializeEditor );
}
This is the model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace IntegrationOfSVG.Models
{
public class SvgData
{
public string SvgDataId { get; set; }
public string SvgUser { get; set; }
public string Data { get; set; }
}
}
Thank you SVG-EDIT community for the great tool.
Next I am planning to add a view mode to this module that opens the data from a sequal server and if the mode is admin, lets the user to edit the existing data. I will keep this posted updated.
1- One way is to remove the tools from the client side, but it has a certain limitation that is the fact that css does not adjust a
function RemoveTools() {
var frame = document.getElementsByClassName("iFrameHtmlTag")[0];
doc = frame.contentWindow.document;
if (doc != null) {
var Tools = [
'tools_top', 'tools_left', 'tools_bottom', 'sidepanels', 'main_icon', 'rulers', 'sidepanels', 'canvashadow'];
for (i=0; i<Tools.length;i++)
{
doc.getElementById(Tools[i]).style.display = "none";
}
} else
alert("Doc was null");
};
$(document).ready(function () {
$("#hide").click(function () {
RemoveTools();
});
});
It is an effective way, but there should be a better method to view the object with few parameters also to readjust the size of the window. I will continue with that topic too.
I am facing problem here as in phonegap image is uploaded to the server once u select a picture.I don't want to upload image before submitting form. Image is uploaded automatically to server which is something i don't want.I want to upload image with the form, where form contains many more fields which is required to send along with image. What are the possible ways to submit with form?
<!DOCTYPE HTML >
<html>
<head>
<title>Registration Form</title>
<script type="text/javascript" charset="utf-8" src="phonegap-1.2.0.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for PhoneGap to load
document.addEventListener("deviceready", onDeviceReady, false);
// PhoneGap is ready
function onDeviceReady() {
// Do cool things here...
}
function getImage() {
// Retrieve image file location from specified source
navigator.camera.getPicture(uploadPhoto, function(message) {
alert('get picture failed');
},{
quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
});}
function uploadPhoto(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(imageURI, "http://yourdomain.com/upload.php", win, fail, options);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
alert(r.response);
}
function fail(error) {
alert("An error has occurred: Code = " = error.code);
}
</script>
</head>
<body>
<form id="regform">
<button onclick="getImage();">select Avatar<button>
<input type="text" id="firstname" name="firstname" />
<input type="text" id="lastname" name="lastname" />
<input type="text" id="workPlace" name="workPlace" class="" />
<input type="submit" id="btnSubmit" value="Submit" />
</form>
</body>
</html>
Create two functions you can call separately. One function for just getting the image, and another function to upload the image.
You can do something like below.
<!DOCTYPE html>
<html>
<head>
<title>Submit form</title>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
var pictureSource; // picture source
var destinationType; // sets the format of returned value
// Wait for device API libraries to load
//
document.addEventListener("deviceready",onDeviceReady,false);
// device APIs are available
//
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
// Called when a photo is successfully retrieved
//
function onPhotoURISuccess(imageURI) {
// Show the selected image
var smallImage = document.getElementById('smallImage');
smallImage.style.display = 'block';
smallImage.src = imageURI;
}
// A button will call this function
//
function getPhoto(source) {
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50,
destinationType: destinationType.FILE_URI,
sourceType: source });
}
function uploadPhoto() {
//selected photo URI is in the src attribute (we set this on getPhoto)
var imageURI = document.getElementById('smallImage').getAttribute("src");
if (!imageURI) {
alert('Please select an image first.');
return;
}
//set upload options
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType = "image/jpeg";
options.params = {
firstname: document.getElementById("firstname").value,
lastname: document.getElementById("lastname").value,
workplace: document.getElementById("workplace").value
}
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI("http://some.server.com/upload.php"), win, fail, options);
}
// Called if something bad happens.
//
function onFail(message) {
console.log('Failed because: ' + message);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
//alert("Response =" + r.response);
console.log("Sent = " + r.bytesSent);
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
</script>
</head>
<body>
<form id="regform">
<button onclick="getPhoto(pictureSource.PHOTOLIBRARY);">Select Photo:</button><br>
<img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
First Name: <input type="text" id="firstname" name="firstname"><br>
Last Name: <input type="text" id="lastname" name="lastname"><br>
Work Place: <input type="text" id="workplace" name="workPlace"><br>
<input type="button" id="btnSubmit" value="Submit" onclick="uploadPhoto();">
</form>
</body>
</html>
You're already sending custom fields in your example.
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
Just populate params with your form fields.
I also faced same problem, but I have done using two server side calls on one click. In this, in first call submit data and get its id in callback using JSON then upload image using this id. On server side updated data and image using this id.
$('#btn_Submit').on('click',function(event) {
event.preventDefault();
if(event.handled !== true)
{
var ajax_call = serviceURL;
var str = $('#frm_id').serialize();
$.ajax({
type: "POST",
url: ajax_call,
data: str,
dataType: "json",
success: function(response){
//console.log(JSON.stringify(response))
$.each(response, function(key, value) {
if(value.Id){
if($('#vImage').attr('src')){
var imagefile = imageURI;
$('#vImage').attr('src', imagefile);
/* Image Upload Start */
var ft = new FileTransfer();
var options = new FileUploadOptions();
options.fileKey="vImage";
options.fileName=imagefile.substr(imagefile.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
options.chunkedMode = false;
ft.upload(imagefile, your_service_url+'&Id='+Id+'&mode=upload', win, fail, options);
/* Image Upload End */
}
}
});
}
}).done(function() {
$.mobile.hidePageLoadingMsg();
})
event.handled = true;
}
return false;
});
On server side using PHP
if($_GET['type'] != "upload"){
// Add insert logic code
}else if($_GET['type'] == "upload"){
// Add logic for image
if(!empty($_FILES['vImage']) ){
// Copy image code and update data
}
}
I could not get these plugins to upload a file with the other answers.
The problem seemed to stem from the FileTransfer plugin, which states:
fileURL: Filesystem URL representing the file on the device or a data URI.
But that did not appear to work properly for me. Instead I needed to use the File plugin to create a temporary file using the data uri to get me a blob object: in their example, writeFile is a function which takes a fileEntry (returned by createFile) and dataObj (blob). Once the file is written, its path can be retrieved and passed to the FileTransfer instance. Seems like an awful lot of work, but at least it's now uploading.
I used to use the following Ajax code to pass variables. However, it doesn't seem to work with images. Any suggestions?
<p>
<input type="file" name="image" /><br />
<input type="button" value="Submit" onclick="addImage()" />
</p>
<div id="content"> </div>
<script>
function addImage() {
var image = $('input[name=image]').val();
$.ajax({
type: "POST",
url: "/chat",
data: {'image': image},
cache: false
});
}
</script>
Correctly speaking, you'll need to pass the data to the page in a special manner. Check out this tutorial by Nettuts+, I used it when I was confronted with a similar problem.
The only difference is that you are only allowing a single upload, while it allows many uploads. You can fix that by turning off the multiple attribute.
Also, it automatically uploads the image after selection, so you might wanna try this:
document.getElementById('yourbuttonsid').onclick = function () {
var i = 0, len = this.files.length, img, reader, file;
document.getElementById("response").innerHTML = "Uploading . . ."
for ( ; i < len; i++ ) {
file = this.files[i];
if (!!file.type.match(/image.*/)) {
}
}
}
instead of this:
if (input.addEventListener) {
input.addEventListener("change", function (evt) {
var i = 0, len = this.files.length, img, reader, file;
document.getElementById("response").innerHTML = "Uploading . . ."
for ( ; i < len; i++ ) {
file = this.files[i];
if (!!file.type.match(/image.*/)) {
}
}
}, false);
}
Hope I helped. Twiddle the settings to your personal need if necessary.
JSON objects are made only to transfer strings, basic objects, integers and a few other things. They are not meant for sending images. However, if you still want to try implementing this in your own way, I can think of two ways to do it. Firstly, just send the name of the images (exact link) or upload it and provide the path.
Or secondly, convert it to base64 in the browser, send it, and have code convert it back whenever required.
That would look something like this:
<form method="async" onsubmit="addImage(this.image)">
<input type="file" name="image" /><br />
<input type="submit" value="Submit" />
</form>
<div id="content"></div>
<script>
function addImage(img) {
$.ajax({
type: "POST",
url: "/chat",
data: {'image': toBase64(img)},
cache: false
});
}
function toBase64(img) {
// Create an HTML5 Canvas
var canvas = $( '<canvas></canvas>' )
.attr( 'width', img.width )
.attr( 'height', img.height );
// Initialize with image
var context = canvas.getContext("2d");
context.drawImage( img, 0, 0 );
// Convert and return
return context.toDataURL("image/png");
}
</script>