How to create manual inputs in CakePHP 2 using SecurityComponent? - php

I want to create a form in CakePHP whilst having the SecurityComponent active. So far so good, now I want to add custom input elements which I can't generate using the FormHelper. I do however to have these fields included in the security and validation checks.
The main problem is that I can't render radio buttons outside of their labels. So I render them myself like so:
<div class="radio radio-inline">
<input id="genderMALE" type="radio" name="data[User][gender]" value="MALE"/>
<label for="genderMALE">Male</label>
</div>
<div class="radio radio-inline">
<input id="genderFEMALE" type="radio" name="data[User][gender]" value="FEMALE"/>
<label for="genderFEMALE">Female</label>
</div>
Which in itself works perfectly. Yet the FormHelper has no notice of them so the SecurityComponent registers this as tampering with the form. Blackholing my request.
I tried to generate the inputs using the FormHelper but radio support is limited. The format option does not work here since:
Radio buttons cannot have the order of input and label elements controlled with these settings.
-- Cookbook
Next to that I couldn't find any way to render a plain detached radio button. And the only way I found to have the input accepted was through ignoring it in the SecurityComponent.
What is the Cake way to fix this?
Update 14-09 09:16
My current fix/hack would be to create the custom radio buttons in plain HTML as shown above. Then link the value of those radio inputs to an input field created using the FormHelper. Using CSS I can hide this input allowing it to be changed by JavaScript, as opposed to using type="hidden".
Are there any dangers/problems that could occur using this method?
side note: In the end this is a styling issue. Yet I'm forced to use Bootstrap and have only 2 days left to finish my task. And I don't feel like going down the path of writing custom CSS/JS to get this working.

At the point of getting content with the hack solution, I stumbled upon the FormHelper::$fields field. This field keeps track of all inputs created using the FormHelper and is later used by the SecurityComponent to check whether the form has been tampered with.
The solution does require some additional work as you need to implement the following steps:
Add custom form element the the fields array
Restore value from previous submit (if redirect back to form)
Add default option so field won't be omitted from post data
Working CTP
<div class="radio radio-inline">
<input id="genderMALE" type="radio" name="data[User][gender]" value="MALE"
<?= $this->request->data('User.gender') == 'MALE' ? 'checked' : ''?> />
<label for="genderMALE">Male</label>
</div>
<div class="radio radio-inline">
<input id="genderFEMALE" type="radio" name="data[User][gender]" value="FEMALE"
<?= $this->request->data('User.gender') == 'FEMALE' ? 'checked' : ''?> />
<label for="genderFEMALE">Female</label>
</div>
<input type="radio" name="data[User][gender]" value="" class="hidden"
<?= $this->request->data('User.gender') ? '' : 'checked'?> />
<?php $this->Form->fields[] = 'User.gender' ?>
It is far from pretty, yet I recon it is close to the internals of Cake itself. Might want to create a helper instead of manually implementing the inputs every time.

Related

Set default radio button to check in laravel vuejs

I'm having a trouble on how can I check the radio button when the v-models is empty, . If the value of my formfields.status is empty the radio button should automatically checked. Is there anyway trick how to implement it?
This is status value looks like in my dev tools extension when status value is empty
This is what I've tried but nothing works, thanks in advance!.
<div class="checkbox-inline">
<label class="radio mr-2">
<input class="details-input" type="radio" name="status_radio" value="1" v-model="formFields.status" :checked="formFields.status == null"/> Active
</label>
<label class="radio">
<input class="details-input" type="radio" name="status_radio" value="0" v-model="formFields.status"/> Inactive
</label>
</div>
V-model is working with the checked property of radio buttons, so setting that on your own as well might result in faulty behaviour.
When you're using V-model, you'd expect the UI to be always in sync with the data. Note that the "empty selection" state is invalid for radio buttons, there should be one always selected. If you wanted to allow empty selection using an optional select field would be better from UX perspective as well.
So, the easiest way to fix it is disallowing the empty state for your model by providing a default value to the status field, which would control which radio button should be checked by default.
In short:
use "status: 1" in your data to set the default value
remove the :checked bindings from the template

What are the advantages of using multidimensional arrays in a HTML form?

