Monday, February 6, 2012

Ajax Update Panel Scroll to Top Issue

I found this great post on how to force a scroll to top when you have a long page that is contained inside an UpdatePanel. For myself, I was having issues with items inside a Wizard control. Some of the pages had very long text. So when the user clicked "Next" it would move to the next page, but it would go the middle of the page (whereever the last page position was) rather than go to the top. So the user would be confused as to where they were. So I wanted the page to go to the top of the page on the Next button click. I added the following script just after my script manager:

<script type="text/javascript" language="javascript">

var postbackElement;
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded)

function beginRequest(sender, args) {
postbackElement = args.get_postBackElement();
}

function pageLoaded(sender, args) {
if (typeof (postbackElement) === "undefined") {
return;
}

if ((postbackElement.id) === "btnStepNext" || (postbackElement.id) === "btnStepPrevious") {
window.scrollTo(0, 0);
}
}

</script>

Then I set the Next and Previous button in the Wizard control to ClientIDMode="Static" so the Javascript could identify them and it worked great!

Wednesday, November 30, 2011

iTextSharp AcroField Font Size

While working with iTextSharp to fill AcroFields in a PDF, I noticed the font size of the text fields were a little larger than I wanted.

I found this great post that helped me out http://www.keithnordstrom.com/?tag=/itextsharp

which boils down to this:

AcroFields fields = stamper.AcroFields;
bool set = fields.SetFieldProperty(fieldName, "textsize", 12.0f, null);

The only thing to note is that you must set the form field size before putting text into the field otherwise it won't work...

Sunday, November 13, 2011

PHP PEAR Spreadsheet

I had my PHP/PEAR Spreadsheet writing working for several months on GoDaddy, however, GoDaddy did an upgrade of Apache to 1.3.33 without me knowing. So I found out a month later that my spreadsheet writer was no longer working. I found that the OLE was erroring out that is could not create a temp file.(after days of debugging).

To fix this error, I added a temp directory to the code like this:

$excel = new Spreadsheet_Excel_Writer($name);

//needed for upgrade to apache 1.3
$excel->setTempDir('temp');


Of course, I added the folder to the server, and it is working...after days and days of head-banging....

Wednesday, November 2, 2011

DocuSign Missing Form Field Data

So I have been testing out DocuSign to see if it will fit a need I have for documents to be electronically signed. I have been using the Embedded signing and I've like it so far. It took some tinkering to get the CreateEnvelopeFromTemplatesAndForms to work with an inline template but once it worked it was great.

Here is my short sample:

// Configure the envelope information
DocuSignAPI.EnvelopeInformation envelopeInfo = new DocuSignAPI.EnvelopeInformation();
envelopeInfo.AccountId = "XX";
envelopeInfo.EmailBlurb = "You sign this.";
envelopeInfo.Subject = "Please sign!";

DocuSignAPI.CompositeTemplate template = new DocuSignAPI.CompositeTemplate();

DocuSignAPI.Recipient[] signers = ConstructRecipients();

DocuSignAPI.InlineTemplate inlineTemplate = new DocuSignAPI.InlineTemplate();
inlineTemplate.Sequence = "1";
inlineTemplate.Envelope = new DocuSignAPI.Envelope();
inlineTemplate.Envelope.Recipients = signers;
inlineTemplate.Envelope.AccountId = ConfigurationManager.AppSettings["DSAPIAccountID"].ToString();

Tab tab = new Tab();
tab.DocumentID = "1";
tab.RecipientID = randomId;
tab.Type = TabTypeCode.SignHere;
tab.PageNumber = "9";
tab.AnchorTabItem = new AnchorTab();
tab.AnchorTabItem.AnchorTabString = "Person Signature Line";
tab.AnchorTabItem.Unit = UnitTypeCode.Pixels;
tab.AnchorTabItem.UnitSpecified = true;
tab.AnchorTabItem.XOffset = -10;
tab.AnchorTabItem.YOffset = -20;

inlineTemplate.Envelope.Tabs = new DocuSignAPI.Tab[] { tab };

template.InlineTemplates = new InlineTemplate[] { inlineTemplate };

// Configure the document
template.Document = new DocuSignAPI.Document();

template.Document.ID = "1";
template.Document.Name = "Document Name";

PDFGenerator generator = new PDFGenerator();
byte[] documentBytes = generator.DownloadFile();

template.Document.PDFBytes = documentBytes;

template.Document.TransformPdfFields = true;
template.Document.FileExtension = "pdf";

status = client.CreateEnvelopeFromTemplatesAndForms(envelopeInfo, new DocuSignAPI.CompositeTemplate[] { template }, true);

if (status.SentSpecified)
{
base.AddEnvelopeID(status.EnvelopeID);
// Start the first signer
SignFirst(status);
}
...

Ok. Although I could run the code, make the document show up in the iframe and have the little "Sign Here" block show up in the right spot, the BIG problem I had was my form field data that I was populating was missing when it was uploaded to DocuSign.

