Reputation: 113
I am using a custom validation rule in CakePHP to be sure a value is entered into a field when a corresponding checkbox is marked:
Here's the validation rule within my model's validation array...
'tv_price'=>array(
'check'=>array(
'rule'=>array('check_for_tv_price'),
'message'=>'Please enter the television pricing information.',
),
)
...and here's my really simple custom validation function:
public function check_for_tv_price($check) {
if($this->data['Client']['tv']==1&&$this->data['Client']['tv_price']=="") {
return false;
}
if($this->data['Client']['tv']==1&&$this->data['Client']['tv_price']!="") {
return true;
}
if($this->data['Client']['tv']==0) {
return true;
}
}
I've tried adding 'required'=>false
and 'allowEmpty'=>true
at different points in the validation array for my tv_price
field, but they always override my custom rule! As a result, a user can not submit the form because the browser prevents it (due to the required attribute).
For reference, the browser spits out the following HTML:
<input id="ClientTvPrice" type="text" required="required" maxlength="255" minyear="2013" maxyear="2018" name="data[Client][tv_price]"></input>
(Note the minyear and maxyear attributes are from the form defaults.)
Has anyone found a way to prevent the automatic insertion of the required
attribute when using custom validation rules?
Any guidance would be much appreciated.
Thanks!
Chris
Upvotes: 5
Views: 17190
Reputation: 113
Thank you for the input!
Upon further investigation, I actually do want the required attribute turned on when the form is checked; to achieve this I wrote two simple JavaScript functions (and used a third that I found online) to check the current status of the checkboxes and mark the field as required when appropriate.
In the view file, I added the function calls in two locations. The first block is in the onload function and is called when the window is loaded:
<script type="text/javascript">
window.onload = function() {
toggle_setup(document.getElementById('ClientTv'), 'tvPrice', false)
toggle_required(document.getElementById('ClientTv'), "ClientTvPrice")
}
</script>
These are a mess, I know. But they worked!
Note the fields that appear when the checkbox is clicked are enclosed in a div with a name that is used in the toggle_setup function to show or hide the div as needed. In this case, I named the div 'tvPrice'
<?php echo $this->Form->input('Client.tv', array('label'=>'Purchasing TV? <small>(Check if Yes)</small>', 'onclick'=>'toggle_setup(this, "tvPrice", "TV pricing");toggle_required(this, "ClientTvPrice")'));
echo $this->Form->input('Client.tv_price', array('label'=>'Enter TV Price','div'=>array('class'=>'hidden', 'id'=>'tvPrice')));
?>
And here are the JavaScript functions themselves:
function toggle_required(element, id) {
var object = document.getElementById(id)
if(element.checked) {
object.setAttribute( 'required', "required")
} else {
object.removeAttribute('required')
}
}
function toggle_setup(element, div, human_term) {
if(element.checked) {
document.getElementById(div).style.display='block'
} else {
if(!human_term) {
clearChildren(document.getElementById(''+div))
document.getElementById(div).style.display='none'
} else {
if(confirm('Are you sure you want to clear the client\'s '+human_term+' settings?')) {
clearChildren(document.getElementById(div))
document.getElementById(div).style.display='none'
} else {
element.checked = true
}
}
}
}
function clearChildren(element) {
for (var i = 0; i < element.childNodes.length; i++) {
var e = element.childNodes[i];
if (e.tagName) switch (e.tagName.toLowerCase()) {
case 'input':
switch (e.type) {
case "radio":
case "checkbox": e.checked = false; break;
case "button":
case "submit":
case "image": break;
default: e.value = ''; break;
}
break;
case 'select': e.selectedIndex = 0; break;
case 'textarea': e.innerHTML = ''; e.value=""; break;
default: clearChildren(e);
}
}
}
The above code uses a CSS class called "hidden" which I've defined as below:
.hidden {
display: none;
}
Per the above suggestions, I've added the 'required'=>false
and 'allowEmpty'=>true
lines to my validation array and it appears to be working.
Thank you for all the help!
Upvotes: 0
Reputation: 4969
These seems like 2.3's new HTML5 magic stuff.
Try adding 'formnovalidate' => true
to the $this->FormHelper->input()
options in the view.
ref:
http://book.cakephp.org/2.0/en/appendices/2-3-migration-guide.html#formhelper
http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::input
Upvotes: 1
Reputation: 409
Set required to false and allowEmpty to true, that should do it for you.
'tv_price'=>array(
'check'=>array(
'rule'=>array('check_for_tv_price'),
'message'=>'Please enter the television pricing information.',
'required' => false,
'allowEmpty' => true
),
)
Hope this helps.
Upvotes: 11