Archive for the ‘JavaScript/AJAX’ Category

BlackBerry Simulator Error with SQLite and HTML5

When testing an HTML5 app on multiple BlackBerry simulators, on some of them I was getting the error:

SECURITY_ERR: DOM Exception 18

What this turned out to be was the lack of an SD card in certain simulators. The browser was expecting to use that storage space for the SQLite DB files. Once I set up the SD card for the emulator the error disappeared.

Printing a PDF from a web page

The requirement in this case is to print a PDF document, but not allow the user to manipulate the PDF in any other way. The user should see the Print Dialog box and be able to manipulate the settings. This requirement was born out of an auditing policy where the document is audited differently for printing or viewing the PDF.  I found lots of web discussion about printing a pop-up window from the parent window, or trying to print the contents of an IFrame, but none of it worked for me. I was hit with security errors from IE about cross-domain issues, even though my pages were in the same domain, or just got a blank page. So to get a working solution, I had to step out of the web page.

The tool that really allowed me to do this is iTextSharp, a C# implementation of the iText open source java library for manipulating PDF files, and the fact that you can use JavaScript within a PDF file. I used an ASPX page which manipulates and streams the PDF file into a zero-height, zero-width IFrame to keep the user from manipulating the PDF in any way (I realize tech-savvy users could still get the PDF).  I embedded the JavaScript into the PDF, where it runs once the document is loaded and pops up the Print dialog from Adobe Reader (not the browser).

The JavaScript for printing a PDF is not so complex, I embedded it into a function:

protected string GetAutoPrintJs()
{
    var script = new StringBuilder();

    script.Append("var pp = getPrintParams();");
    script.Append("pp.interactive = pp.constants.interactionLevel.full;");
    script.Append("print(pp);");

    return script.ToString();
}

In the code-behind for the ASPX page that will stream the PDF and place the script inside the PDF file, I built this function:

protected void StreamPdf(Stream pdfSource)
{
    var outputStream = new MemoryStream();

    var pdfReader = new PdfReader(pdfSource);

    var pdfStamper = new PdfStamper(pdfReader, outputStream);

    //Add the auto-print javascript
    var writer = pdfStamper.Writer;
    writer.AddJavaScript(GetAutoPrintJs());

    pdfStamper.Close();

    var content = outputStream.ToArray();
    outputStream.Close();
    Response.ContentType = "application/pdf";
    Response.BinaryWrite(content);
    Response.End();
    outputStream.Close();
    outputStream.Dispose();
}

The PDFReader and PDFStamper  classes are members of the iTextSharp library. I used the classes together to get the stream for output and also access to PDFWriter object that allowed me to add the JavaScript.

Invalid postback or callback argument – AJAX Control Toolkit

I was working to add some Ajax interactivity to a page that needed some asynchronous workings. Unfortunately, after displaying a ModalPopupExtender and the user clicking the Close button on the “popup”, the page would throw the following exception:

System.ArgumentException occurred
  Message=”Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation=\”true\”/> in configuration or <%@ Page EnableEventValidation=\”true\” %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.”
  Source=”System.Web”
  StackTrace:
       at System.Web.UI.ClientScriptManager.ValidateEvent(String uniqueId, String argument)
  InnerException:

There are lots of explanations out there for this kind of problem, but none of the common answers really fit. The most common answer was to disable event validation. That wasn’t a good answer for me, I don’t think disabling an important security feature because you have complex code is a good solution. The other common answer was to override the render event to register the control posting back with the ScriptManager. This did not work at all for me.

After finding an reading through this post and the comments, I realized the problem was indeed in the code. After the call to ModalPopupExtender.Show(), the original code was re-binding a grid on the page. This order of events was causing the problem. I changed the binding to occur before the call to the ModalPopupExtender by changing which event containing the rebinding call, and the error went away.

Linq Foray

I’m working on a website with lots of user controls interacting with one another using ASP.NET Ajax using events. So I end up needing to find other controls often, especially within repeaters. Nested controls all over the place. I found this wonderful post about using an extension method to the Controls Collection that flattens the tree and allows for much simpler Linq queries. The extension method adds and All() function which is seriously useful.

Using XMLHTTP in Javascript

I attended a terrific meeting tonight of GANG, the Great Lakes Area .Net user Group, based in the Detroit-area. The main presenter was Jason Beres who gave an excellent presentation on ASP.Net tricks, many of them utilizing Javascript. One of my favorites came up in discussion and I agreed to post the code snippet here.


