<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.dovetailsoftware.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Sam Tyson</title><subtitle type="html" /><id>http://blogs.dovetailsoftware.com/blogs/styson/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.dovetailsoftware.com/blogs/styson/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.61129.2">Community Server</generator><updated>2009-01-12T18:11:41Z</updated><entry><title>Running mklink in NAnt</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2010/02/05/running-mklink-in-nant.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2010/02/05/running-mklink-in-nant.aspx</id><published>2010-02-05T19:10:23Z</published><updated>2010-02-05T19:10:23Z</updated><content type="html">&lt;p&gt;Since there is not an executable for &lt;strong&gt;mklink&lt;/strong&gt;, it took me a minute to figure a good solution to running &lt;strong&gt;mklink&lt;/strong&gt; as a target in my build script.&lt;/p&gt;  &lt;p&gt;The NAnt has an exec task that is used for running command line targets, but it requires an executable as its target. The command shell works in this situation, so I just need to exec the command shell, and have it execute &lt;strong&gt;mklink &lt;/strong&gt;as its target.&lt;/p&gt;  &lt;p&gt;Here is my NAnt target:&lt;/p&gt;  &lt;p&gt;&amp;lt;exec program=&amp;quot;cmd&amp;quot; commandline=&amp;quot;/c mklink /d mobile\source\CustomControllers customizations\Controllers&amp;quot;/&amp;gt;&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=12037" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author></entry><entry><title>Transitioning Beyond 255 Transitions</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2010/01/29/transitioning-beyond-255-transitions.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2010/01/29/transitioning-beyond-255-transitions.aspx</id><published>2010-01-29T23:49:28Z</published><updated>2010-01-29T23:49:28Z</updated><content type="html">&lt;p align="justify"&gt;&lt;img style="margin:0px 0px 10px 10px;display:inline;" align="right" src="http://artstudiosecrets.com/wp-content/uploads/2009/03/colorwheel.jpg" width="201" height="198" /&gt;In Clarify, Logistics and Quality both use transitions to determine how a request moves from one condition to another. To change a condition, a transition must be defined between the two conditions for that part request type. To restrict access to critical part operations, you can administer permissions according to privilege classes.&lt;/p&gt;  &lt;p align="justify"&gt;In complex installations, the number of transitions across both business areas can easily reach the imposed limit of 256 transitions. This limitation can truly impose headaches when the transitions cannot be accurately configured to match the business process.&lt;/p&gt;  &lt;p align="justify"&gt;&lt;strong&gt;Dovetail Admin &lt;/strong&gt;can also be used to configure the transitions, and now it does not enforce the same limitation. It does use the same mechanism for storage, so a little bit of work needs to be done to allow more transitions to be set up, and using &lt;strong&gt;Dovetail Agent&lt;/strong&gt; (or the &lt;strong&gt;Dovetail SDK&lt;/strong&gt;) to take advantage of the enhanced capability.&lt;/p&gt;  &lt;p align="justify"&gt;The limitation is actually caused by the size of the trans_mask field in table_privclass. Normally, transitions are ranked from 0 to 254, and this string field size is set to 255 characters in the baseline database. The use of a transition is stored for each privilege class is indicated by the corresponding character in this field according to the rank of the transition.&lt;/p&gt;  &lt;p align="justify"&gt;To allow for more transitions, the size of the trans_mask field in table_privclass has to be increased. For example, to double the number of transitions allowed, the field size would need to be changed to a string of 512 characters. This change in the schema can be easily accomplished using &lt;strong&gt;Dovetail SchemaEditor&lt;/strong&gt;, by applying the following &lt;em&gt;SchemaScript&lt;/em&gt; file to the database:&lt;/p&gt;  &lt;div align="justify"&gt;   &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;     &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;       &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;schemaScript&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;xmlns&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;http://www.dovetailsoftware.com/2006/10/SchemaScript.xsd&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;updateColumn&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;trans_mask&amp;quot;&lt;/span&gt;  &lt;span style="color:#ff0000;"&gt;table&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;privclass&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;length&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;512&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;length&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;updateColumn&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


      &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;schemaScript&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;Once this change is done, open &lt;strong&gt;Dovetail Admin&lt;/strong&gt; and update the Schema cache.&lt;/p&gt;

