logo

New Response

« Return to the main article

You are replying to:

  1. Here is a way to show multiple attachments (up to 100, but could be 1000!). I like this, because its an @function that you can tear apart and use in all sorts of situations involving lists of things and extracting things from them.

    What it does is to display nice small icons next to links to the files anywhere on the form, rather than the big ugly ones at the bottom only like we are trying to do in these articles. Actually it splits the collection of attachments in half, so they list in two columns (hence the @modulo). You could easily modify it to show descriptions instead of filenames or include a delete link/icon/checkbox like Jake did.

    In a two cell table put this into a pass through computed text in the left cell: @If(@Attachments; "";@Return("There are no attachments on this document.")); size := @Integer(@Attachments/2)+(@Modulo(@Attachments;2) != 0); num1 := 0:1:2:3:4:5:6:7:8:9; num10p := 10 ** num1; num100 :=(num10p*+num1); exts:="doc":"dot":"xls":"xlt":"txt":"zip":"exe":"mdb":"gif":"jpg":"bmp":"htm":"h tml":"wav":"pdf":"ppt":"hlp":"wav":"swf":"mov":"mpg":"mpeg":"xml":"xsl":"unk"; maps := "wrd":"wrd":"xl":"xl":"txt":"zip":"exe":"mdb":"img":"img":"img":"url":"url":"wav ":"pdf":"ppt":"hlp":"wav":"swf":"mov":"mov":"mov":"xml":"xml":"unk"; unks := @Explode(@Trim(@Repeat("unk ";@Attachments))); nums := @Text(@Subset(num100;@Elements(exts))); att_exts := @MiddleBack(@AttachmentNames;".";10); nms := @Replace(@Replace(@Replace(@Replace(att_exts;exts;nums);att_exts;unks);nums;exts );exts;maps); @Implode( @Subset( "<img src=\"/"+webDbName+"/icon-" + nms + ".gif\"> <a href=\"" + @Text(@DocumentUniqueID) + "/$file/" + @AttachmentNames+ "\">" + @AttachmentNames + "</a> " + @Text(@Round(@AttachmentLengths/1024)) + " (KB)"; size ); "<br/>"+@NewLine )

    Then do the same thing for the right cell with this formula: @If(@Attachments; "";@Return("")); size := (@Integer(@Attachments/2)+(@Modulo(@Attachments;2) != 0)) - @Attachments; @If(size>-1; @Return(""); ""); num1 := 0:1:2:3:4:5:6:7:8:9; num10p := 10 ** num1; num100 :=(num10p*+num1); exts:="doc":"dot":"xls":"xlt":"txt":"zip":"exe":"mdb":"gif":"jpg":"bmp":"htm":"h tml":"wav":"pdf":"ppt":"hlp":"wav":"swf":"mov":"mpg":"mpeg":"xml":"xsl":"unk"; maps := "wrd":"wrd":"xl":"xl":"txt":"zip":"exe":"mdb":"img":"img":"img":"url":"url":"wav ":"pdf":"ppt":"hlp":"wav":"swf":"mov":"mov":"mov":"xml":"xml":"unk"; unks := @Explode(@Trim(@Repeat("unk ";@Attachments))); nums := @Text(@Subset(num100;@Elements(exts))); att_exts := @MiddleBack(@AttachmentNames;".";10); nms := @Replace(@Replace(@Replace(@Replace(att_exts;exts;nums);att_exts;unks);nums;exts );exts;maps); @Implode( @Subset( "<img src=\"/"+webDbName+"/icon-" + nms + ".gif\"> <a href=\"" + @Text(@DocumentUniqueID) + "/$file/" + @AttachmentNames+ "\">" + @AttachmentNames + "</a> " + @Text(@Round(@AttachmentLengths/1024)) + " (KB)"; size ); "<br/>"+@NewLine )

    Then add the computed for display $V2AttachmentOptions field with the value "0" hidden at the top of the form. Also you will need a field named "WebDbName" which is @dbname with the "\" chars changed to "/" (Jake's "DbPath" field). You will also need some image resources for the small icons. I named mine "icon-xxx.gif" where xxx is the file attachment extention listed in the "maps" variable, "pdf":"doc":"txt":"html":"zip" etc. Basically it says "map zip, gzip, z, tar" files to "icon-zip.gif" etc.

    Also, you have to have fileuploads somewhere. I used four. I displayed them in edit mode and hid the above computed texts in read mode. I never wanted to remove attachments, so I didn't build that into it.

    Here is a detailed explanation, at least of the first of the two formulas:

    Check if there are any attachments. If not then emit some nice message @If(@Attachments; "";@Return("There are no attachments on this document."));

    Size is the number of attachments divided by 2, or as close as you can if its an odd number. It’s the number of icons to show in the left column. size := @Integer(@Attachments/2)+(@Modulo(@Attachments;2) != 0);

    Make a list of 100 sequencial numbers from 0 to 99. A couple more lines, and it could be 1000. We will use a subset of this list… The number of total attachments has to be less than the length of this list, so if you expect more than 100 attachments you better change the formula here (and add a large hard drive, a few memory sticks and an disaster recovery plane to your server). Note the use of the permuted ** and *+ operators. num1 := 0:1:2:3:4:5:6:7:8:9; num10p := 10 ** num1; num100 :=(num10p*+num1);

    This is the list of extentions of files that people might attach. If its not one of these, then it will revert to the last one in it, “unk”, so that we can display the questionmark icon. exts:="doc":"dot":"xls":"xlt":"txt":"zip":"exe":"mdb":"gif":"jpg":"bmp":"htm":"h tml":"wav":"pdf":"ppt":"hlp":"wav":"swf":"mov":"mpg":"mpeg":"xml":"xsl":"unk";

    Each of the above extentions needs an icon. “doc” and “dot” are MS-Word files, so they get the mapping “wrd” so that we can later use the icon named “icon- wrd.gif”. Same with “xml” and “xsl”, they get the icon-xml.gif icon. If you have some really weird ones, then make your own here. (“pl”,”pm” for perl?) Depends on what you expect. maps := "wrd":"wrd":"xl":"xl":"txt":"zip":"exe":"mdb":"img":"img":"img":"url":"url":"wav ":"pdf":"ppt":"hlp":"wav":"swf":"mov":"mov":"mov":"xml":"xml":"unk";

    This is a list containing “unk”:”unk”:”unk”… up to the total number of attachments. We will use it in an @replace in a minute. unks := @Explode(@Trim(@Repeat("unk ";@Attachments)));

    This is a sequential list of numbers from 0 to however many attachments there are. We will soon use it to replace known file extentions with them. nums := @Text(@Subset(num100;@Elements(exts)));

    This is the list of the actual extentions that the attachements have. I had to use @middleback, but I forget why. Maybe it was because the filename included the url which had a period in it. Any this works for me, ymmv. Pick another number besides ten, or use @rightback or something. The point is, to get a list of file extentions here. att_exts := @MiddleBack(@AttachmentNames;".";10);

    Here is where we do the replacements. I’ll break it down since there are four of them working from the middle. Replace the the actual file extentions that match the ones we know about with the something that is unique. sequencial numbers are unique, so they fit the bill. If they weren’t, we would never be able to undo it. This makes a list like this: “9”:”pdq”:”blah”:”4”:”ini” basically anything we know about will be set to a number, anything we don’t know about will be left alone. Next, using that list where it matches the original list (and the numbers won’t match anymore) replace the ones we don’t know about with “unk”. Hence the list of “unk”:”unk” etc. Note that @Replace likes lists to be the same size or divine retribution will be yours. This makes a list like this: “9”:”unk”:”unk”:”4”:”unk” Next, we replace the numbers in the list with their equivalent extentions that we know about. “gif”:”unk”:”unk”:”xlt”:”unk” We are now left with a list of extentions that we know all about. (we know about “unk”, its in the list). All we do now is replace them with the mapped names of the icons (the part of the name that counts anyway) and set “nms” equal to it. “img”:”unk”:”unk”:”xl”:”unk” So if you say, for example “icon-“ + nms + “.png” this will be the list “icon-img.png”:”icon-ink.png”:”icon-unk.png”:”icon-xl.png”:”icon-unk.png” which looks like a list of image names, and it is, (except I’m using gifs for some god awful reason, so my line is a little different)

    nms := @Replace(@Replace(@Replace(@Replace(att_exts;exts;nums);att_exts;unks);nums;exts );exts;maps);

    Next, since we are creating computed text, we make such a list, but adding html into it in the right places. Also, since computed text prefers to be one long string, we implode it so that it doesn’t have those weird commas. And since we only want to show the first half of the list, we use @subset, and that “size” variable I made at the beginning.

    @Implode( @Subset(

    Start with the img tag and give it its source attribute. WebDbName is the modified @dbname in a hidden computed for display field at the top. This should look familiar to the example “.png” code above if you strip away the html… "<img src=\"/"+webDbName+"/icon-" + nms + ".gif\"> <a href=\"" + @Text(@DocumentUniqueID) + These and the above line makes the link to the file attachment. You can change all this to run ?openAgent etc to run an agent that will print content-type headers, read binary and write them out etc. "/$file/" + @AttachmentNames+ "\">" + This is the text of the links. It’s got the same number of elements as @attachments, nms etc, so you can add the arrays one for one, no problem. @AttachmentNames + "</a> " + Same thing here, except it’s the size of each attachment @Text(@Round(@AttachmentLengths/1024)) + " (KB)"; Ok, that just created the list of links for the whole shebang, here is where we get the first half of it. The second half is done with the other formula size ); Add to that list of links, a break tag and a newline to keep things neat in the browser and in the html... (don’t use <br/> in emails to notes users. The notes client doesn’t know what to do with it, use <br> instead, and complain a lot to lotus about complying to html standards NS4 doesn’t know what to do with it either… does anyone use that anymore? Aack!). "<br/>"+@NewLine ) And that’s it. Note that the icon is just that, an icon, its not a live link or a delete button, or a “download here” button. It could be, I suppose. The real meat here is the Big @Replace statement preceded by the sequencial number list generator, the list of expected extentions, actual extentions, and maps to the icon filenames.

    Of course, you have to have image resources or some other method for the icons. I hate using vwicoXXX.gif icons because, well, they are gifs, and that’s proprietary (owned by Unisys) and they just look so… 1990s. (back when we all had great jobs because we knew Domino)

    Regards, -Bill Wheaton

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment: