I am searching for an alternative to Ionic's image-picker plugin or some guidance on using it to attach a file to a Form for upload. The api that I am using requires that file be uploaded via form. Thoughts or suggestions are much appreciated. The feature of multiple file selection is the most important part of this.
You can use standard web api (file input) to achieve this and use "multiple" as attribute.
Your template:
<button ion-button>
<ion-icon name="image"></ion-icon>
<input multiple type="file” (change)="loadImageFromDevice($event)" accept="image/png, image/jpeg">
</button>
Your ts:
myImages: Array<string>;
...
loadImageFromDevice(event) {
const files = event.target.files;
const blobReader = new FileReader();
files.forEach(file => {
blobReader.readAsArrayBuffer(file);
blobReader.onload = () => {
let blob: Blob = new Blob([new Uint8Array((blobReader.result as ArrayBuffer))]);
let blobURL: string = URL.createObjectURL(blob);
this.myImages.push(blobURL);
};
blobReader.onerror = (error) => {
console.log(error);
};
})
};
I am facing same issue
use this code to choose file in Ionic HTML
<ion-input type="file" (change)="changeListener($event)"></ion-input>
Ts file
changeListener(event) {
var reader = new FileReader();
reader.readAsDataURL(event.target.files[0]);
reader.onload = (_event) => {
this.imgURL = reader.result;
//base64 image
console.log("Image File =>", this.imgURL);
}
}
Then make file controller array and make one button to increase it then you can make multiple file controls to handle and upload to server.
check this for reference
http://masteringionic.com/blog/2018-02-06-dynamically-add-and-remove-form-input-fields-with-ionic/
Related
Accepting image uploads from a paste into the browser window is much easier than traditional file upload form inputs and even the newer style drag 'n' drop file uploads.
How do I implement it?
Here's an example PHP/JavaScript page that accepts drag 'n' drop image uploads. It's not dependent on PHP though - you could adapt it quite easily to work with another server-based language. This code was based on a snippet I found on jsFiddle by someone called Nick.
This is a full page - so you should be able to copy the code below and put it in a file on your web-server as-is (if you're not running PHP then you'll need to update the PHP code at the top or point the form to your own form handler script).
<?php
if (!empty($_POST)) {
// Handle the POSTed data here - the image is actually base64 encoded data in
// the $_POST['myTextarea'] variable which you can run through the base64_decode()
// function and then write to a file
$pos = strpos($_POST['myTextarea'], 'base64,');
$encoded = substr($_POST['myTextarea'], $pos + 7);
$raw = base64_decode($encoded);
// Show the base64 encoded $data - use the $raw variable when writing to a file
var_dump($_POST);
exit;
}
?>
<!DOCTYPE html >
<html>
<body>
<h1>File upload using paste</h1>
<p>
You can paste an image, which is on your clipboard, into this window and it will appear below.
If you use Windows you can press <b>PrtScr</b> to get a screenshot on your clipboard. Then
press <b>CTRL+V</b> to paste it into this document.
</p>
<!-- PUT THE ADDRESS OF YOUR FORM HANDLER SCRIPT IN THE ACTION ATTRIBUTE -->
<form action="" method="post">
<div id="form-elements-container">
<input type="text" value="An example text input..." name="myTextInput"><br />
<input type="submit" value="Submit form"><br />
</div>
</form>
<!-- THIS IS WHERE THE IMAGE THUMBNAILS WILL APPEAR -->
<div id="images-container"></div>
<script>
counter = 0;
document.body.onpaste = function (e)
{
// use event.originalEvent.clipboard for newer chrome versions
var items = (e.clipboardData || e.originalEvent.clipboardData).items;
// Find pasted image among pasted items
var blob = null;
for (var i=0; i<items.length; i++) {
if (items[i].type.indexOf("image") === 0) {
blob = items[i].getAsFile();
}
}
// Load image if there is a pasted image
if (blob !== null) {
var reader = new FileReader();
reader.onload = function(e)
{
// Create a new image object from the pasted data
var img = new Image();
img.src = e.target.result;
img.width = 128;
img.height = 128;
img.style.margin = '5px';
// Append the file to the document
document.getElementById('images-container').appendChild(img);
// Add a new textarea to the form
var textarea = document.createElement('textarea');
textarea.name = 'myTextarea_' + counter++;
textarea.value = img.src;
textarea.style.width = '200px';
textarea.style.height = '200px';
document.getElementById('form-elements-container').appendChild(textarea);
};
reader.readAsDataURL(blob);
}
}
</script>
</body>
</html>
I'd like to use form.io in order to allow my admin users to create a new forms but I want save all data into my database, not in form.io platform. Is it possible?
I want use form builder but at save time I want save the form structure into my database.
I don't understand if this option is possible.
Thanks
Yes.
Step 1: Store your components in your database. If you use the form builder, you can get them by a call to builder.schema.
Step 2: Retrieve your components from your database and render the form.
Step 3: Save the data to your DB.
components = {{component string from DB}}
let formio = new Formio.createForm(document.getElementById(element),
components,
{
saveDraft: true,
readOnly: ((readonly) ? readonly : false)
}
).then(function (form) {
if (data) {
var subm = JSON.parse(data)
form.submission = { data: subm };
}
form.on('submit', function (submission) {
//Submission Code
});
form.on('change', function (x) {
//Change Code
})
form.on('error', (errors) => {
//Error Code
})
form.on("render", function () {
//Any Render Overrides?
})
}).catch(function (ex) {
});
Some of this stuff is well documented. Some - not so much. Lots of trial and error. (Mostly error).
Something similar is what works for me. Note this is for saving the schema for the Form Builder. This schema can be deserialized and used as a source for the Form Renderer
#uglyCodeSry
JavaScript
var form;
var formTemplateToSave; // this is the serialized form template to save
window.onload = function() {
var builder = Formio.builder(document.getElementById('builder'), {}, {builder: {}
}).then((_form) => {
form = _form;
form.on('change', function(payload) {
formTemplateToSave = JSON.stringify(form.schema, null, 4);
});
formTemplateToSave = JSON.stringify(form.schema, null, 4);
});
};
HTML
<div>
<div id='builder'></div>
</div>
Don't forget to include the libraries (as well as your usual jquery stuff)
<link rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://cdn.form.io/formiojs/formio.full.min.css'>
<script src='https://cdn.form.io/formiojs/formio.full.min.js'></script>
You can then save the formTemplateToSave variable as the JSON to rehydrate your forms
I'm connecting ionic application with MySql database using PHP, all functionalities are working fine but when i upload data in database it is taking atleast hour of time for data updation in ionic application, Please find sample code for the same:
I havent used any sessions and when loading component every time will fire request to fetch data from dabase using PHP, tried placing ngZone but still issue remains same.
this.zone.run(() => {
this.http
.get('http://localhost:8100/dbcon/retreive-monthcircular.php')
.subscribe((monthdata : any) =>
{
console.dir(monthdata);
this.loadData = false;
this.circularmonthdata = monthdata;
if (this.circularmonthdata == null) {
this.displayCircular = false;
} else {
this.displayCircular = true;
}
},
(error : any) =>
{
console.dir(error);
});
});
Ideally Application should dynamically update
Look at this example
HTML :
<ion-item>
<ion-label>Date</ion-label>
<ion-datetime displayFormat="DD/MM/YYYY" pickerFormat="DD/MM/YYYY" [(ngModel)]="myDate"></ion-datetime>
</ion-item>
<button ion-button block (click)="getData(myDate)">Get Data</button>
Bellow is your current data from array we created.
<ion-item *ngFor="let data of fetchedData">
Date: {{data.date}} - Description: {{data.description}}
</ion-item>
your TS:
fetchedData = [ // suppose your data looks like this
{
date: '20-02-1990',
description: 'this is First date'
},
{
date: '21-03-1991',
description: 'this is Second date'
}
]
getData(myDate){
this.headers = {'Content-Type': 'application/json'};
this.http.get('http://localhost:8100/dbcon/retreive-monthcircular.php', {headers: this.headers})
.map(res => res.json())
.subscribe(data => {
console.log(data);
this.fetchedData = data.data; // update your variable it will update data on your view.
});
}
by clicking on this function will update your data at DOM. Or you should post your HTML and fetched Data from server.
I observed that the Native File has not been supported by the Ionic View anymore see list here.
I am trying to get a video from my library by using Native Camera to access the videos. It can return me 3 different formats of path to my videos (DATA_URL, FILE_URI, and NATIVE_URI).reference to Native Camera here
I am currently using FILE_URI as recommended in this post. It returns something like "/storage/emulated/0/DCIM/Camera/VID_20180312_210545.mp4"
Please have a look at my code below. Aiming a better understanding, the current behavior is highlighted by comments with "//** comment ***" :
addVideoToOffer(){
this.platform.ready().then(() =>{
const options: CameraOptions = {
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
destinationType: this.camera.DestinationType.FILE_URI,
mediaType: this.camera.MediaType.VIDEO,
}
this.camera.getPicture(options).then((data_uri) => {
this.readVideoFileasGeneral(data_uri);
});
});
}
readVideoFileasGeneral(data_uri) {
if(!data_uri.includes('file://')) {
data_uri = 'file://' + data_uri;
}
return this.file.resolveLocalFilesystemUrl(data_uri)
.then((entry: FileEntry) => {
//***it does not get in here***
this.presentQuickToastMessage(data_uri);
return new Promise((resolve)=>{//, reject) => {
entry.file((file) => {
let fileReader = new FileReader();
fileReader.onloadend = () => {
let blob = new Blob([fileReader.result], {type: file.type});
resolve({blob: blob, file: file});
};
fileReader.readAsArrayBuffer(file);
});
})
})
.catch((error) => {
this.presentQuickToastMessage(error);
//***it presents "plugin_not_installed" here***
});
}
I understand that I am having this message because Native File is not supported anymore (maybe reason of the plugin_not_installed message). However, I still have to do this task. So, if someone has any idea of what I could be using in order to have the selected videos in a blob, it would be great!
Thanks for reading until here,
Cheers,
Roger A L
makeFileIntoBlob(uri) {
// get the correct path for resolve device file system
let pathIndex = uri.indexOf('var');
let correctPath = uri.slice(+pathIndex);
this.file
.resolveLocalFilesystemUrl((this.platform.is('ios') ? 'file:///' : '') + correctPath)
.then(entry => (<FileEntry>entry).file(file => this.readFile(file)))
.catch(err => console.log('ERROR: ', err));
}
readFile(file) {
if(file) {
const reader = new FileReader();
reader.onloadend = () => {
const blob: any = new Blob([reader.result], { type: file.type });
blob.name = file.name;
console.log(blob);
return blob;
};
reader.readAsArrayBuffer(file);
}
}
You need to get rid of the /private/ and keep file:///, so that your path goes like file:///var/
I'm currently working on something similar.. I have the video recorded with media-capture and then I can display it within a normal video html tag.. if this is all you need then this code may help you...
this.mediaCapture.captureVideo({duration: 10, quality: 0}).then(
(data: MediaFile[]) => {
if (data.length > 0) {
let originname = data[0].fullPath.substr(data[0].fullPath.lastIndexOf('/') + 1);
let originpath = data[0].fullPath.substr(0, data[0].fullPath.lastIndexOf('/') + 1);
let alerta = this.alerts.create({
buttons: ['ok'],
message: this.file.externalDataDirectory
});
alerta.then(set => set.present());
this.file.copyFile(originpath, originname, this.file.externalDataDirectory, 'video.mp4')
.then(result =>{
let videopath = this.webview.convertFileSrc(result.nativeURL)
let video = (document.getElementById('myvideo') as HTMLVideoElement).src = videopath;
.... rest of the code
The problem raise when you try to use the native File plugin... converting files with any method (readAsDataURL, readAsArrayBuffer or readAsBinaryString) will never resolve, this is a known problem with the Ionic Native File plugin but is not taken care of...
What I did is to take the ionic native Filesystem and use it to read the file, this does read the file and get you with a base64 (pretty sure as I don't specify the encoding field) and then you can handle it the way you want...
const data = Filesystem.readFile({
path: result.nativeURL
})
.then(data =>{
...handle data as base64
...rest of the code
I am able to upload images from my desktop to an Angular based Web Application overlayed on SharePoint without issue, but if I upload from a Mobile phone, such as an iPhone, using the take "Take Photo or Video" or "Photo Library" function, it causes the image to be sideways when taken in portrait or upside down when taken in landscape. Here is my current upload function. Any clues/have others had the same issues uploading to Mobile Web Applications from iPhones/Mobile Phones to a SharePoint library?
Here is my upload function:
// Upload of images
$scope.upload = function () {
//console.log($scope.files);
if (document.getElementById("file").files.length === 0) {
alert('No file was selected');
return;
}
var parts = document.getElementById("file").value.split("\\");
var uploadedfilename = parts[parts.length - 1];
var basefilename = uploadedfilename.split(".")[0];
var fileextension = uploadedfilename.split(".")[1];
var currentdate = new Date();
var formatteddate = $filter('date')(new Date(currentdate), 'MMddyy-hmmssa');
var filename = basefilename + formatteddate + '.' + fileextension;
var file = document.getElementById("file").files[0];
uploadFileSync("/sites/asite", "Images", filename, file);
}
//Upload file synchronously
function uploadFileSync(spWebUrl, library, filename, file)
{
console.log(filename);
var reader = new FileReader();
reader.onloadend = function(evt)
{
if (evt.target.readyState == FileReader.DONE)
{
var buffer = evt.target.result;
var completeUrl = spWebUrl
+ "/_api/web/lists/getByTitle('"+ library +"')"
+ "/RootFolder/Files/add(url='"+ filename +"',overwrite='true')?"
+ "#TargetLibrary='"+library+"'&#TargetFileName='"+ filename +"'";
$.ajax({
url: completeUrl,
type: "POST",
data: buffer,
async: false,
processData: false,
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"content-length": buffer.byteLength
},
complete: function (data) {
console.log(data);
},
error: function (err) {
alert('failed');
}
});
}
};
reader.readAsArrayBuffer(file);
}
The output of these is just pushed into an array for use in an Angular UI Carousel:
// Control of Image Carousel
$scope.myInterval = 0;
// Population of carousel
$scope.slides = [];
appImages.query({
$select: 'FileLeafRef,ID,Created,Title,UniqueId',
$filter: 'ReportId eq ' + $routeParams.Id + ' and DisplayinReport eq 1',
}, function (getimageinfo) {
// Data is within an object of "value"
var image = getimageinfo.value;
// Iterate over item and get ID
angular.forEach(image, function (imagevalue, imagekey) {
$scope.slides.push({
image: '/sites/asite/Images/' + imagevalue.FileLeafRef,
});
});
});
The image carousel is on page as follows:
<div style="height: 305px; width: 300px">
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;height:300px">
<div class="carousel-caption">
<h4>Slide {{$index}}</h4>
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
</div>
IMPORTANT: The images are sideways and upside down upon upload to the SharePoint library, so irrespective of outputting them, they seem to be misoriented when they hit the destination library I am using as a source to display on page.
How do I upload the images so SharePoint respects the EXIF data/orientation?
It may be related to EXIF. See JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images
If you want a better answer, we will need the code which show the image, and the code server side.
UPDATE : I'm not an expert at all on SharePoint, but you can found a lot about it in the SharePoint Stack Exchange. For example, https://sharepoint.stackexchange.com/questions/131552/sharepoint-rotating-pictures-in-library, should do the trick.
To sum up a little : in your case, their could be a lot of cases to study. So, I recommended you auto-correct the exif, and then permit to your user to correct it if the auto-correct was wrong. Their is a lot of tools to do that. If you want to do it server-side, look at the link above, and if you want to do it on the client side, you could use JS-Load-Image for example.