Dynamic Stamp has multiple pop-up windows

This Forum is for the use of End Users requiring help and assistance for Tracker Software's PDF-Tools.

Moderators: PDF-XChange Support, Daniel - PDF-XChange, Chris - PDF-XChange, Sean - PDF-XChange, Vasyl - PDF-XChange, Stefan - PDF-XChange

nfs
User
Posts: 1
Joined: Wed Feb 11, 2026 11:56 am

Dynamic Stamp has multiple pop-up windows

Post by nfs »

Hello

I have very little-to-zero knowledge of javascript so would appreciate any help/advice you can give me.

I have searched the forum/internet and cobbled together snippets of code to create the attached dynamic stamp which has various text boxes, radio buttons and dropdown boxes.

It (surprisingly) works, but the 2 dropdown boxes appear in separate popup windows so there are 3 popup windows in total.

Is it possible to have just one popup window that combines everything?

It would also be incredibly helpful if the dropdown boxes didn’t have to be selected every time and had default choices (Approved & Coded for DropdownApproved and File for DropdownFile).

I have attached my stamp, and the code is below - apologies for the state of it - as it’s a mashup of random bits I’ve found through searching the internet, I’m sure its full of unnecessary text and is pretty ugly.

Thanks again

Code: Select all

event.value = (new Date()).toString(); AFDate_FormatEx("HH:MM  dd/mm/yyyy");
[attachment=0]Invoice Stamp.pdf[/attachment]
theItems=["Approved","Coded","Approved & Coded"];
theField="I have...";
theList="theList \= \{\""+theField+"\": "+(theItems.length+1)+",";
for (var i=0; i<theItems.length; i++) {
	itemName=theItems[i];
	theList+="\""+itemName+"\": "+(-1*(i+1)).toString()+",";
}
theList=theList.substring(0,theList.length-1);
theList+="\}";
eval(theList);
dialogBox={
	initialize: function(dialogBox) {
		this.loadDefaults(dialogBox);
	},
	loadDefaults: function(dialogBox) {
		dialogBox.load({
			LCha: theList,
		})
	},
	validate: function(dialogBox) {
		oRslt=dialogBox.store();
		elements=dialogBox.store()["LCha"];
		testOK=true;
		for (var i in elements) {
			if (elements[i]>0) {
				listValue=theList[i];
				listName=i;
			}
		}
		if (listValue>0) var testOK=false;
		if (!testOK) app.alert("Please select an item",3);
		return testOK;
	},
	description: {
		name: "Stamp with Dropdown",
		elements: [
			{
				type: "view",
				elements: [
					{
						type: "view",
						alignment: "align_left",
						elements: [
							{
								type: "static_text",
								name: "I have...",
								font: "dialog",
								bold: true,
							},
							{
								type: "popup",
								item_id: "LCha",
								width: 150,
								alignment: "align_left",
							},
						]
					},
					{
						type: "gap",
						height: 5
					},
					{
						type: "ok_cancel",
					},
				]
			},
		]
	}
};
if (event.source.forReal && event.source.stampName=="#UAd48LM4KuAhtTWHxkQ-DA") {
	if("ok"==app.execDialog(dialogBox)){
		event.value=listName;
	}
}

var theItems=["File","Do Not File"];
var theField="OK to File?";
var theList="var theList \= \{\""+theField+"\": "+(theItems.length+1)+",";
for (var i=0; i<theItems.length; i++) {
	var itemName=theItems[i];
	theList+="\""+itemName+"\": "+(-1*(i+1)).toString()+",";
}
var theList=theList.substring(0,theList.length-1);
theList+="\}";
eval(theList);
var dialogBox={
	initialize: function(dialogBox) {
		this.loadDefaults(dialogBox);
	},
	loadDefaults: function(dialogBox) {
		dialogBox.load({
			LCha: theList,
		})
	},
	validate: function(dialogBox) {
		var oRslt=dialogBox.store();
		var elements=dialogBox.store()["LCha"];
		var testOK=true;
		for (var i in elements) {
			if (elements[i]>0) {
				listValue=theList[i];
				listName=i;
			}
		}
		if (listValue>0) var testOK=false;
		if (!testOK) app.alert("Please select an item",3);
		return testOK;
	},
	description: {
		name: "Stamp with Dropdown",
		elements: [
			{
				type: "view",
				elements: [
					{
						type: "view",
						alignment: "align_left",
						elements: [
							{
								type: "static_text",
								name: "Stamp",
								font: "dialog",
								bold: true,
							},
							{
								type: "popup",
								item_id: "LCha",
								width: 150,
								alignment: "align_left",
							},
						]
					},
					{
						type: "gap",
						height: 5
					},
					{
						type: "ok_cancel",
					},
				]
			},
		]
	}
};
if (event.source.forReal && event.source.stampName=="#UAd48LM4KuAhtTWHxkQ-DA") {
	if("ok"==app.execDialog(dialogBox)){
		event.value=listName;
	}
}

var builder = 
{
 // These map to Text Fields in the Stamp
 textBoxes :
 [
{ field:"Authorised", description:"Authorised by:", default:function() { return Collab.user; } },
{ field:"Code", description:"Code:", default:function() { return Collab.user; } },
{ field:"Contract", description:"Contract:", default:function() { return Collab.user; } }
],
 // This maps to a Radio Group in the PDF named 'Type'
 radioGroup : "Type", 
 radioButtons :
 [
  // value maps to the 'Choice' of each radio button in the group, description will show on the dialog
  { value:"Invoice", description:"Invoice" },
  { value:"CreditNote", description:"Credit Note" },
  { value:"DirectDebit", description:"Direct Debit" },
  { value:"CreditCard", description:"Credit Card" },
 ],
 radioErrorMsg : "Please select a Type",
 // This maps to Check Boxes in the PDF
 checkBoxes :
 [
  { field:"A", description:"Pay"},
  { field:"C", description:"Do Not Pay"}
 ],

}

