Add Attachment Problem with binary File

Jul 26, 2010 at 4:43 PM
Edited Jul 28, 2010 at 1:16 PM

Hallo

My Add Attachment Script work fine with Text-File, but wont work with binary files like pdf and/or docx.
I have tried a lot ... and now i'm out of new ideas. Can somebody help me.

Store this in a SharePoint Doclib, change the path to the JS-Script (don't change the order) and the variables SPwebURL, SPlistName.
This Script work only in IE (ActiveXObject("Scripting.FileSystemObject")). With ADODB.Stream i have a securtiy issue.
This Block in the Script is only a test to write back the input to the filesystem. The new file is ok.

                         // Test: Write Back to Filesysstem
                         // fio = fso.CreateTextFile("V:/temp/x" + fileName, true);
                         // for ( i = 0; i < strTransform.length; i++)
                         // {
                         //          fio.Write( strTransform[i]);
                         // }
                         // fio.Close();
                         // End Test


***

<!DOCTYPE HTML>
<HTML>
  <head>
         <title>SharePoint List - Create Item with Attachment</title>
         <script type="text/javascript" src="http://mysharepoint/js/jquery.min.js"></script>
         <script type="text/javascript" src="http://cdn.jquerytools.org/1.2.3/full/jquery.tools.min.js"></script>
         <script type="text/javascript" src="http://mysharepoint/js/jquery.SPServices.min.js"></script>
         <link rel="stylesheet" type="text/css" href="http://static.flowplayer.org/tools/demos/validator/css/form.css"/>
  </head>
<body>
<!--
  jQuery JavaScript Library v1.4.2
  SPServices Version 0.5.6

  http://spservices.codeplex.com/Thread/View.aspx?ThreadId=215346
  http://msdn.microsoft.com/en-us/library/lists.lists.addattachment%28v=office.12%29.aspx

  This is a html File stored in the SharePoint 2007 (MOSS)
-->

<form id="myform" name="myForm">

   <fieldset>
      <h3>SharePoint List <br> Create Item with Attachment</h3>

      <p> Fill Out and press OK. </p>
      <p>
         <label>Title *</label>
         <input name="titel" required="required" type="text" maxlength="100" style="width:500px" />
      </p>
      <p>
         <label>ToDo *</label>
         <input name="todo" required="required" type="text" maxlength="100" style="width:500px" />
      </p>
      <p>
        <label>Prio</label>
        <select name="prioritaet" required="required" size="1">
          <option value="(1) Hoch">Hoch</option>
          <option value="(2) Normal" selected>Normal</option>
          <option value="(3) Niedrig">Niedrig</option>
        </select>
      </p>
       <p>
         <label>Add Attachment</label>
         <input name="attfile" type="file" id="attfile" style="width:622px" />
      </p>

      <button type="submit">OK</button>
   </fieldset>

</form>

<script type="text/JavaScript">

  var SPwebURL = "http://mysharepoint";
  var SPlistName = "mylist";

// Javascript base64
// http://www.webtoolkit.info/javascript-base64.html
var Base64 = {

        // private property
        _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

        // public method for encoding
        encode : function (input) {
                var output = "";
                var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
                var i = 0;

                input = Base64._utf8_encode(input);

                while (i < input.length) {

                        chr1 = input.charCodeAt(i++);
                        chr2 = input.charCodeAt(i++);
                        chr3 = input.charCodeAt(i++);

                        enc1 = chr1 >> 2;
                        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                        enc4 = chr3 & 63;

                        if (isNaN(chr2)) {
                                enc3 = enc4 = 64;
                        } else if (isNaN(chr3)) {
                                enc4 = 64;
                        }

                        output = output +
                        this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
                        this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

                }

                return output;
        },

        // public method for decoding
        decode : function (input) {
                var output = "";
                var chr1, chr2, chr3;
                var enc1, enc2, enc3, enc4;
                var i = 0;

                input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

                while (i < input.length) {

                        enc1 = this._keyStr.indexOf(input.charAt(i++));
                        enc2 = this._keyStr.indexOf(input.charAt(i++));
                        enc3 = this._keyStr.indexOf(input.charAt(i++));
                        enc4 = this._keyStr.indexOf(input.charAt(i++));

                        chr1 = (enc1 << 2) | (enc2 >> 4);
                        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                        chr3 = ((enc3 & 3) << 6) | enc4;

                        output = output + String.fromCharCode(chr1);

                        if (enc3 != 64) {
                                output = output + String.fromCharCode(chr2);
                        }
                        if (enc4 != 64) {
                                output = output + String.fromCharCode(chr3);
                        }

                }

                output = Base64._utf8_decode(output);

                return output;

        },

        // private method for UTF-8 encoding
        _utf8_encode : function (string) {
                string = string.replace(/\r\n/g,"\n");
                var utftext = "";

                for (var n = 0; n < string.length; n++) {

                        var c = string.charCodeAt(n);

                        if (c < 128) {
                                utftext += String.fromCharCode(c);
                        }
                        else if((c > 127) && (c < 2048)) {
                                utftext += String.fromCharCode((c >> 6) | 192);
                                utftext += String.fromCharCode((c & 63) | 128);
                        }
                        else {
                                utftext += String.fromCharCode((c >> 12) | 224);
                                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                                utftext += String.fromCharCode((c & 63) | 128);
                        }

                }

                return utftext;
        },

        // private method for UTF-8 decoding
        _utf8_decode : function (utftext) {
                var string = "";
                var i = 0;
                var c = c1 = c2 = 0;

                while ( i < utftext.length ) {

                        c = utftext.charCodeAt(i);

                        if (c < 128) {
                                string += String.fromCharCode(c);
                                i++;
                        }
                        else if((c > 191) && (c < 224)) {
                                c2 = utftext.charCodeAt(i+1);
                                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                                i += 2;
                        }
                        else {
                                c2 = utftext.charCodeAt(i+1);
                                c3 = utftext.charCodeAt(i+2);
                                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                                i += 3;
                        }

                }

                return string;
        }

}

// SharePoint FileName
  function SetSharePointFileName(filename_input)
  {
         filename_input = filename_input.replace("\\", "");
         filename_input = filename_input.replace("/", "");
         filename_input = filename_input.replace(":", "");
         filename_input = filename_input.replace("*", "");
         filename_input = filename_input.replace("?", "");
         filename_input = filename_input.replace('"', '');
         filename_input = filename_input.replace("<", "");
         filename_input = filename_input.replace(">", "");
         filename_input = filename_input.replace("|", "");
         filename_input = filename_input.replace("#", "");
         filename_input = filename_input.replace("{", "");
         filename_input = filename_input.replace("}", "");
         filename_input = filename_input.replace("%", "");
         filename_input = filename_input.replace("~", "");
         filename_input = filename_input.replace("&", "");

         return filename_input;
  }

</script>

<script type="text/javascript">

$(document).ready(function() {

  // Auf Titel positionieren
  self.focus();

  $("#myform").validator();

  // get handle to the Validator API
  var api = $("#myform").data("validator");

  // use API to assign an event listener
  api.onSuccess(function(e, els) {

         if ( els.length != 4 ) { return false; };

         var newID = 0;
         var inputfile = $("#myform").attr("attfile").value;

         var t_Kategorie = "Change Request"; // $("#myform").attr("kategorie").value ;
         var t_DokumentenName = $("#myform").attr("titel").value ;
         var t_ToDo = $("#myform").attr("todo").value ;

         $().SPServices(
         {
                 operation: "UpdateListItems",
                 async: false,
                 webURL: SPwebURL,
                 listName: SPlistName,
                 batchCmd: "New",
                 ID: 0,
                 valuepairs: [
                  ["Title", t_DokumentenName],
                  ["ToDo", t_ToDo]
                 ],
                 completefunc: function(xData, Status)
                 {
                         $(xData.responseXML).find('[nodeName=z:row]').each(function()
                         {
                                 //alert("Message : "  + Status + " Text " + xData.responseXML.xml);
                                 if ( Status != "error" )
                                 {
                                          newID = $(this).attr("ows_ID");
                                          alert ( "Item with Number " + newID + " created" );
                                 } else {
                                         alert("Error : " + xData.responseXML.xml);
                                 }
                        });         // $(xData.responseXML).find('[nodeName=z:row]').each(function()
                 }        // completefunc: function(xData, Status)
         });          // $().SPServices({
         // *1* alert ( inputfile.length );
         // On Success Add Attachment
         if ( inputfile.length > 0 )
         {
                 var fso = new ActiveXObject("Scripting.FileSystemObject");
                 var fio = fso.GetFile( inputfile);
                 // *2* alert ( "file input : " + inputfile + " file exists : " + fso.FileExists( inputfile ) + " file size : " + fio.Size );
                 // check file exist and is not empty
                 if ( fso.FileExists( inputfile ) && fio.Size > 0   )
                 {
                         var fileName = SetSharePointFileName(fso.GetFileName( inputfile ));

                         // Prepare Attachment
                         // var attFile_V0 = fso.OpenTextFile( inputfile, 1, false, -0 );  // -1 = unicode, 0 = Opens the file as ASCII, -2 = Use System Default
                         // var fText_V0 = attFile_V0.ReadAll();

                         var streamIO = fio.OpenAsTextStream();
                         var strTransform = new Array();
                         for ( i = 0; i < fio.Size; i++ )
                         {
                                 var strContent = streamIO.Read(1);
                                 //fehler  strTransform[i] = strContent.charCodeAt(0);
                                 strTransform[i] = strContent;
                         }
                         streamIO.Close();

                         // Test: Write Back to Filesysstem
                         // fio = fso.CreateTextFile("V:/temp/x" + fileName, true);
                         // for ( i = 0; i < strTransform.length; i++)
                         // {
                         //          fio.Write( strTransform[i]);
                         // }
                         // fio.Close();
                         // End Test

                         var Content = strTransform.join("");
                         var fileContent = Base64.encode( Content );

                         // *3* alert ( "Add Attachment to #" + newID + " with the Name " + fileName + " and the Content " + fileContent );

                         $().SPServices(
                         {
                           operation: "AddAttachment",
                           webURL: SPwebURL,
                           listName: SPlistName,
                           listItemID: newID,
                           fileName: fileName,
                           attachment: fileContent,
                           async: false,
                           completefunc: function(xData, Status)
                           {

                             // *4* alert("Message : "  + Status + " Text " + xData.responseXML.xml);
                             $(xData.responseXML).find('[nodeName=AddAttachmentResult]').each(function(){
                                 if ( Status != "error" )
                                 {
                                         alert ( "Attachment with the name " + fileName + " attached to the item " + newID + " "  );
                                 } else {
                                         alert("Error : " + xData.responseXML.xml);
                                 }
                             });
                           }
                         });
                 }
         }

         // Close Window
         // window.opener = "whocares";
         // window.close();

         alert ( "Close Window" );
         return false;

  });          // api.onSuccess(function(e, els) {
});         // $(document).ready(function() {

</script>

  </body>
</html>


***

 

- bernardo -

Jul 26, 2010 at 7:03 PM
polarbear_ch thanks for sharing this. but i believe I will need some help from you as I'm having trouble testing this code out. I took your code and saved it as demo.aspx page. Then I placed the demo.aspx page in my SharePoint Documents Lib. Also, changed the path to my respective js files (not the order) and the values for var SPwebURL = "http://bi-qa"; var SPlistName = "Request Services"; Testing demo.aspx in IE8 but no dice, I'm looking into FirebugLT for IE to see if the XHR POST call is being made but don't observe anything happening when I click the OK button. Any suggestions?
Jul 26, 2010 at 7:42 PM
Edited Jul 26, 2010 at 7:48 PM

Hallo new2all

 a) I'm stored the sample as .htm file.

 b) Have yout the fields "Titel" and "ToDo"  in our SharePoint-Lists. 

 c) I tested this with IE6. i can test this sample with IE8 tomorrow. (And this script runs for the second, importent part not in FF. ActiveXObject("Scripting.FileSystemObject") is not support in FF or Safari.)