&lt;p align="justify"&gt;With the new schema, &lt;strong&gt;Dovetail Admin&lt;/strong&gt; can now be used to add the rest of the transitions required to match the business process. There will still be a message displayed when the maximum number of transitions is reached, but now you have the power to transition beyond this limitation.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=12034" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author></entry><entry><title>Using jQuery to check all CheckBoxes in an iframe</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2010/01/21/using-jquery-to-check-all-checkboxes-in-an-iframe.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2010/01/21/using-jquery-to-check-all-checkboxes-in-an-iframe.aspx</id><published>2010-01-21T18:03:52Z</published><updated>2010-01-21T18:03:52Z</updated><content type="html">&lt;p&gt;In Dovetail Admin, there are a few pages where there is an option to check or uncheck a list of checkbox controls that are in an iframe. The &lt;em&gt;Select All &lt;/em&gt;and &lt;em&gt;Unselect All &lt;/em&gt;buttons perform the action, and using &lt;a href="http://docs.jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt; the codes becomes really simple and efficient.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/image_26DB79C3.png"&gt;&lt;img style="border-right-width:0px;margin:0px 10px 0px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" align="left" src="http://blogs.dovetailsoftware.com/blogs/styson/image_thumb_39244085.png" width="304" height="345" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The code that the buttons use is shared, and the true/false value is passed in to the function to check or uncheck the boxes.&lt;/p&gt;  &lt;p&gt;The old code gets the iframe, gets all of the &lt;strong&gt;input &lt;/strong&gt;fields, and then loops through all of the &lt;strong&gt;input &lt;/strong&gt;fields. As it loops, if the field type is a &lt;em&gt;checkbox&lt;/em&gt;, then the field’s &lt;u&gt;checked&lt;/u&gt; attribute is set to the true/false value that was passed in.&lt;/p&gt;  &lt;p&gt;Here is the original function:&lt;/p&gt;   &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; SetAllCheckBoxes(bOnOff) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; the_iframe= document.getElementById(&lt;span style="color:#006080;"&gt;'priv_classes'&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; doc = the_iframe.contentWindow.document;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  all_fields = doc.getElementsByTagName(&lt;span style="color:#006080;"&gt;&amp;quot;input&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; element_count = all_fields.length;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt;(i = 0;i &amp;lt; element_count; i++) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;     objInput = all_fields&lt;img src="http://blogs.dovetailsoftware.com/emoticons/emotion-55.gif" alt="Idea" /&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;     &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (objInput.getAttribute(&lt;span style="color:#006080;"&gt;'type'&lt;/span&gt;) == &lt;span style="color:#006080;"&gt;'checkbox'&lt;/span&gt;) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        objInput.&lt;span style="color:#0000ff;"&gt;checked&lt;/span&gt;=bOnOff;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;  }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Using jQuery, this code is reduced to one simple line:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;$(&lt;span style="color:#006080;"&gt;&amp;quot;#priv_classes&amp;quot;&lt;/span&gt;).contents().find(&lt;span style="color:#006080;"&gt;&amp;quot;input:checkbox&amp;quot;&lt;/span&gt;).attr(&lt;span style="color:#006080;"&gt;&amp;quot;checked&amp;quot;&lt;/span&gt;, bOnOff);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;jQuery selects the iframe by its id tag, and gets all of the checkbox input controls from the iframe content, and sets the checked attribute on each one. &lt;/p&gt;

&lt;p&gt;Once again, jQuery makes javascript simple, accurate, and easy to maintain.&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a4b05b55-b848-4d1a-bfd6-caf3a5a887ea" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/jQuery" rel="tag"&gt;jQuery&lt;/a&gt;,&lt;a href="http://technorati.com/tags/iframe" rel="tag"&gt;iframe&lt;/a&gt;,&lt;a href="http://technorati.com/tags/javascript" rel="tag"&gt;javascript&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=12027" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author></entry><entry><title>Removing an iframe by using AJAX</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/11/25/removing-an-iframe-by-using-ajax.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/11/25/removing-an-iframe-by-using-ajax.aspx</id><published>2009-11-25T17:53:45Z</published><updated>2009-11-25T17:53:45Z</updated><content type="html">&lt;p&gt;One of our core products at Dovetail Software is our classic ASP application, Dovetail Agent. This application has been in production for many years, and is very stable and reliable. However, since it is a classic ASP application, there is a lot of room for improvement.&lt;/p&gt;  &lt;p&gt;I recently upgraded the Notification feature of the application. Dovetail Agent is a web application that has a main page (the console), and notifications need to be delivered to users automatically, without the users having to find them manually. &lt;/p&gt;  &lt;p&gt;In the previous releases of Dovetail Agent, this process used an iframe control on the console. The source page for the iframe control would query the database for new messages. If new messages were found, a hyperlink would be displayed on the console, and a window for the notifications was opened. The source page for the iframe control used a meta tag to make it automatically refresh after a number of seconds (x_notify_frequency - set by the user).&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;meta&lt;/span&gt; &lt;span class="attr"&gt;http-equiv&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;refresh&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;content&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;&amp;lt;%=x_notify_frequency%&amp;gt;;url=&amp;quot;&lt;/span&gt;&lt;span class="attr"&gt;check_notifier&lt;/span&gt;.&lt;span class="attr"&gt;asp&lt;/span&gt;&amp;quot;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The first change was to replace this iframe and meta-refresh with an AJAX call, which is set to repeat. I am a big fan of &lt;a href="http://docs.jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt;, so I added a few lines of code to set up the timer and make it call the AJAX function.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;height:125px;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;$(document).ready(&lt;span style="color:#0000ff;"&gt;function&lt;/span&gt;() {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;   $.timer(&amp;lt;%=x_notify_frequency%&amp;gt;, &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; (timer) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;         checkNotifier(timer);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      });&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;});&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This uses the &lt;a href="http://plugins.jquery.com/project/Timer" target="_blank"&gt;jQuery timer plugin&lt;/a&gt;, which makes it easy to set the frequency and target for the recurring event. The timer plugin uses the standard javascript methods setInterval() and clearInterval(), but makes them shorter and easier to use.&lt;/p&gt;

