Who is this guy?

PlanetLotus.org

Idea Jam

Flickr Photos

www.flickr.com
This is a Flickr badge showing photos in a set called BlogPics. Make your own badge here.

Blogroll

The Badges

July 23rd, 2008

S&TT - Tagging Mail Documents...slightly extended

One day early for S&TT, but I couldn't wait...

Ever since I read the post that Chris Blatnick put up last month about adding tagging to your mail file, I have been intrigued.  I quickly did as he suggested and created a new toolbar button with the code he provided and starting tagging away. 

I quickly realized that this was going to be a tedious process in a couple of ways if I was going one document at a time and had virtually no way of knowing whether the documents had been tagged.  I of course don't want to, and can't, make design changes to the design elements of my mail file, but I could create a new view based off of an existing view then add a column for the tagging information and also some actions related to tagging, instead of just using the toolbar icon.

I created a new view based off the All Documents view (called it 'All by Tags') and threw 2 columns into it, in front of the Who column, one being a category totals column with detail rows hidden, and then a categorized column, showing multiple values as separate entries, and with the formula - @If(txt_customtags = ""; "*No tags applied";txt_customtags).  This now brings the tags applied to the forefront, and also shows which emails do not have any tags applied yet, all together.

I modified the code for setting the tags on the document slightly resulting in this view action called "Tag Document":

REM {Get tags stored in database};
Tags := @GetProfileField("TagsProfile";"txt_CurrentTags";@UserName);

REM {Get any tags from the selected document};
DocTags := txt_CustomTags;

Selection := @Prompt([OkCancelListMult]; "Select Tag(s)"; "Please select the tag(s) to apply to this document"; DocTags; @Trim("*-add new-*" : @Unique(Tags : DocTags)));

@If(Selection = 1;
              @Return("");
@IsMember("*-add new-*"; Selection);
               @Set("NewTag"; @Prompt([OkCancelEdit]; "Enter New Tag"; "Please enter the new tag(s) you would like to apply to this document.  Separate tags with a comma"; ""));
                "");

UpdatedList := @Trim(@Unique(@Replace(Selection; "*-add new-*"; "") : @Explode(NewTag;"," )));

FIELD txt_CustomTags := UpdatedList;

@SetProfileField("TagsProfile"; "txt_CurrentTags"; @Unique(UpdatedList : Tags); @UserName)



Then I wanted to be able to see the list of tags applied to a document (especially when it is more than one tag), so I created this action called "Display Tags":

@Prompt([Ok]; "This Document's Tag(s)"; "Tags applied to this document: " + @NewLine + @NewLine + @Implode(txt_CustomTags;@NewLine));
@True

Lastly, I wanted a way to clear all the tags as Chris suggested, so I create another action called "Clear Tags":


FIELD  txt_CustomTags := @Unavailable;
@True


Now, back to what I mentioned earlier, this is all well and good, but what if I want to set a tag or various tags on a whole bunch of documents at once?  Vitor Pereira suggested in a comment on the original post that perhaps this code coupled with a little bit of Chad Schelfhout's Edit Document Fields code could allow us to modify more than one document.

So I had a go at it...

Here's what I came up with, in an action called "Tag Multiple Documents":

REM {Get tags stored in database};
Tags := @GetProfileField("TagsProfile";"txt_CurrentTags";@UserName);

Selection := @Prompt([OkCancelListMult]; "Select Tag(s)"; "Please select the tag(s) to apply to these documents"; ""; @Trim("*-add new-*" : @Unique(Tags)));

@If(Selection = 1;
              @Return("");
@IsMember("*-add new-*"; Selection);
               @Set("NewTag"; @Prompt([OkCancelEdit]; "Enter New Tag"; "Please enter the new tag(s) you would like to apply to this document.  Separate tags with a comma"; ""));
                "");

UpdatedList := @Trim(@Unique(@Replace(Selection; "*-add new-*"; "") : @Explode(NewTag;"," )));

