Primefaces - Get files in alphabetical order in multiple file upload component - jsf

I am using Primefaces Multiple file upload component in an application. Here i choose 'n' number of files and clicked on upload button. Then i need to get each files in fileUploadListener according to alphabetical order. How it possible?

As the multiple file upload component is a jQuery-File-Upload plugin, the default state is not sequential, that means all the files get upload asynchronously.
To get the component to do a sequential upload, you have to set sequentialUploads to true, and on change we do a little alphabetical sorting of the current files. all this is done by javascript.
Assuming your widgetVar is fileUploadWV
<p:fileUpload widgetVar="fileUploadWV"
fileUploadListener="#{attachmentBean.onUpload}" />
<script>
$(function() {
// setTimeout waits till the widgetVar is ready!
setTimeout(sortFileUpload, 2000);
});
function sortFileUpload() {
//Set this option to true to issue all file upload requests in a sequential order instead of simultaneous requests.
PF('fileUploadWV').jq.data().blueimpFileupload.options.sequentialUploads = true;
//every time a new file is added, sort the files based on name
PF('fileUploadWV').jq.change(function() {
PF('fileUploadWV').files.sort(function fileSort(a, b) {
return a.name.localeCompare(b.name)
})
});
}
</script>
So in this scenario your files would get uploaded in an alphabetical order.
Note: if you don't set sequentialUploads into true, you have no control which file is going to be sent first.
Github, Online Demo
Hope this helps.

yes, but this solution is not very elegant:
<p:remoteCommand action="#{attachmentBean.processAttachments}"
name="processAttachments" update="attachmentTable"/>
<p:fileUpload fileUploadListener="#{attachmentBean.onUpload}"
oncomplete="processAttachments()" />
attachmentBean.onUpload stores each file inside a List/Map/SortedMap
attachmentBean.processAttachments eventually sorts that List/Map and process attachments in order
attachmentBean must be at least #ViewScoped

Related

Retrieve uploaded relativePath file on server side

I'm using fileUpload from Primefaces (JSF framework) based on jQuery-File-Upload. I'm trying to make this component supporting drag&drop folder thanks to new File API of Firefox or Chrome. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory#Example So far, I've been able to make it happen thanks to passthrough attribute.
One of the interesting feature is "webkitRelativePath" allowing to know the relative path of an uploaded file.
I'm wondering how I could retrieve this info on server side, so I can create an object with this new info.
Thanks for your help.
Well I just read his from fileupload.js:
_initXHRData: function (options) {
...
formData.append(
($.type(options.paramName) === 'array' &&
options.paramName[index]) || paramName,
file,
file.uploadName || file.name
);
...
}
(file containing webKitRelativePath)
So I guess the info is already pass to the server, don't you think? Since i'm using Servlet 3.0, I should be able to retrieve it from Part object, finger crossed...

Formidable Node module... How to get non-file field names/values before file upload progress starts

