How to create your own Edit control plugin

News, PHP, PHP Code Generator, Tutorials

PHPRunner 6.2 and ASPRunnerPro 7.2 add an exciting new feature – custom edit controls. You are longer limited by stock Edit controls that come with the software. And the best of all, creating new Edit controls is not complicated and we’ll show how this can be done.

We will show you how to create ColorPicker and SignaturePad plugins. Before we proceed I recommend to check the following live demo that showcases both edit controls plugins. SignaturePad control works on mobile devices as well.



ColorPicker control

Lets say we want to add a color picker control that allows users select color the same way they do in Adobe Photoshop. Since our software comes with jQuery bundled we’ll be searching web for “jQuery colorpicker”. This search returns a number of results and the one we’ll be using is miniColors. It looks nice and easy to integrate. Sources can be find at Github.

  • create a new folder under <Documents>\PHPRunnerPlugins\edit named ColorPicker
  • copy files EditMyField.js and EditMyField.php from ‘MyField’ folder to ‘ColorPicker’ folder
  • rename those files to EditColorPicker.js and EditColorPicker.php respectively
  • if you plugin needs extra files copy them to ColorPicker folder keeping folders structure
  • open EditColorPicker.js in any text editor and replace all occurences of ‘EditMyField’ with ‘EditColorPicker’. Do the same with EditColorPicker.php file.
  • use addJSFiles() function in ColorPicker.php to add refeences to external Javascript files:

PHP

$this->pageObject->AddJSFile("jquery.miniColors.min.js");

ASP

this.pageObject.AddJSFile_p1 "jquery.miniColors.min.js"
  • use addCSSFiles() function to add CSS files

PHP

$this->pageObject->AddCSSFile("jquery.miniColors.css");

ASP

this.pageObject.AddCSSFile_p1 "jquery.miniColors.css"

In EditColorPicker.php file find buildUserControl() function. This is were you build HTML code for your control. If you leave predefined code as is it will display a simple text edit box. We only going add a minor change telling colorpicker control to use black color theme:

class="black"

Lets see how we can turn this edit box into a colorpicker control. According to colorpicker instructions we need to call miniColors Javascript referencing edit box. We’ll do so adding the following code to constructor function:

$("#"+this.valContId).miniColors({
letterCase: 'uppercase'
});

letterCase option tells control to convert color values entered manually to upper case. this.valContId is the id of the control.

This is it, our control is ready. You can now launch PHPRunner, select ColorPicker as ‘Edit as’ type for any text field and enjoy your color picker on Add/Edit pages.

You may consider some additional enhancements.

1. It would be nice if instead of hex color value we can show some visual representation of selected color on List/View pages. We’ll do so choosing ‘View as’ type ‘Custom’ and putting the following code there:

PHP

$value="".$value."";

ASP

strValue="" & strValue & ""

2. By default PHPRunner set focus to the first edit control when Add or Edit page is loaded. This is not a desired behaviour for colorpciker control as we do not want to see colorpicker popup window to open every time page is loaded. To prevent this from happening we’ll implement setFocus function. Our job is to simply return false every time.

You you need to change control behaviour check all functions and events in source\include\common\runnerJS\Control.js file.

SignaturePad

The SignaturePad plugin allows to a add signature pad to your forms. SignaturePad works with both mouse and touch devices. We will be using SignaturePad jQuery plugin that comes with excellent documentation and examples.

The basic setup is the same: create new folder for SignaturePad plugin, copy and rename files, add files that plugin needs to plugin directory. This plugin is a bit more complicated and takes a few extra steps to integrate.

1. Build control’s HTML code

Here is how we do this in buildUserControl() function:

PHP

echo '';

ASP

dim str
str = "
" & _ "" & _ "
" & _ "
" & _ "" & _ "" & _ "
" ResponseWrite str

2. Convert signature data to image

Signature data is recorded in JSON format as a sequence of lines and passed to the web server this way. Now we need to convert JSON data to PNG file and save it in ‘files’ folder on the web server. Luckily all the hard work was already done and all we need to do is to add a few lines of code to  readWebValue() function:

PHP

if ($this->webValue) {
	// save signature to file			
	require_once 'signature-to-image.php';
	$img = sigJsonToImage($this->webValue, array(
				'imageSize' => array($this->width, $this->height)
				,'bgColour' => $this->bgcolor
				));
	$filename= $this->folder."/".generatePassword(15).".png";
	imagepng($img, $filename);
	$filesize = filesize($filename);

	// prepare image info to be saved in db
	$result[] = array("name" => $filename,
	"usrName" => 'signature.png', "size" => $filesize, "type" => "image/png",
	"searchStr" => 'signature.png'.":sStrEnd");
	$this->webValue = my_json_encode($result);
	}