Regarding the code below: What is the advantage of using the data[Category][county][Macon] array instead of just making the name 'county' or county[], and the value 'Macon', and how would they process the form data on the server side with each checkbox sharing the same value of 1? Also, why does each checkbox have a hidden input with the same name but with a value of 0?
Any assistance with helping this make sense would be appreciated.
<li>
<div class="input checkbox">
<input type="hidden" name="data[Category][county][Macon]" id="CategoryCountyMacon_" value="0" />
<input type="checkbox" name="data[Category][county][Macon]" value="1" id="CategoryCountyMacon" />
<label for="CategoryCountyMacon">Macon</label>
</div>
</li>
<li>
<div class="input checkbox">
<input type="hidden" name="data[Category][county][Madison]" id="CategoryCountyMadison_" value="0" />
<input type="checkbox" name="data[Category][county][Madison]" value="1" id="CategoryCountyMadison" />
<label for="CategoryCountyMadison">Madison</label>
</div>
</li>
Actually it is quite common in some frameworks. Imagine that Category is the table or a model, county is the column and Madison is the data for the column, or a related data in another lookup table. Looks a little like CakePHP.
Let's say you have a form where a user can update something that has multiple related tables. How do you intelligently and repeatably define what data is bound for what table etc... The framework has logic in the receiving code that looks for the first level keys as the table/model and then the columns and values.
Also, checkboxes are only submitted if they are checked, so if not they won't be in the $_POST array. Defining a hidden input with the same name and value of 0 before the checkbox insures that there will be a value, either 0 if not checked or 1 if checked. It's a way of taking submitted values and using them as opposed to checking if something is present and then doing one thing or the other.
I think you may have over complicated this a bit.
I assume you are showing the user a set of counties and they tick the ones they are interested in.
Now first thing to remember is that a checkbox is only sent back to the script if it is checked, if its not you never see it back in your script. Also what is sent back to the script is the value="something"
So if you are just interested in which counties were selected this is much easier to understand and process back in your script. Also I am not sure what function the hidden fields was serving, I am guessing none.
<li>
<div class="input checkbox">
<input type="checkbox" name="counties[]" value="Macon" id="CategoryCountyMacon" />
<label for="CategoryCountyMacon">Macon</label>
</div>
</li>
<li>
<div class="input checkbox">
<input type="checkbox" name="counties[]" value="Madison" id="CategoryCountyMadison" />
<label for="CategoryCountyMadison">Madison</label>
</div>
</li>
So now if Macon and Madison are checked you will get an array called counties returned in the $_POST array like this.
counties[0] = 'Macon'
counties[1] = 'Madison'
So you can process it easily with a
foreach( $_POST['counties'] as $county ) {
// $county will = 'Macon' on first iteration
// $county will = 'Madison' on second iteration
}
Of course it may be better still to put the unique key of the counties row from the database into the value attribute i.e. value="99 rather than the name value="Macon". That depends upon what you want to do with it later and how you have designed your database.

Auto checked radio buttons and php form processing - How to avoid blank field?

SOLVED: Just need to add autocomplete="off" to the radio buttons.
EDIT: I was incorrect in my original assessment of what's causing the error. It is not dependent on whether or not the user makes a selection. It's when I use Chrome's autofill feature for the rest of the form. If I use the autofill then no value gets passed through :-/
EDIT2: Looks like it's a known bug. Chrome autofill unfills radio buttons http://productforums.google.com/forum/#!topic/chrome/WNBd8p6q7YQ
I have a form where the recommended postage options are pre-selected using "checked":
<fieldset class="outwardpostage">
<legend>Outward postage</legend>
<label for="outwardpostageeconomy">Economy<br><span class="greenprice">£3.95</span></label>
<input type="radio" name="outwardpostage" value="3.95" id="outwardpostageeconomy" checked>
<label for="outwardpostagestandard">Standard<br><span class="greenprice">£7.95</span></label>
<input name="outwardpostage" type="radio" id="outwardpostagestandard" value="7.95">
<label for="outwardpostagepremium">Premium<br><span class="greenprice">£11.95</span></label>
<input type="radio" name="outwardpostage" value="11.95" id="outwardpostagepremium">
<label for="outwardpostagepostyourself">I will post myself using my own preferred delivery service</label>
<input type="radio" name="outwardpostage" value="0" id="outwardpostagepostyourself">
</fieldset>
The problem is the value doesn't get passed through the php form processor unless the user has clicked on the radio button. If they have just left the recommended option then the field is left as blank.
How can I fix this?
$outwardpostage = $_POST['outwardpostage'];
Can't you do something like:
if( !isset($_POST['outwardpostage']) ) {
$_POST['outwardpostage'] = 3.99;
}
To get round it not picking up the default?

How to display results from either searchbox OR from Checkbox

