Using an Alfresco Share Form Page, How do I upload a new file with metadata? - file-upload

I'm working With Alfresco Community Edition.
Here's the code I've tried so far: Alfresco-Smalgyax.
I have created an All-in-One Project, to add a new page to the create.. menu. My Page Loads just fine.
I followed, the Adding a menu item to the "Create..." menu in DocLib tutorial, before adding a custom form field and JavaScript to the newly added share page.
I've added a custom field to upload a file to cm:content.
I've added some Javascript to get and set the cm:name and mimetype once an Upload file is chosen.
All the Metadata is correctly ingested. However, the file is not.
Previously I was successfully, able to upload a file with custom data by following the documentation: Processing multipart forms. However, that created a whole new Service endpoint and a custom page that didn't inherit the same look/feel as the rest of the web-application.
The page under create.. has the same look/feel as the rest of the site. But Upload Fails, Is there a way to leverage the Look/feel of the site and upload a file with metadata and set a custom type in Alfresco?
Clarification
The cm:content field has been customized like so:
<field id="cm:content" label-id="" mandatory="true">
<constraint-handlers>
<constraint type="MANDATORY" event="input"
validation-handler="Smalgyax.forms.validation.setNameValue" />
</constraint-handlers>
<control template="/file.ftl">
<control-param name="editorAppearance">explorer</control-param>
</control>
</field>
file.ftl sets the form input element like so:
<input id="${fieldHtmlId}" type="file"
name="${field.name}"
<#if field.disabled>disabled="true"</#if> />
additionally, file.ftl adds custom JavaScript to the page, because I was unable to get it successfully loaded as a separate file using
<forms>
<dependencies>
<js src="/set-name-field.js"/>
</dependencies>
<!-- form definition here -->

As the Alfresco documentation clearly suggests it won't supports the upload feature. The field type shows cm:content that won't accept a file to accept a file even though you have customized and added a explorer option in the code. That is the reason file is not and only content is uploading.
https://docs.alfresco.com/community/tasks/dev-extensions-share-tutorials-add-menuitem-create-menu.html
<field id="cm:content" label-id="">
<control>
<control-param name="editorAppearance">explorer</control-param>
</control>
</field>
For upload a file , you should use the html component like below,
<input type="file" multiple="" name="files[]" class="dnd-file-selection-button">
and the javascript should be same as the file-upload.js and dnd-upload.js.
http://localhost:8180/share/res/components/upload/file-upload.js
http://localhost:8180/share/res/components/upload/dnd-upload.js
Please refer the link below to upload a file through a ajax call.
https://hub.alfresco.com/t5/alfresco-content-services-forum/how-to-upload-a-file-from-a-custom-share-page/td-p/32361

Related

Receiver of Upload Button Vaadin

I am trying to upload a file. It uploads fine, but while uploading it shows all file. I want to restrict to only selected files like pdf,jpg and jpeg files.
I need to while uploading a file when a browser window open that time only these files are visible remaining file should be hide. So that user is not able to select wrong file.
Can anyone tell me how can I do this?
I am using Vaadin 7.5.1 and Upload component and a Receiver.
The current Vaadin Upload component does not support this. There's an enhancement request for it which would be dead easy for Vaadin Inc (or a contributor) to implement now that all the major browsers support this functionality.
Here's the technical explanation: The Vaadin Upload component creates HTML like this:
<input type="file" name="foo">
but what you would have liked it to produce would be something like this:
<input type="file" name="foo" accept=".pdf,.jpg,.jpeg">
Here's how the above HTML will look in Firefox:
Basically the accept attribute will tell the browser to open a file selection dialog with a certain filter.
Note that this is a client-side thing. It doesn't prevent a savvy end user from uploading something that doesn't match your filter to your server. That goes for any kind of filtering done on the client-side no matter how it is done. For this reason you'll still need some server-side validation as well.
Piece of cake with JavaScript - you just have to check into the HTML source of page where that button/browse field is placed to find actuall class name of generated html element - this is example for .csv, Vaadin generates class name titled "gwt-FileUpload", so you have to set it like this to see only .csv files after clicking on "Import" button:
upload.setButtonCaption("Import");
JavaScript.getCurrent().execute("document.getElementsByClassName('gwt-FileUpload')[0].setAttribute('accept', '.csv')");
Add this dependency to your pom file
<dependency>
<groupId>com.wcs.wcslib</groupId>
<artifactId>wcslib-vaadin-widget-multifileupload</artifactId>
<version>1.10</version>
</dependency>
And use the following code to upload files, set filter using setAcceptFilter method:
UploadStateWindow uploadStateWindow = new UploadStateWindow();
uploadStateWindow.setOverallProgressVisible(true);
MultiFileUpload fileUpload = new MultiFileUpload(uploadFinishedHandler,
uploadStateWindow, true);
fileUpload.setAcceptFilter(".png,.jpg");
fileUpload.setImmediate(true);
fileUpload.getSmartUpload().setUploadButtonCaptions("upload", "upload");

Upload a file to a website programmatically?

I am using Lazarus I have an app with webbrowser component on it that logs into a website loads a page as below (see html code below), and fills in different inputs. The last input is a file to upload. I would like my app to "click" Browse, select a file i want to, and Open. After that I could do a post the form OR just upload the file and carry on.
1
I have the following html code on the site:
<td align="left" class="RequiredInput">File:</td>
<td class="datafield">
<form name="frmMain" id="frmMain" action="upload.asp?step=2&output=1" method="post" enctype="multipart/form-data">
<input type="file" name="filename" id="filename">
</form>
I tried executing JS from my app : document.getElementById('filename').value = 'C:\x.csv'
2
I tried using the following code HttpPostFile from synapse:
uFileName := 'C:\x.csv';
uStream := TFileStream.Create(uFileName, fmOpenRead);
uList:=TStringList.Create;
if HttpPostFile('upload.asp?step=2&output=1', 'filename', uFileName, uStream, uList) then
ShowMessage('OK');
It did nothing at all (I followed the activity of the app with Fiddler)
This is a known problem, and there is a solution, but you're going to have to convert it from ะก# to Delphi.
Another possible solution is to upload the file using URL Moniker APIs. The upload will then happen on the same session the WebBrowser control is already using. There is an MSKB article:
How To Handle POST Requests in a Pluggable Protocol Handler
The POSTMON.EXE sample linked to the article has disappeared from Microsoft website, but still can be found here.

Getting HTML of Smart Form Content in Ektron

I am working in Ektron 8.0.
I have created a smart form configuration in Settings,I assigned this particular smart form configuration for
a Folder and created a Smart form content.Now i am trying to access the Smart Form content programmatically.
I am getting the "XML" data as the content.Html property.Is there is any way i can get the HTML data corresponding to a smartform content,rather than these XML data?
There are a few ways to this, here are two.
XSLT:
<CMS:ContentBlock runat="server" Visible="true" DisplayXslt="/xmlfiles/SmartForm.xslt" DefaultContentID="23" />
The SmartForm.xslt file translates the xml into formatted html.
Use XSD to access SmartForm Content on the code behind.
This article explains the process.
http://developer.ektron.com/Templates/KBDetail.aspx?id=603
You need to get a copy of the .xsd file and use it to create an object definition for your smart form.
Use the xsd.exe tool to create a class. The command looks like this.
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\xsd.exe" "C:\inetpub\site\xsd\SmartFormContet.xsd" /classes /language:CS /namespace:SmartForm.SmartFormContent
This will generate a class file named SmartFormContet.cs
Copy this file and paste into the code behind of the page.
Deserialize the XML from the Content.Html property.

Automatically add tag to uploaded document in sharepoint

