This topic is locked

Dynamic READ ONLY field without javascript

1/23/2015 2:55:49 PM
PHPRunner Tips and Tricks
F
FunkDaddy author

PHPRunner currently allows us to easily make a form control "read only" by using the makeReadonly();
Ex:



var ctrl = Runner.getControl(pageid, 'Make');

ctrl.makeReadonly();


However, the control can be disabled manually via browser inspector by a user, which requires us to add server-side validation to ensure our form rules are followed. The form field is simply "disabled" instead of actually changing into a read only type field (which you can set in the visual editor in phpr). This has implications in how the field is displayed on page (ex: Google Chrome the field gets grayed out but still retains the field with box border).
Additionally, when controlling fields to be read only based on some dynamic condition, we often need to pass PHP data over to JS by way of using the built-in $pageObject page class.
A simpler approach is to handle everything exclusively via PHP and bypass the need to JS all together.
Here's how:
Step 1:

In either "Process Record Values" events (Add/Edit pages) add whatever code you need that would dynamically determine whether your given record should turn a form field into a "read only" field when displayed.

Then declare a superglobal variable using $GLOBALS with a binary value.



//Insert here whatever php code you need to determine whether given field should be displayed as read only

Global $conn;

$sql = "SELECT * FROM users_tbl WHERE UserID = ".$values['UserID']." AND GroupID = ".$values['GroupID']."";

$rs = db_query($sql,$conn);

$fetch = db_fetch_array($rs);
//Then create a conditional that would handle the result of your code

if($fetch['GroupID'] < 8){

$GLOBALS['LockDepartmentField']= 1;//this will tell our form to turn the field into read only

}else{

$GLOBALS['LockDepartmentField']= 01;//this will tell our form to keep the field default as writeable

}


Step 2:

In Before Display event (Add/Edit pages) add conditional to convert a form field into read-only by reassigning the template engine object



//Here we are going to lock down the "department" field for a user based on the $GLOBALS we declared in our other script

if($GLOBALS['LockDepartmentField'] == 1){

$xt->assign('Department_editcontrol',$values['Department']);

}


Step 3:

Done! We've locked our field down into read-only mode and bypassed the need for any JS code to lock it... and it's all done dynamically from within our php events code.

admin 1/30/2015

Marcelo,
wanted to say thank you for sharing this technique. This certainly can be useful in many scenarios.
Just need to add that this approach doesn't solve the issue you trying to solve and can be also easily bypassed. Even if your field doesn't appear on the screen nothing prevents user from sending manual POST request that includes that readonly field value. There is a number of extensions that can help you with this: http://stackoverflow.com/questions/4797534/how-do-i-manually-fire-http-post-requests-with-firefox-or-chrome
That being said, server-side validation rules are the only way to go. All other stuff you do on the client side is for convenience purpose only.

N
nti 7/15/2015

can you simplify this code to work with any field in table...

which is not based on specific user or group ?
like: Field_A and Table_A
if yes, can you demonstrate such code as reply.
Many thanks...

F
FunkDaddy author 7/15/2015

Good point Sergey. You are correct that in fact you can bypass with a direct POST to the form, and hence server side validation is still in fact needed (a big oversight on my part). I guess my main focus was not having to deal with the variations of how browsers display the read only fields when they are altered via javascript to behave as read only fields on screen.