maybe is this the solution for our IE8 problem http://stackoverflow.com/questions/2964531/ie8-activexobject-problem

d) My Sample works only with textfile

- Bernardo -

Jul 26, 2010 at 9:17 PM
polarbear_ch I followed all the steps you mention but this time I tested in IE6 and it worked :) - the demo.htm does give me an alert about the item being created but does not transfer the attachment? I'm using a simple TXT file called upload.txt and the contents of the upload.txt is "hello" I have attachments enabled on the list I'm using for testing your code. any suggestions? thx
Jul 27, 2010 at 9:54 AM
Edited Jul 27, 2010 at 10:54 AM

it works with IE8 (Zone local intranet).

a) you have not changed the order of .js files in the header?

b) // alert ( "Add Attachment to #" + newID + " with the Name " + fileName + " and the Content " + fileContent );

   Activate this alert -> You can see how it looks befor you call the SPService

c)  // alert("Message : " + Status + " Text " + xData.responseXML.xml);

Activate this alert -> Sometime he have the Status "success" but he make no attachment. When this happen the xData is empty and my kind of feedback say nothing.....!!!!

d) when both alert not fire make an new alert prior to line
 if ( fso.FileExists( inputfile ) && fio.Size > 0   )

alert ( "file input : " + inputfile + " file exists : " + fso.FileExists( inputfile ) + " file size : " + fio.Size );
---

to state more precisely: you can use evrey kind of filestpyes. but when upload an pdf or a docx file, the attachment is not readable...... thats my problem.

- Bernardo -

Coordinator
Jul 28, 2010 at 12:41 AM

Guys:

This is a great discussion. I'm just standing back and enjoying it!

M.

Jul 28, 2010 at 4:24 AM

polarbear_ch same thing :( I re-checked all the code once again line by line but I get the same result, the HTM page creates the ITEM but does not transfer the attachments. I'm only testing TXT files here.

 

  <head>
         <title>SharePoint List - Create Item with Attachment</title>
         <script type="text/javascript" src="../js/jquery-1.4.2.min.js"></script>
         <script type="text/javascript" src="http://cdn.jquerytools.org/1.2.3/full/jquery.tools.min.js"></script>
         <script type="text/javascript" src="../js/jquery.SPServices-0.5.6.min.js"></script>
         <link rel="stylesheet" type="text/css" href="http://static.flowplayer.org/tools/demos/validator/css/form.css"/>
  </head>

Good knowing that once could transfer all types of files (as you mention) but I'm understanding the concepts as well as doing development, I'm a newbie/rookie :) - I did notice one thing though, when I turned on the first alert to read the success text I observed in the soap:Envelope that ows_Attachments="0"