I have used this techniqe mainly on classic ASP pages as a way to populate secondary dropdown lists before ASP.Net and control-based postbacks came along. It still works with ASP.Net… BUT…the secondary listbox is not in the Viewstate so it’s value isn’t set properly when accessing the control in server code on the postback where you handle the data. The secondary list’s selected value is still in the Request.Form collection though. It is still a great technique to use to fetch data from the server without reloading the page.


The technique is IE-only as it uses an ActiveX object (XMLHTTP) in the Javascript. It also uses the XML DOM to parse the response from the server. In this example the server is an ASP page, but it could easily be a web service as well with the addition of one a little more code. This code is related to a previous post where I used VBA to enable Excel to be a web service client.


Here is the Javascript function:


/*  Purpose: Fill secondary list boxes with content
    Arguments:  oItem – the primary dropdownlist object
                sFieldName – The name of the field filling the secondary list
                oDestination – the secondary list object
    Returns: None, fills list box using MSXML*/
 
function fillSecondary(oItem, sFieldName, oDestination)
{
  var nValue = oItem[oItem.selectedIndex].value;
 
  var xmlHTTP = new ActiveXObject(“Microsoft.XMLHTTP”);
  xmlHTTP.open(“POST”, “./listboxesXML.asp”, false);
  xmlHTTP.send(‘<’ + sFieldName + ‘>’ + nValue + ‘    
  var xmlDOM = new ActiveXObject(“Microsoft.XMLDOM”);


  xmlDOM.loadXML(xmlHTTP.ResponseText);


  if (xmlDOM.parseError != 0)
  {
   alert(“Error occurred: ” + xmlDOM.parseError.reason);
   return false;
  }


  var oNode = xmlDOM.documentElement.firstChild;
  var n=0;
  if(oNode != null)
  {
   //Clear out the secondary list box, it might already have items
   oDestination.length = 0;
   while (oNode != null)
   {
    oDestination[n] = new Option(oNode.text, oNode.attributes(0).text);
    n++;
    oNode = oNode.nextSibling;
   }
   if(n==1)
    oDestination.selectedIndex = 0;
  }
}


In the HTML on the page, add an OnChange handler to the primary dropdown list to call the Javascript when the user changes the value:


<FORM id=“Form1“>

<SELECT id=“Primary“ onchange=“fillSecondary(this, “Primary“, document.form1.secondary)“><OPTION value=“1“ selected>A list Item</OPTION></SELECT>

<SELECT id=“Secondary“ name=“Secondary“></SELECT>
</FORM>


The classic ASP page (listboxesXML.asp) called by the Javascript looks like this:


Dim xmlDOM   ‘XML DOM object
Dim oRS    ‘Recordset for child records
Dim sXML   ‘XML String returned to browser
Dim oNode   ‘DOM node containing data for searching
Dim sType   ‘The type/name of the unknown child node


set xmlDOM = Server.CreateObject(“MSXML2.DOMDocument”)
xmlDOM.async = false
xmlDOM.Load Request
xmlDOM.setProperty “SelectionLanguage”, “XPath”
if xmlDOM.parseError = 0 then
 ‘Select the request node
    set oParent = xmlDOM.selectSingleNode(“request”)
    ‘Get the child of the request node
    set oNode = oParent.firstChild
    ‘Store the child’s value
    sSearchValue = oNode.Text
    ‘Store the child’s name
    sType = oNode.nodeName

    set oRS = Server.CreateObject(“ADODB.recordset”)

    ‘Fetch the appropriate data into the recordset using sType to tell which
    ‘  secondary list we should be fetching, in this case it is called “secondarytype“

    ‘ADO Code should be here, removed for brevity

 if not oRS.EOF then
  ‘Build a response XML string
  sXML = “
  while not oRS.EOF
   sXML = sXML & “<” & sType & ” id=”"” & oRS.Fields(0).Value & “”">”
   sXML = sXML & Server.HTMLEncode(ors.Fields(1).Value) & “   oRS.MoveNext
  wend
  sXML = sXML & “

  oRS.Close
 else
  sXML = “
  sXML = sXML & “<” & sType & ” id=”"0″”>”
  sXML = sXML & “None listed  sXML = sXML & “

  oRS.Close
 end if
 set oRS = nothing
Response.Write sXML
else
Err.Raise 1, “ParseError”, “There was a parse error in the request.”
end if


This can be very tricky to debug if you have any problems. Try looking at the xmlHTTP.ResponseText in an alert in the Javascript function to see any 500 errors generated by the server.

Bad Behavior has blocked 53 access attempts in the last 7 days.