{"id":640,"date":"2012-09-07T17:46:14","date_gmt":"2012-09-07T22:46:14","guid":{"rendered":"http:\/\/xlinesoft.com\/blog\/?p=640"},"modified":"2026-08-16T16:26:07","modified_gmt":"2026-08-16T21:26:07","slug":"how-to-create-your-own-edit-control-plugin","status":"publish","type":"post","link":"https:\/\/xlinesoft.com\/blog\/2012\/09\/07\/how-to-create-your-own-edit-control-plugin\/","title":{"rendered":"Create a Custom Edit Control Plugin in PHPRunner"},"content":{"rendered":"<p>Custom Edit controls let you replace a standard field input with a specialized control while keeping it integrated with PHPRunner Add and Edit pages.<\/p>\n<p>This article explains the underlying plugin structure using ColorPicker and SignaturePad as practical examples. It covers the PHP and JavaScript parts of a control, adding CSS and other assets, passing settings, validation and installing the finished plugin in PHPRunner.<\/p>\n<p><strong>Looking for a faster way to create a new control?<\/strong> You can also use the PHPRunner custom Edit controls skill with ChatGPT to generate the PHP, JavaScript, CSS and supporting files for a new control. See <a href=\"https:\/\/xlinesoft.com\/blog\/2026\/07\/21\/building-a-world-cup-prediction-challenge-in-phprunner\/\">Building a World Cup Prediction Challenge in PHPRunner<\/a>, especially the section about creating custom Edit controls with ChatGPT.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-649\" title=\"signature\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2012\/09\/signature.png\" alt=\"\" width=\"534\" height=\"275\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2012\/09\/signature.png 534w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2012\/09\/signature-300x154.png 300w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2012\/09\/signature-150x77.png 150w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2012\/09\/signature-400x205.png 400w\" sizes=\"(max-width: 534px) 100vw, 534px\" \/><\/p>\n<p><!--more--><\/p>\n<h2>How a custom Edit control is structured<\/h2>\n<p>A PHPRunner custom Edit control normally contains a PHP file and a JavaScript file. It may also include CSS, images and other supporting files.<\/p>\n<p>A typical plugin may look like this:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"\" name=\"mshighlighter\" >\r\nEditMyControl.php\r\nEditMyControl.js\r\nsample.php\r\nmycontrol.css\r\nimages\/<\/textarea><\/pre>\n<\/div>\n<p>The PHP part extends PHPRunner&#8217;s <strong>UserControl<\/strong> class and handles server-side setup and HTML generation.<\/p>\n<p>The JavaScript part defines the browser-side control under <strong>Runner.controls<\/strong>.<\/p>\n<p>Common plugin methods include:<\/p>\n<ul>\n<li><strong>initUserControl()<\/strong> &#8211; initializes the control and passes settings to JavaScript;<\/li>\n<li><strong>buildUserControl()<\/strong> &#8211; generates the HTML for the Edit control;<\/li>\n<li><strong>addJSFiles()<\/strong> &#8211; loads additional JavaScript files;<\/li>\n<li><strong>addCSSFiles()<\/strong> &#8211; loads stylesheets;<\/li>\n<li><strong>addJSSetting()<\/strong> &#8211; passes server-side settings to the JavaScript control.<\/li>\n<\/ul>\n<p>You can develop the plugin in any working folder and import it into PHPRunner when it is ready.<\/p>\n<h2>Installing a custom Edit control in PHPRunner<\/h2>\n<p>Once your plugin is ready, import it into PHPRunner.<\/p>\n<ol>\n<li>Open your project in PHPRunner.<\/li>\n<li>Proceed to <strong>Page Designer<\/strong>.<\/li>\n<li>Select a field and open its <strong>View As \/ Edit As<\/strong> properties.<\/li>\n<li>Click <strong>Install plugins<\/strong> in the lower-left corner of the dialog.<\/li>\n<li>Click <strong>Browse<\/strong>.<\/li>\n<li>Select either the plugin ZIP archive or the plugin PHP file from your working folder.<\/li>\n<li>Import the plugin.<\/li>\n<\/ol>\n<p>Once imported, the custom control becomes available in PHPRunner and can be selected as the field&#8217;s <strong>Edit as<\/strong> type.<\/p>\n<h2>ColorPicker control<\/h2>\n<p>Let&#8217;s create a color picker that allows users to select a color instead of entering a hexadecimal value manually.<\/p>\n<p>Create a working folder for the plugin, for example:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"\" name=\"mshighlighter\" >\r\nColorPicker<\/textarea><\/pre>\n<\/div>\n<p>Create the basic plugin files in that folder:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"\" name=\"mshighlighter\" >\r\nEditColorPicker.php\r\nEditColorPicker.js\r\nsample.php<\/textarea><\/pre>\n<\/div>\n<p>If the control requires additional JavaScript, CSS, images or other assets, place those files in the plugin folder as well.<\/p>\n<p>The ColorPicker example uses the jQuery miniColors component. Its source is available on <a href=\"https:\/\/github.com\/claviska\/jquery-miniColors\">GitHub<\/a>.<\/p>\n<h3>Add JavaScript and CSS files<\/h3>\n<p>Use the plugin PHP class to load additional JavaScript files required by the control:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->pageObject->AddJSFile(\"jquery.miniColors.min.js\");<\/textarea><\/pre>\n<\/div>\n<p>If JavaScript files need to be loaded in a particular order, you can specify a dependency:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->pageObject->AddJSFile(\"second.js\", \"first.js\");<\/textarea><\/pre>\n<\/div>\n<p>Add the stylesheet in the same way:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->pageObject->AddCSSFile(\"jquery.miniColors.css\");<\/textarea><\/pre>\n<\/div>\n<p>These calls can be placed in the plugin&#8217;s <strong>addJSFiles()<\/strong> and <strong>addCSSFiles()<\/strong> methods.<\/p>\n<h3>Build the control<\/h3>\n<p>The <strong>buildUserControl()<\/strong> method generates the HTML for the control.<\/p>\n<p>For example, the ColorPicker control can add a CSS class to its input:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"html\" name=\"mshighlighter\" >\r\nclass=\"black\"<\/textarea><\/pre>\n<\/div>\n<p>The JavaScript side initializes the color picker:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"js\" name=\"mshighlighter\" >\r\n$(\"#\"+this.valContId).miniColors({\r\n\tletterCase: 'uppercase'\r\n});<\/textarea><\/pre>\n<\/div>\n<p><strong>this.valContId<\/strong> identifies the HTML input used by the control.<\/p>\n<p>After importing the plugin into PHPRunner, select ColorPicker as the field&#8217;s <strong>Edit as<\/strong> type.<\/p>\n<h3>Display the selected color<\/h3>\n<p>On List and View pages, you may want to display the selected color visually instead of showing only its hexadecimal value.<\/p>\n<p>Set the field&#8217;s <strong>View as<\/strong> type to <strong>Custom<\/strong> and use:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$value = \"<span style='padding: 5px; background: \".$value.\"'>\".$value.\"<\/span>\";<\/textarea><\/pre>\n<\/div>\n<p>See the <a href=\"https:\/\/xlinesoft.com\/phprunner\/docs\/view_as_settings_custom.htm\">View as: Custom documentation<\/a> for more information.<\/p>\n<h2>SignaturePad<\/h2>\n<p>A SignaturePad Edit control collects signature data in the browser and saves the resulting image on the server.<\/p>\n<p>The plugin needs to:<\/p>\n<ul>\n<li>generate the signature-pad interface;<\/li>\n<li>load the required JavaScript and CSS;<\/li>\n<li>collect the signature in the browser;<\/li>\n<li>submit the signature data with the form;<\/li>\n<li>convert the submitted data to an image on the server.<\/li>\n<\/ul>\n<h3>Build the control&#8217;s HTML<\/h3>\n<p>The <strong>buildUserControl()<\/strong> method outputs the signature-pad interface:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\necho '<div class=\"sigPad\" style=\"width: '.($this->width+2).'px;\">\r\n<ul class=\"sigNav\">\r\n<li class=\"clearButton\"><a href=\"#clear\">Clear<\/a><\/li>\r\n<\/ul>\r\n<div class=\"sig sigWrapper\">\r\n<div class=\"typed\"><\/div>\r\n<canvas class=\"pad\" width=\"'.$this->width.'\" height=\"'.$this->height.'\"><\/canvas>\r\n<input id=\"'.$this->cfield.'\" type=\"hidden\" '\r\n.'name=\"'.$this->cfield.'\" class=\"output\">\r\n<\/div><\/div>';<\/textarea><\/pre>\n<\/div>\n<p>The canvas is used for drawing the signature, while the hidden field contains the value submitted with the form.<\/p>\n<h3>Convert signature data to an image<\/h3>\n<p>The signature data is submitted in JSON format. The server-side part of the plugin converts that data to a PNG image and prepares the value PHPRunner stores for the uploaded file.<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\nif ($this->webValue) {\r\n\trequire_once 'signature-to-image.php';\r\n\r\n\t$img = sigJsonToImage(\r\n\t\t$this->webValue,\r\n\t\tarray(\r\n\t\t\t'imageSize' => array($this->width, $this->height),\r\n\t\t\t'bgColour' => $this->bgcolor\r\n\t\t)\r\n\t);\r\n\r\n\t$filename = $this->folder.\"\/\".generatePassword(15).\".png\";\r\n\r\n\timagepng($img, $filename);\r\n\r\n\t$filesize = filesize($filename);\r\n\r\n\t$result[] = array(\r\n\t\t\"name\" => $filename,\r\n\t\t\"usrName\" => \"signature.png\",\r\n\t\t\"size\" => $filesize,\r\n\t\t\"type\" => \"image\/png\",\r\n\t\t\"searchStr\" => \"signature.png\".\":sStrEnd\"\r\n\t);\r\n\r\n\t$this->webValue = my_json_encode($result);\r\n}<\/textarea><\/pre>\n<\/div>\n<p>The uploaded-file information is stored as structured JSON rather than only a filename.<\/p>\n<p>A typical stored value looks like this:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"\" name=\"mshighlighter\" >\r\n[\r\n\t{\r\n\t\t\"name\": \"files\/h8hsoz5hd23b0ik.jpg\",\r\n\t\t\"usrName\": \"Chrysanthemum.jpg\",\r\n\t\t\"size\": 879394,\r\n\t\t\"type\": \"image\/jpeg\",\r\n\t\t\"searchStr\": \"Chrysanthemum.jpg:sStrEnd\"\r\n\t}\r\n]<\/textarea><\/pre>\n<\/div>\n<h2>Passing settings to a custom control<\/h2>\n<p>A reusable Edit control should accept project-specific settings instead of hardcoding every value.<\/p>\n<p>For a SignaturePad control, useful settings include:<\/p>\n<ul>\n<li>width and height;<\/li>\n<li>background color;<\/li>\n<li>the folder where images are stored;<\/li>\n<li>whether the field is required.<\/li>\n<\/ul>\n<p>The plugin can provide example initialization settings in <strong>sample.php<\/strong>:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->settings[\"height\"] = 100;\r\n$this->settings[\"width\"] = 300;\r\n$this->settings[\"bgcolor\"] = array(0xff, 0xff, 0xff);\r\n$this->settings[\"required\"] = false;\r\n$this->settings[\"folder\"] = \"files\";<\/textarea><\/pre>\n<\/div>\n<p>The PHP part can read these settings in <strong>initUserControl()<\/strong> and pass values to JavaScript with <strong>addJSSetting()<\/strong> when necessary.<\/p>\n<p>For example:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->required = false;\r\n\r\nif ($this->settings[\"required\"])\r\n\t$this->required = $this->settings[\"required\"];\r\n\r\n$this->addJSSetting(\"required\", $this->required);<\/textarea><\/pre>\n<\/div>\n<h3>Make the signature required<\/h3>\n<p>In the JavaScript control:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"js\" name=\"mshighlighter\" >\r\nif (this.required)\r\n\tthis.addValidation(\"IsRequired\");<\/textarea><\/pre>\n<\/div>\n<p>Then enable the option in the initialization settings:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->settings[\"required\"] = true;<\/textarea><\/pre>\n<\/div>\n<h3>Set the width and height<\/h3>\n<p>Set the dimensions in the initialization settings:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->settings[\"height\"] = 100;\r\n$this->settings[\"width\"] = 300;<\/textarea><\/pre>\n<\/div>\n<p>The values can then be used while building the canvas:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"html\" name=\"mshighlighter\" >\r\n<canvas class=\"pad\" width=\"'.$this->width.'\" height=\"'.$this->height.'\"><\/canvas><\/textarea><\/pre>\n<\/div>\n<h3>Choose the folder for signature images<\/h3>\n<p>Set the folder:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->settings[\"folder\"] = \"files\";<\/textarea><\/pre>\n<\/div>\n<p>Use the setting when creating the image:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$filename = $this->folder.\"\/\".generatePassword(15).\".png\";<\/textarea><\/pre>\n<\/div>\n<h3>Change the background color<\/h3>\n<p>Set the background color:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$this->settings[\"bgcolor\"] = array(0xff, 0xff, 0xff);<\/textarea><\/pre>\n<\/div>\n<p>The example above represents white in RGB.<\/p>\n<p>The JavaScript control can use the corresponding setting when initializing SignaturePad:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"js\" name=\"mshighlighter\" >\r\n$('.sigPad').signaturePad({\r\n\tdrawOnly: true,\r\n\tbgColour: this.bgColor\r\n});<\/textarea><\/pre>\n<\/div>\n<p>The same value can be used when generating the PNG on the server:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$img = sigJsonToImage(\r\n\t$this->webValue,\r\n\tarray(\r\n\t\t'imageSize' => array($this->width, $this->height),\r\n\t\t'bgColour' => $this->bgcolor\r\n\t)\r\n);<\/textarea><\/pre>\n<\/div>\n<h2>Creating custom Edit controls with ChatGPT<\/h2>\n<p>Understanding the PHP and JavaScript structure is useful when you need to customize a control, troubleshoot it or build specialized functionality.<\/p>\n<p>You can also use ChatGPT together with the PHPRunner custom Edit controls skill to generate a new plugin.<\/p>\n<p>In our <a href=\"https:\/\/xlinesoft.com\/blog\/2026\/07\/21\/building-a-world-cup-prediction-challenge-in-phprunner\/\">World Cup 2026 tutorial<\/a>, we created three custom Edit controls:<\/p>\n<ul>\n<li>ImagePicker;<\/li>\n<li>ImageDropdown;<\/li>\n<li>ImageChoice.<\/li>\n<\/ul>\n<p>These controls follow the same basic plugin structure described above, with PHP, JavaScript and optional CSS and image assets.<\/p>\n<p>The workflow is:<\/p>\n<ol>\n<li>download the PHPRunner custom Edit controls skill pack from the World Cup article;<\/li>\n<li>start a ChatGPT conversation and provide the skill;<\/li>\n<li>describe the control you want to create;<\/li>\n<li>review and test the generated PHP, JavaScript, CSS and supporting files;<\/li>\n<li>keep the completed plugin in a working folder or package it as a ZIP;<\/li>\n<li>in PHPRunner, open <strong>Page Designer<\/strong> and the field&#8217;s <strong>View As \/ Edit As<\/strong> properties;<\/li>\n<li>click <strong>Install plugins<\/strong> and import the completed plugin.<\/li>\n<\/ol>\n<p>This gives you a quick way to create specialized controls while still allowing you to modify the generated PHP and JavaScript when you need more control.<\/p>\n<p>For additional information about custom Edit controls, see the <a href=\"https:\/\/xlinesoft.com\/phprunner\/docs\/how_to_create_a_custom_edit_control.htm\">PHPRunner custom Edit control documentation<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Custom Edit controls let you replace a standard field input with a specialized control while keeping it integrated with PHPRunner Add and Edit pages. This article explains the underlying plugin structure using ColorPicker and SignaturePad as practical examples. It covers the PHP and JavaScript parts of a control, adding CSS and other assets, passing settings, validation and installing the finished plugin in PHPRunner. Looking for a faster way to create a new control? You can also use the PHPRunner custom Edit controls skill with ChatGPT&#8230;<span class=\"clearfix clearfix-post\"><\/span><a href=\"https:\/\/xlinesoft.com\/blog\/2012\/09\/07\/how-to-create-your-own-edit-control-plugin\/\" class=\"more-link\">Continue Reading <span class=\"screen-reader-text\">&#8220;Create a Custom Edit Control Plugin in PHPRunner&#8221;<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,1,4,8],"tags":[],"_links":{"self":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/640"}],"collection":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/comments?post=640"}],"version-history":[{"count":67,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/640\/revisions"}],"predecessor-version":[{"id":3449,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/640\/revisions\/3449"}],"wp:attachment":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/media?parent=640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/categories?post=640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/tags?post=640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}