I will try once again on another server, and will update you with my results (hopefully successful). thx once again for all the help

 

 

M - it is a great discussion, any blessings? :-)

Jul 28, 2010 at 2:51 PM
Edited Jul 28, 2010 at 2:55 PM

ok new2all

Strange. I checked the source yesterday - fine.
You say you have Attachments enabled on the list - ok. I have Contributions rights on the list.
-> Please make a test with the SharePoint Native function and add a attachment.

When you create a new item with this code, the field ows_Attachments must be zero (="0" ). The script create the new item and then add the attachment.
With this script and you add a attachment the item has the version 2.

I changed the source a litte bit (one new alert, insert the new alert form the post and give all 4 alert a number)

my attachment for this test is upload.txt with the content "hello"

a) alert *1* // *1* alert ( inputfile.length );                      
 *** MY SAMPLE *** = 18
 - inputfile.length: must be a number higher then zero - otherwise your string from the formfield is empty ...!
  -> var inputfile = $("#myform").attr("attfile").value

b) alert *2* - // *2* alert ( "file input : " + inputfile + " file exists : " + fso.FileExists( inputfile ) + " file size : " + fio.Size ); 
 *** MY SAMPLE *** = file input : C:\temp\upload.txt file exists : true file size : 5
 - file input: you have the path and the name of the file
 - file exists: must be true - otherwise your script dont find the file ...!
 - file size: must be a number higher then zero - otherwise you have no size or size zero = both bad ...!