ASP

	this_object.getPostValueAndType 
	if bValue(FieldSubmitted((CSmartStr(this_object.goodFieldName) & "_") & CSmartStr(this_object.id))) then
		doClassAssignment this_object,"webValue",prepare_for_db(this_object.field,this_object.webValue,this_object.webType,"","")
	else
		this_object.webValue = false
	end if
	
	if Left(this_object.webValue,Len("data:image/png;base64,"))="data:image/png;base64," then
		this_object.webValue = Mid(this_object.webValue, Len("data:image/png;base64,")+1)
	end if
	
	filename = generatePassword(15)
	var = Base64Decode(this_object.webValue)
	runner_save_file CSmartStr(getabspath(this_object.settings("folder"))) & "\" & filename & ".png" , var
	
	set result=CreateDictionary()
	set result1 = CreateDictionary()
	
	setArrElement result,"name",this_object.settings("folder") & "/" & filename & ".png"
	setArrElement result,"usrName","signature.png"
	setArrElement result,"size",LenB(var)
	setArrElement result,"type","image/png"
	setArrElement result,"searchStr","signature.png" & ":sStrEnd"
	set result1(0) = result
	this_object.webValue = my_json_encode(result1)
	
	if not (IsFalse(this_object.webValue)) then
		setArrElement avalues,this_object.field,this_object.webValue
	end if

You can read more info JSON to image conversion here.

Note the way how file info is stored in the database. Since new version offers multiple files upload we need to be able to store more info there than just file name. Besides the file name itself we also save file size, file type and path to the file in JSON format. Here is how typical file upload field looks in the database:

[{"name":"files\/h8hsoz5hd23b0ik.jpg","usrName":"Chrysanthemum.jpg","size":879394,"type":"image\/jpeg","searchStr":"Chrysanthemum.jpg:sStrEnd"},
{"name":"files\/2p85jz854o6fbv8.jpg","usrName":"Desert.jpg","size":845941,"type":"image\/jpeg","searchStr":"Desert.jpg:sStrEnd"},
{"name":"files\/pm4fu8uv2u6xc1w.jpg","usrName":"Hydrangeas.jpg","size":595284,"type":"image\/jpeg","searchStr":"Hydrangeas.jpg:sStrEnd"}]

3. Customization

Now it’s the time to customize our plugin. Users may need to change the appearance and behaviour of signature pad i.e.

  • change width and height of signature pad
  • change background color
  • change folder where image files are stored
  • make signature pad field required

As a first step we need to learn to pass settings from PHPRunner wizard to plugin. Proceed to “Edit as” dialog in PHRRunner and click ‘Add initialization script’ button. Here is the sample set of settings of SignaturePad control:

PHP

// signature field height
$this->settings["height"] = 100;
// signature field width
$this->settings["width"] = 300;
// signature background color
$this->settings["bgcolor"] = array(0xff, 0xff, 0xff);
// set it to true to make signature field required
$this->settings["required"]=false;
// folder to store signature files
$this->settings["folder"]="files";

ASP

' signature field height
this_object.settings("height") = 100
' signature field width
this_object.settings("width") = 300
' signature background color
this_object.settings("bgcolor") = "#FFFFFF"
' set it to true to make signature field required
this_object.settings("required")=false
' folder to store signature files
this_object.settings("folder")="files"

This code is self-descriptive, you can pass any number of settings there. If you create your own edit control plugin place sample initialization script to sample.php file that needs to be located in the plugin folder.

Now we can access those settings in plugin’s initUserControl() function. We can also pass settings to Javascript part of the plugin.

PHP

// setting default value
$this->required = false;

// saving settings to the local variable
if ($this->settings["required"])
	$this->required=$this->settings["required"];		

// passing settings to Javascript
$this->addJSSetting("required", $this->required);

ASP

this.addJSSetting_p2 "required", this.settings("required")

Now let’s actually add some new functionality

Making signature field required

In Javascript init() function add the following code:

if (this.required)
this.addValidation("IsRequired");

Signature is not required by default. To make it required add the following line of code to initialization script under ‘Edit as’ properties:

PHP

$this->settings["required"]=true;