if (event.source.forReal)
{
 var stampDialog = CreateDialog(builder);
 app.execDialog(stampDialog); 
 
 this.getField(builder.radioGroup).value = stampDialog.radioSelection;

 for (var i = 0; i < builder.textBoxes.length; ++i)
 {
  var t = builder.textBoxes[i];
  this.getField(t.field).value = stampDialog.textBoxResults[i];
 }
 
 for (var i = 0; i < builder.checkBoxes.length; ++i)
 {
  var k = builder.checkBoxes[i];
  if (stampDialog.checkBoxResults[i])
   this.getField(k.field).checkThisBox(0,true);
 }

}

function CreateDialog(dialogBuilder)
{
 var sd = new Object();
 sd.builder = dialogBuilder;
 // declare locations for the user input to be stored
 sd.radioSelection = "";
 sd.textBoxResults = new Array();
 sd.checkBoxResults = new Array();
   
 
 // Radio Buttons
 var radElements = new Array(); 
 for (var i = 0; i < dialogBuilder.radioButtons.length; ++i) // loop through all of the radio buttons on the form
 {
  var c = dialogBuilder.radioButtons[i];
  radElements[i] = 
   {type: "radio", name: c.description, item_id: "rad" + i, group_id: "grp1"};  
 } 
 var radCluster = //create the "Type" part of the Stamp Dialog, change "Type" to rename the group of radio buttons 
 {
  type: "cluster", name: "Type", elements: radElements
 };
 
 // Text Boxes
 var txtElements = new Array(); 
 for (var i = 0; i < dialogBuilder.textBoxes.length; ++i)
 {
  var view = new Object();  
  view.type = "view";
  view.align_children = "align_row";
  view.elements = new Array();
  
  var t = dialogBuilder.textBoxes[i];
  
  var s = new Object();
  s.type = "static_text";
  s.item_id = "sta" + i;
  s.name = t.description;
  s.width = 90;
  
  var e = new Object();
  e.type = "edit_text";
  e.item_id = "edt" + i;
  e.width = 150;
  
  view.elements[0] = s;
  view.elements[1] = e;  
 
  txtElements[i] = view;
 }
 
 var txtCluster = 
 {
  type: "cluster", name: "Details", elements: txtElements
 }; 
 
 // Check Boxes 
 var ckbElements = new Array();
 for (var i = 0; i < dialogBuilder.checkBoxes.length; ++i)
 {
  var c = dialogBuilder.checkBoxes[i];
  ckbElements[i] = 
   {
    type: "check_box", name: c.description, item_id: "ckb" + i   
   };  
 }
  
 var ckbCluster = 
 {
  type: "cluster", name: "Authorisation", elements: ckbElements
 };
 
 /// the following sets initial values for the dialog box 
 sd.initialize = function(dialog) 
 {
  var init = new Object(); // set initial values for the text boxes etc
  for (var i = 0; i < this.builder.textBoxes.length; ++i)
  {
   var t = this.builder.textBoxes[i];
   var id = "edt" + i;   
   init[id] = t.default();
  }
  
  dialog.load(init);
 };
 
 //This stores the user inputted values so they can be used after the dialog window closes 
 sd.commit = function(dialog) 
 {
  var res = dialog.store();    
  for (var i = 0; i < this.builder.radioButtons.length; ++i)
  {
   var r = this.builder.radioButtons[i];
   var id = "rad" + i;
   if (res[id] == true)
   {
    this.radioSelection = r.value;
    break;
   }
  }  
  
  for (var i = 0; i < this.builder.textBoxes.length; ++i)
  {
   var t = this.builder.textBoxes[i];
   var id = "edt" + i;
   this.textBoxResults[i] = res[id];   
  }
  for (var i=0; i < this.builder.checkBoxes.length; ++i)
  {
   var c = this.builder.checkBoxes[i];
   var id = "ckb" + i;
   if (res[id] == true)
   {
    this.checkBoxResults[i] = res[id];
   }
  }
 };
 
 sd.validate = function(dialog)
 {
  var res = dialog.store();
  for (var i = 0; i < this.builder.radioButtons.length; ++i)
  {
   var c = this.builder.radioButtons[i];
   var id = "rad" + i;
   if (res[id] == true)
    return true;
  }
  
  app.alert(this.builder.radioErrorMsg);
  return false;
 };
  
 sd.description = 
 {
  name: "Stamp Dialog",
  elements:
  [
   {
    type: "view", align_children: "align_fill", elements:[radCluster, txtCluster, ckbCluster]
   },
   {
    type: "ok"
   }
  ]
 };
 
 return sd;
}
You do not have the required permissions to view the files attached to this post.
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 12441
Joined: Wed Jan 03, 2018 6:52 pm

Re: Dynamic Stamp has multiple pop-up windows

Post by Daniel - PDF-XChange »

Hello, nfs

It is possible to have a single popup window, but there is no default call to do this, you would need to "build" the whole dialogue in the JS for a single field in the file, and then have that script push the values to the other empty fields directly.
I am afraid I cannot help with writing this, but I can confirm it is definitely possible.

Kind regards,
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com