We have a searchbox shown below where users can enter a value, say 1234 ABC street, click Search and the results get displayed.
<!--form1 -->
<div id="inputBG">
<form id="searchForm" class="search_field" method="get" action="">
<input name="searchBox" id="searchBox" value="3440 Mark Drive" />
<button type="button" onclick="searchMap()"><img src="Viewer/images/search.png" alt="Search" /></button>
</form>
</div>
This works great.
If, however, users wish to display more than one type of results, the user clicks on an icon called Advanced Search. When this happens, a form with only checkbox shown below opens up in a new window.
<!--Form2 --->
<div id="featuresDiv">
<form id="featuresForm">
<br/>
<input type="checkbox" name="srcoptions" onClick="checkAll(this.form,this)" checked>Check/Uncheck All<br>
<label><input type="checkbox" name="featType" checked value="Addresses">Addresses</label><br/>
<label><input type="checkbox" name="featType" checked value="Voter Precincts">Voter Precincts</label><br/>
<label><input type="checkbox" name="featType" checked value="Voter Precincts (Pending)">Voter Precincts (Pending)</label><br/>
<label><input type="checkbox" name="featType" checked value="Voting Polls">Voting Polls</label><br/>
<label><input type="checkbox" name="featType" checked value="Voting Polls (Pending)">Voting Polls (Pending)</label><br/>
<label><input type="checkbox" name="featType" checked value="Zip Codes">Zip Codes</label><br/>
<label><input type="checkbox" name="featType" checked value="Zoning Petitions">Zoning Petitions</label><br/>
<button type="button" onclick="searchMap()"><img src="MapViewer/images/magnifying_glass.png" alt="Search" /></button>
</form>
</div>
Users have the option of checking all boxes or just a couple of boxes.
When the user clicks on Search, the results of those checked boxes are supposed to be displayed.
In situations where checkbox option is used, and more than one boxes are checked, the searchbox becomes irrelevant in the search.
I have tried several things and nothing seems to work so far.
When I use the checkboxes option and check more than one options, I get custom message that "Your search returned no results"
Here is the Javascript we have attempted which is supposed to show when the search is from searchbox (form1) or checkbox (form2).
Then we have php that is supposed to grab all search values (searchbox or checkbox) in to comma-separated values.
This has been driving us nuts for over 3 days now.
It is noteworthy to point out that the searchbox has a default value of 3440 Mark Street.
I am really stumped.
Any help is greatly appreciated.
// Construct query
**$features = $_GET["featType"];**
$tsql = "SELECT * FROM globes AS TBL
WHERE KEY_TBL.RANK > 0
ORDER BY ListOrder, Name, TBL.RANK DESC";
Some more information about what happens in doGlobalSearch and how the data is processed in PHP would be helpful. Offhand I'd guess there's some discrepancy in how the data sent to PHP is formatted and how it is expected to be formatted. Taking a total stab in the dark, have you tried just doing featureList = features.join()? Are you sure the individual values need to be quoted?
Just a suggestion, but here's how I would do it:
Combine the two forms into one.
Default all checkboxes to unchecked (or disable them) while the advanced search div is hidden.
Check (or enable) them when the advanced search div is shown.
Add [] to the end of each checkbox name so that the (checked) values are passed to PHP as an array when the form is submitted.
This way PHP would directly receive the searchData and featTypes (if any) together and you wouldn't have to parse the featTypes back out from a string in PHP. Then all you would need to do with javascript is submit the form and process the response. Again, this is without knowing what's going on in the backend or what control you have over it.

PHP - Get checkbox value Twitter Bootstrap

I'm building an app using Laravel and Twitter Bootstrap. And now i've come to a point i where want to use checkboxes. Bootstrap styles the checkboxes automatically which is nice.
But in PHP i can't get the value of the checkbox to determine whether it's checked. Bootstrap seems to use "uniform" to style the checkbox. When i exclude that file i CAN get the value of the checkbox.
I do this to get the value:
$checkbox = Input::get('checkbox', function() {return 0;});
If the input has a value, use the value, else return 0.
It works fine, except when Bootstrap styles the checkbox. With jQuery it's possible to check if the span of the checkbox has the class "checked" but I want to check server-side. But Bootstrap/Uniform doesn't apply "checked" to the checkbox itself.
Are there more people that have the same problem? Or even better, does someone have the solution for this? Thanks!
On form submittal you can always check for the validation of the checkbox:
PHP Code:
<?php if(isset($_POST['$yourName'])){}; ?>
HTML Code:
<div class="form-group input-group-sm">
<label class="col-md-4 control-label" for="$yourName">Your Title</label>
<div class="col-md-1 input-group-sm">
<input id="$yourName" name="$yourName" type="checkbox" class="form-control">
</div>
</div>

Categories