After hours and hours of testing, looking at my PDF's...blah blah blah..I noticed that sometimes that data did show up in a couple of my documents. And after more testing, I found that if my form fields first showed up on page 6, I was good to go. However, if they showed up on page 7, they were blank..and what good is signing off on document when the data is blank? (this was in the API and online console)

Anyhow, so I contacted DocuSign. They said this was an issue with the Chrome browser. So I tried out uploading thru the online console using IE. And sure enough that did work. So they recommended I user IE/FireFox. However when I tried again thru the API in IE/FF it was no go.

So being frustrated over this for many days, I FINALLY had a crazy thought - put a dummy field on page 4 (could be 1,2,3,4,5,or 6) but I had room on 4. I made it invisible too.

And viola...it worked! Relief...now I can move on in life. I do hope DocuSign does get that resolved though. If a difference of a single page can make or break it, I think you might have some coding problems. Hehe.

Monday, October 10, 2011

ClientScript.RegisterStartupScript Not Working?

ClientScript.RegisterStartupScript is used to call javascript in the .net code-behind. Once you learn this nice little trick, you think it is great, until one day years later on another page/project you try it again, but it does not work.

First, please check if the control/page you are trying to update contains an UpdatePanel. If so, keep reading.

This WON'T work with an UpdatePanel (in my experience). You will need to use: ScriptManager.RegisterStartupScript

For example:
ScriptManager.RegisterStartupScript(this, this.GetType(), "saving", "doneSaving();", true);

Also, in VS, it did not seem to recognize ScriptManager, when I right-clicked to "Resolve" it gave me no options. I am not sure why but I had to add "using System.Web.UI;" to my using clauses manually. Maybe that was some quirk with my page though...

Wednesday, September 21, 2011

ScriptManager History UpdatePanel

I just beat my head against the wall for an entire morning trying to figure out why the simple ScriptManager History functionality was not working with my UpdatePanel.

First off, I inherited this code, so I was just working with what was there without paying much attention to it. The previous person had setup an UpdatePanel without putting in a Trigger tag. So that should have been clue NUMBER 1, but I overlooked that so that was a good two hours wasted in just not paying attention to that.

Oh well, so I kept following all the simple steps listed on the 'net for setting up the ScriptManager to keep history points. Brief overview:

1) Add a ScriptManager to the page like this:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnableHistory="True" OnNavigate="MainScriptManager_Navigate" EnableSecureHistoryState="True"/>


2)Add the associated function to the code-behind :
protected void MainScriptManager_Navigate(object sender, HistoryEventArgs e)
{
    string panelName = e.State["S"];

     switch (panelName)
     {
      case "Panel_Store_CC":
      Panel_Store_CC.Visible = true;
      break;
      default:
      break;
     }
}

3) Add history points when needed in code calls (in my example it was a button click):
if (ScriptManager1.IsInAsyncPostBack && !ScriptManager1.IsNavigating)
 ScriptManager.GetCurrent(this).AddHistoryPoint("S", "Panel_Store_CC");


After several hours, history was not being added the browser's back in any browser (Chrome/IE/FireFox)....I began noticing during my debugging I was hitting the Page_Load code on each button click. DUH! This was not right...so I finally figured out that I needed a trigger for the updatepanel. At first I added an Asynchoronous trigger, but that still did not work HOWEVER once I added the PostBackTrigger for the button, it finally worked since the entire page was not being posted back!

<asp:UpdatePanel ID="UpdatePanel1" runat="server" >
<Triggers>
<asp:PostBackTrigger ControlID="Button1" />
</Triggers>

Sunday, August 14, 2011

PHP Pear Spreadsheet Write - File Error: Data may have been lost

I needed to write out data to a spreadsheet file so I installed PHP PEAR's Spreadsheet Excel Writer. It is pretty easy to use. I wrote the code I needed but kept getting the following error upon opening the file:
File Error: Data may have been lost.

So then I went to PHPExcel, however, when I installed the code to production I realized it was still on PHP4, and that only works with PHP5...

So I went back to the Spreadsheet Excel Writer. I noticed that the files opened just fine, and all the data was there, so it really worked, however, I imagined fielding calls from user's asking what the error was...and I felt it would be more credible if I did not have this error popping up.

So along the way I figured out what caused the error for myself. I had several 'for loops' that wrote out data like this:

foreach ($collection as $key => $value)
{
$value = trim($value);

if($value != "")
$sheet->write($index,$cellLetter, $value);

}

So I replaced the 'for loops' with the 'writeCol' function that would write out an entire collection into a column.

$sheet->writeCol (8 , 3 , $collection);

This worked for almost every instance where I was looping thru collections, there was one instance where I could not apply this logic, but since it was only about 10 lines of repeating code, I opted to do that rather than cause the Data Lost error. So I am pretty happy with that.

If we ever upgrade to PHP5, I will consider just using the PHPExcel code since I never had the Data Lost error with it.

Hope that helps!