[moss][SharePoint]メール送信機能付きファイルアップローダをブックマークレットで作った

[moss][SharePoint]メール送信機能付きファイルアップローダをブックマークレットで作ったをはてなブックマークに追加 [moss][SharePoint]メール送信機能付きファイルアップローダをブックマークレットで作ったをdel.icio.usに追加 Yahoo!ブックマークに登録 [moss][SharePoint]メール送信機能付きファイルアップローダをブックマークレットで作ったをGoogle Bookmarksに追加

mossupload01.png

sharePointでファイルアップロード&メール送信ブックマークレット作ってみました。

ブックマークレットをクリックすると、プロンプトがポップして
送信先をpeople.asmxを使ったサジェストから選んで
flexでローカルからファイルを読み込んでbase64エンコードして
lists.asmxのuploadListItemsを使ってアイテムつくって
同じくlists.asmxのaddAttachmentsでbase64エンコード後のファイルをアイテムに添付して
workflow.asmxのstartWorkflowでメール送信ワークフローをキックする

というものです。

mossupload02.png

このスクリーンショットがクリップボタンをクリックしたときにあがるプロンプトです。javascriptですと、ファイルを読み込んでbase64エンコードとかは出来ないのでflexのFileReferenceで読み込んだものをBase64Encoderでエンコードしました。ブラウザ(プラグイン)で行うのであまり大きなファイルは扱えないので20Mを限度として作っています。

mossupload03.png

最後のスクリーンショットは、mylistというリストライブラリにアイテムが登録され、添付もされ、メール送信ワークフローまで動いたものです。

mossUploader.js

// util
document.scroll = function(){
return {
x: this.body.scrollLeft || this.documentElement.scrollLeft,
y: this.body.scrollTop  || this.documentElement.scrollTop
};
};
function $( id ){
return document.getElementById( id );
}
// MossUploader
if( !MossUploader ){
var MossUploader = {
suggestList : [],
suggestIdx : 0,
initialize : function(){
var mulload = $( "mulload" );
if( $( "_mulload" ) ){
mulload.removeChild( mulload.firstChild );
}
// outer div
var mossUpldrPrmpt = $( "mossUpldrPrmpt" );
if( !mossUpldrPrmpt ){
mossUpldrPrmpt = document.createElement( "div" );
mossUpldrPrmpt.id = "mossUpldrPrmpt";
document.body.appendChild( mossUpldrPrmpt );
}
$( "mossUpldrPrmpt" ).style.display = "";
// inner div
var _mossUpldrPrmpt = $( "_mossUpldrPrmpt" );
if( !_mossUpldrPrmpt ){
_mossUpldrPrmpt = document.createElement( "div" );
_mossUpldrPrmpt.id = "_mossUpldrPrmpt";
_mossUpldrPrmpt.style.position = 'absolute';
_mossUpldrPrmpt.style.lineHeight = '15px';
_mossUpldrPrmpt.style.left = ((( document.body.clientWidth + document.scroll().x ) / 2 ) - 200 ) + 'px';
_mossUpldrPrmpt.style.top  = ( document.scroll().y + 100 ) + 'px';
_mossUpldrPrmpt.style.width = '400px';
_mossUpldrPrmpt.style.height = '160px';
_mossUpldrPrmpt.style.backgroundColor = "#FFFFFF";
_mossUpldrPrmpt.style.border = "solid 1px #B0C4DE";
_mossUpldrPrmpt.innerHTML = '<div style="text-align:right;padding:8px 8px 2px;background-image: url(http://moss/Documents/uploadTitle.png);background-color:#d6e8ff;"><span id="mulCloseIcon"><img style="padding-bottom:6px;vertical-align:top;cursor:pointer;" src="http://moss/Documents/close.gif"/></span></div><div style="color:#000000;font-size:12px;margin: 12px;text-align:left;">送信先を入力して下さい<br /><br /><table style="color:#000000;font-size:12px"><tr><td>宛先</td><td><input type="text" style="width:320px" id="mulSearchUser" /><br /><div id="mul_suggest" style="padding:1px;position: absolute;background-color: #FFFFFF;border: 1px solid #CCCCFF;font-size: 12pxwidth: 321px;text-align:left;"></div></td></tr><tr><td>ファイル</td><td><div style="float:left" id="fileNameArea"></div><div style="text-align:right;" id="uploadBtn"></div></td></tr></table></div><div style="text-align: right;padding-right:16px;"><input style="width:100px;font:9pt "MS UI Gothic";height:3.1em;padding-top:0.1em;padding-bottom:0.4em;" type="button" id="mulReferPage" value="送信" /><input style="width:100px;font:9pt "MS UI Gothic";height:3.1em;padding-top:0.1em;padding-bottom:0.4em;" type="button" id="mulCancelBtn" value="キャンセル" /><input type="hidden" id="mulHdnSearchUser" /><input type="hidden" id="mulHdnDiffTo" /></div>';
mossUpldrPrmpt.appendChild( _mossUpldrPrmpt );
MossUploader.renderSwf( $( "uploadBtn" ) );
$( "mulCloseIcon" ).attachEvent( 'onclick', MossUploader.closePrompt );
$( "mulSearchUser" ).attachEvent( 'onkeyup', MossUploader.userSearch );
$( "mulSearchUser" ).attachEvent( 'onkeydown', MossUploader.tabDown );
$( "mulReferPage" ).attachEvent( 'onclick', MossUploader.sendData );
$( "mulCancelBtn" ).attachEvent( 'onclick', MossUploader.closePrompt );
$( "mulSearchUser" ).focus();
$( "mulReferPage" ).disabled = true;
MossUploader.clearSuggestArea();
}
},
closePrompt : function(){
var mossUpldrPrmpt = $( "mossUpldrPrmpt" );
mossUpldrPrmpt.removeChild( mossUpldrPrmpt.firstChild );
var mulload = $( "mulload" );
if( $( "_mulload" ) ){
mulload.removeChild( mulload.firstChild );
}
},
sendData : function() {
var sendto = $( "mulHdnSearchUser" ).value;
MossUploader.clearSuggestArea();
if( sendto == null || sendto.length == 0 ){
alert( "無効なユーザです" )
return;
}
window[ "externalFileBase64Cvt" ].mossSrch( $( "mulHdnSearchUser" ).value, $( 'fileNameArea' ).innerText, 1 );
$( "mossUpldrPrmpt" ).style.display = "none";
var mulload = $( "mulload" );
if( !mulload ){
var mulload = document.createElement( "div" );
mulload.id = "mulload";
document.body.appendChild( mulload );
}
// inner div
var _mulload = $( "_mulload" );
if( !_mulload ){
_mulload = document.createElement( "div" );
_mulload.id = "_mulload";
_mulload.style.position = 'absolute';
_mulload.style.lineHeight = '15px';
_mulload.style.left = ((( document.body.clientWidth + document.scroll().x ) / 2 ) - 200 ) + 'px';
_mulload.style.top  = ( document.scroll().y + 100 ) + 'px';
_mulload.style.width = '400px';
_mulload.style.height = '160px';
_mulload.style.backgroundColor = "#FFFFFF";
_mulload.style.backgroundImage = "url(http://moss/Documents/mulload.png)";
_mulload.style.border = "solid 1px #B0C4DE";
_mulload.innerHTML = '<div style="text-align:center;margin-top:80px"><img src="http://moss/Documents/loading.gif"/></div>';
mulload.appendChild( _mulload );
}
//            MossUploader.closePrompt();
},
tabDown : function(){
if( event.keyCode == 9 && MossUploader.suggestIdx != -1 ){
if( $( 'sug_' + MossUploader.suggestIdx ) ){
$( 'mulSearchUser' ).value = $( 'sug_' + MossUploader.suggestIdx ).innerHTML;
$( 'mulHdnSearchUser' ).value = MossUploader.suggestList[ MossUploader.suggestIdx ].UserInfoID;
$( 'mulHdnDiffTo' ).value = $( 'sug_' + MossUploader.suggestIdx ).innerHTML;
MossUploader.clearSuggestArea();
}
}
// clear on esc
if( event.keyCode == 27 && $( 'mulSearchUser' ).value.length == 0 ){
MossUploader.closePrompt();
return;
}
else if( event.keyCode == 27 ){
$( 'mulSearchUser' ).value = "";
}
},
userSearch : function (){
// clear field by diff
if( $( "mulHdnDiffTo" ).value.length != 0 && ( $( 'mulSearchUser' ).value != $( "mulHdnDiffTo" ).value ) ){
$( 'mulSearchUser' ).value = "";
$( "mulHdnDiffTo" ).value = "";
$( "mulHdnSearchUser" ).value = "";
}
// enter confirm
if( event.keyCode == 13 && $( "mulHdnSearchUser" ).value.length != 0 &&  $( 'mulSearchUser' ).value == $( "mulHdnDiffTo" ).value ){
MossUploader.sendData();
return;
}
// clear field.
if( $( 'mulSearchUser' ).value.length == 0 ){
$( "mulHdnSearchUser" ).value = "";
$( "mulHdnDiffTo" ).value = "";
MossUploader.clearSuggestArea();
return;
}
event.returnValue = false;
event.cancelBubble = true;
if( MossUploader.suggestList.length != 0 ){
var isSelKeyCode = false;
if( event.keyCode == 38 ){
MossUploader.suggestIdx--;
if( MossUploader.suggestIdx < 0 ) MossUploader.suggestIdx = MossUploader.suggestList.length -1;
isSelKeyCode = true;
}
else if( event.keyCode == 40 ){
MossUploader.suggestIdx++;
if( MossUploader.suggestIdx > MossUploader.suggestList.length -1 ) MossUploader.suggestIdx = 0;
isSelKeyCode = true;
}
else if( event.keyCode == 13 ){
if( $( "sug_" + MossUploader.suggestIdx ) ){
$( 'mulSearchUser' ).value = $( "sug_" + MossUploader.suggestIdx ).innerHTML;
$( 'mulHdnSearchUser' ).value = MossUploader.suggestList[ MossUploader.suggestIdx ].UserInfoID;
$( 'mulHdnDiffTo' ).value = $( "sug_" + MossUploader.suggestIdx ).innerHTML;
MossUploader.clearSuggestArea();
}
}
if( isSelKeyCode ){
for( var idx = 0; idx < MossUploader.suggestList.length; idx++ ){
var elem = $( "sug_" + idx );
if( elem ){
if( MossUploader.suggestIdx == idx ){
if( MossUploader.suggestList[ MossUploader.suggestIdx ].DeptFlg == 1 ){
elem.style.backgroundColor = "#CCFF66";
}
else {
elem.style.backgroundColor = "#99CCFF";
}
}
else {
elem.style.backgroundColor = "";
}
}
}
}
}
var searchText = $( 'mulSearchUser' ).value;
if( searchText.length < 2 ) return;
if( !MossUploader.isVaildKeyCode() ) return;
window[ "externalFileBase64Cvt" ].mossSrch( searchText, null, 0 );
},
clearSuggestArea : function(){
var suggestArea = $( "mul_suggest" );
suggestArea.innerHTML = '';
suggestArea.style.display = 'none';
},
getUserSuggest: function( param ){
MossUploader.suggestList = param;
MossUploader.suggestIdx = -1;
MossUploader.clearSuggestArea();
var suggestArea = $( "mul_suggest" );
for( var idx = 0; idx < param.length; idx++ ) {
var dpt = param[ idx ].Department;
if( dpt.length > 18 ){
dpt = dpt.substr( 0, 18 ) + '...';
}
var element = document.createElement( 'div' )
element.style.display = "block";
element.style.width = "321px";
element.style.overflow = "hidden";
element.style.whiteSpace = "nowrap";
element.innerHTML = param[ idx ].DisplayName + " [ " + dpt + " ]";
element.id = "sug_" + idx;
suggestArea.appendChild( element );
element.attachEvent( 'onmouseover', function(){
var target = event.target || event.srcElement;
var targetIdx = target.id;
targetIdx = targetIdx.substr( targetIdx.indexOf( "_" ) + 1, targetIdx.length );
$( 'mulHdnSearchUser' ).value = MossUploader.suggestList[ targetIdx ].UserInfoID;
if( MossUploader.suggestList[ targetIdx ].DeptFlg == 1 ){
target.style.backgroundColor = "#CCFF66";
}
else {
target.style.backgroundColor = "#99CCFF";
}
});
element.attachEvent( 'onmouseout', function(){
var target = event.target || event.srcElement;
target.style.backgroundColor = "";
});
element.attachEvent( 'onclick', function(){
var target = event.target || event.srcElement;
$( 'mulSearchUser' ).value = target.innerHTML;
$( 'mulHdnDiffTo' ).value = target.innerHTML;
var targetIdx = target.id;
targetIdx = targetIdx.substr( targetIdx.indexOf( "_" ) + 1, targetIdx.length );
$( 'mulHdnSearchUser' ).value = MossUploader.suggestList[ targetIdx ].UserInfoID;
MossUploader.clearSuggestArea();
});
}
suggestArea.style.display = '';
},
isVaildKeyCode : function(){
keyList = [ 9, 12, 13, 16, 17, 18, 19, 28, 29, 33, 34, 35, 36, 37, 38, 39, 40, 45, 91, 93, 121, 122, 123, 144, 145, 240, 242, 243, 244 ];
for( var idx = 0; idx < keyList.length; idx++ ){
if( event.keyCode == keyList[ idx ] ) return false;
}
return true;
},
setFileName : function( param, enable ){
$( "mulReferPage" ).disabled = ( enable == 1 ) ? false : true;
if( $( "fileNameArea" ) ){
$( "fileNameArea" ).innerHTML = param;
}
},
renderSwf : function( elem ){
var obj = document.createElement( "object" );
obj.setAttribute( "width", "16" );
obj.setAttribute( "height", "16");
elem.appendChild( obj );
var prm = document.createElement( "param" );
prm.setAttribute( "name", "movie" );
prm.setAttribute( "value","http://moss/Documents/mossUploader.swf" );
obj.appendChild( prm );
prm = document.createElement("param");
prm.setAttribute( "name", "allowScriptAccess" );
prm.setAttribute( "value", "always");
obj.appendChild( prm );
obj.setAttribute( "classid","clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" );
obj.setAttribute( "id", "externalFileBase64Cvt" );
obj.setAttribute( "name", "externalFileBase64Cvt" );
obj.setAttribute( "data", "http://moss/Documents/mossUploader.swf" );
obj.setAttribute( "type", "application/x-shockwave-flash" );
obj.setAttribute( "wmode", "transparent" );
obj.setAttribute( "bgcolor", "#FFFFFFf" );
}
}
}
( function(){
MossUploader.initialize();
})();

汚いけどキニシナイ( ゚3゚)

mossUploader.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="0xffffff" styleName="plain" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.utils.StringUtil;
import flash.external.ExternalInterface;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import flash.system.Security;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.utils.ByteArray;
import mx.utils.Base64Encoder;
private var userParam:String;
private var base64Param:Array;
private var fileNameParam:String;
private var fileReference:FileReference;
private var base64encoder:Base64Encoder;
private var regstPath:String;
public function init(): void
{
Security.loadPolicyFile("http://moss/Documents/crossdomain.xml");
Security.allowDomain("*");
btn.addEventListener( MouseEvent.MOUSE_DOWN, onSelectButtonDown );
base64encoder = new Base64Encoder();
ExternalInterface.addCallback( "mossSrch", mossSrch );
}
private function mossSrch( user:String, fileName:String, sw:int ):void
{
var requestXML:XML;
if( sw == 0 ){
userParam = user;
requestXML = new XML('<SearchPrincipals xmlns="http://schemas.microsoft.com/sharepoint/soap/"><searchText>' + user + '</searchText><maxResults>20</maxResults><principalType>User</principalType></SearchPrincipals>');
people.SearchPrincipals( requestXML );
}
// catch base64File
else {
userParam = user;
fileNameParam = fileName;
var qry:String = '<Batch><Method ID="1" Cmd="New">' +
'<Field Name="Title">' + fileNameParam + '</Field>' +
'<Field Name="user">' + userParam + '</Field>' +
'<Field Name="url">http://moss/Lists/mylist</Field>' +
'</Method></Batch>';
requestXML = new XML('<UpdateListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>mylist</listName><updates>' + qry + '</updates></UpdateListItems>');
lists.UpdateListItems( requestXML );
}
}
private function pwsRsltEvt(event:ResultEvent):void{
var retAry:Array = new Array();
var rsltXML:XML = new XML( event.message.body.toString() );
var ns:Namespace = new Namespace( "http://schemas.xmlsoap.org/soap/envelope/" );
var bodyns:Namespace = new Namespace( "http://schemas.microsoft.com/sharepoint/soap/" );
var xmlList:XMLList = rsltXML.ns::Body[ 0 ].bodyns::SearchPrincipalsResponse[ 0 ].bodyns::SearchPrincipalsResult[ 0 ].bodyns::PrincipalInfo;
for each( var elemXML:XML in xmlList ){
var dpt:String = elemXML.bodyns::Department;
//                if( !dpt ) continue;
var acnt:String = elemXML.bodyns::AccountName.toString().replace( "\\", "\\\\" );
var dspName:String = elemXML.bodyns::DisplayName.toString().replace( "\\", "\\\\" );
retAry.push({
"AccountName" : acnt,
"UserInfoID" : elemXML.bodyns::UserInfoID.toString(),
"DisplayName" : dspName,
"Email" : elemXML.bodyns::Email.toString(),
"Department" : dpt
});
}
retAry.sortOn( "Department" );
ExternalInterface.call( "MossUploader.getUserSuggest", retAry  )
}
private function pwsFltEvt(event:FaultEvent):void{}
private function rgstwsRsltEvt(event:ResultEvent):void{
var rsltXML:XML = new XML( event.message.body.toString() );
var ns:Namespace = new Namespace( "http://schemas.xmlsoap.org/soap/envelope/" );
var bodyns:Namespace = new Namespace( "http://schemas.microsoft.com/sharepoint/soap/" );
var zns:Namespace = new Namespace( "#RowsetSchema" );
var base64:String = base64encoder.toString().replace( /\n/g, "" );
var regstId:String = rsltXML.ns::Body[ 0 ].bodyns::UpdateListItemsResponse[ 0 ].bodyns::UpdateListItemsResult[ 0 ].bodyns::Results[ 0 ].bodyns::Result[ 0 ].zns::row[ 0 ].@ows_ID
regstPath = rsltXML.ns::Body[ 0 ].bodyns::UpdateListItemsResponse[ 0 ].bodyns::UpdateListItemsResult[ 0 ].bodyns::Results[ 0 ].bodyns::Result[ 0 ].zns::row[ 0 ].@ows_FileRef
regstPath = "http://moss/" + regstPath.split( "#" )[ 1 ];
lists.AddAttachment( new XML('<AddAttachment xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>mylist</listName><listItemID>' + regstId + '</listItemID><fileName>' + fileNameParam + '</fileName><attachment>' + base64 + '</attachment></AddAttachment>') );
}
private function rgstwsFltEvt(event:FaultEvent):void{
ExternalInterface.call( "MossUploader.closePrompt" );
}
private function addwsRsltEvt(event:ResultEvent):void{
workflow.GetTemplatesForItem( new XML('<GetTemplatesForItem xmlns="http://schemas.microsoft.com/sharepoint/soap/workflow/"><item>' + regstPath + '</item></GetTemplatesForItem>') );
}
private function addwsFltEvt(event:FaultEvent):void{
ExternalInterface.call( "MossUploader.closePrompt" );
}
private function onSelectButtonDown(event:MouseEvent):void
{
ExternalInterface.call( "MossUploader.setFileName", "<img style=\"float:left\" src=\"http://moss/Documents/loader.gif\" /> now loading...", 0 );
fileReference = new FileReference();
fileReference.addEventListener( Event.SELECT, onSelect );
fileReference.addEventListener( Event.COMPLETE, onComplete );
fileReference.addEventListener( Event.CANCEL, function() : void {
ExternalInterface.call( "MossUploader.setFileName", "", 0 );
});
var fileFilter:FileFilter = new FileFilter( "すべてのファイル", "*.*" );
fileReference.browse( [fileFilter] );
}
private function onSelect(event:Event):void
{
fileReference.load();
}
private function onComplete(event:Event):void
{
var byteArray:ByteArray = fileReference.data;
if( fileReference.size > 20971520 ){
ExternalInterface.call( "window.alert", "20M以上のファイルはアップロードできません" );
ExternalInterface.call( "MossUploader.setFileName", "", 0 );
return;
}
if ( byteArray == null ) return;
base64encoder.encodeBytes( byteArray );
ExternalInterface.call( "MossUploader.setFileName", fileReference.name, 1 );
}
private function tmplwsFltEvt( event:FaultEvent ) : void
{
ExternalInterface.call( "MossUploader.closePrompt" );
}
private function tmplwsRsltEvt( event:ResultEvent ) : void
{
var rsltXML:XML = new XML( event.message.body.toString() );
var ns:Namespace = new Namespace( "http://schemas.xmlsoap.org/soap/envelope/" );
var bodyns:Namespace = new Namespace( "http://schemas.microsoft.com/sharepoint/soap/workflow/" );
var tmplId:String = rsltXML.ns::Body[ 0 ].bodyns::GetTemplatesForItemResponse[ 0 ].bodyns::GetTemplatesForItemResult[ 0 ].bodyns::TemplateData[ 0 ].bodyns::WorkflowTemplates[ 0 ].bodyns::WorkflowTemplate[ 0 ].bodyns::WorkflowTemplateIdSet[ 0 ].@TemplateId
workflow.StartWorkflow( new XML('<StartWorkflow xmlns="http://schemas.microsoft.com/sharepoint/soap/workflow/"><item>' + regstPath + '</item><templateId>' + tmplId + '</templateId><workflowParameters><Data /></workflowParameters></StartWorkflow>') );
}
private function strtwsFltEvt( event:FaultEvent ) : void
{
ExternalInterface.call( "MossUploader.closePrompt" );
}
private function strtwsRsltEvt( event:ResultEvent ) : void
{
ExternalInterface.call( "window.alert", "アップロードが完了しました" );
ExternalInterface.call( "MossUploader.closePrompt" );
}
]]>
</mx:Script>
<mx:WebService id="people" wsdl="http://moss/_vti_bin/People.asmx?wsdl" service="People">
<mx:operation name="SearchPrincipals" fault="pwsFltEvt(event)" result="pwsRsltEvt(event)"/>
</mx:WebService>
<mx:WebService id="lists" wsdl="http://moss/_vti_bin/Lists.asmx?wsdl" service="Lists">
<mx:operation name="UpdateListItems" fault="rgstwsFltEvt(event)" result="rgstwsRsltEvt(event)"/>
<mx:operation name="AddAttachment" fault="addwsFltEvt(event)" result="addwsRsltEvt(event)"/>
</mx:WebService>
<mx:WebService id="workflow" wsdl="http://moss/_vti_bin/workflow.asmx?wsdl" service="Workflow">
<mx:operation name="GetTemplatesForItem" fault="tmplwsFltEvt(event)" result="tmplwsRsltEvt(event)"/>
<mx:operation name="StartWorkflow" fault="strtwsFltEvt(event)" result="strtwsRsltEvt(event)"/>
</mx:WebService>
<mx:Button id="btn" width="16" height="16" skin="@Embed(source='upAttach.png')" downSkin="@Embed(source='downAttach.png')"/>
</mx:Application>

bookmarklet

javascript:(function(){if(window.MossUploader){MossUploader.initialize();} else {var x=document.createElement('script');x.src='http://moss/Documents/mossUploader.js';x.type='text/javascript';x.charset='utf-8';document.body.appendChild(x);}})();

ソースに出てくるURLなんかは適宜変更する必要があります。アイコンファイルなんかも用意する必要があります。

コメントをどうぞ