//
// This code is part of Document Solutions for PDF demos.
// Copyright (c) MESCIUS inc. All rights reserved.
//
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Pdf.AcroForms;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf.Spec;
namespace DsPdfWeb.Demos
{
// This sample demonstrates using the GcPdfViewer's Form Filler
// to load PDF form created by using DsPdf or GcExcel (containing custom input types).
// This and other samples in this section demonstrate the features of GcPdfViewer
// (a JavaScript PDF viewer control included with DsPdf), mainly the ability
// to change PDF files (add or edit annotations and AcroForm fields, rotate pages etc.)
// when the JS viewer on the client is supported by DsPdf running on the server.
//
// To enable the editing features of the viewer, its supportApi property must be set
// to a URL on the server that implements all or some of the edit supporting APIs
// that are known to/expected by the viewer. This DsPdf demo site provides those APIs,
// which makes it possible to demonstrate the editing when you open the PDF viewer
// in this sample. When you download this sample, in addition to the .NET Core
// console app project that generates the sample PDF, an ASP.NET Core project is
// also included in the download zip (located in the GcPdfViewerWeb sub-folder of the
// downloaded zip), which also provides the necessary APIs. In particular, it includes
// a project that implements the APIs and provides them via a special controller.
// It is actually the same controller that is used by this DsPdf demo site, and which
// can be used in any ASP.NET Core site to enable the viewer editing features.
//
// Look at the following files in the sample download zip for more info:
// - GcPdfViewerWeb\SupportApiDemo: the sample ASP.NET Core web site.
// - GcPdfViewerWeb\SupportApiDemo.sln: solution to build/run the sample web site.
// - GcPdfViewerWeb\SupportApi: support API implementation (can be used in any site).
// - GcPdfViewerWeb\SupportApi\Controllers\GcPdfViewerController.cs: support API controller.
//
// Please note that this and other samples in this section are only available in C# at this time.
//
public class ViewerPdfInputTypes
{
public void CreatePDF(Stream stream)
{
CreateFormFieldsPDF(stream);
}
private Dictionary<string, KeyValuePair<string, object>[]> GetSampleGcPropTextFields()
{
return new Dictionary<string, KeyValuePair<string, object>[]>() {
{
"date", new KeyValuePair<string, object>[]{
new KeyValuePair<string, object>("type", "date"),
new KeyValuePair<string, object>("placeholder", "Input date")}
},
{
"read-only date", new KeyValuePair<string, object>[]{
new KeyValuePair<string, object>("type", "date"),
new KeyValuePair<string, object>("defaultvalue", "2018-01-01"),
new KeyValuePair<string, object>("readonly", true)
}
},
{
"time", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "time") }
},
{
"time with default value", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "time"),
new KeyValuePair<string, object>("defaultvalue", "18:00") }
},
{
"tel", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "tel"),
new KeyValuePair<string, object>("validateoninput", true) }
},
{
"tel with pattern", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "tel"),
new KeyValuePair<string, object>("pattern", @"^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$"),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("validationmessage", "Valid formats:" +
"(123) 456-7890" +
"(123)456-7890" +
"123-456-7890" +
"123.456.7890" +
"1234567890" +
"+31636363634" +
"075-63546725") }
},
{
"email", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "email"),
new KeyValuePair<string, object>("autocomplete", "email"),
new KeyValuePair<string, object>("validateoninput", true) }
},
{
"multiple emails", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "email"),
new KeyValuePair<string, object>("autocomplete", "email"),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("multiple", true) }
},
{
"emails with pattern", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "email"),
new KeyValuePair<string, object>("pattern", @"\S+@example\.com"),
new KeyValuePair<string, object>("autocomplete", "email"),
new KeyValuePair<string, object>("placeholder", "Expected domain @example.com."),
new KeyValuePair<string, object>("validationmessage", "test@example.com."),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("multiple", true) }
},
{
"url", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "url"),
new KeyValuePair<string, object>("autocomplete", "url"),
new KeyValuePair<string, object>("validateoninput", true) }
},
{
"password", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "password"),
new KeyValuePair<string, object>("autocomplete", "new-password"),
new KeyValuePair<string, object>("validateoninput", true) }
},
{
"password with minlength", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "password"),
new KeyValuePair<string, object>("placeholder", "minlength=8"),
new KeyValuePair<string, object>("minlength", 8),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("autocomplete", "new-password")} },
{
"password with maxlength", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "password"),
new KeyValuePair<string, object>("placeholder", "maxlength=4"),
new KeyValuePair<string, object>("maxlength", 4),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("autocomplete", "off")} },
{
"password with pattern", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "password"),
new KeyValuePair<string, object>("placeholder", "4 to 8 characters"),
new KeyValuePair<string, object>("pattern", @"^(?=.*\d).{4,8}$"),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("validationmessage", "The password must be between 4 and 8 characters."),
new KeyValuePair<string, object>("autocomplete", "off")}
},
{
"password PIN", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "password"),
new KeyValuePair<string, object>("title", "Input your PIN"),
new KeyValuePair<string, object>("placeholder", "PIN"),
new KeyValuePair<string, object>("pattern", @"^[0-9]{3,3}$"),
new KeyValuePair<string, object>("maxlength", 3),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("validationmessage", "PIN password must be 3 digits."),
new KeyValuePair<string, object>("autocomplete", "one-time-code")}
},
{
"text with autofocus", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "text"),
new KeyValuePair<string, object>("autofocus", "true") }
},
{
"required text", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "text"),
new KeyValuePair<string, object>("required", true),
new KeyValuePair<string, object>("validateoninput", true) }
},
{
"text, spellcheck='true'", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "text"),
new KeyValuePair<string, object>("defaultvalue", "mistaake"),
new KeyValuePair<string, object>("spellcheck", "true")}
},
{
"text, spellcheck='false'", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "text"),
new KeyValuePair<string, object>("defaultvalue", "mistaake"),
new KeyValuePair<string, object>("spellcheck", "false")}
},
{
"month", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "month") }
},
{
"week", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "week") }
},
{
"number with min/max", new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("type", "number") ,
new KeyValuePair<string, object>("placeholder", "number"),
new KeyValuePair<string, object>("required", true),
new KeyValuePair<string, object>("title", "Please enter a number between 1 and 100"),
new KeyValuePair<string, object>("min", 1),
new KeyValuePair<string, object>("max", 100),
new KeyValuePair<string, object>("validateoninput", true),
new KeyValuePair<string, object>("validationmessage", "Expected number from 1 to 100") }
},
{
"search", new KeyValuePair<string, object>[] { new KeyValuePair<string, object>("type", "search") }
},
{
"range", new KeyValuePair<string, object>[] { new KeyValuePair<string, object>("type", "range"),
new KeyValuePair<string, object>("title", "Please select a number between 1 and 100"),
new KeyValuePair<string, object>("defaultvalue", 50),
new KeyValuePair<string, object>("min", 1),
new KeyValuePair<string, object>("max", 100)}
},
{
"color", new KeyValuePair<string, object>[] { new KeyValuePair<string, object>("type", "color"),
new KeyValuePair<string, object>("title", "Please select a color"),
new KeyValuePair<string, object>("defaultvalue", "#385dab") }
}
};
}
public void CreateFormFieldsPDF(Stream stream)
{
var doc = new GcPdfDocument();
var page = doc.NewPage();
var g = page.Graphics;
var tf = new TextFormat();
tf.Font = StandardFonts.Helvetica;
tf.FontSize = 14;
var ip = new PointF(72, 72);
float fldOffset = 72f * 3f;
float fldHeight = tf.FontSize * 1.6f;
float dY = 28;
// Add sample fields:
int orderindex = 1;
var sampleGcPropTextFields = GetSampleGcPropTextFields();
foreach (var data in sampleGcPropTextFields)
{
string fieldName = data.Key;
g.DrawString($"{fieldName}:", tf, ip);
var field = new TextField();
// Fill GcProps dictionary:
KeyValuePair<string, object>[] gcProps = data.Value;
foreach(var gcProp in gcProps)
{
field.GcProps[new PdfName(gcProp.Key)] = IPdfObjectExt.FromObject(gcProp.Value);
}
field.GcProps[new PdfName("orderindex")] = new PdfNumber(orderindex);
field.Name = fieldName;
field.Widget.Page = page;
field.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight);
field.Widget.DefaultAppearance.Font = tf.Font;
field.Widget.DefaultAppearance.FontSize = tf.FontSize;
doc.AcroForm.Fields.Add(field);
ip.Y += dY;
orderindex++;
}
// Done:
doc.Save(stream);
}
// Used by SupportApiDemo to initialize GcPdfViewer.
public static GcPdfViewerSupportApiDemo.Models.PdfViewerOptions PdfViewerOptions
{
get => new GcPdfViewerSupportApiDemo.Models.PdfViewerOptions(
GcPdfViewerSupportApiDemo.Models.PdfViewerOptions.Options.SupportApi ,
viewerTools: new string[] { "open", "save", "form-filler", "$navigation", "$split", "text-selection", "pan", "$zoom", "print", "rotate", "hide-annotations", "doc-properties", "about" });
}
public const string JS_CODE = @"
function createPdfViewer(selector, baseOptions) {
var options = baseOptions || {};
options.formFiller = { title: 'Fill custom input Form Fields'}
var viewer = new GcPdfViewer(selector, options);
viewer.addDefaultPanels();
// Configure toolbar buttons:
viewer.toolbarLayout.viewer = {
default: ['open', 'save', 'form-filler', '$navigation', '$split', 'text-selection', 'pan', '$zoom', 'print', 'rotate', 'hide-annotations', 'doc-properties', 'about'],
mobile: ['open', 'save', 'form-filler', '$navigation', '$split', 'text-selection', 'pan', '$zoom', 'print', 'rotate', 'hide-annotations', 'doc-properties', 'about'],
fullscreen: ['$fullscreen', 'open', 'save', 'form-filler', '$navigation', '$split', 'text-selection', 'pan', '$zoom', 'print', 'rotate', 'hide-annotations', 'doc-properties', 'about']
};
viewer.applyToolbarLayout();
viewer.applyOptions();
return viewer;
}
";
}
}