c) alert *3* // *3* alert ( "Add Attachment to #" + newID + " with the Name " + fileName + " and the Content " + fileContent );
 *** MY SAMPLE *** = Add Attachment to #501 with the Name upload.txt and the content aGVsbG8=
 - newId : is the number of the new Listitem
 - fileName: is the name (only the name) of the file without characters they would blocked by SharePoint for filenames
 - fileContent: is the file base64 encode - prepared to store in sharepoint

d) alert *4* // *4* alert("Message : "  + Status + " Text " + xData.responseXML.xml);
 *** MY SAMPLE *** =  Message : success Text <?xml version="1.0"?>
     <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><AddAttachmentResponse           xmlns="http://schemas.microsoft.com/sharepoint/soap/"><AddAttachmentResult>..........
     ...../Attachments/501/upload.txt</AddAttachmentResult></AddAttachmentResponse></soap:Body></soap:Envelope>
 - Status: the return code form the service
 - xData : the message from the service

 

When you have the alert "Item with Number 999 created" you must also have the new alert #1 with a number
 is this not a number higher then zero -> something wrong with the way from the form field to var -> check it

When alert #1 is fire and ok you must also have the alert #2; when not: it must be a problem with "ActiveXObject("Scripting.FileSystemObject");"
 inputfile something like "c:\temp\update.txt", file.exists = true and file size a number over zero -> check it

When alert #2 is fire and ok you must also have the alert #3; when not: ??? strange ???
 newID must be the number from create item (or a valid id from a existing item), fileName and fileContent must have some strings/values

When alert #3 is fire and ok you must also have the alert #4; when not a) No alert "Close Window": the service is crashed
                                                                                                      b) with alert "Close window": ??? strange ????
 must be success and data must be a xml-text  
 

good luck - bernardo -

 

Coordinator
Jul 29, 2010 at 2:50 AM

Oh, you definitely have my blessings, and I'm looking forward to having more time to really dig into this!

M.

Nov 3, 2010 at 3:34 PM

Can anyone please help me out with the attachment , using this js files please.....

Do you have any articales for this..!?

This is the only functionality missing in my form...!! :(

Thanks

Parth

Coordinator
Nov 3, 2010 at 5:59 PM

Parth:

It probably makes more sense to start a new thread, as you're not really continuing thins discussion. However, I'd suggest that you read through the documentation for the AddAttachment operation and then ask specific questions if you have them.

M.

May 20, 2011 at 8:48 PM

Don't know if it  is a good idea reviving this thread. But I seem to have this script working for non-text files. Even in IE8/IE9 (You need to enable a few ActiveX settings in IE as linked from one of the above posts). The attachments are getting created and uploaded. However, there is something wrong with the Base64 encoding algorithm. The attached files appear to be corrupted. On re-download, their file size is increased (as compared to the original size) and they no longer open in the associated program.

Jul 4, 2013 at 4:43 AM
Not sure if this is still relevant but have had a similar issue uploading pdf's and images and have a solution that seems to work in the browsers I have tested.
Spservices add attachments