ASP

this_object.settings("required")=true

Setting width and height of signature pad

Passing width and height from ‘Edit as’ settings in PHPRunner:

PHP

$this->settings["height"] = 100;
$this->settings["width"] = 300;

ASP

this_object.settings("height") = 100
this_object.settings("width") = 300

Then we can use $this->width and $this->height in buildUserControl() function to specify width and height of our control:

<canvas class=”pad” width=”‘.$this->width.'” height=”‘.$this->height.'”></canvas>

Changing folder where signature images stored

Passing folder name from ‘Edit as’ settings in PHPRunner:

PHP

$this->settings["folder"]="files";

ASP

this_object.settings("folder")="files"

Using this variable in readWebValue() function:

PHP

$filename= $this->folder."/".generatePassword(15).".png";

ASP

filename = generatePassword(15)
var = Base64Decode(this_object.webValue)
runner_save_file CSmartStr(getabspath(this_object.settings("folder"))) & "\" & filename & ".png" , var

Changing signature pad background color

Passing background color from ‘Edit as’ settings in PHPRunner:

PHP

$this->settings["bgcolor"] = array(0xff, 0xff, 0xff);

ASP

this_object.settings("bgcolor") = "#FFFFFF"

bgcolor array contains color value in RGB format (Red, Green, Blue, each color ranges from 0 to 255, 0xff is a hexadecimal representation of 255. array(0xff, 0xff, 0xff) means white color.

Now in Javascript control constructor function we can use this.bgColor to pass background color to SignaturePad control:

$('.sigPad').signaturePad({drawOnly:true, bgColour: this.bgColor});

We also need to pass backgound color to sigJsonToImage() function that converts JSON signature data to image. We use $this->bgcolor variable here in readWebValue() PHP function.

PHP

$img = sigJsonToImage($this->webValue, array(
		'imageSize' => array($this->width, $this->height)
		,'bgColour' => $this->bgcolor
		));

This is it. As you can creating your own edit control plugins is not a rocket science and you can build something useful in just a few lines of code.

Lets us know what kind of edit controls you want us to implement. If you have one in mind feel free to post detailed description here and provide some links to sample implementation.

Developer notes

File naming conventions

Your edit plugin might need to utilize some additional PHP, JS and CSS files. Files can be added to the main plugin folder or to subfolders like “include” or “img”. Files from the main plugin directory will be copied to the output directory. Files from “include” directory will be copied to “/include” etc. Considering the fact that your application may use multiple plugins we suggest providing unique names to helper files. For instance, if your plugin name is Slider naming CSS file slider.css is a good idea.

Inline edit considerations

To make sure edit control content is not wrapped while in inline edit mode we recommend to enclose the whole control into a <div> tag. This needs to be done in buildUserControl function in PHP or ASP code.

Access to field properties

In some situations you might need to access database field properties i.e. to find this field type. Here is PHP code that does the job:

PHP

global $strTableName;
$pSet = new ProjectSettings($strTableName);
if(IsDateFieldType($pSet->getFieldType($this->field)))
   {
      $this->webValue = "2000-01-01 ".$this->webValue;
   }

ASP

if(IsDateFieldType(this_object.pageObject.pSetEdit.getFieldType_p1(this_object.field))) then
	this_object.webValue = "2000-01-01 " & this_object.webValue
end if

Cleaning up

If your plugin creates popup you need to destroy them properly. The best option is to implement a destructor of Javascript control destroying all previously open windows. An example from BootstrapTimepicker control:

destructor: function(){
// call parent
Runner.controls.EditBootstrapTimepicker.superclass.destructor.call(this);
$("#"+this.valContId).timepicker('hideWidget');

Using z-index property

We suggest to avoid using z-index CSS property in your custom controls to minimize interference with built-in functionality like popup windows. If you absolutely must to use this property make sure the top most container of your control has z-index of 0.

6 thoughts on “How to create your own Edit control plugin

  1. I tested this out and IT WORKS SUUUUUUUUUUPPPPPPPPPERRRRRRRRRRR NICE!!!!!!!!!!!!!!
    Great Job Sergey!!

  2. Would you be able to post a tutorial on how to use rating plugin?
    I am planning to develop a an image gallery with the use of the asprunner and the image rating besides each image.
    thanks

  3. i can not Find help on adding plugins to asprunner.net
    the included Help in asprunner.net is related to classic ASP.

Leave a Reply

Your email address will not be published. Required fields are marked *