CakePHP: Prevent GET form fields in URL - php

I've got a CakePHP search form that has 'type'=>'get'. Basically, one of the elements in the form is a submit button of type image. When the form is posted, in the URL I always get these x & y coordinates of the image submit button:
http://site.com/controller/action?x=22&y=36&query=hello
Is there any way I can prevent the coordinates from showing up in the URL? The reason is so that someone else could use the same URL to perform the same search, without that unintuitive stuff in the link.
Thanks!

You could use some javascript on the button:
document.getElementById('myImageButton').onclick = function() {
this.form.submit();
return false;
};
Alternatively, in your controller in the beforeFilter function, you could check for the presence of the unwanted variables, strip them out and redirect to the nice URL. This does mean there'll be 2 HTTP requests made though.

Sounds like you are looking to do a Post/Redirect/Get.
Here are two examples of doing this in CakePHP:
Searching on surname
Searching on multiple fields
Advantages of redirecting a POST to a GET request are:
Users don't get the "Do you want to resubmit?" dialog if they refresh
The resulting page/query can be bookmarked
You can utilise CakePHP's built-in SEF routing, so instead of URLs with /search?q=contact you can get /search/contact

Instead of using submit helper function, use button function and set button type to submit.
echo $this->Form->**button**($this->Html->image('header_search_icon.png'), array(**'type'=>'submit'**));

Related

Submit form to different action with typo3 flow

I have a page with a form for creating users. A user has an hobby, which can be created on the same page by clicking on the second button which opens the page for creating a hobby. After creating the hobby, the previous user form should be shown with the user input inserted before going to the hobby page.
Is there a way to do something like with typo3 flow / fluid without using AJAX?
I tried to submit the input to a different action by clicking on the createHobby button --> The action redirects to the new hobby page, where the user can create the hobby and after creation it should redirect back to the user form with the already filled out input fields by the user .
I used...
<input type='submit' value='Create' formaction='/hobby/create' />`
to achive this, but it seems there are some problems with the uris... I get following error:
#1301610453: Could not resolve a route and its corresponding URI for the given parameters.
I think the using the attribute formaction is not a good solution for every case, as it is not supported by IE < 10 as you can see here. I think a JavaScript backport should also be considered (dynamically change the action attribute of the form when clicking on the second button, before actually submitting the form).
Concerning your error, you should not – and probably never – use direct HTML input, instead try to focus on Fluid ViewHelpers, which allow TYPO3 to create the correct HTML input.
Try this instead:
<f:form.submit value="Create" additionalAttributes="{formaction: '{f:uri.action(controller: \'hobby\', action: \'create\')}'}" />
You can make an $this->forward(...) in an initializeActiondepending on an param of your action.
Lets imagine your default Form action is "create". So you need an initializeCreateAction:
public function initializeCreateAction()
{
if ($this->arguments->hasArgument('createHobby')) {
$createHobby = $this->request->getArgument('createHobby');
if ($createHobby) {
$this->forward('create', 'Hobby', NULL, $this->request->getArguments());
}
}
}
Now you must name your input createHobby and assign your createAction this param:
In fluid:
<f:form.button type="submit" name="createHobby" value="1">Create Hobby</f:form.button>
In your Controller:
public function createAction($formData, $createHobby = false)
{
...
}
can you explain something more ... what you show has nothing to do with typo3, I don't know where you inserted that, what version of typo3 , using any extension extra ?

Checkbox that submits form on click

I'm using Codeigniter and wants to know how I can make a checkbox that submits the form on click?
Secondly, this checkbox will be one of several checkboxes that will act as a filter like products > $20, products < $30, how do i pass it in the url? I'm thinking /1+2+3
Haven't worked with Codeigniter much, but I can answer how to make the form submit on checking the checkbox with JS:
<form id="something">
<input type="checkbox" name="foo" id="foo" value="yes" />
</form>
<script type="text/javascript">
$("#foo").click(function() {
if ($(this).is(":checked"))
$("#something").submit();
});
</script>
The javascript questions seem to have been solved already; let's step to the codeigniter ones.
You can pass the url in one of those two ways.
Idiomatic but limited: as /1/2/3/4/etc. The controller function handling that url could both use func_get_args to read them or, if you already know how many parameters will be passed at the most, give a default value of null to all non-necessary paramenters;
Not Codeigniterish but seriously better for search parameters: enable the query strings on your config file, pass arguments as you would normally with GET (min=2&max=3 and so on) and get their value with CI's input class ($min = $this->input->get('min')).
This has nothing to do with PHP, nor CodeIgniter. The solution is to submit the form in the onclick event of the element.
<input type="checkbox" name="filterx" onclick="document.forms[0].submit()" />
You can use the OnSubmit event of the form to nicely format the url, if you like.
To do this, you can
get the values of all desired elements,
build a nice url from it,
set the url using location.href = yourniceurl,
cancel the regular submit by returning false.
Note that both solutions require javascript to be enabled. So it is a good thing to have other means of submitting the form (submit button). Don't rely on submitting by pressing Enter. Opera will use the Enter key for toggling the checkbox instead of submitting the form.
If you like, you can hide the submit button using Javascript, that way, users having Javascript will have their form auto-submitted, while users without can use the button.
You will need to make sure that your server side form validator not only accepts the nice url, but the ugly url (which posts values like ?filterx=on) too.

Passing the value to the next page without a form

I have a page I am constructing and I need to pass in the values of the option dropdowns to the next page. The problem is that these dropdowns are not in a form.
http://posnation.com/test/pre_config/pre_config_step_2.html
Basically what i need to pass to the next page is that when i click "Proceed To Next Step" I need to pass the value of the type of field like "restaurant" and the number of stations "2" if the user selects restaurant and 2.
HTML:
<a id="proceed" href="foo.html">Proceed!</a>
JS:
$('#proceed').click(function() {
location.href = this.href +'?someVal='+ escape($('#my_select').val());
return false;
});
Working example that executes a formless google search: http://jsfiddle.net/CKcbU/
You basically just add what you want to the query string with javascript.
But really, if at all possible, you should use a form with method="get" which pretty much does this for you without any JavaScript at all.
Use a query string.
http://posnation.com/test/pre_config/pre_config_step_2.html?restaurant=The+Eatery&stations=2
In other words, pass them as part of the URL when calling the next page. The next page will be responsible for reading the query string and extracting the values out.
http://en.wikipedia.org/wiki/Query_string
I do not know what you are using to code in so I cannot be detailed regarding the mechanics of constructing the URL or parsing out the values from the query string on the receiving page.
Here is an article on doing it using JavaScript:
http://javascript.about.com/library/blqs.htm
You can use JavaScript for the same. Assign a onclick event with button of proceed and call a function. In this function use:
windows.location=url?rest=valuerest&opt=valueopt
I am not sure what you are working with, but with almost any framework that I know of you can pass a parameter as part of the url.
These would work fine.
http://posnation.com/test/pre_config/step_2
http://posnation.com/test/pre_config/step_3
Then, just grab the parameter and react accordingly.

Add and remove form fields in Cakephp

Im looking for a way to have a form in cakephp that the user can add and remove form fields before submitting, After having a look around and asking on the cake IRC the answer seems to be to use Jquery but after hours of looking around i cannot work out how to do it.
The one example i have of this in cake i found at - http://www.mail-archive.com/cake-php#googlegroups.com/msg61061.html but after my best efforts i cannot get this code to work correctly ( i think its calling controllers / models that the doesn't list in the example)
I also found a straight jquery example (http://mohdshaiful.wordpress.com/2007/05/31/form-elements-generation-using-jquery/) which does what i would like my form to do but i cannot work out how to use the cakephp form helper with it to get it working correctly and to get the naming correct. (obviously the $form helper is php so i cant generate anything with that after the browser has loaded).
I an new to cake and have never used jQuery and i am absolutely stumped with how to do this so if anyone has a cakephp example they have working or can point me in the right direction of what i need to complete this it would be very much appreciated.
Thanks in advance
I would take the straight jquery route, personally. I suppose you could have PHP generate the code for jquery to insert (that way you could use the form helper), but it adds complexity without gaining anything.
Since the form helper just generates html, take a look at the html you want generated. Suppose you want something to "add another field", that when clicked, will add another field in the html. Your html to be added will be something like:
<input type="text" name="data[User][field][0]" />
Now, to use jquery to insert it, I'd do something like binding the function add_field to the click event on the link.
$(document).ready( function() {
$("#link_id").click( 'add_field' );
var field_count = 1;
} );
function add_field()
{
var f = $("#div_addfield");
f.append( '<input type="text" name="data[User][field][' + field_count + ']" />' );
field_count++;
}
Of course, if a user leaves this page w/o submitting and returns, they lose their progress, but I think this is about the basics of what you're trying to accomplish.
This was my approach to remove elements:
In the view, I had this:
echo $form->input('extrapicture1uploaddeleted', array('value' => 0));
The logic I followed was that value 0 meant, not deleted yet, and value 1 meant deleted, following a boolean logic.
That was a regular input element but with CSS I used the 'display: none' property because I did not want users to see that in the form. Then what I did was that then users clicked the "Delete" button to remove an input element to upload a picture, there was a confirmation message, and when confirming, the value of the input element hidden with CSS would change from 0 to 1:
$("#deleteextrapicture1").click(
function() {
if (confirm('Do you want to delete this picture?')) {
$('#extrapicture1upload').hide();
// This is for an input element that contains a boolean value where 0 means not deleted, and 1 means deleted.
$('#DealExtrapicture1uploaddeleted').attr('value', '1');
}
// This is used so that the link does not attempt to take users to another URL when clicked.
return false;
}
);
In the controller, the condition $this->data['Deal']['extrapicture1uploaddeleted']!='1' means that extra picture 1 has not been deleted (deleting the upload button with JavaScript). $this->data['Deal']['extrapicture1uploaddeleted']=='1' means that the picture was deleted.
I tried to use an input hidden element and change its value with JavaScript the way I explained above, but I was getting a blackhole error from CakePHP Security. Apparently it was not allowing me to change the value of input elements with JavaScript and then submit the form. But when I used regular input elements (not hidden), I could change their values with JavaScript and submit the form without problems. My approach was to use regular input elements and hide them with CSS, since using input hidden elements was throwing the blackhole error when changing their values with JavaScript and then submitting the form.
Hopefully the way I did it could give some light as a possible approach to remove form fields in CakePHP using JavaScript.

Is there a built in way in Zend-Form to hide the value of the SUBMIT input field?

If I build a form:
$search_words = new Zend_Form_Element_Text('text');
$search_words->setRequired(true)->setDecorators(array(array('ViewHelper')));
$form->addElement($search_words);
$go = new Zend_Form_Element_Submit('gogogo');
$go->setDecorators(array(array('ViewHelper')))
->setIgnore(true);
$form->addElement($go);
With method GET.
I will see in the URL gogogo=gogogo. If I was writing the markup myself, I simply wouldn't give the submit any [name] attribute and that would have solved that. Trying to set the name of a submit to '' won't work (either throws an exception or is being ignored, depends on the way you do it).
Any (built in) ideas?
Another possibility would be to disable the submit button before the form is submitted:
$go->setDecorators(array(array('ViewHelper')))
->setIgnore(true)
->setAttrib('onclick', 'this.disabled = true');
This way, the value of the submit button will be ignored upon submitting the form.
There are a few possible options:
Use a custom decorator to build the markup, so a name attribute is not specified
Use a string replacement function on the markup returned by Zend_Form's render methods, to remove the attribute
What I often do, as follows
I usually add a custom route so that either of the following is valid:
domain.tld/search/keyword
domain.tld/search?q=keyword
Then you can use javascript to redirect to the cleaner form of the URL, taking care to urlencode the keyword field
Most of your users will see the cleaner URL this way.

Categories