My environment is sharepoint 2010 and vs 2010.
I already have an OOTB document library that I am using and I wanted to know how I can add a tag or keyword to a METADATA column.
I am using the same document library in all subsites and so would like to tag the uploaded document with the name of the current site (ie if it's being used in a subsite, that subsite's name would be the tag).
Would I need to build a custom document library or some sort of add-on webpart that attaches to the existing document library?
If you could provide some code samples if any that would be appreciated.
thanks,
KS
If you are starting from scratch you can create a custom content type based on the build in content type Document (a child content type of Document). Add a custom field to your content type. For more information regarding creating content types look here: http://msdn.microsoft.com/en-us/library/gg295290.aspx
A content type can also have a custom event receiver for ItemAdding, ItemUpdated etc. Look at the xml below:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ContentType ID="0x010100xxxxxx"
Name="MyContentType"
Group="My custom group" Version="0" Inherits="True" Overwrite="TRUE" >
<FieldRefs>
<FieldRef ID="{AC8A823D-EB2F-4D4D-8BF0-14CACA509539}" Name="myMetadataField" Required="FALSE" />
</FieldRefs>
<XmlDocuments>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/events">
<spe:Receivers xmlns:spe="http://schemas.microsoft.com/sharepoint/events">
<Receiver>
<SequenceNumber>1010</SequenceNumber>
<Name>HandoverOffshore_ItemAddedReceiver</Name>
<Type>ItemAdded</Type>
<Assembly>MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=79315a88caec227a</Assembly>
<Class>MyAssembly.CustomEventReceivers</Class>
</Receiver>
</spe:Receivers>
</XmlDocument>
</XmlDocuments>
</ContentType>
</Elements>
Then you'll have to create the event receiver class witch handles the custom event:
public class HandoverOffshoreEventReceivers : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
// your code for updating metadata field here...
}
}
Then you deploy this to your site collection and add this content type to all your libraries. Also set this as the default content type in all libraries.
If you are creating many libraries you should consider to create a custom library definition based on this content type.
If you want this custom event fired for existing documents you'll have to change their content type to the new one you created here.
Note that document library content types are child content types of the site collection content types.

Create Folders in Library when submitting a list form in SharePoint 2010

I would like to know if it's possible to create folders when submitting a form in SharePoint. I created a custom SharePoint list form in Infopath and I want to add an action to the submit button to create four folders, one for each of the four doc libraries, that contains the title of the submitted item.
I see however that the custom code button is not enabled for a SharePoint list in Infopath so I cannot add any code in the background. The workflows that come out of the box also does not allow me to do it, unless I'm missing something...What other way is there to do it?
Thanks in advance for any help!!
Yes you can do this, however, it's quite tricky.
In theory, you could call the "UpdateListItems" method of the Lists.asmx web service and pass a batch statement but due the implementation of the Lists web service you cannot use it in InfoPath. That's why you need to write your own web service that wraps the UpdateListItems method so you can use it with IP.
If you do not know how to write a web service (and host it within SharePoint) please use the search function of StackOverflow or consider google - many great tutorials out there ;-)
Once you got the web service running, you need to add a service reference to the http://myserver/_vti_bin/Lists.asmx web service and then create the following method:
[WebMethod]
public void UpdateListItems(string listGuid, string xmlBatch)
{
var batch = new XmlDocument();
batch.LoadXml(xmlBatch);
//create an instance of the lists proxy client
var listSvc = listService = new ListsWebService.Lists();
//set the url of the client
listService.Url = "http://myserver/_vti_bin/Lists.asmx";
listSvc.UpdateListItems(listGuid, batch);
}
Note that if you configure the listSvc's Url hardcoded (like in this example), you need to make sure that the List, you want to add the folders to, is within the same site as the Url. If you want to make it this method more generic (which i'd suggest you do), you could simply pass the SiteCollection Url as a parameter and set listSvc.Url to SiteCollectionUrl + "_vti_bin/Lists.asmx".
Once this is set up, you can create the data connection to your newly created web service in InfoPath and configure it like this:
The field "listName" is actually the GUID of the List - you can get it via the UI by clicking "Library Settings" - "Information management policy settings" and then copy it from the address bar in your browser. Example:
{39d01277-4ba1-4589-90f8-c957b4b2dd09}
The field "XML" contains the batch script to create the folder. You can declare it staticly, or in your case, you can build it dynamically using the concat() function. This example creates a folder named "MyFolder" in the root of the Library.
<Batch>
<Method ID='1' Cmd='New'>
<Field Name='ID'>New</Field>
<Field Name='FSObjType'>1</Field>
<Field Name='BaseName'>MyFolder</Field>
</Method>
</Batch>
If you need to have sub-folders, this is possible too. This following example will create a folder named "MySubFolder" within the folder "MyFolder".
<Batch>
<Method ID='1' Cmd='New'>
<Field Name='ID'>New</Field>
<Field Name='FSObjType'>1</Field>
<Field Name='BaseName'>MyFolder/MySubFolder</Field>
</Method>
</Batch>
Then you simply add a submit button action and you're done :-)
Also note that the code above is just an example (which works though). If you use it in production be sure to add proper exception logging because you'll be needing it :-)
hope this helps!