HTML code:
<form id="pdfForm" class="display-inline" method="POST" action="{{document.PdfActionUrl}}">
<button uib-tooltip="Download PDF" type="submit" ng-disabled="document.CaseStudies.length == 0" class="uui-button button-action"><span class="icons-action icon-action-load"></span></button>
</form>
AngularJS code:
$scope.jsonToDoc = function (doc) {
document.PdfActionUrl = '/odata/DocumentsApi(' + document.Id + ')/API.DownloadPdf';
The server side code:
public HttpResponseMessage DownloadPdf([FromODataUri] Guid key)
{
var document = _documentService.GetPdfDocument(key, Request.RequestUri.BaseUri(System.Configuration.ConfigurationManager.AppSettings["setting"]));
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new StreamContent(document.Content);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = document.Name
};
return response;
}
I'm not sure what approach best fits to this case and how to calculate downloading real time.
Related
I want to register data in a Google Sheet from a ReactJS form (2 fields if the user has possible suggestion or comments).
This is my feedback form in React :
import React,{useState,useEffect} from 'react';
import './App.css';
const formUrl = 'https://script.google.com/macros/s/AK.../exec'
export default function FrmTable(){
const [loading,setLoading] = useState(false)
return(
<div className="section-form">
<form name="frm"
method="post"
action={formUrl}
>
<div className="form-elements">
<div className="pure-group">
<label className="pure-group-label">Suggestion content pdf</label>
<input id="Suggestion content pdf" name="Suggestion content pdf" className="pure-group-text"
type="text"
/>
</div>
<div className="pure-group">
<label className="pure-group-label" >Comments</label>
<textarea id="Comments" name="Comments" rows="10" className="pure-group-text"
placeholder=""
maxLength="1000"
></textarea>
</div>
</div>
<p className="loading-txt">{loading == true ? 'Loading.....' : ''}</p>
<div className="pure-group pure-group-btn">
<button className="button-success pure-button button-xlarge btn-style" >Send</button>
</div>
</form>
</div>
)
}
The GSheet script in order to register the suggestion content and comments :
var SHEET_NAME = "Feedback";
// 2. Run > setup
// 3. Publish > Deploy as web app
// - enter Project Version name and click 'Save New Version'
// - set security level and enable service (most likely execute as 'me' and access 'anyone, even anonymously)
// 4. Copy the 'Current web app URL' and post this in your form/script action
//
// 5. Insert column names on your destination sheet matching the parameter names of the data you are passing in (exactly matching case)
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
// If you don't want to expose either GET or POST methods you can comment out the appropriate function
function doGet(e){
return handleResponse(e);
}
function doPost(e){
return handleResponse(e);
}
function handleResponse(e) {
// shortly after my original solution Google announced the LockService[1]
// this prevents concurrent access overwritting data
// we want a public lock, one that locks for all invocations
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp(Date)' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
Everything works fine I can register the 2 fields(suggestion and comment) in the GSheet but I would like to have another view after submiting
I've followed some tutorials because I'm new into React. At the end after submiting you are sent to script.googleusercontent.... because in the GSheet script we have this code
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
I want just to show a simple message like a popup in order to say the submit form is ok. Any idea is welcomed :) thank you very much.
New Edit : I've changed my code (React + Google Script) but I have an CORB blocked cross-origin.
import React,{useState,useEffect} from 'react';
import './App.css';
const formUrl = 'https://script.google.com/macros/s/AKfycbz4hMELOHff2Yd_ozpOid2cAWFSWPm_7AOD15OIeQRdYrocv0wa/exec'
export default function FrmTable(){
const jsonp = (url, callback) => {
var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
window[callbackName] = function(data) {
alert("Formulaire envoyé ");
delete window[callbackName];
document.body.removeChild(script);
callback(data);
};
var script = document.createElement('script');
script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
document.body.appendChild(script);
}
const mySubmitHandler = (event) => {
event.preventDefault();
jsonp(formUrl + '?La+FAQ+en+question=' + encodeURIComponent(faqName), (data) => {
// alert(data);
});
event.target.reset();
}
// const { register, errors, required ,handleSubmit } = useForm();
const [loading,setLoading] = useState(false)
const [faqName,setFaqName] = useState('')
const myChangeHandler1 = (event) => {
setFaqName(event.target.value);
}
return(
<div className="section-form" >
<form name="frm"
method="post"
onSubmit={mySubmitHandler}
>
<div className="form-elements">
<div className="pure-group ">
<label className="pure-group-label">La FAQ en question </label>
<input name="FAQ en question" className="pure-group-text"
type="text" onChange={myChangeHandler1}
/>
</div>
</div>
<input type='submit' />
</form>
</div>
)
}
The Google Script :
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
// If you don't want to expose either GET or POST methods you can comment out the appropriate function
function doGet(e){
return handleResponse(e);
}
function doPost(e){
//return handleResponse(e);
}
function handleResponse(e) {
// shortly after my original solution Google announced the LockService[1]
// this prevents concurrent access overwritting data
// [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
// we want a public lock, one that locks for all invocations
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp(Date)' column
row.push(new Date());
} else { // else use header name to get data
row.push(e.parameter[headers[i]]);
}
}
// more efficient to set values as [][] array than individually
sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
var callback = e.parameter.callback;
// return json success results
// return ContentService
// .createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
// .setMimeType(ContentService.MimeType.JSON);
return ContentService.createTextOutput(callback+'('+ JSON.stringify({"result":"success", "row": nextRow})+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
} catch(error){
// if error return this
//return ContentService
// .createTextOutput(JSON.stringify({"result":"error", "error": e}))
// .setMimeType(ContentService.MimeType.JSON);
var callback = e.parameter.callback;
return ContentService.createTextOutput(callback+'('+ JSON.stringify({"result":"error", "error": error})+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
I would like to propose the following 2 patterns.
Modification points:
In the current stage, there is no getPublicLock().
In your shared Spreadsheet, there is only one sheet of Sheet2. But at var SHEET_NAME = "Feedback";, no sheet name is used. By this, var sheet = doc.getSheetByName(SHEET_NAME); is null and an error occurs at var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0].
At formUrl + "&Commentaires=" + encodeURIComponent(faqComment) in react side, in this case, the endpoint becomes https://script.google.com/macros/s/###/exec&Commentaires=test?callback=jsonp_callback_###.
Pattern 1:
In this pattern, your script is modified and JSONP is used.
React side: App.js
From:
jsonp(formUrl + "&Commentaires=" + encodeURIComponent(faqComment), data => {
// alert(data);
});
To:
jsonp(formUrl + "?Commentaires=" + encodeURIComponent(faqComment), data => {
// alert(data);
});
Google Apps Script side:
When you want to use your shared Spreadsheet, please modify as follows.
From:
var lock = LockService.getPublicLock();
To:
var lock = LockService.getDocumentLock();
And,
From:
var SHEET_NAME = "Feedback";
To:
var SHEET_NAME = "Sheet2";
In this case, you can also modify the sheet name from Sheet2 to Feedback instead of modifying the script.
Pattern 2:
In this pattern, your script is modified and fetch is used instead of JSONP. Because when above script is used, I could confirm that there is sometimes the error related to CORS. So as another pattern, I would like to propose to use fetch. When fetch is used, I could confirm that no error related to CORS occurs.
React side: App.js
From:
export default function FrmTable() {
const jsonp = (url, callback) => {
var callbackName = "jsonp_callback_" + Math.round(100000 * Math.random());
window[callbackName] = function(data) {
alert("Formulaire envoyé ");
delete window[callbackName];
document.body.removeChild(script);
callback(data);
};
var script = document.createElement("script");
script.src =
url + (url.indexOf("?") >= 0 ? "&" : "?") + "callback=" + callbackName;
document.body.appendChild(script);
};
const mySubmitHandler = event => {
event.preventDefault();
/* const request = new XMLHttpRequest();
const formData = new FormData();
formData.append("La FAQ en question", form.faqName);
formData.append("Suggestion contenu pdf", form.faqSuggest);
formData.append("Commentaires", form.faqComment);
request.open("POST", formUrl);
request.send(formData); */
jsonp(formUrl + "&Commentaires=" + encodeURIComponent(faqComment), data => {
// alert(data);
});
event.target.reset();
};
To:
export default function FrmTable() {
const mySubmitHandler = event => {
event.preventDefault();
fetch(formUrl + "?Commentaires=" + encodeURIComponent(faqComment))
.then(res => res.text())
.then(res => console.log(res))
.catch(err => console.error(err));
event.target.reset();
};
In this case, res.json() can be also used instead of res.text().
Google Apps Script side:
When you want to use your shared Spreadsheet, please modify as follows.
From:
var lock = LockService.getPublicLock();
To:
var lock = LockService.getDocumentLock();
And,
From:
var callback = e.parameter.callback;
return ContentService.createTextOutput(callback+'('+ JSON.stringify({"result":"success", "row": nextRow})+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
} catch(error){
var callback = e.parameter.callback;
return ContentService.createTextOutput(callback+'('+ JSON.stringify({"result":"error", "error": error})+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
} finally { //release lock
lock.releaseLock();
}
To:
return ContentService.createTextOutput(JSON.stringify({"result":"success", "row": nextRow})).setMimeType(ContentService.MimeType.JSON);
} catch(error){
return ContentService.createTextOutput(JSON.stringify({"result":"error", "error": error})).setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
And,
From:
var SHEET_NAME = "Feedback";
To:
var SHEET_NAME = "Sheet2";
In this case, you can also modify the sheet name from Sheet2 to Feedback instead of modifying the script.
Note:
When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script
Class LockService
Im trying to fetch photo of a particular userId which is stored in the database,
Im able to generate response from the API as shown:
but it is received in the error part of the getPhotopath() method of controller as shown:
HTML:
<div class="col-md-3 " ng-init="modifyphoto()" >
<img class="smaller" ng-src="fetchedimg" ng-model="fetchedimg"><br>
<p>{{userName}}</p>
<div ng-model="userType">
<p>{{userType | UserFilter}}</p>
</div>
<div ng-controller="AskController">
<button class="btn btn-default" ng-click="gotouserdetails()">View
My Details</button>
</div>
</div>
Controller:
$scope.modifyphoto = function() {
$scope.getPhotoPath();
if($scope.userPhoto==null){
$scope.fetchedimg=$scope.defaultimg;
}
else{
$scope.fetchedimg=$scope.userPhoto;
}
};
$scope.getPhotoPath = function() {
var obj = JSON.parse($cookies.get('user'));
$scope.passUserId = obj.userId;
$http.get(URI + "user/getphoto"+"/"+$scope.passUserId).then(
function(response) {
alert("hifrsegfsfgv");
alert(response.data.message);
$scope.userPhoto=response.data.userPhoto;
}, function(response) {
alert("hi");
alert(response.data);
$scope.userPhoto =null;
alert("danger"+response.data.userPhoto);
});
};
API:
#Path("getphoto/{an}")
#GET
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response getPhoto(#PathParam("an") String userId) throws Exception {
String returnValue = null;
Response response = null;
User user = null;
try {
System.out.println(userId);
UserService userService = Factory.createUserService();
String photoPath=userService.getPhotoPath(userId);
user = new User();
user.setUserPhoto(photoPath);
System.out.println(photoPath);
returnValue = JSONParser.toJson(user);
System.out.println(returnValue);
response = Response.status(Status.OK).entity(returnValue).build();
} catch (Exception e) {
String errorMessage = AppConfig.PROPERTIES.getProperty(e.getMessage());
User user1 = new User();
user1.setMessage(errorMessage);
String returnString = JSONParser.toJson(user1);
response = Response.status(Status.SERVICE_UNAVAILABLE).entity(returnString).build();
}
return response;
}
Im not understanding if the status is OK in backend then why it is recieved in the error part?
Try returning your image in base64 format to avoid JSON Parse errors. and bind that image to the img tag
Hello i will tell you step by step,what i did,
1.I have HTML page named ManualChargesListV2.html,when page loads need to load the data in the Dropdown,so i use thymeleaf to show...
Here is #Controller Code
#GetMapping(value="/manualbillentry")
public ModelAndView doFetchUnitCharges(HttpSession session)
{
ModelAndView model = new ModelAndView();
WrpSession wrpsession = new WrpSession();
wrpsession = (WrpSession) session.getAttribute("totalObj");
try {
model.setViewName("ManualChargesListV2");
List<EntSetCharges> flatBillsManualList = new ArrayList<>();
flatBillsManualList = serbilldetails.doFetchUnitCharges(wrpsession);
model.addObject("manuallist",flatBillsManualList);
}
catch (Exception e){
e.printStackTrace();
}
return model;
}
2.The html page loads the data in dropdown perfectly,when choosing dropdown again need to hit the controller to show the data regarding selected dropdown value so i use to code like
<div class="form-group col-md-6">
<label for="chargelist">Select Charge *</label>
<select id="chargelist" class="form-control"
ng-model="selectedcharge"
ng-change="getChargeDetails(selectedcharge)">
<option> Select</option>
<option th:each="manualunitcharge:${manuallist}"
th:value="${manualunitcharge.pkSetCharges}"
th:text="${manualunitcharge.fkAssignCharges.chargeName}"></option>
</select>
</div>
it will call AngularJS ng-change="getChargeDetails(selectedcharge) method,it successfully hits the controller incl selected data.And Sends the data
#GetMapping(value = "manualbillentry/showmanuallist/{chargeid}")
private ResponseMsg doFetchManualChargesList(#PathVariable("chargeid")int chargeid,HttpSession session)
{
ResponseMsg response = new ResponseMsg();
WrpSession wrpsession = new WrpSession();
wrpsession = (WrpSession) session.getAttribute("totalObj");
try {
List<EntFlatIncome> unitChargesList = new ArrayList<>();
unitChargesList = serbilldetails.doFetchManualChargesList(chargeid,wrpsession);
response.setStatus("success");
response.setDataObj(unitChargesList);
}
catch (Exception e){
e.printStackTrace();
response.setStatus("failed");
}
return response;
}
var app = angular.module('ngapppmanual', []);
app.controller('ngctrlmanual', function($scope, $http, $location) {
$scope.ngshowchargelist = false;
$scope.getChargeDetails = function()
{
var url = $location.absUrl() + "/showmanuallist/" + $scope.selectedcharge;
var config = {
headers : {
'Content-Type' : 'application/json;charset=utf-8;'
}
}
$http.get(url, config).then(function(response)
{
if (response.data.status == "success")
{
$scope.manualresult = response.data.dataObj;
$scope.ngshowchargelist = true;
} else
{
$scope.getResultMessage = "Customer Data Error!";
}
},
function(response)
{
$scope.getResultMessage = "Fail!";
});
}
});
I need to Load the Data in in same HTML page But the issue is while responding result as incl Error code 500
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "manualbillentry/showmanuallist/1", template might not exist or might not be accessible by any of the configured Template Resolvers.
i cant understand the issue ,please someone helpme out...
you are using #Controller which returns html, instead you can use #RestController that returns JSON which angularJS is expecting
here is my all code i am trying to upload small image and large image separate but angularjs not let me allow to do this, it only taking one file but not taking other one. plz anyone help with this. thanks in advance.
<div ng-app="eventModule" >
<div ng-controller="eventController">
<div>
<span >Thumbnail Image</span>
<input type="file" id="fileToUpload" onchange="angular.element(this).scope().selectThumbnail(this.files)" accept="image/*" />
</div>
<div>
<span >Large Image</span>
<input type="file" onchange="angular.element(this).scope().selectLargeImage(this.files)" class="LargeImageSubCategory" />
</div>
</div>
<span data-ng-click="SaveFile()">Submit</span>
</div>
<script>
var eventModule = angular.module('eventModule', []);
eventModule.controller('eventController', function ($scope,ArticleService, $http, $sce) {
$scope.selectThumbnail = function (file) {
$scope.SelectedThumbnail = file[0];
}
$scope.selectLargeImage = function (file) {
$scope.SelectedLargeImage = file[0];
}
$scope.SaveFile = function () {
$scope.IsFormSubmitted = true;
$scope.Message = "";
ArticleService.UploadFile($scope.SelectedThumbnail, $scope.SelectedLargeImage).then(function (d) {
alert(d.Message);
ClearForm();
}, function (e) {
alert(e);
});
};
});
eventModule.service("ArticleService", function ($http, $q) {
this.UploadFile = function (Thumbnail, LargeImage, TitleHeading, Topic, SmallDesc, LargeDesc) {
var formData = new FormData();
formData.append("Thumbnail", Thumbnail);
formData.append("LargeImage", LargeImage);
// here when i am trying to send two files so controller is not called
//and function is breaking and alert is comming "File Upload Failed"
formData.append("TitleHeading", TitleHeading);
formData.append("Topic", Topic);
var defer = $q.defer();
$http.post("/Articles/SaveFiles", formData,
{
withCredentials: true,
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
}).success(function (d) {
defer.resolve(d);
}).error(function () {
defer.reject("File Upload Failed!");
});
return defer.promise;
}
});
</script>
//And My ArticlesController.cs code is
[HttpPost]
public JsonResult SaveFiles(string TitleHeading, string Topic)
{
string Message, fileName, actualFileName;
Message = fileName = actualFileName = string.Empty;
bool flag = false;
if (Request.Files != null)
{
var file = Request.Files[0];
actualFileName = file.FileName;
fileName = Guid.NewGuid() + Path.GetExtension(file.FileName);
int size = file.ContentLength;
try
{
file.SaveAs(Path.Combine(Server.MapPath("~/UploadedFiles"), fileName));
using (TCDataClassesDataContext dc = new TCDataClassesDataContext())
{
Article insert = new Article();
insert.ArticleId = Guid.NewGuid();
insert.TitleHeading = TitleHeading;
insert.SmallImagePath = fileName;
dc.Articles.InsertOnSubmit(insert);
dc.SubmitChanges();
Message = "File uploaded successfully";
flag = true;
}
}
catch (Exception)
{
Message = "File upload failed! Please try again";
}}
return new JsonResult { Data = new { Message = Message, Status = flag } };
}
You are appending the files to the formdata, thus you need to specify the Thumbnail and LargeImage as parameters of your MVC controller. Please see below:
[HttpPost]
public JsonResult SaveFiles(
HttpPostedFileBase thumbnail
, HttpPostedFileBase largeImage
, string titleHeading
, string topic)
{
string Message, fileName, actualFileName;
Message = fileName = actualFileName = string.Empty;
bool flag = false;
if (thumbnail != null && thumbnail.ContentLength != 0)
{
SaveFile(thumbnail);
}
if (largeImage != null && largeImage.ContentLength != 0)
{
SaveFile(largeImage);
}
return new JsonResult { Data = new { Message = Message, Status = flag } };
}
private void SaveFile(
HttpPostedFileBase httpFile)
{
var actualFileName = httpFile.FileName;
var fileName = Guid.NewGuid() + Path.GetExtension(httpFile.FileName);
int size = httpFile.ContentLength;
try
{
httpFile.SaveAs(Path.Combine(Server.MapPath("~/UploadedFiles"), fileName));
using (TCDataClassesDataContext dc = new TCDataClassesDataContext())
{
Article insert = new Article();
insert.ArticleId = Guid.NewGuid();
insert.TitleHeading = TitleHeading;
insert.SmallImagePath = fileName;
dc.Articles.InsertOnSubmit(insert);
dc.SubmitChanges();
Message = "File uploaded successfully";
flag = true;
}
}
catch (Exception)
{
Message = "File upload failed! Please try again";
}
}
This is part of my servlet:
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
#SuppressWarnings("deprecation")
Map<String, BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterator;
try {
iterator = upload.getItemIterator(req);
Picture pic = null;
PictureAccess access = null;
while(iterator.hasNext()){
FileItemStream item = iterator.next();
pic = new Picture( blobs.get(item.getFieldName()).getKeyString() );
access = new PictureAccess();
access.addPictures(pic, user.getEmail() );
}
} catch (FileUploadException e) {
e.printStackTrace();
}
res.sendRedirect("/user/picture/upload.jsp");
}
In my client side, I used JavaScript to change the names of the file:
<script type="text/javascript">
function uploadFile() {
if (window.File && window.FileList) {
var fd = new FormData();
var files = document.getElementById('fileToUpload').files;
for ( var i = 0; i < files.length; i++) {
fd.append("file" + i, files[i]);
}
var xhr = new XMLHttpRequest();
xhr.open("POST", document.getElementById('uploadForm').action);
xhr.send(fd);
alert('already saved');
document.getElementById('uploadForm').value = '';
} else {
document.getElementById('uploadForm').submit(); //no html5
}
}
</script>
In my html/jsp:
<form id="uploadForm" enctype="multipart/form-data" method="post" action="<%= blobstoreService.createUploadUrl("/user/uploadPics") %>">
<input type="file" name="fileToUpload" id="fileToUpload" multiple="multiple" size="5"/>
<input type="button" onclick="uploadFile();" value="Upload" />
</form>
The above codes works in development machine but not working when deployed. What are the possible error and solution to the problem? How can I see the error in appengine?
Deprecated method getUploadedBlobs(..) does not support multiple='true'. Try using getUploads(..) instead.