REM {Unchangable constants};
cPromptTitle := @DbTitle + " - " + @ViewTitle;
cNoteEntryLength := 11;
cArraySeparator := ";";
cMaxSearchForSelectedDocs := 5520;
cCategoryNoteID := "NT00000000";
cPromptNewLineOne := @Char(13);
cPromptNewLineTwo := cPromptNewLineOne + cPromptNewLineOne;
cPromptTab := @Char(9);
cErrorInformation := "\"Error documents: \" + @Implode( @Unique( @Explode( ErrorNoteIDList ; cArraySeparator ; @False ) ) ; \", \" ) + cPromptNewLineOne + \"Not updated documents: \" + @Implode( @Unique( @Explode( ErrorNoteIDList ; cArraySeparator ; @False ) ) ; \", \" )";

REM {Store all Note IDs before manipulation in case field modifications cause categorized views or sorted columns to reorganize};
NoteIDList := @Text( @NoteID );
ErrorNoteIDList := "";
@Command([NavNextSelected]);
@UpdateFormulaContext;

REM {Start Looping Selected documents to gather all the documents that need to be updated.};
@While( ( @Left( NoteIDList ; cNoteEntryLength ) != ( @Text( @NoteID + cArraySeparator ) ) ) & ( @Length( NoteIDList ) < cMaxSearchForSelectedDocs ) ;
 NoteIDList := NoteIDList + cArraySeparator + @Text( @NoteID );
 NoteIDList := @ReplaceSubstring( NoteIDList ; cCategoryNoteID + cArraySeparator ; "" );
 @Command([NavNextSelected]);
 @UpdateFormulaContext
);

REM {Remove all category Note IDs};
NoteIDList := @ReplaceSubstring( NoteIDList ; cCategoryNoteID ; "" );

REM {Remove all duplicate Note IDs};
NoteIDList := @Unique( @Explode( NoteIDList ; cArraySeparator ; @False ) );
@StatusBar( "Found " + @Text( @Elements( NoteIDList ) ) + " documents." );
NotNoteIDList := "";

EditField :=  form;

REM {Loop through selected docs taking each NoteIDList out of the list as it is processed};
DocUpdateCount := 0;
DocNavigationCount := 0;
@While( DocUpdateCount < @Elements( NoteIDList ) ;
 @If( @TextToNumber( @Text( @DocumentUniqueID ) ) != 0 ;
  @Do(
   NoteIDList := @Replace( NoteIDList ; @NoteID ; "" ) ;
   NotNoteIDList := NotNoteIDList : @NoteID;
   formulaResult := @Eval( @SetField("txt_CustomTags"; @Trim(@Unique(UpdatedList:txt_CustomTags))));
               DocUpdateCount := DocUpdateCount + 1;
   @UpdateFormulaContext
             );
 "")
);

@StatusBar( "Navigated through " + @Text( DocUpdateCount + DocNavigationCount ) + " documents." );

@SetProfileField("TagsProfile"; "txt_CurrentTags"; @Unique(UpdatedList : Tags); @UserName)

This last action does have some more work to be done on it, but it works (as far as I can tell) if you stick to the following rules:
  - The set of selected documents must be contiguous (all together in the view)
  - You must leave your cursor (highlight, whatever...) on the first document of the list of selected (checked) documents.
   - The action doesn't de-select the documents once they have been modified, so you need to be careful to clear any selections before doing your next set of tagging (easy to do via Edit...Deselect All)

I'd love to hear if any of your try this set of functionality out and it works for you, and also if you can get around any of the shortcomings of my current code for tagging multiple documents at once, as this was a true trial and error (many, many errors) thing.

Special thanks to Chris Blatnick for putting this in front of us in the first place!

August 2008
Su
Mo
Tu
We
Th
Fr
Sa
2
3
5
6
7
8
9
10
11
12
13
14
16
18
19
20
21
22
23
24
25
26
27
28
29
30
31

OpenNTF.org

Latest Googles

Latest Referrers

Credit where it's due

Special thanks to Chris Miller at Connectria for providing hosting services for this site.

How many did you say?

brave souls have visited this strange place

Super Secret Web Admin Thingie ;-)