sapui5 how to read PDF file content in controller - sapui5

Im facing an issue in PDF File Uploading..
In the above Screenshot if you see, When im trying to upload a PDF file, Im not able to read the content in that pdf file.
My requirement is like, I need to get the content as String from that file and that content i need to send to back-end server..
Im getting below error if im trying to read the content
HTTP Status 405 - Bad Method
Below is my Code ..
Im using xmlns:u="sap.ui.unified" library
<u:FileUploader id="fileUploader" name="myFileUpload" tooltip="Upload Service Sheet"
uploadComplete="handleUploadComplete" change="handleValueChange" typeMissmatch="handleTypeMissmatch" style="Emphasized" fileType="pdf"
placeholder="Choose a file for Upload..." maximumFileSize="2000" mimeType="pdf" buttonText="Upload">
</u:FileUploader>
handleUploadComplete: function(oEvent) {
var fileName = oEvent.getSource().getProperty("value");
var sResponse = oEvent.getParameter("response");
if (sResponse) {
var sMsg = "";
var m = /^\[(\d\d\d)\]:(.*)$/.exec(sResponse);
if (m[0] == "200") {
sMsg = "Return Code: " + m[0] + "(Upload Success)";
oEvent.getSource().setValue("");
} else {
sMsg = "Return Code: " + m[0] + "(Upload Error)";
}
MessageToast.show(sMsg);
}
},
Can some one please help me how can i read the data in the PDF??
Thank you in advance

Take a look at this example. Hope this helps.
View
<u:FileUploader change="onChange" fileType="pdf" mimeType="pdf" buttonText="Upload" />
Controller
convertBinaryToHex: function(buffer) {
return Array.prototype.map.call(new Uint8Array(buffer), function(x) {
return ("00" + x.toString(16)).slice(-2);
}).join("");
},
onChange: function(oEvent){
var that = this;
var reader = new FileReader();
var file = oEvent.getParameter("files")[0];
reader.onload = function(e) {
var raw = e.target.result;
var hexString = that.convertBinaryToHex(raw).toUpperCase();
// DO YOUR THING HERE
};
reader.onerror = function() {
sap.m.MessageToast.show("Error occured when uploading file");
};
reader.readAsArrayBuffer(file);
},

Related

Issue trying to change a loaded PDF in the embed

I'm using the Adobe PDF Embed API and can successfully display a PDF after a user selection. When my app starts up, I initialize a DC View object:
let dcView = new AdobeDC.View({
clientId: ADOBE_KEY,
divId: div
});
And after a user has dragged a file, I use a file reader to to throw a promise at it:
let reader = new FileReader();
let name = this.pdfFile.name;
reader.onloadend = function(e) {
let filePromise = Promise.resolve(e.target.result);
dcView.previewFile({
content: { promise: filePromise },
metaData: { fileName: name }
});
};
reader.readAsArrayBuffer(this.pdfFile);
This works perfectly... once. If I drag a file again, when it gets to the render portion, only the filename on top of the embed changes, not the actual rendered contents.
You'll need to recreate the AdobeDC.View object prior to loading a new document. I'm guessing that this is because there may be unresolved Promises if an operation takes a while to resolve like loading annotations or performing a search. Your new code might look like this...
let reader = new FileReader();
let name = this.pdfFile.name;
reader.onloadend = function(e) {
let filePromise = Promise.resolve(e.target.result);
let dcView = new AdobeDC.View({
clientId: ADOBE_KEY,
divId: div
});
dcView.previewFile({
content: { promise: filePromise },
metaData: { fileName: name }
});
};
reader.readAsArrayBuffer(this.pdfFile);

Protractor upload stuck when filesearch pops up

I'm trying to figure out what's wrong with the code below:
it('should upload a photo', function(){
var photo = './photos/et-test.jpeg',
exactPhoto = path.resolve(__dirname, photo);
var form = element(by.id('fileupload'));
var upload = element(by.css('input[type = "file"]'));
var addFiles = element(by.cssContainingText('.btn.btn-success.fileinput-button.mb-10','Add files...'));
var uploadBtn = element(by.css('.btn.btn-primary.start.mt-20'));
element(by.cssContainingText('.inline_link','Upload more album photos now')).click();
element(by.id('secondary_upload_link')).click();
browser.wait(EC.visibilityOf(addFiles), 5000);
addFiles.click();
upload.sendKeys(exactPhoto);
browser.wait(EC.visibilityOf(uploadBtn), 5000);
uploadBtn.click();
expect(element(by.css('.table')).getText()).toBe('Upload Finised');
});
I keep getting stuck on the filesearch popup and receive this error:
Message:
Failed: Wait timed out after 5006ms
Is there anything lacking or should've been done based on the flow of my code?
If I'm understanding your issue correctly you are seeing a popup window when uploading a file. Can you try the following capability in your conf (assuming you are using Chrome)
capabilities: {
browserName: 'chrome',
chromeOptions: {
prefs: {
download: {
'prompt_for_download': false,
'directory_upgrade': true,
'default_directory': 'src/test/javascript/e2e/downloads'(or where ever you prefer)
}
}
}
}
Yes, you don't need to click on it, just sendKeys() for this input element
Sometimes it needs to make this input visible. Just try like that (it works in my case for await/async protractor):
private addAttachment = element(by.css('input[type="file"]'))
await browser.executeScript("arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1; arguments[0].style.display = 'inline'; arguments[0].style.overflow = 'visible'", this.addAttachment)
await browser.executeScript("arguments[0].focus();", await this.addAttachment.getWebElement())
await this.addAttachment.sendKeys(path)
Try this:
var photo = './photos/et-test.jpg',
exactPhoto = path.resolve(__dirname, photo);
var form = element(by.id('fileupload')); ///Users/leochardc/ET/photos/et-test.jpg
var upload = element(by.css('.fileupload_section input[type = "file"]'));
var addFiles = element(by.cssContainingText('.btn.btn-success.fileinput-button.mb-10','Add files...'));
var uploadBtn = element(by.css('.btn.btn-primary.start.mt-20'));
var uploadFinished = element(by.css('.fileupload_section .text-center p'));
browser.get(url);
element(by.cssContainingText('.inline_link','Upload more album photos now')).click();
element(by.id('secondary_upload_link')).click();
browser.wait(EC.visibilityOf(addFiles), 5000);
// addFiles.click();
upload.sendKeys(exactPhoto);
var previewPic = element(by.css('.fileupload_section.fileupload_files'));
browser.wait(EC.visibilityOf(previewPic), 5000);
browser.wait(EC.visibilityOf(uploadBtn), 5000);
uploadBtn.click();
browser.wait(EC.visibilityOf(uploadFinished), 30000);
expect(uploadFinished.getText()).toBe('Upload Finished');

Cannot read property 'download' of undefined $cordovaFileTransfer in Ionic

I want to use $cordovaFileTransfer in my app to dowload image data, but after trying to implement the code, this error is showing up:
Cannot read property 'download' of undefined
here is my code:
var url = "blablabla.com/img.png";
var targetPath = "img/"+ imgpaths;
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
// Success!
console.log('Download Success' + targetPath);
}, function(err) {
// Error
}, function (progress) {
$timeout(function () {
var downloadProgress = (progress.loaded / progress.total) * 100;
console.log('Progress : '+downloadProgress);
});
});
anybody can help me?
Check this issues list:
http://ngcordova.com/docs/common-issues/
For example have you wrapped the call to $cordovaFileTransfer.download() inside deviceready handler or better inside $ionicPlatform.ready() ?

Chrome App FileReader

I'm trying to make use of the file system API in a Chrome App. I've tried all the sample code I can find and can't get a simple text file to read. I'm logging almost every step, and what seems to happen (or not happen) is everything stops the first time I reference a file reader object. It creates just fine, because I can log the .readyState, but after that I can't seem to even set an onload()event or execute a .readAsText().
Here's what I'm calling from a button:
function clickButton(){
chrome.fileSystem.chooseEntry({type: 'openFile', acceptsMultiple: false}, function(FileEntry){
if(chrome.runtime.lastError) {console.warn("Warning: " + chrome.runtime.lastError.message);}
else{
console.log(FileEntry);
var thing = new FileReader();
console.log(thing.readyState);
thing.onloadstart(function(){
console.log("Started loading " & FileEntry);
});
console.log("added onloadstart");
console.log(thing.readyState);
console.log(thing);
thing.readAsText(FileEntry);
console.log(thing.readyState);
console.log(thing.result);
}
});
document.getElementById("status").innerHTML = "I did something";
}
I did read somewhere that Chrome doesn't allow access to local files, but the chrome apps seem to be different. At least, the documentation seems to suggest that.
The only thing I end up with in my console is the FileEntry object.
https://developer.chrome.com/apps/app_storage#filesystem
I've used the example code right from the above link and still can't get it right. Anyone else have this issue or know what I'm doing wrong?
There is a difference between a FileEntry and a File. You need to call FileEntry's .file() method. So, replace
thing.readAsText(FileEntry);
with
FileEntry.file(function(File) {
thing.readAsText(File)
})
https://developer.mozilla.org/en-US/docs/Web/API/FileEntry#File
Try this code...
<!doctype html>
<html>
<script>
function handle_files(files) {
for (i = 0; i < files.length; i++) {
file = files[i]
console.log(file)
var reader = new FileReader()
ret = []
reader.onload = function(e) {
console.log(e.target.result)
}
reader.onerror = function(stuff) {
console.log("error", stuff)
console.log (stuff.getMessage())
}
reader.readAsText(file) //readAsdataURL
}
}
</script>
<body>
FileReader that works!
<input type="file" multiple onchange="handle_files(this.files)">
</body>
</html>
I've written a function to extract text from a file.
function getFileEntryText(fileEntry) {
return new Promise(function (resolve, reject) {
fileEntry.file(function (file) {
var fileReader = new FileReader();
fileReader.onload = function (text) {
resolve(fileReader.result);
};
fileReader.onerror = function () {
reject(fileReader.error);
};
fileReader.readAsText(file);
});
});
}
You can invoke this method like so:
getFileEntryText(fileEntry).then(function(text) {
// Process the file text here
}, function(error) {
// Handle the file error here
});
One thing I'm grappling with when working with the FileSystem is that every call is asynchronous. Having multiple levels of nested callbacks can make for code that's hard to read. I'm currently working around this by converting everything I can to a Promise.
for anyone who is interested, here's my final (working) code, complete with all the console.log()'s I needed to follow all those callbacks.
var chosenEntry = null;
function clickButton(){
console.log("Button clicked");
var accepts = [{
mimeTypes: ['text/*'],
extensions: ['js', 'css', 'txt', 'html', 'xml', 'tsv', 'csv', 'rtf']
}];
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(theEntry) {
if (!theEntry) {
output.textContent = 'No file selected.';
return;
}
// use local storage to retain access to this file
chrome.storage.local.set({'chosenFile': chrome.fileSystem.retainEntry(theEntry)});
console.log("local data set. calling loadFileEntry");
loadFileEntry(theEntry);
console.log("loadFileEntry called, returned to clickButton()");
});
}
function loadFileEntry(_chosenEntry) {
console.log("entered loadFileEntry()");
chosenEntry = _chosenEntry;
chosenEntry.file(function(file) {
readAsText(chosenEntry, function(result) {
console.log("running callback in readAsText");
document.getElementById('text').innerHTML = result;
console.log("I just tried to update textarea.innerHTML");
});
});
console.log("added function to chosenEntry.file()");
}
function readAsText(fileEntry, callback) {
console.log("readAsText called");
fileEntry.file(function(file) {
var reader = new FileReader();
console.log("Created reader as FileReader");
reader.onload = function(e) {
console.log("called reader.onload function");
callback(e.target.result);
};
console.log("calling reader.readAsText");
reader.readAsText(file);
});
}

Titanium: can't switch tabs, close tabs, anything other than my current tab

Everything I try just does nothing, no errors, message, really anything. So I have three tabs, the first being a login tab, each tab has its own .js code, so for example, the login has its own login.js. Now, I use the httpClient to authenticate back to our website, and now want to remove the login tab and display the other tabs, cannot get it to work for the life of me, I can now remove the login tab but cannot load ay of the other tabs. Driving me nuts because I am finding 20 examples but they either don't separate the tabs into their own .js files or the example just plain doesn't work for me. Help! This seems so basic but yet...
app.js
// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#000');
// create tab group
var tabGroup = Titanium.UI.createTabGroup();
// create base UI tab and root window
//
var scan = Titanium.UI.createWindow({
title:'Scan',
backgroundColor:'#fff',
url:'scan.js',
mylabel:'Hello Scan'
});
var tab1 = Titanium.UI.createTab({
icon:'KS_nav_views.png',
title:'Scan',
window:scan
});
var login = Titanium.UI.createWindow({
title:'User Authentication',
tabBarHidden:true,
url:'login.js'
});
var loginTab = Titanium.UI.createTab({
title:"Login",
window:login
});
//
// create controls tab and root window
//
var win2 = Titanium.UI.createWindow({
title:'Manual',
backgroundColor:'#fff'
});
var tab2 = Titanium.UI.createTab({
icon:'KS_nav_ui.png',
title:'Manual',
window:win2
});
var label2 = Titanium.UI.createLabel({
color:'#999',
text:'I am Manual Window ',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
win2.add(label2);
//
// add tabs
//
tabGroup.addTab(loginTab);
tabGroup.addTab(tab1);
tabGroup.addTab(tab2);
// open tab group
tabGroup.open();
login.js
var win = Titanium.UI.currentWindow;
var tabGroup = Ti.UI.currentWindow.tabGroup;
var appUrl = "http://localhost:3001/ticket_agents/sign_in";
var email = Titanium.UI.createTextField({
color:'#336699',
top:10,
left:10,
width:300,
height:40,
hintText:'Email',
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(email);
var password = Titanium.UI.createTextField({
color:'#336699',
top:60,
left:10,
width:300,
height:40,
hintText:'Password',
passwordMask:true,
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(password);
var loginBtn = Titanium.UI.createButton({
title:'Login',
top:110,
width:90,
height:35,
borderRadius:1,
font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14}
});
var loginReq = Titanium.Network.createHTTPClient({
onload : function(e) {
var json = this.responseText;
var response = JSON.parse(json);
Ti.API.info("Received text: " + this.responseText);
if (response.id > 0)
{
alert("login Success");
win.tabGroup.close();
tabGroup.removeTab(loginTab);
tabGroup.setActiveTab(2);
tabGroup.open();
}
else
{
alert("Unknown login error");
}
},
onerror : function(e) {
var response = this.responseText;
Ti.API.debug(e.error);
alert('error: ' + this.responseText);
},
timeout : 5000
});
loginBtn.addEventListener('click',function(e)
{
if (email.value != '' && password.value != '')
{
loginReq.open("POST",appUrl);
var params = {ticket_agent: {email: email.value, password: password.value, remember_me: 0}
};
var authstr = 'Basic ' + Titanium.Utils.base64encode(email.value + ':' + password.value);
loginReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
loginReq.setRequestHeader('Authorization', authstr);
loginReq.send(JSON.stringify(params));
}
else
{
alert("Email/Password are required");
}
});
win.add(loginBtn);
I think that's all you'd need to see, the login.js has my latest attempt but I've tried things like tabGroup.open({url : 'app.js'}) and about three our four other option. Thanks.
You may want to add this eventListener to your app.js where the tabGroup is.
You can then fire a "app:gotoTab" event from anywhere.
app.js
Ti.App.addEventListener('app:gotoTab', function(e) {
tabGroup.setActiveTab(e.tab);
});
login.js
// tab index starts with 0, so 0 is your first tab
Ti.App.fireEvent('app:gotoTab', { tab: 0 });
Simply Copy paste this code
Login.js
var win = Titanium.UI.currentWindow;
var appUrl = "http://localhost:3001/ticket_agents/sign_in";
var email = Titanium.UI.createTextField({
color:'#336699',
top:10,
left:10,
width:300,
height:40,
hintText:'Email',
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(email);
var password = Titanium.UI.createTextField({
color:'#336699',
top:60,
left:10,
width:300,
height:40,
hintText:'Password',
passwordMask:true,
keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(password);
var loginBtn = Titanium.UI.createButton({
title:'Login',
top:110,
width:90,
height:35,
borderRadius:1,
font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14}
});
var loginReq = Titanium.Network.createHTTPClient({
onload : function(e) {
var json = this.responseText;
var response = JSON.parse(json);
Ti.API.info("Received text: " + this.responseText);
if (response.id > 0)
{
alert("login Success");
tabGroup.setActiveTab(2);
}
else
{
alert("Unknown login error");
}
},
onerror : function(e) {
var response = this.responseText;
Ti.API.debug(e.error);
alert('error: ' + this.responseText);
},
timeout : 5000
});
loginBtn.addEventListener('click',function(e)
{
if (email.value != '' && password.value != '')
{
loginReq.open("POST",appUrl);
var params = {ticket_agent: {email: email.value, password: password.value, remember_me: 0}
};
var authstr = 'Basic ' + Titanium.Utils.base64encode(email.value + ':' + password.value);
loginReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
loginReq.setRequestHeader('Authorization', authstr);
loginReq.send(JSON.stringify(params));
}
else
{
alert("Email/Password are required");
}
});
win.add(loginBtn);
Hey Ross, You always remember window.close work on child Window perfectly.
In this application. You can use single Window base Application.
If, In First Window Login Successfully then, you can OPEN Second child Window.
for more details you can use KICHEN Shink Example. this is very useful for You.
You may want to redesign your UI. The Apple Human Interface Guidelines specifically say that you shouldn't programmatically switch tabs or add/remove tabs. They expect that a tabgroup should only be controlled by the user once you put it in front of them.
If the user needs to log in before they can use other features of your app you can present the a login window before the window with the tab group. Otherwise, you should replace the content of the login tab with something else after a successful login, perhaps with user profile information or some instructions.