Uploading files using html5 FormData in dojo(without using XmlHttpRequest) - dojo

I want to upload files using FormData Object(html5) in dojo and without using XmpHttpRequest.
I am using dojo.xhrPost to upload files.
Please post your ideas/thoughts and experience.
Thanks
Mathirajan S

Based on your comment I am assuming you do want to use XHR (which would make sense given that FormData is part of the XHR2 spec).
dojo/request/xhr (introduced in Dojo 1.8) supports passing a FormData object via the data property of the options object, so that may get you what you want.
request.post(url, {
data: formdataObjectHere
// and potentially other options...
}).then(...);
The legacy dojo/_base/xhr module does not explicitly support XHR2, but it does lean on dojo/request/xhr now, so it might end up working anyway, but no guarantees there.
More information on dojo/request/xhr can be found in the Reference Guide.

Related

Change results URL in Alfresco AIkau faceted search page

I have some difficulties customizing the Aikau faceted search page on Alfresco, which may be more a matter of lack of my knowledge about dojo/AMD.
What I want to do is to replace the document details page URL by a download URL.
I extended the Search Results Widget to include my own custom module :
var searchResultWidget = widgetUtils.findObject(model.jsonModel, "id", "FCTSRCH_SEARCH_RESULT");
if(searchResultWidget) {
searchResultWidget.name = "mynamespace/search/CustomAlfSearchResult";
}
I understand search results URLs are rendered this way :
AlfSearchResult module => uses SearchResultPropertyLink module => mixins _SearchResultLinkMixin renderer => bring the "generateSearchLinkPayload" function => renders URLs depending on the result type
I want to override this "generateSearchLinkPayload" function but I can't figure out what is the best way to do that.
Thanks in advance for the help !
This answer assumes you're able to use the latest version of Aikau (at the time of writing this is 1.0.61). Older versions might require slightly different overriding...
In order to do this you're going to need to override the createDisplayNameRenderer function of AlfSearchResult in your CustomAlfSearchResult widget. This will allow you to create an extension of alfresco/search/SearchResultPropertyLink.
If you want to take advantage of the the download capabilities provided by the alfresco/services/DocumentService for downloading both documents and folders (as a zip) then you're going to want to change both the publishTopic and publishPayload of the SearchResultPropertyLink.
You should extend the getPublishTopic and generateSearchLinkPayload functions. For the getPublishTopic function you'll want to change the return value to be "ALF_SMART_DOWNLOAD" (there are constants available for these strings in the alfresco/core/topics module). This topic can be used to tell the DocumentService to take care of figuring out if the node is a folder or document and will make an XHR request for the full node metadata (in order to get the contentUrl attribute that is not included in the data returned by the Search API.
You should extend the generateSearchLinkPayload function so that for document or folder types the payload contains the attribute nodes that is a single array where the object is the search result object that you wish to download.
I would recommend that you call this.inherited first to get the default payload and only update it for documents and folders.
Hopefully that all makes sense - if not, add a comment and I'll try to provide further assistance!
This is the answer for 1.0.25.2 - unfortunately it's not quite so straightforward...
You still need to extend the alfresco/search/AlfSearchResult widget, however this time you need to extend the postCreate function (remembering to call this.inherited(arguments)). It's not possible to stop the original alfresco/search/SearchResultPropertyLink widget from being created... so it will be necessary to find it and destroy it.
The widget is not assigned to a variable, so it will be necessary to find it using dijit/registry. Use the byNode function from dijit/registry to find the widget assigned to this.nameNode and then call destroy on it (be sure to pass the argument true to preserve the DOM). However, you will then need to empty the DOM node so that you can start again...
Now you need to add in your extension to alfresco/search/SearchResultPropertyLink. Unfortunately, because the smart download capability is not available you'll need to do more work. The difference here is that you'll need to make an XHR request to retrieve the full node metadata in order to obtain the contentURL. It's possible to publish a request to the DocumentService(via the "ALF_RETRIEVE_SINGLE_DOCUMENT_REQUEST" topic). However, you need to be aware that having the XHR step will not allow you to then proceed with the download as is. Instead you'll need to use an iframe download solution, I'd suggest you take a look at the changes in the pull request we recently made to solve this problem and backport them into your own solution.

Fine Uploader - using both Direct S3 and Traditional in same project