I am using Node's formidable module for form processing. Works perfect. Now I need to have access to the non-file field names/values posted before the file upload starts. The field names/values are available only AFTER the file uploads are done. Is there any way to get the field names before the file uploads start?
formProcess = new formidable.IncomingForm();
...
formProcess.parse(req, function(error, myFields, myFiles) {
//I get access to the field values here...
//But only after the files are uploaded.
//I need this info before the file uploads start.
}
..
formProcess.on('progress', function(alreadyReceived, expectedToRcv) {
//Fileupload progress info available here...
//I need field names here while processing the upload progress.
//Application specific requirement...
}
Does this have to do with how http post method works or is it specific to the implementation of Node's Formidable module?
There are file and field events that are emitted. Just make sure your non-file fields come before your file fields in your form since fields are sent/received in order.

Upload file to hidden field in WedriverIO Using CucumerJS

Hi I need to automate a website using cucumberJS and webdriverIO. For that I need to Upload a file but the field is hidden. For Example :
<input type="file" id='uploadFile' style="display: none"'>
but webdriver is unable to identify the element on the UI.
Thanks in Advance...
In webdriverIO v5, files are uploaded to inputs of type="file" by calling .setValue() on them with the local file path as an argument. This doesn't seem to work for hidden inputs though, because .setValue() first calls .clearValue() which will throw Element could not be scrolled into view. To work around this, call .addValue() directly on the element:
input.addValue(filePath);
Relevant API docs: https://webdriver.io/docs/api/element/addValue.html
I got the solution for this Issue.Using webdriverIO we can execute javascript to change the style display from "none" to "block".
client.execute(function() {
document.getElementById("element_id").style.display="block";
},function(err) {
client.uploadFile(localPath[,callback])
if(err){
console.log("Error "+err);
}
});
then upload the file to the field and then change the display again to none.

How to modify dashlets to auto-refresh?

Is there a simple way to modify a dashlet to automatically re-load itself periodically?
I am particularly thinking of the "My Tasks" dashlet - we are using pooled review workflows, so tasks may come and go all the time as they are created and then are claimed.
It may be frustrating for users to keep clicking on tasks that turn out to have already been claimed - or having to remember to keep re-loading their Dashboard page. I'd prefer the dashlet to refresh on a timed interval so it's always reasonably up to date.
In order to do this you will need to add a new capability to the client-side class Alfresco.dashlet.MyTasks (docs, source) found in the file components/dashlets/my-tasks.get.js. First you will need to add a new method to the prototype extension specified as the second parameter in the YAHOO.lang.augmentObject() call, e.g.
...
}, // end of last OOTB function - add a comment here
// begin changes
reloadData: function MyTasks_onReady()
{
this.widgets.alfrescoDataTable.loadDataTable(
this.options.filters[this.widgets.filterMenuButton.value]
);
}
// end changes
});
})();
It's not the ideal development environment, you can modify the JS file directly in the Share webapp, although you will also need to update the corresponding -min.js file.
Once you've done this, check that it works by running the following line in your browser's JavaScript console
Alfresco.util.ComponentManager.findFirst("Alfresco.dashlet.MyTasks").reloadData();
If that works, then you can wire up your new method to a title bar action (see my DevCon presentation for more background info), in the dashlet web script. The method depends on whether you are using v4.2 or a previous version, but if it is the latter then you need to add some code to the dashlet's Freemarker file my-tasks.get.html.ftl (under WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/dashlets).
In that file you should see some JavaScript code inside a <script> tag, this sets up an instance of the client-side class and some utility classes, the contents of which you can replace with the following, to add your custom title bar action.
(function()
{
var dashlet = new Alfresco.dashlet.MyTasks("${jsid}").setOptions(
{
hiddenTaskTypes: [<#list hiddenTaskTypes as type>"${type}"<#if type_has_next>, </#if></#list>],
maxItems: ${maxItems!"50"},
filters:
{<#list filters as filter>
"${filter.type?js_string}": "${filter.parameters?js_string}"<#if filter_has_next>,</#if>
</#list>}
}).setMessages(${messages});
new Alfresco.widget.DashletResizer("${id}", "${instance.object.id}");
var refreshDashletEvent = new YAHOO.util.CustomEvent("onDashletRefresh");
refreshDashletEvent.subscribe(dashlet.reloadData, dashlet, true);
new Alfresco.widget.DashletTitleBarActions("${args.htmlid}").setOptions(
{
actions:
[
{
cssClass: "refresh",
eventOnClick: refreshDashletEvent,
tooltip: "${msg("dashlet.refresh.tooltip")?js_string}"
},
{
cssClass: "help",
bubbleOnClick:
{
message: "${msg("dashlet.help")?js_string}"
},
tooltip: "${msg("dashlet.help.tooltip")?js_string}"
}
]
});
})();
You will need to add some styles for the class name specified, in the dashlet's CSS file my-tasks.css, such as the following
.my-tasks .titleBarActions .refresh
{
display: none;
background-image: url('refresh-icon.png');
}
The icon file (here is one you could re-use) must be in the same directory as the CSS file.
Lastly you'll need to define the label dashlet.refresh.tooltop used for the title bar action's tooltip. You can do this in the dashlet web script's .properties file.
For a similar example, check out the source of my Train Times dashlet, which features a refresh title bar action.
In some ways it's actually easier to define your own dashlets than it is to extend the Alfresco-supplied ones, but if you have the option of using 4.2.x, the new method allows you to extend the existing components without duplicating any code, which obviously makes upgrades much easier.

Restricting file upload size in JSF

I am using the Tomahawk inputFileUpload component to allow users to upload files to a server. I have implemented a "soft" file size limit by checking the size of the file after it has been uploaded and displaying an error if it is too large. However I would also like a larger "hard" limit, where uploading immediately stops once it has passed the limit. For example if the hard limit is 500MB and the user attempts to upload a 2GB file, uploading will immediately stop once 500MB has been uploaded and an error is displayed.
I had hoped that using the MyFaces ExtensionsFilter and setting uploadMaxFileSize would fix the problem, but the file is completely uploaded before the SizeLimitExceededException is thrown.
Is it possible to do this? Ideally I'd still be able to use Tomahawk but any other solution would be good.
The web server can't abort a HTTP request halfway and then return a HTTP response. The entire HTTP request has to be consumed fully until the last bit before a HTTP response can ever be returned. That's the nature of HTTP and TCP/IP. There's nothing you can do against it with a server side programming language.
Note that the Tomahawk file upload size limit already takes care that the server's memory/disk space won't be polluted with the entire uploaded file whenever the size limit has been hit.
Your best bet is to validate the file length in JavaScript before the upload takes place. This is supported in browsers supporting HTML5 File API. The current versions of Firefox, Chrome, Safari, Opera and Android support it. IE9 doesn't support it yet, it'll be in the future IE10.
<t:inputFileUpload ... onchange="checkFileSize(this)" />
with something like this
function checkFileSize(inputFile) {
var max = 500 * 1024 * 1024; // 500MB
if (inputFile.files && inputFile.files[0].size > max) {
alert("File too large."); // Do your thing to handle the error.
inputFile.value = null; // Clears the field.
}
}
Try this:
<div>
<p:fileUpload id="fileUpload" name="fileUpload" value="#{controller.file}" mode="simple" rendered="true"/>
<input type="button" value="Try it" onclick="checkFileSize('fileUpload')" />
</div>
When user click in the button "Try it", checkFileSize() function is called and the fileUpload primefaces component is validated. If file size is greater than 500MB the file not is uploaded.
<script>
// <![CDATA[
function checkFileSize(name) {
var max = 500 * 1024 * 1024; // 500MB
var inputFile = document.getElementsByName(name)[0];
var inputFiles = inputFile.files;
if (inputFiles.lenght > 0 && inputFiles[0].size > max) {
alert("File too large."); // Do your thing to handle the error.
inputFile.value = null; // Clears the field.
}
}
// ]]>
</script>
The checkFileSize() logic is based on the BalusC answered above.
Versions tested:
primefaces 3.5
jsf 2.1

Resources