&lt;p&gt;The checkNotifier() function sets up the jQuery AJAX call and evaluates the result. If successful and new messages were found, a hyperlink is displayed on the console, and a window for the notifications is opened. If an error occurs, the recurring event is stopped, and an alert is displayed to the user.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:'Courier New', courier, monospace;direction:ltr;height:209px;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;p dir="ltr"&gt;&lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; checkNotifier(timer) {&lt;/p&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;   &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; strURL = strAppPath + &lt;span style="color:#006080;"&gt;&amp;quot;notifier/ajax_notifier.asp&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;   $.ajax({&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      type: &lt;span style="color:#006080;"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      url: strURL,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      dataType: &lt;span style="color:#006080;"&gt;&amp;quot;json&amp;quot;&lt;/span&gt;,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      success: &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt;(results){&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;(results.success == &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;(results.messages &amp;gt; 0) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;               $(&lt;span style="color:#006080;"&gt;&amp;quot;#notifier_message&amp;quot;&lt;/span&gt;).text(&lt;span style="color:#006080;"&gt;&amp;quot;New Notifier Messages&amp;quot;&lt;/span&gt;).css(&lt;span style="color:#006080;"&gt;&amp;quot;color&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;&amp;lt;%=x_notify_color1%&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;               &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;(&amp;lt;%=x_notify_immediate%&amp;gt; == 1) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                  OpenNotifierWindow();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;               }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            } &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;               $(&lt;span style="color:#006080;"&gt;&amp;quot;#notifier_message&amp;quot;&lt;/span&gt;).empty();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;         } &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            alert(&lt;span style="color:#006080;"&gt;&amp;quot;An error occurred while checking for Notifications: &amp;quot;&lt;/span&gt; + results.errorMessage);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            timer.stop();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      },&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      error: &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt;(xhr) {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;         alert(&lt;span style="color:#006080;"&gt;&amp;quot;An error occurred while checking for Notifications&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;         timer.stop();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;      }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;   });&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:'Courier New', courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The success actions were previously being done by the iframe source page, and it was updating the iframe’s parent window (the console) controls. &lt;/p&gt;

&lt;p&gt;Now the iframe and its surrounding div are completely removed. Making the updates directly from the console is much more reliable than referring to a parent window. After writing this post I realize it doesn’t sound like a huge change, but it does make the application easier to maintain.&lt;/p&gt;

&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7582967f-a561-4f12-a747-8494f0272f43" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/jQuery" rel="tag"&gt;jQuery&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ajax" rel="tag"&gt;ajax&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASP" rel="tag"&gt;ASP&lt;/a&gt;,&lt;a href="http://technorati.com/tags/iframe" rel="tag"&gt;iframe&lt;/a&gt;,&lt;a href="http://technorati.com/tags/upgrade" rel="tag"&gt;upgrade&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11993" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author></entry><entry><title>Developer Walkthrough - Workflow Event Handling</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/09/17/developer-walkthrough-workflow-event-handling.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/09/17/developer-walkthrough-workflow-event-handling.aspx</id><published>2009-09-17T23:14:57Z</published><updated>2009-09-17T23:14:57Z</updated><content type="html">&lt;p&gt;&lt;strong&gt;Dovetail SDK &lt;/strong&gt;is a software development kit for writing applications, using .NET, to access Clarify™ databases. One of the more common requirements for objects created for Clarify is performing workflow operations on those objects, such as assigning cases or dispatching change requests. &lt;strong&gt;Dovetail SDK &lt;/strong&gt;provides a powerful set of tools to make workflow operations easy to implement. This guide explains how to get started.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h2&gt;Using WorkflowManager for Workflow Actions&lt;/h2&gt; &lt;p&gt;&amp;nbsp; &lt;p&gt;&lt;strong&gt;Dovetail SDK &lt;/strong&gt;supports the following Workflow Methods for Queueable Objects in Clarify with the WorkflowManager object:  &lt;ul&gt; &lt;li&gt;Accept  &lt;li&gt;Assign  &lt;li&gt;Dispatch  &lt;li&gt;Forward  &lt;li&gt;Move  &lt;li&gt;Reject  &lt;li&gt;Yank  &lt;li&gt;ChangeStatus &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Queueable Object Types that are currently supported:  &lt;p&gt;CASE, SUBCASE, DEMAND_DTL, TASK, OPPORTUNITY, CONTRACT, BUG, PROBDESC, DIALOGUE  &lt;p&gt;All of these methods follow the same basic model for parameters. For example, the Dispatch method takes  &lt;ul&gt; &lt;li&gt;id number of the object being dispatched&lt;/li&gt; &lt;li&gt;type of object being dispatched&lt;/li&gt; &lt;li&gt;queue that the object is being dispatched to&lt;/li&gt; &lt;li&gt;time that the dispatch occurred&lt;/li&gt; &lt;li&gt;login name of the user performing the dispatch&lt;/li&gt; &lt;li&gt;boolean indicating to generate time bombs&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Here is the signature for the Dispatch method: &lt;/p&gt;&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;   public WorkFlowInfo Dispatch(string idNum, string objectName, string queueName, DateTime dispatchDate, string userName, bool generateTimeBomb)
&lt;/pre&gt;
&lt;h4&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&lt;strong&gt;Examples of using WorkflowManager:&lt;/strong&gt;&lt;/h4&gt;
&lt;h5&gt;&lt;/h5&gt;
&lt;p&gt;The following examples demonstrate use of WorkflowManager APIs. The first example dispatches the case to the queue, and the second example accepts the case into the user’s wipbin.&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;   [C#]

   // Dispatch Case 1 to the Support queue

   string caseId = "1";
   string queueName = "Support";
   string userName = "sa";
   bool generateTimeBombs = true;
   DateTime eventTime = DateTime.Now;

   ClarifyDataSet ds = new ClarifyDataSet(session);

   WorkflowManager workflowManager = new WorkflowManager(ds);
   workflowManager.Dispatch(caseId, "case", queueName, eventTime, userName, generateTimeBombs);



   // Accept Case 1 into the default wipbin

   string caseId = "1";
   string wipbinTitle = "default";
   string userName = "sa";
   bool generateTimeBombs = true;
   DateTime eventTime = DateTime.Now;

   ClarifyDataSet ds = new ClarifyDataSet(session);

   WorkflowManager workflowManager = new WorkflowManager(ds);
   workflowManager.Accept(caseId, "case", wipbinTitle, eventTime, userName, generateTimeBombs);
&lt;/pre&gt;
&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;Using .Net Version of Compatibility Toolkits for Workflow Actions&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dovetail SDK &lt;/strong&gt;also support workflow methods for queueable objects through the Compatibility Toolkits. These APIs are grouped by the toolkit which govern the objects primary functions. For example, the Case workflow APIs are found in the Support Toolkit. At this time, all of the queueable objects except Dialogue have compatibility versions of the workflow APIs.
&lt;p&gt;Since the Compatibility Toolkits were originally developed in VB, all of the Compatibility Toolkit APIs are also provided for use in .Net applications. These APIs have names similar to the VB versions. Each one has a name with the pattern of “&amp;lt;Action&amp;gt;&amp;lt;Object&amp;gt;”, i.e. &lt;strong&gt;DispatchCase&lt;/strong&gt;. These APIs have a different signature, and all use a matching setup object, i.e. &lt;strong&gt;DispatchCaseSetup&lt;/strong&gt;. The setup objects are created first, and have parameters for each required property. 
&lt;p&gt;Looking at the DispatchCase API, the only required properties are the case id number and the queue name. Correspondingly, the setup object only has two parameters: &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;   [C#]

   DispatchCaseSetup( string caseIdNum, string queue )
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; &lt;p&gt;Once the setup object is created, then the other properties can also be set. This allows less code to be required to perform the operation, which makes it easier to use. It also allows the API to be easily modified if necessary. Here is an example of setting the optional properties: &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;   [C#]

   string caseId = "1";
   string queueName = "Support";

   DispatchCaseSetup setup = new DispatchCaseSetup(caseId, queueName);
   setup.DispatchDate = DateTime.Now;
   setup.UserName = "sa";
   setup.GenerateTimeBombs = false;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; &lt;p&gt;At this point, the setup object is ready for use. The corresponding API uses its setup object as input, and the API is invoked: &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;   [C#]

   SupportToolkit supportToolkit = new SupportToolkit(fcApplication, fcSession);
   ToolkitResult result = supportToolkit.DispatchCase(setup);
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; &lt;p&gt;The ToolkitResult will have all of the details from executing the API. Any error code would be in the ReturnCode property. &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;   [C#]

   int returnCode = result.ReturnCode;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp; &lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;The APIs for the workflow events can be implemented in multiple environments. &lt;strong&gt;Dovetail SDK &lt;/strong&gt;executes the same code to perform a workflow action, regardless of how the API is called. All of the necessary validation of the input parameters is done, and the appropriate activity logs and time bombs will be generated as required.&lt;pre&gt;&lt;/pre&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11930" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author><category term="Dovetail" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/Dovetail/default.aspx" /><category term="API" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/API/default.aspx" /><category term="SDK" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/SDK/default.aspx" /><category term="Workflow" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/Workflow/default.aspx" /><category term=".Net" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/.Net/default.aspx" /></entry><entry><title>Using jQuery to Sort a List</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/08/25/using-jquery-to-sort-a-list.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/08/25/using-jquery-to-sort-a-list.aspx</id><published>2009-08-25T17:44:09Z</published><updated>2009-08-25T17:44:09Z</updated><content type="html">&lt;p&gt;I needed to add a new feature today, and wanted an easy client-side solution. Since I use jQuery in the project already, I searched and found a good starting point in a &lt;a href="http://www.wrichards.com/blog/2009/02/jquery-sorting-elements/" target="_blank"&gt;blog post by Bill Richards&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The code I found adds a function and a sort handler that can be applied to a list.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;span style="widows:2;text-transform:none;text-indent:0px;border-collapse:separate;font:16px 'Times New Roman';white-space:normal;orphans:2;letter-spacing:normal;word-spacing:0px;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;" class="Apple-style-span"&gt;&lt;span style="font-family:-webkit-monospace;white-space:pre-wrap;font-size:13px;" class="Apple-style-span"&gt;&lt;font face="cou"&gt;jQuery.fn.sort = function() { &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="widows:2;text-transform:none;text-indent:0px;border-collapse:separate;font:16px 'Times New Roman';white-space:normal;orphans:2;letter-spacing:normal;word-spacing:0px;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;" class="Apple-style-span"&gt;&lt;span style="font-family:-webkit-monospace;white-space:pre-wrap;font-size:13px;" class="Apple-style-span"&gt;&lt;font face="cou"&gt;&amp;#160;&amp;#160;&amp;#160; return this.pushStack( [].sort.apply( this, arguments ), []); &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="widows:2;text-transform:none;text-indent:0px;border-collapse:separate;font:16px 'Times New Roman';white-space:normal;orphans:2;letter-spacing:normal;word-spacing:0px;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;" class="Apple-style-span"&gt;&lt;span style="font-family:-webkit-monospace;white-space:pre-wrap;font-size:13px;" class="Apple-style-span"&gt;&lt;font face="cou"&gt;}; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="widows:2;text-transform:none;text-indent:0px;border-collapse:separate;font:16px 'Times New Roman';white-space:normal;orphans:2;letter-spacing:normal;word-spacing:0px;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;" class="Apple-style-span"&gt;&lt;span style="font-family:-webkit-monospace;white-space:pre-wrap;font-size:13px;" class="Apple-style-span"&gt;&lt;font face="cou"&gt;function sortAlpha(a,b){ &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="widows:2;text-transform:none;text-indent:0px;border-collapse:separate;font:16px 'Times New Roman';white-space:normal;orphans:2;letter-spacing:normal;word-spacing:0px;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;" class="Apple-style-span"&gt;&lt;span style="font-family:-webkit-monospace;white-space:pre-wrap;font-size:13px;" class="Apple-style-span"&gt;&lt;font face="cou"&gt;&amp;#160;&amp;#160;&amp;#160; return a.innerHTML &amp;gt; b.innerHTML ? 1 : -1; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;&lt;span style="widows:2;text-transform:none;text-indent:0px;border-collapse:separate;font:16px 'Times New Roman';white-space:normal;orphans:2;letter-spacing:normal;word-spacing:0px;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;" class="Apple-style-span"&gt;&lt;span style="font-family:-webkit-monospace;white-space:pre-wrap;font-size:13px;" class="Apple-style-span"&gt;&lt;font face="cou"&gt;}; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Here is a simple example of the HTML I am working with:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;ul id=&amp;quot;caseListing&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;li&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;1&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;a href=&amp;quot;/Cases/Show/1&amp;quot;&amp;gt;Case 1&amp;lt;/a&amp;gt;: need help with VPN connection      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/li&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;li&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;3&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;a href=&amp;quot;/Cases/Show/3&amp;quot;&amp;gt;Case 3&amp;lt;/a&amp;gt;: blue screen of death upon login      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/li&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;li&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;6&amp;quot;&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;a href=&amp;quot;/Cases/Show/6&amp;quot;&amp;gt;Case 6&amp;lt;/a&amp;gt;: Computer has no power      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160; &amp;lt;/li&amp;gt;      &lt;br /&gt;&amp;lt;/ul&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;When the page loads, all of the list items are sorted by the id number of the case. Since I need to be able to inverse the order of a list of items after it is displayed, I added this anchor element to change the sort order:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;a id=&amp;quot;sortOrder&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Sort Desc&amp;lt;/a&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;For the javascript required, I added another sort handler for reversing the order, and added code for the hyperlink to initiate the sort function. The jQuery code I end up with looks like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="cou"&gt;jQuery.fn.sort = function() {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return this.pushStack([].sort.apply(this, arguments), []);        &lt;br /&gt;}; &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="cou"&gt;function sortAscending(a, b) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return a.innerHTML &amp;gt; b.innerHTML ? 1 : -1;        &lt;br /&gt;}; &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="cou"&gt;function sortDescending(a, b) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return a.innerHTML &amp;lt; b.innerHTML ? 1 : -1;        &lt;br /&gt;};&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="cou"&gt;$(document).ready(function() {       &lt;br /&gt;&lt;/font&gt;&lt;font face="cou"&gt;&amp;#160;&amp;#160;&amp;#160; $(&amp;quot;#sortOrder&amp;quot;).toggle(       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; function() {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $('#caseListing li').sort(sortDescending).appendTo('#caseListing');        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(this).text(&amp;quot;Sort Asc&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; function() {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $('#caseListing li').sort(sortAscending).appendTo('#caseListing');        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(this).text(&amp;quot;Sort Desc&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });        &lt;br /&gt;}); &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&amp;lt;/script&amp;gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Each time the anchor tag is clicked, the order of the list elements is reversed. The toggle event handler for the anchor element does most of the work. It calls the correct sort handler, and updates the text of the anchor tag to keep it clear for the user.&lt;/p&gt;  &lt;p&gt;This ends up being a very light-weight, fast client side sorting solution for small sets of list items.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f4bed197-beb7-48f7-be87-ee793841566b" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/jQuery" rel="tag"&gt;jQuery&lt;/a&gt;,&lt;a href="http://technorati.com/tags/sort()" rel="tag"&gt;sort()&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11880" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author></entry><entry><title>Using SqlHelper in a .Net application</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/06/24/using-sqlhelper-in-a-net-application.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/06/24/using-sqlhelper-in-a-net-application.aspx</id><published>2009-06-24T18:16:58Z</published><updated>2009-06-24T18:16:58Z</updated><content type="html">&lt;p&gt;In the Dovetail SDK, there is a very useful &lt;a href="http://www.dovetailsoftware.com/user_guides/dovetailSDK/2.4.0.8316/html/FChoice.Common~FChoice.Common.Data.SqlHelper.html" target="_blank"&gt;SqlHelper&lt;/a&gt; class. SqlHelper provides a convenience and data provider-agnostic wrapper around ADO.NET. This allows an application to execute SQL commands in a database.&lt;/p&gt; &lt;p&gt;SqlHelper has various ways of being initialized, which all depend on a &lt;a href="http://www.dovetailsoftware.com/user_guides/dovetailSDK/2.4.0.8316/html/FChoice.Common~FChoice.Common.Data.DbProvider.html" target="_blank"&gt;DbProvider&lt;/a&gt; instance to make a connection to the database. In most applications the DbProvider is separately instantiated based on configuration, so the examples here will not detail that process.&lt;/p&gt; &lt;p&gt;SqlHelper can execute a variety of SQL commands. SQL SELECT statements are usually performed by the ExecuteDataSet method. The ExecuteNonQuery method can be used to perform other SQL commands such as UPDATE or DELETE statements. ExecuteScalar is used frequently to get a value returned from a SQL statement for use later in the application.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;In the first example, a simple database select statement is being executed to retrieve an ADO dataset. The dataset is then processed, writing the value from each of the two columns for each row in the first table in the dataset to the console. If no rows were retrieved, then nothing would be written to the console. &lt;/p&gt;&lt;pre&gt;		public void SqlHelper_example()
		{
			var sqlCommand = "select title, id_number from table_subcase";
			var sqlHelper = new SqlHelper(_dbProvider, sqlCommand);

			var dataset = sqlHelper.ExecuteDataSet();
			var table = dataset.Tables[0];

			foreach (DataRow row in table.Rows)
			{
				var subcaseInfo = String.Format("Subcase {0}: {1}", row["id_number"], row["title"]);
				
				Console.WriteLine(subcaseInfo);
			}
		}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In this example, a database DELETE statement is being executed using a static SqlHelper instance to delete rows from the notes_log table. &lt;/p&gt;&lt;pre&gt;		public void SqlHelper_example()
		{
			SqlHelper.ExecuteNonQuery(“DELETE from table_notes_log WHERE internal = ‘-666’”);
		}&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Finally, here is an example using ExecuteScalar. The SQL SELECT statement will return the requested identifier, which is converted to an integer.&lt;/p&gt;&lt;pre&gt;		public void SqlHelper_example()
		{
			int caseObjid = Convert.ToInt32(SqlHelper.ExecuteScalar(“SELECT objid from table_case WHERE id_number = ‘1’”));
		}&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;p&gt;In reality, these examples just scratched the surface of possibilities for the uses of SqlHelper. The online documentation for &lt;a href="http://www.dovetailsoftware.com/user_guides/dovetailSDK/2.4.0.8316/html/FChoice.Common~FChoice.Common.Data.SqlHelper.html" target="_blank"&gt;SqlHelper&lt;/a&gt; provides a list if all the available methods, and putting them to use in applications gets easier with experience, and good examples.&lt;/p&gt;
&lt;p&gt;Please add other examples that you have implemented in your comments, and we can all discuss!&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11828" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author></entry><entry><title>Getting Dates Localized in Dovetail Agent</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/03/03/getting-dates-localized-in-dovetail-agent.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/03/03/getting-dates-localized-in-dovetail-agent.aspx</id><published>2009-03-03T22:40:15Z</published><updated>2009-03-03T22:40:15Z</updated><content type="html">&lt;p&gt;&lt;/p&gt;  &lt;p&gt;The abilities to have global users and a centralized server is an important feature of Dovetail Agent. Making localized date handling for all of the users is an important part of getting the right date format displayed to the users, and making sure the dates are stored correctly in the database.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Dovetail Agent &lt;/strong&gt;recognizes the computer and browser settings for each user. &lt;strong&gt;Dovetail Agent &lt;/strong&gt;allows each user to input dates in their localized date format, and relies on &lt;strong&gt;Dovetail SDK &lt;/strong&gt;to convert the dates into a consistent format for storage in the database.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Regional Options&lt;/h5&gt;  &lt;p&gt;From the Control Panel for each client, the &lt;em&gt;Regional Options&lt;/em&gt; tab of the &lt;em&gt;Regional and Language Options&lt;/em&gt; has a big impact on &lt;strong&gt;Dovetail Agent &lt;/strong&gt;functionality. &lt;strong&gt;Dovetail Agent &lt;/strong&gt;uses the standard Visual Basic FormatDate routine, which uses the Regional settings to determine the client's preferred date format.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;For this discussion, the client is located in the Bristol, England office. His regional setting is set to &lt;strong&gt;English (United Kingdom)&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/image_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="484" alt="image" src="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/image_thumb.png" width="404" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Language Preferences&lt;/h5&gt;  &lt;p&gt;More importantly though, in order for &lt;strong&gt;Dovetail SDK &lt;/strong&gt;to recognize the localized date formats and make the necessary adjustments, the browser needs to have the Language setting in IE correspond to the user's &lt;em&gt;Regional Options&lt;/em&gt; setting.&lt;/p&gt;  &lt;p&gt;From the &lt;em&gt;Tools Menu&lt;/em&gt; in &lt;em&gt;Internet Explorer&lt;/em&gt;, click &lt;em&gt;Internet Options&lt;/em&gt;, then click on the &lt;em&gt;Languages&lt;/em&gt; button to open the &lt;em&gt;Language Preference&lt;/em&gt; dialog. &lt;/p&gt;  &lt;p&gt;Since our user is located in the Bristol, England office, the &lt;strong&gt;English (United Kingdom) [en-GB]&lt;/strong&gt; needs to be selected. If is is not displayed, click the &lt;em&gt;Add&amp;#8230;&lt;/em&gt; button and select it from the list. Once it is shown, move the &lt;strong&gt;English (United Kingdom) [en-GB]&lt;/strong&gt; line to the top of the list by clicking the row and using the &lt;em&gt;Move Up&lt;/em&gt; button.&lt;/p&gt;  &lt;p&gt;&lt;a name="_MailAutoSig"&gt;&lt;b&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/clip_image001_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="484" alt="clip_image001" src="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/clip_image001_thumb.png" width="441" border="0" /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Verifying in Dovetail Agent&lt;/h5&gt;  &lt;p&gt;Have the user log in to &lt;strong&gt;Dovetail Agent&lt;/strong&gt;, and open the &lt;em&gt;About Dovetail Agent&lt;/em&gt; page from the &lt;em&gt;Profile &lt;/em&gt;menu. The &lt;strong&gt;Current Culture&lt;/strong&gt; is displayed at the bottom of the page, and should now show &lt;strong&gt;en-GB&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/clip_image002_2.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="633" alt="clip_image002" src="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/clip_image002_thumb.png" width="1028" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;After these configuration changes are made, dates throughout &lt;strong&gt;Dovetail Agent&lt;/strong&gt; are displayed to the UK user in DD/MM/YYY format, but saved to the database in MM/DD/YYYY format.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/image_4.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="640" alt="image" src="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/GettingDatesLocalizedinDovetailAgent_DC59/image_thumb_1.png" width="614" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;Summary&lt;/h4&gt;  &lt;p&gt;Having dates localized is important for ease of use for the users, and is pretty easy to set up.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11660" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author></entry><entry><title>jQuery 1.3 is now official!</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/01/14/jquery-1-3-is-now-official.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/01/14/jquery-1-3-is-now-official.aspx</id><published>2009-01-14T22:01:35Z</published><updated>2009-01-14T22:01:35Z</updated><content type="html">&lt;p&gt;jQuery just released its latest version, and celebrates its 3rd birthday as a JavaScript Library.&lt;/p&gt;  &lt;p&gt;The big features of this release are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Sizzle: A sizzlin&amp;#8217; hot CSS selector engine. &lt;/li&gt;    &lt;li&gt;Live Events: Event delegation with a jQuery twist. &lt;/li&gt;    &lt;li&gt;jQuery Event Overhaul: Completely rewired to simplify event handling. &lt;/li&gt;    &lt;li&gt;HTML Injection Rewrite: Lightning-fast HTML appending. &lt;/li&gt;    &lt;li&gt;Offset Rewrite: Super-quick position calculation. &lt;/li&gt;    &lt;li&gt;No More Browser Sniffing: Using feature detection to help jQuery last for many more years to come. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;jQuery at Dovetail Software&lt;/h4&gt;  &lt;p&gt;Almost all of our current development projects are using jQuery, so upgrading to the new version to take advantage of the new features and performance will be an exciting improvement. The performance gains in the selector engine and HTML injection should help us improve our software. The benefits of using jQuery is already apparent, and we continue to use it more every day in development and maintenance of our software.&lt;/p&gt;  &lt;h4&gt;&amp;#160;&lt;/h4&gt;  &lt;h4&gt;jQuery API browsers&lt;/h4&gt;  &lt;p&gt;One of the best development aids for jQuery is &lt;a href="http://remysharp.com/visual-jquery/" target="_blank"&gt;Visual jQuery&lt;/a&gt;. It shows the syntax and definition for every jQuery method available, in a very easy-to-use interface. &lt;a href="http://remysharp.com/" target="_blank"&gt;Remy Sharp&lt;/a&gt; just released a new jQuery API browser, and this one is available offline as well as an Adobe AIR application.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://api.jquery.com/" target="_blank"&gt;Download and install the AIR API browser&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The new API browser includes the following features:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;All the latest jQuery and jQuery UI documentation&lt;/li&gt;    &lt;li&gt;The ability to mark pages as favorites for those pages you keep wanting to return to&lt;/li&gt;    &lt;li&gt;Syntax highlighting in the code examples&lt;/li&gt;    &lt;li&gt;Live running of examples within the browser&lt;/li&gt;    &lt;li&gt;Links to edit and experiment with the code examples&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/jQuery1.3isnowofficial_D34D/image_6.png"&gt;&lt;img style="border-right:0px;border-top:0px;border-left:0px;border-bottom:0px;" height="789" alt="image" src="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/jQuery1.3isnowofficial_D34D/image_thumb_2.png" width="858" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11614" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author><category term="tech" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/tech/default.aspx" /><category term="jQuery" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/jQuery/default.aspx" /><category term="Dovetail" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/Dovetail/default.aspx" /></entry><entry><title>Announcing a New Product Release...</title><link rel="alternate" type="text/html" href="http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/01/12/announcing-a-new-product-release.aspx" /><id>http://blogs.dovetailsoftware.com/blogs/styson/archive/2009/01/12/announcing-a-new-product-release.aspx</id><published>2009-01-13T00:11:41Z</published><updated>2009-01-13T00:11:41Z</updated><content type="html">&lt;p&gt;This is always a good sign for a software company, and here at &lt;a href="http://www.dovetailsoftware.com/" target="_blank"&gt;Dovetail Software&lt;/a&gt; this has just become an easier task.&lt;/p&gt;  &lt;p&gt;It is important for us to get the news about a new product release to our customers. By automating some of the steps in this task, we can get the information to the customer faster, and also add some business value to the process.&lt;/p&gt;  &lt;p&gt;Now when a new release is ready, we can use the new Product Announcement tool to prepare the message for our customers.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/AnnouncingaNewProductRelease_D91A/image_2.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="484" alt="image" src="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/AnnouncingaNewProductRelease_D91A/image_thumb.png" width="535" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Opening this application from within our in-house version of &lt;a href="http://www.dovetailsoftware.com/resources/docs.aspx?product=DovetailAgent" target="_blank"&gt;Dovetail Agent&lt;/a&gt;, we can see a list of all of our products that are currently under contract with any of our customers. &lt;/p&gt;  &lt;p&gt;Clicking on one of the products will retrieve all of the customers under contract, and show a second grid filled with the contact information for those sites. Each contact that has an email address will be selected, and those without an email address are highlighted differently.&lt;/p&gt;  &lt;p&gt;The contact information can be updated by double-clicking the contact's row in the grid. Once the changes are saved for the contact, then the contact grid can be refreshed by clicking on the product again.&lt;/p&gt;  &lt;p&gt;Each available email address is added to the BCC list, and the product details are filled into the subject and email body text. All of these text areas can be changed before the email is sent.&lt;/p&gt;  &lt;p&gt;The body of the email is stored in the database, so the default template can be changed from within Dovetail Agent, instead of having to change to source code of the Product Announcement application.&lt;/p&gt;  &lt;p&gt;When all of the changes are complete, the email can be sent. We send the message using Outlook, so clicking the Send Email button is the last step. It really makes it easy for us to get the word out to our customers.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Inside the Code&lt;/h3&gt;  &lt;p&gt;Inside the source code there a few interesting things that show how our applications are evolving as we develop new applications and features in our software.&lt;/p&gt;  &lt;p&gt;The Product Announcement application has a built-in Help Page, accessible by clicking on the &lt;strong&gt;&lt;em&gt;&lt;u&gt;Help&lt;/u&gt;&lt;/em&gt;&lt;/strong&gt; link at the top of the page. We use JavaScript to show the help contents directly in the page, so the focus of the user is not taken somewhere else.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/AnnouncingaNewProductRelease_D91A/image_4.png"&gt;&lt;img style="border-top-width:0px;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" height="484" alt="image" src="http://blogs.dovetailsoftware.com/blogs/styson/WindowsLiveWriter/AnnouncingaNewProductRelease_D91A/image_thumb_1.png" width="535" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h5&gt;Table Sorting&lt;/h5&gt;  &lt;p&gt;Both of the grids use the jQuery &lt;a href="http://tablesorter.com/docs/" target="_blank"&gt;tableSorter&lt;/a&gt; plugin. This is a very simple way to add sorting for all of the columns in the grid. Here is the code that adds sorting for the customer grid, which adds the option of making the first column non-sortable.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;$(&amp;quot;.tablesorter&amp;quot;).tablesorter({        &lt;br /&gt;&amp;#160;&amp;#160; headers: {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0: {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sorter: false         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160; sortList: [[1,0]]         &lt;br /&gt;}); &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Tracking Announcement Activity&lt;/h5&gt;  &lt;p&gt;When the emails are sent, we also add an activity log for each contact, and one for the product itself. This allows us to track when the announcements were sent to the customers. To do this we are using AJAX through jQuery to add these activity entries for each customer and part.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;$.ajax({        &lt;br /&gt;&amp;#160;&amp;#160; url: &amp;quot;addActivityLogs.asp&amp;quot;,         &lt;br /&gt;&amp;#160;&amp;#160; type: &amp;quot;POST&amp;quot;,         &lt;br /&gt;&amp;#160;&amp;#160; data: &amp;quot;site_part_list=&amp;quot; + site_part_list + &amp;quot;&amp;amp;product=&amp;quot; + escape(product) + &amp;quot;&amp;amp;contact_list=&amp;quot; + contact_list,         &lt;br /&gt;&amp;#160;&amp;#160; error: function(xhr) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; alert(&amp;quot;Failed to add Activity Logs for &amp;quot; + product);         &lt;br /&gt;&amp;#160;&amp;#160; }         &lt;br /&gt;}); &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The addActivityLogs.asp code that gets executed by the AJAX call loops through the contacts and site parts, and uses the &lt;a href="http://www.dovetailsoftware.com/resources/docs.aspx?product=DovetailSDK" target="_blank"&gt;Dovetail Software SDK&lt;/a&gt; to create the new records for the database.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Better Layout and Style&lt;/h5&gt;  &lt;p&gt;All of the HTML layout and styling for the Product Announcement application is done using CSS. This is very different from the previous versions of Dovetail Agent. Dovetail Agent and Dovetail Admin will both be improving in this area as well in future releases.&lt;/p&gt;  &lt;p&gt;This makes it easier to develop new applications, and much easier to change when necessary.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;Using Outlook&lt;/h5&gt;  &lt;p&gt;Creating and sending emails through Outlook is very easy to do. First, when the the Product Announcement application is opened, we establish a connection to Outlook.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;var objSession = new ActiveXObject(&amp;quot;MAPI.Session&amp;quot;);        &lt;br /&gt;objSession.Logon(&amp;quot;&amp;quot;,&amp;quot;&amp;quot;,true,false); &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;To create and send the email, we create the new Message with the subject and text, add the recipients to the BCC list and send!&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;var objMessage = objSession.Outbox.Messages.Add;        &lt;br /&gt;var objRecipients = objMessage.Recipients;         &lt;br /&gt;objMessage.Subject = $(&amp;quot;#txtSubject&amp;quot;).val();         &lt;br /&gt;objMessage.Text&amp;#160;&amp;#160;&amp;#160; = $(&amp;quot;#txtBody&amp;quot;).val(); &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;var bcc = new String($(&amp;quot;#txtBCC&amp;quot;).val()).split(&amp;quot;;&amp;quot;);        &lt;br /&gt;for(var i=0; i &amp;lt; bcc.length; i++) {         &lt;br /&gt;&amp;#160;&amp;#160; email = bcc&lt;img src="http://blogs.dovetailsoftware.com/emoticons/emotion-55.gif" alt="Idea" /&gt;;         &lt;br /&gt;&amp;#160;&amp;#160; if(email &amp;gt; &amp;quot;&amp;quot;) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; objRecip = objMessage.Recipients.Add();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; objRecip.Name = email;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; objRecip.Type = 3;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; objRecip.Resolve();         &lt;br /&gt;&amp;#160;&amp;#160; }         &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;// Send the Message        &lt;br /&gt;try{         &lt;br /&gt;&amp;#160;&amp;#160; objMessage.Send();         &lt;br /&gt;} catch (e){         &lt;br /&gt;&amp;#160;&amp;#160; objMessage = null;         &lt;br /&gt;&amp;#160;&amp;#160; objRecipients = null;         &lt;br /&gt;&amp;#160;&amp;#160; alert(&amp;quot;Unexpected error:\n\n&amp;quot; + e.description + &amp;quot;\nError Number: &amp;quot; + e.number);         &lt;br /&gt;&amp;#160;&amp;#160; return false;         &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;$(&amp;quot;#sendButton&amp;quot;).attr(&amp;quot;disabled&amp;quot;, true); &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;alert(&amp;quot;Email successfully sent.&amp;quot;); &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You may notice that we use jQuery to interact with the page. This simplifies the JavaScript code required to get the subject, body, and recipients. We also disable the &lt;strong&gt;&lt;em&gt;Send Email&lt;/em&gt;&lt;/strong&gt; button after completion.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Summary&lt;/h3&gt;  &lt;p&gt;As we develop new applications, we also improve our techniques. Hopefully these examples will help you improve your techniques as well. Comments/Ideas/Suggestions are always welcome.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11611" width="1" height="1"&gt;</content><author><name>styson</name><uri>http://blogs.dovetailsoftware.com/members/styson.aspx</uri></author><category term="tech" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/tech/default.aspx" /><category term="customization" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/customization/default.aspx" /><category term="jQuery" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/jQuery/default.aspx" /><category term="Dovetail Agent" scheme="http://blogs.dovetailsoftware.com/blogs/styson/archive/tags/Dovetail+Agent/default.aspx" /></entry></feed>