I have an existing FineUploader implementation for small files using the Traditional (upload-to-server) version which is working great. However, I'd like to also allow Direct S3 uploads from a different part of the application which deals with large attachments, without rewriting the existing code for small files.
Is there some way to allow both Direct S3 and Traditional uploads to work alongside each other? This is a single-page application, so I can't just load one or the other fine-uploader versions depending on which page I'm on.
I tried just including both fine-uploader JS files, but it seemed to break my existing code.
Client-side code:
$uploadContainer = this.$('.uploader')
$uploadButton = this.$('.upload-button')
$uploadContainer.fineUploader(
request:
endpoint: #uploadUrl
inputName: #inputName
params:
authenticity_token: $('meta[name="csrf-token"]').attr('content')
button: $uploadButton
).on 'complete', (event, id, fileName, response) =>
#get('controller').receiveUpload(response)
Good find, #Melinda.
Fine Uploader lives within a custom-named namespace so that it does not conflict with other potential global variables, this is the qq namespace (historically named). What is happening is that each custom build is redeclaring this namespace along with all member objects when you include it in the <script> tags on your page.
I've opened up an issue on our bug tracker that explains the issue in more technical details, and we're looking to prioritize a fix to the customize page so that in the future no one will have this issue.

Dynamic Javascript using Scala template

I am trying to localize my Javascript files. For instance, I would have:
var count = 0;
$('#choices .choice').each(function(i) {
$('input', this).each(function() {
count++
$(this).attr('placeholder', '#Message("placeholder.choice") ' + count)
})
})
This would obviously work if the Javascript file is inside the Scala HTML template but I would prefer to have it in a dedicated file.
To begin with, I am wondering if it is a good idea: what about caching file if it's content may change? In this case, there is a single parameter: having it in the URL would solve this problem? Eg: /assets/javascripts/:lang/my-file.js.
And the real question is: is it possible to do that using Play! framework? It does not seem that Javascript templates are supported (or I missed something). Is there a way to do it correctly?
Actually you don't need to translate your JavaScripts dynamically, it's reduntant waste of resources, instead prepare static JS files like messages.en.js, messages.de.js etc and include required file basing on the user's language directly into the view.
Here you have some description how to make it easy (JavaScript approach)
There is a module allowing javascript internationalization using the same mechanism as in Play templates, have a look at :
https://github.com/julienrf/play-jsmessages
This will definitely fits your needs. I use it for a while know with success. You can expose your translations through a javascript file and then use browser caching with a proper fingerprinting configuration.

In Dojo 1.7+, FilteringSelect appear to no longer workwith ItemFileReadStore

I am upgrading an application from dojo 1.5 to 1.7. This application has several FilteringSelects that are backed by ItemFileReadStores. E.g.,
this.docTypeSel = this.adopt(dijit.form.FilteringSelect, {
name: "docType",
autoComplete: true
}, document.createElement("select"));
this.docTypeSel.placeAt(this.formNode);
var url = dojo.moduleUrl("imed", "DocumentTypes.txt");
this.documentTypeStore = new dojo.data.ItemFileReadStore({ url: url, urlPreventCache: "true" });
this.docTypeSel.store = this.documentTypeStore;
In 1.7, calls to this.docTypeSel.set('value',foo) fail as they try to call this.store.get(value). My understanding is that this is the new dojo/store API. Is there some sort of adapter between the old dojo.data API's and the new dojo/store API? If not, what is the recommended replacement for ItemFileReadStore. dojo/store/Memory seems close, but it does not appear to have a way pull the data from an url.
Have you looked at using the dojo/store/DataStore? I haven't used it personally but it appears to be what you want to use since the dijit/form/FilteringSelect is looks for stores using the dojo/store API.
On the other hand the dijit/form/Select expects a dojo/data implementation. If you had a dojo/store implementation you wanted to use with dijit/form/Select you would use dojo/data/ObjectStore.

Uploadify with NodeJS | Post parameters not being sent

I'm building my latest app using nodeJS and need to be able to upload multiple files. I have chosen to use Uploadify flash based file uploader.
Unfortunately the 'scriptData' vars don't seem to be being sent. Usual method of retrieval of POST vars in node looks like var postDataValue = req.body.postDataKey; but with Uploadify the req.body object is empty.
Hope someone can help with this.
I had to send the parameters via query string in the end. Must be something to do with NodeJS.
It's not Node.js. req.body is not part of node. It's built into BodyParser and provided by Connect. Mainly used in Express.
See http://senchalabs.github.com/connect/middleware-bodyParser.html
If you don't use it, the req.body object should be empty.