asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Advanced Form Presentation and Printing w/ PDF, FDF, ASP, and DHTML - Part 2
By Eric Coffman
Rating: 4.0 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    Introduction

    Ty Button's 15 Seconds article "Creating a PDF with ASP" does a good job of explaining the installation of the FDF Toolkit ActiveX version on your server and using the methods of the FDFApp object. Rather than repeat what has already been covered, I will just explain the handling of the most common form elements within a PDF Forms file and demonstrate the handling of a Forms Data Format (FDF) file in a real-world situation.

    Download all the sample files for part II here: 010823.zip.

    Getting Started

    We will discuss everything covered in Part I, however, the FDF Toolkit's ActiveX version will be used. I will not go into any detail on retrieving data from a database, client-side or server-side validation, or getting the data back into a database. Everything discussed here will be relative to the form itself.

    Everything discussed is HTML 4.01 compliant, compatible with ASP 2.0, Adobe Acrobat and Adobe Acrobat Reader 5.0, and FDF Toolkit ActiveX version 4. All code examples have been tested on a IIS 4 server with an IE 5.1 browser on the client.

    Required Software

    Adobe Acrobat 5.0 (the full version) is required by the form developer.
    Adobe Acrobat Reader 5.0 is required by the client or user.
    The FDF Toolkit ActiveX version must be installed on the server.

    Step 1: Using the same FormTest.pdf file from Part I of this article, edit the Submit button's Submit Form Action URL to "FormTestFDFSubmit.asp." If you used the Import Data button, edit the Submit Form Action URL to "FormTestFDFSubmit.asp#FDF." Add a "Recommendation" FreeText area and three sets of two radio buttons named "radApprv1," "radApprv2," and "radApprvFinal." Label each set "Yes" and "No." Set the export value of each set to "Yes" and "No," respectively. Save the PDF as FormTestFDF.pdf. I have set the style to "Check."

    Alternately, you can use my FormTestFDF.pdf file found in the complete downloadable source code. However, it would be wise to go through the trouble of modifying your own pdf.

    Step 2: Create the front-end ASP that retrieves data from a database (if desired) and prepopulates all the fields in FormTestFDF.pdf. Name this file FormTestFDFImport.asp, and don't forget to specify your unique URL.

    
    <%@ LANGUAGE = VBScript%>
    <%
    ' SET UP YOUR PAGE
    '***********************************************************************
    
    Option Explicit
    
    '  DECLARE ALL THE VARIABLES
    '***********************************************************************
    
    Dim strFirstName   ' First Name value for the txtFirstName field
    Dim strProgExp     ' Short description of programming experience
    Dim strVBS         ' Title for Program Language(s) most familiar w/-VBScript
    Dim strC           ' Title for Program Language(s) most familiar w/-C++
    Dim strJava        ' Title for Program Language(s) most familiar w/-Java
    Dim strGender      ' Gender of individual
    Dim strFavSite      ' Favorite Web site
    Dim arrColors       ' An array of HTML colors
    Dim intFavColor      ' Index of HTML colors array - Favorite
    Dim i                ' Counter used to iterate through arrColors
    Dim FDFAcX         ' FDF Toolkit ActiveX Version Object
    Dim objFDF           ' FDF Object
    
    ' SET UP YOUR CONNECTION OBJECT HERE 
    '************************************************************************
    
    ' SET UP YOUR RECORDSETS OR COMMAND OBJECTS HERE 
    '************************************************************************
    
    ' SET THE VARIABLES BASED ON DATABASE RESULTS 
    ' (Here, I am setting them with literals as there is no actual database.)
    '****************************************************************************
    
    strFirstName = "Eric"
    strProgExp = "9 months in HTML, 6 months in ASP & VBScript, 1 month in JavaScript, CSS2 & DOM"
    strProgExp = strProgExp & " (Combination commonly referred to as DHTML)"
    strVBS = "Yes"
    strC = "No"
    strJava = "No"
    strGender = "Male"
    strFavSite = "microsoft.com"
    arrColors = Array("FFFF00", "000080", "DF0029", "666666", "009F62")
    intFavColor = 1
    
    ' CLOSE & CLEAN UP YOUR RS, COMMAND OBJECTS, & CONNECTION OBJECT HERE 
    '**************************************************************************
    
    ' END DATA COLLECTION, CREATE THE FDF OBJECT HERE
    '********************************************************** 
    Set FDFAcX = Server.CreateObject("FDFApp.FDFApp")
    
    Set objFDF = FDFAcX.FDFCreate
    
    ' SET THE FULL ABSOLUTE URL OF YOUR PDF FILE
    '*****************************************************
    objFDF.FDFSetFile "http://Inetpub/wwwroot/PDF/FormTestFDF.pdf"
    
    ' USE THE FDFSetValue METHOD TO POPULATE THE PDF's FORM FIELDS 
    '*********************************************************************
    ' PDF form field name, Value you want entered, a value used to comply
    ' with Adobe Acrobat version 3.0 and below.
    objFDF.FDFSetValue "txtFirstName", strFirstName, False
    objFDF.FDFSetValue "txtExperience", strProgExp, False
    objFDF.FDFSetValue "chkVBS", strVBS, False
    objFDF.FDFSetValue "chkC", strC, False
    objFDF.FDFSetValue "chkJava", strJava, False
    objFDF.FDFSetValue "radGender", strGender, False
    objFDF.FDFSetValue "selSite", strFavSite, False
    
    ' Loop through the arrColors array to populate the selColor drop down 
    ' FDFSetOpt "Field Name", Option Index (Begins at 0), Export Value,
    ' Option Item Name
    ' Option Item Name is Null or Empty if there is no
    ' Export Value(Item Name will then equal the Export Value)
    ' Setting FDFSetOpt to "selColor", i, "#" & arrColors(i), "#" & arrColors(i)
    ' has exactly the same affect as below in the actual code. But,
    ' setting FDFSetOpt to "SelColor", i, i, "#" & arrColors(i) will
    ' appear normally, however
    ' the numeric value of i will be sent to the server when submitted.
    For i = 0 to UBound(arrColors)
    objFDF.FDFSetOpt "selColor", i, "#" & arrColors(i), ""
    Next
    
    ' Set i to the indexed Favorite Color
    i = intFavColor
    
    ' Select the Favorite color from the selColor drop down just populated above
    objFDF.FDFSetValue "selColor", "#" & arrColors(i), False
    
    ' USE THE FDFSetStatus METHOD TO DISPLAY AN ALERT BOX 
    ' (recommend that you don't, but it's cool that you can)
    objFDF.FDFSetStatus "You must complete all sections of this form."
    
    ' WRITE THE ASSOCIATED VALUES INTO THE BUFFER STREAM AS AN FDF
    Response.ContentType = "application/vnd.fdf"
    Response.BinaryWrite objFDF.FDFSaveToBuf
    
    ' CLOSE YOUR FDF OBJECT AND CLEAN UP
    objFDF.FDFClose
    Set objFDF = Nothing
    Set FDFAcX = Nothing
    
    Response.End
    %>
    
    
    Step 3: Create the back-end ASP that collects the user's inputs and stores it to a database (if desired). Name this file as FormTestFDFSubmit.asp. Don't forget to specify the location where you want your FDF file saved and the hyperlink.
    
    <%@ LANGUAGE = VBScript%>
    <%
    
    ' SET UP YOUR PAGE 
    '********************************************************
    
    Option Explicit
    Response.Buffer = True
    Response.Expires = -1441
    
    ' DECLARE ALL THE VARIABLES 
    '*********************************************************
    
    Dim strFirstName      ' First Name value for the txtFirstName field
    Dim strProgExp        ' Value of description of programming experience
    Dim strVBS           ' Value of Program Language(s) most familiar w/-VBScript
    Dim strC             ' Value of Program Language(s) most familiar w/-C++
    Dim strJava          ' Value of Program Language(s) most familiar w/-Java
    Dim strGender         ' Gender of individual
    Dim strFavSite        ' Favorite Web site
    Dim strFavColor       ' String of favorite HTML color
    Dim i                 ' Counter used to iterate all field names
    Dim FDFAcX            ' FDF Toolkit ActiveX Version Object
    Dim objFDF            ' FDF Object
    Dim strVersion        ' FDF version number of this toolkit
    Dim strColor          ' Font color to compliment the favorite color
    Dim strFormFileName  ' PDF file name complete with the path
    Dim strFld         ' Temporary reference passed to the FDFNextFieldName method
    Dim strFieldName     ' Field Name extracted from the FDFNextFieldName method
    Dim strFieldValue     ' Field Value extracted from the FDFGetValue method
    Dim intUserLevel      ' User's position within a workplace environment
    
    ' INITIALIZE NECESSARY VARIABLES
    '***********************************************************
    ' 0 = Requestor
    ' 1 = Requestor's immediate supervisor
    ' 2 = Level 1's supervisor
    ' 3 = Level 2's supervisor, has final authority
    
    intUserLevel = 0   ' Normally this value would be extracted from 
    			  'a Session variable.
    
    
    ' BEGIN FORM DATA COLLECTION USING THE FDF OBJECT HERE 
    '************************************************************ 
    Set FDFAcX = Server.CreateObject("FDFApp.FDFApp")
    
    Set objFDF = FDFAcX.FDFOpenFromBuf (Request.BinaryRead(Request.TotalBytes))
    
    ' USE THE FDFGetValue METHOD TO COLLECT THE PDF's FORM FIELDS VALUES
    ' This is one method of collecting the field values.
    '************************************************************
    strFirstName = objFDF.FDFGetValue("txtFirstName")
    strProgExp = objFDF.FDFGetValue("txtExperience")
    strVBS = objFDF.FDFGetValue("chkVBS")
    strC = objFDF.FDFGetValue("chkC")
    strJava = objFDF.FDFGetValue("chkJava")
    strGender = objFDF.FDFGetValue("radGender")
    strFavSite = objFDF.FDFGetValue("selSite")
    strFavColor = objFDF.FDFGetValue("selColor")
    
    ' Additional FDF information
    strFormFileName = objFDF.FDFGetFile
    strVersion = FDFAcX.FDFGetVersion
    
    If strFavColor = "#FFFF00" OR strFavColor = "#FFCC00" Then
    strColor = "black"
    Else
    strColor = "white"
    End If
    
    ' SET UP YOUR CONNECTION OBJECT HERE
    '**************************************************************
    
    'SET UP YOUR RECORDSETS OR COMMAND OBJECTS HERE AND STORE THE
    ' ABOVE-EXTRACTED DATA
    '****************************************************************
    
    ' CLOSE & CLEAN UP YOUR RECORDSETS, COMMAND OBJECTS, 
    '& CONNECTION OBJECT HERE
    '****************************************************************
    
    ' DISPLAY THE ABOVE-EXTRACTED DATA
    '****************************************************************
    %>
    
    <html>
    
    <head>
    <title>FormTestFDF.pdf Posted Results </title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    </head>
    
    <body bgcolor="#FFFFFF">
    <p>This will accept the data from FormTestFDF.pdf</p>
    <!-- Provide a link using the actual saved FDF file (Saved below) -->
    <p><a href="http://Inetpub/wwwroot/PDF/FormTestFDF.fdf">View this form again</a>
     to demonstrate a User's Level (position) within a workplace environment.</p>
    <table width="50%" border="1" cellspacing="5" cellpadding="5">
    <tr>
    <td>This is the value from the txtFirstName field:</td>
    <td> <% = strFirstName %> </td>
    </tr>
    <tr>
    <td>This is the value from the txtExperience field:</td>
    <td> <% = strProgExp %> </td>
    </tr>
    <tr>
    <td>This is the value from the chkVBS field:</td>
    <td> <% = strVBS %> </td>
    </tr>
    <tr>
    <td>This is the value from the chkC field:</td>
    <td> <% = strC %> </td>
    </tr>
    <tr>
    <td>This is the value from the chkJava field:</td>
    <td> <% = strJava %> </td>
    </tr>
    <tr>
    <td>This is the value from the radGender field:</td>
    <td> <% = strGender %> </td>
    </tr>
    <tr>
    <td>This is the value from the selSite field:</td>
    <td> <% = strFavSite %> </td>
    </tr>
    <tr>
    <td>This is the value from the selColor field:</td>
    <td bgcolor="<% = strFavColor %>"><font color="<% = strColor %>">
     <% = strFavColor %> </font></td>
    </tr>
    <tr>
    <td>This FDF Version is:</td>.
    <td> <% = strVersion %> </td>
    </tr>
    <tr>
    <td>This PDF File Name is:</td>
    <td> <% = strFormFileName %> </td>
    </tr>
    
    <%
    ' USE THE FDFNextFieldName METHOD TO COLLECT THE PDF's FORM FIELDS NAMES
    ' First field name is unknown so specify "". 
    ' Store the name to a variable and pass it to your next FDFNextFieldName method
    ' Use the Field Name variable and pass it to the FDFGetValue method
    ' In this case the first field is the Submit button which has no value and
    ' returns an error if passed to the FDFGetValue method
    ' This is another method of collecting the field values
    ' but you must check for an empty value as there is no Length or Count property
    ' of the FDFNextFieldName
    '*************************************************************************
    strFld = objFDF.FDFNextFieldName("") 'Collect the first field name by passing ""
    %>
    
    <tr>
    <td>Field0's name is:</font></td>
    <td> <% = strFld %> </td>
    </tr>
    
    <%
    i = 1
    Do Until i = 0
    strFieldName = objFDF.FDFNextFieldName(strFld)
    If strFieldName & "" = "" Then 'Check for an empty value, end iteration if empty
    i = 0
    Else
    strFieldValue = objFDF.FDFGetValue(strFieldName)
    %>
    
    <tr>
    <td>Field<% = i %>'s name is:</font></td>
    <td> <% = strFieldName %> </td>
    <td> <% = strFieldValue %> </td>
    </tr>
    
    <%
    strFld = strFieldName
    i = i + 1
    End If
    Loop
    %> 
    
    </table>
    
    </body>
    </html>
    
    <%
    ' The object objFDF was initially set to equal all the FDF properties from 
    ' the buffer during the FDFAcX.FDFOpenFromBuf method. So, not only can we
    ' read all of this data (which we have just shown), but we can modify it,
    ' add to it, subtract from it, or whatever, and save this new data as an FDF
    ' file. This is a physical file that can be processed later on or even
    ' attached to an e-mail and sent to a client.
    '******************************************************************
    
    ' Let's say we have a request form that has multiple levels in a workplace 
    ' environment. We can collect and identify a user via a session variable,
    ' and depending on what position the user holds in their company, we can choose
    ' to ignore or change form values that they have no business modifying. For
    ' instance, the originating user (the requestor) cannot recommend whether their
    ' request should be approved or not. So we would ignore or change these
    ' Recommendation blocks to the value of "Off."
    ' Let's also take into account that if a user does have the FINAL say
    ' in the matter but makes this determination based upon what their trusted
    ' subordinates have recommended. They would need to see what that actual 
    ' subordinate recommended, not what
    ' their immediate subordinate may have changed these values to
    '(FDF cannot modify a field's read-only attribute, unfortunately.).
    
    Select Case intUserLevel
        Case 0 '-- Requestor cannot make recommendations
            objFDF.FDFSetValue "radApprv1", "Off", False
            objFDF.FDFSetValue "radApprv2", "Off", False
            objFDF.FDFSetValue "radApprvFinal", "Off", False
            objFDF.FDFSetStatus "Requestor submitted this form, all recommendation blocks set to Off"
        Case 1 '-- Level 1, can only make Level 1 recommendations
            objFDF.FDFSetValue "radApprv2", "Off", False
            objFDF.FDFSetValue "radApprvFinal", "Off", False
            objFDF.FDFSetStatus "Level 1 submitted this form, only recommendation Level 1 was saved"
        Case 2 '-- Level 2, can only make Level 2 recommendations
            objFDF.FDFSetValue "radApprv1", "Yes", False ' Whatever was previously collected
     ' from Level 1 (We'll say 'Yes')
            objFDF.FDFSetValue "radApprvFinal", "Off", False
            objFDF.FDFSetStatus "Level 2 submitted this Form, only recommendation Level 2 was saved"
        Case 3 '-- Level 3, has final authority
            objFDF.FDFSetValue "radApprv1", "Yes", False 'Whatever was collected
            objFDF.FDFSetValue "radApprv2", "Yes", False 'from Level 2 (We'll say 'Yes')
            objFDF.FDFSetStatus "Level 3 submitted this form, only recommendation Level 3 was saved"
        Case Else
            'Normally we would place the FDFSavetoFile method in each case except this one.
    End Select
    
    '-- Save the collected data and any modified data to an FDF file.
    objFDF.FDFSavetoFile "c:\Inetpub\wwwroot\PDF\FormTestFDF.fdf"
    
    '-- CLOSE YOUR FDF OBJECT AND CLEAN UP --
    objFDF.FDFClose
    Set objFDF = Nothing
    Set FDFAcX = Nothing
    '-- The following causes the HTML to actually be sent to the client.
    ' Up to this point, no HTML has actually been downloaded to the client
    ' browser.
    Response.End
    %>
    
    

    Conclusion

    Ensure that you read the comments throughout the ASPs. They detail many of the FDF methods and various possibilities that may be implemented. Please experiment with the intUserLevel value in the FormTestFDFSubmit.asp file.

    Unfortunately Adobe Acrobat Forms has a bug that causes the submission of a form to dump the user to a temporary local HTML document. There are two ways around this bug: Use a client-side script that redirects the user back to your server or provide an Exit button within the PDF form with the Action Type set to World Wide Web Link. (This simply provides an escape; you cannot collect any form data using this Action Type.) This was not included in the samples so that the submitted form data could be viewed.

    Installing the FDF Toolkit -ActiveX version on your server and using the FDFApp object allows for much greater versatility than simply using the FDF text file within an ASP. As the samples have shown, you can save a FDF file and transport this file by any means. A saved FDF file is specifically associated with a PDF file on your server so that no matter where the FDF file is accessed from, it will resolve back to your server (unless your server is an intranet site and the user accesses the FDF file from outside of this environment). There are many more FDFApp methods that were not covered here. Also, there are quite a few additional FDFApp methods that only apply to a saved FDF file that will not work with an FDF object obtained from a submitted PDF form. (But, you can save the FDF submitted from a PDF form, close the object, and reopen the object with the saved FDF file, process some additional modifications, and save over the FDF file, all within the same ASP.)

    Part III deals with the appearance of a form when viewed within a browser and changing this appearance when printing the form using DHTML (JavaScript, Cascading Style Sheets Level 2 [CSS2], and the Document Object Model [DOM]).

    Resources

    For an article on "How to populate a PDF file's form with data from a web server,"see http://www.planetpdf.com/mainpage.asp?webpageid=370.

    For an FDF Toolkit Overview, see http://partners.adobe.com/asn/developer/acrosdk/docs/fdftk/FDFToolkitOverview.pdf.

    For an FDF Toolkit Reference, see http://partners.adobe.com/asn/developer/acrosdk/docs/fdftk/FDFToolkitReference.pdf.

    The FDF Toolkit SDK can be obtained for free at http://partners.adobe.com/asn/developer/acrosdk/forms.html.

    Note: This article covers FDF Toolkit version 4, whereas Adobe's current version is 5. They appear to be compatible.

    About the Author

    Eric Coffman is currently working as an ASP (mostly!) programmer for SIMA San Diego's Web Development and Information Systems. Adobe Acrobat PDF forms are used to automatically route various requests through a user's specific chain of command within an intranet environment. He can be contacted at komodo@backpacker.com.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Supporting Products/Tools
    Proposion N2N
    Proposion N2N connects Microsoft .NET applications to Lotus Notes and Lotus Domino databases. This ADO.NET managed data provider allows you to perform blindingly fast queries and updates of Notes data from ASP.NET pages, .NET web services, Windows, or Mobile applications. An innovative SQL-like query language leverages the unique features of Notes and makes collaborative software accessible to relational database programmers.
    [Top]
    Other Articles
    Sep 15, 2005 - Building an Image Keyword System
    Unlike text-based file formats image files aren't made up of words, which makes searching for an image file by keyword difficult. Instead of being able to simply open the file to see what it contains, we're stuck looking at the text around it and other metadata to determine the image's meaning. In this article, Ziran Sun shows you how to build a simple database-based image keyword system that allows you to associate keywords with images and use these keywords to make finding images easier.
    [Read This Article]  [Top]
    Apr 7, 2005 - A Step-by-Step Guide To Using MySQL with ASP.NET - Part 2
    In the second part of of his article on using MySQL with ASP.NET, Ziran Sun covers how to add a new MySQL user to the database server, assign the user the appropriate permissions, connect to the database, and build a simple ASP.NET page to perform a query.
    [Read This Article]  [Top]
    Feb 10, 2005 - A Step-by-Step Guide To Using MySQL with ASP.NET - Part 1
    Back in the days of classic ASP, if you were building a database-driven web site, your choice was either to invest a lot of money to get a copy of Microsoft SQL Server (or some other enterprise-ready database) or invest a lot of time finding a way to deal with the performance and scalability limitations of Microsoft Access. Luckily these days there's another viable alternative: MySQL.
    [Read This Article]  [Top]
    Jan 27, 2005 - Moving a Database from SQL Server 7.0 to SQL Server 2000
    Moving or copying a SQL Server database from one machine to another requires a lot of preparation in order to ensure a smooth transfer. In this article, Dina Fleet Berry examines the different methods and highlights the different issues associated with each of them.
    [Read This Article]  [Top]
    Jan 6, 2005 - Debugging a SQL Stored Procedure from inside SQL Server 2000 Query Analyzer
    There are many times when using SQL Server 2000 Query Analyzer to debug SQL statements is a better choice than debugging in Visual Studio .NET. In this article, Dina Fleet Berry explains why and walks you through the debugging process step-by step.
    [Read This Article]  [Top]
    Nov 24, 2004 - Persisting .NET Objects to SQL Server Using SQLXML and Serialization
    As a follow up to his article on retrieving objects from SQL Server using SQLXML and serialization, Gianluca Nuzzo discusses saving objects back to SQL Server using a schema definition file and updategrams.
    [Read This Article]  [Top]
    Sep 14, 2004 - Transaction Processing in ADO.NET 2.0
    One area that stands out when comparing ADO.NET 1.x to ADO.NET 2.0 is transaction processing. Bill Ryan shows just how easy transaction processing has become with the TransactionScope object in ADO.NET 2.0.
    [Read This Article]  [Top]
    Sep 8, 2004 - Custom Object Data Binding with .NET
    Developers often use brute force coding to marshal data between the GUI and application objects. In this article, Luther Stanton explains how to use .NET's out-of-the box data-binding functionality to make this job much easier.
    [Read This Article]  [Top]
    Sep 2, 2004 - Queue MSMQ Messages from SQL Server
    Learn how to create a console application to queue a message in Microsoft Message Queuing (MSMQ) and then use an extended stored procedure to call the console application from a SQL Server trigger.
    [Read This Article]  [Top]
    Aug 30, 2004 - Tuning Up ADO.NET Connection Pooling in ASP.NET Applications
    Connection pooling increases the performance of Web applications by reusing active database connections instead of creating a new connection with every request. This article shows how to monitor the connection pool, diagnose a potential problem, and apply the appropriate fix.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry



    JupiterOnlineMedia

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info


    Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers