Yii2, Form and field names - php

Simple question but no solution yet. As we know
<?php $form = ActiveForm::begin(['method'=>'get']); ?>
<?= $form->field($formFilter, 'keyword')
->textInput(['placeholder' => \Yii::t('', 'keyword')]); ?>
...
will create simple form and input fields. Of course we will load $_POST data in action like
if ($this->isPost() && $formFilter->load($this->post())) {
if ($formFilter->validate()) {
...
If we will look in $_POST we will see something like FormFilter[keyword] as name of field. So question is, how can I change it? I need (i think) somehow change in in form\model not in view, because we need proper loading in action.
Where it will be used? Any GET form will show ugly url with class names, for example using simple action and models we will get FormFilter[keyword] but I want change it to keyword, so url will be more understandable than 'long field names'.
Anyone know how to deal with this?

Sorry, later I found solution, I think it will help not just me...
Simple one is to redefine formName() method in our form/model. Using formName() we can even change it what ever we need or disable at all if will set such one
public function formName()
{
return '';
}
So, if forName() returns empty string we will get url :
http://site/items?keyword=&locationID=&employmentType=&educationLevel=&salaryMin=
Default one will be:
http://site/items?FormVacanciesFilter[keyword]=&FormVacanciesFilter[locationID]=6&FormVacanciesFilter[employmentType]=&FormVacanciesFilter[educationLevel]=&FormVacanciesFilter[salaryMin]=

You can change it per field in the view, e.g. I have a form based on yii\base\DynamicModel where I need to control the field names, and, for example:
echo $form->field($model, 'test')->hiddenInput(['name' => 'test'])->label(false);
will output:
<div class="form-group field-dynamicmodel-test">
<input type="hidden" id="dynamicmodel-test" class="form-control" name="test" value="{value of $model->test}">
<p class="help-block help-block-error"></p>
</div>

Related

Retrieve POST-data from view in controller

I'm trying to do something very basic: retrieve a post value from a hidden field. The hidden field is obviously in my view file and I want to retrieve the value in my controller. I'm using the framework SimpleMVCFramework.
I have a hidden field in my projects.php file (the list with projects). When you click on a project, a method in the controller renders the clicked project and the corresponding page. This corresponding page is called project.php
The hidden field in my projects.php view:
<form method="post" action="project.php">
<input type="hidden" name="project-id" value="<?php echo $project['id'];?>">
</form>
This hidden form is displayed correctly in my lists with projects. I checked them in the console.
In my ProjectController.php, I try to retrieve the data using
$data['id'] = $_POST['project-id'];
Then, I send the $data variable with the rendered page, so that I can use the id. So every project in projects.php has a hidden file that outputs correctly. When I try and click on a project, it brings me to project.php, but when I check out the $data variable, the id is just empty.
The routing works like a charm, because e.g. $data['title'] = "Project"; works great and is visible when I check the $data variable. When I change
$data['id'] = $_POST['project-id'];
to
$data['id'] = "foobar";
the id in project.php isn't empty anymore, but shows foobar. So I guess that something goes wrong with retrieving the value.
I also tried to remove the action=".." from the form, but that also didn't work.
The thing I'm trying to achieve is so simple, that I don't understand what is going wrong. Is it possible that the problem lies with the framework and that the code is right?
Thanks in advance and sorry for my bad English.

Joomla 2.5 xml fields - store values after form submit

I have a typical XML file with many field like example
<field
type="custom"
name="city"
id="city"
label="City"
size="40"/>
In the view I display this field - everything is fine.
Moreover I'm using state filtering on this field.
model populateState():
$filter = $app->input->get('city');
$this->setState('filter.city', $filter);
The problem is that, field doesn't has a value after form submit (form has get method). I can't write in field value something like $this->getState('city') because it's xml file. Maybe anyone has a solution... I was thinking about JS, but mainly I want to have a PHP solution.
Problem solved!
Here is solution:
1. Have all fields name in jform array. It makes automatically if you use form in xml.
2. When you're loading form data, send second parameter as true: $model->getForm('formName', true) because second parameter is $loadData. By this option, Joomla will load form data.
3. You have load data from loadFormData function:
protected function loadFormData() {
$data = JFactory::getApplication()->getUserStateFromRequest('jform', 'jform');
if (empty($data)) {
$data = $this->getItem();
}
return $data;
}
That's all.
I'm not 100% clear on what you're asking, but if you're using a standard JForm and inserting it with something like this:
echo $this->form->getInput('articletext');
The it's likely the your field's name in the form isn't city, it's more likely to be something like:
`jform[articletext]`
If you can add more of the XML file, so we can see grouping etc and the php used to display the form we can probably help pin it down exactly, it will also help if you tell us which version of Joomla you're using.

Lost data when moving page to page

I have a form to post with for example "title" data, once the submit button is pressed, the model will be used to process the data. the controller then uses the processed data to display in a view to the user. That is the flow I follow.
After getting the view, the user will choose to edit something. he thus needs to get back to the edittable form (same as the original one) to fix the title data. Here is the form
<?php form_open("blog/edit_updated")?>
Title:<input type="text" col="30" value="<?=$edit[0]['title']?>" name="edit_title"/><br/>
Comment:<br/><textarea name="edit_comment" width="20" col="5"><?=$edit[0]['comment']?></textarea><br/>
<input type="hidden" name="postcomment" value="TRUE"/>
<input type="submit" value="Update"/>
<?=form_close()?>
That form will call the following controler function
public function edit_updated()
{
if(!file_exists('application/views/blog/edit_succeed.php'))
{
show_404();
}
else
{
print_r($this->url_title);
if($this->blog->update_row_with_title(XXXXX,$_POST['edit_title'],$_POST['edit_comment']))
$this->load->view('blog/edit_succeed');
}
}
the function update_row_with_title is only used to seach and update the specified item with exact match of the given title. I test and it always return one (UPDATE command is used). XXXX is the title of the NOT_YET_TO_FIX title used to search in the database, the rest of parameters are those newly entered fields that will be used for SET in UPDATE command. However, XXXXX is always empty. Could you tell me a way to retrieve the original title ?
Summary
Form 1 (with data)--> post --> use data as part of url for GET --> fix the form (with new data) --> UPDATE [right here I lost the original data that is used as an identity for db searching]
It's a bit ambiguous your description, I'm not sure I understand what you want, but I'll try to offer a solution.
If you need the old title in the controller method you can actually send that as a parameter to it in the URL. To do this you have to make the following changes:
in the view containing the form change the argument of form_open to something like
<?php form_open("blog/edit_updated/" . $edit[0]['title'])?>
add an argument to the edit_updated() controller method like this
public function edit_updated($old_title = null) {
...
...
}
and now in the controller method you can replace that XXXXXX variable with $old_title.
Was this helpful ?

Why doesn't set_value() work with foo[bar][x][lorem] array inputs?

So let's say i have a form where the user can add as many dogs as they want by pressing a + button.
The form is like:
Dog #1 <br/>
<input name="house[dogs][][name]" value="<?=set_value('house[dogs][0][name'])?>"/>
<input name="house[dogs][][age]" value="<?=set_value('house[dogs][0][age]')?>" />
Dog #2 <br/>
<input name="house[dogs][][name]" value="<?=set_value('house[dogs][1][name'])?>"/>
<input name="house[dogs][][age]" value="<?=set_value('house[dogs][1][age]')?>" />
On CodeIgniter, I run a form validation in order for set_value() to work as well:
$house = $this->input->post('house');
$dogs = $house['dogs'];
$i = 0;
foreach($dogs AS $dog){
$this->form_validation->set_rules("house[dogs][$i][name]", 'Dog Name', 'required');
$this->form_validation->set_rules("house[dogs][$i][age]" , 'Dog Age' , 'required');
$i++;
}
This whole thing doesn't work, How to make set_value() support array inputs like that?
Thanks in advance.
You might have to make the input name the exact same as the first parameter of set_value().
One might not be able to be [], while the other can use [0].
Very related: http://codeigniter.com/forums/viewthread/179581/ Ironically, a post I made months ago that was bumped this morning.
Also related: CodeIgniter: Validate form with multidimensional POST data
<ignore>
To make a long story short, Codeigniter does not handle indexed field names very well by default.
To simply repopulate the input and work around set_value()'s shortcomings, you can try something like this:
<?php
$value = isset($_POST['house']['dogs'][1]['age']) ? // was the value posted?
form_prep($_POST['house']['dogs'][1]['age']) : // if so, clean it
''; // if not, leave empty
?>
<input name="house[dogs][1][age]" value="<?php echo $value; ?>" />
Since you're probably using a loop to output these, I don't think it will be too much of a bother. You could populate a separate array of values and read those instead if you wish, you get the idea. set_value() automatically runs form_prep(), so that's why I added it.
I'm not too sure about the validation. You may have to do the validation yourself, which while bothersome, shouldn't be too difficult. Remember you can always run the validation methods manually. Example:
if ($this->form_validation->valid_email($this->input->post('email')) {}
You may want to just take the easy way out and change your field names to use a single index, like dog_age[], which I believe will make the validation easier for CI to handle. Best of luck, hoping for a fix one of these days in CI core.
</ignore>
EDIT: I have no idea how this escaped me, but apparently validation and set_value should in fact work as expected - not sure if this was a recent change or if the issue never really existed. I definitely remember having issues with it before, and the linked posts suggests others are too. Check out this answer though:
CodeIgniter: Validate form with multidimensional POST data
I tested it (running 2.0.2) and it does in fact work. I don't see anything in the change log, but I did test it and it did work. Make sure your on the latest version and try again perhaps, or let us know if I'm missing something here.
Like your other answer says, you probably just have to explicitly index the field names like name="house[dogs][1][name]" instead of name="house[dogs][][name]".

how to create search form with into codeigniter uri format?

dear all, i'm a noob in codeigniter,
i would like to ask for advise, on how to create a search form that would result to url as:
http://domain/class/index/searchvar1/searcvar1val/searchvar2/searchvar2val
the form would be like
<form action="http://domain/class/index">
<input name="searchvar1" value="searchvar1val">
<input name="searchvar2" value="searchvar2val">
<input type="submit">
</form>
what is the best practice for this?
i've googled around including stackoverflow posts, still can't find any solution.
thanks :)
~thisismyfirstposthere
update ::
i would like to emphasize that my objective is to process search variables from the uri string (above), not from post vars; so i think setting the form search to POST is not an option? :)
update (2)
i don't think this can be done out of the box in codeigniter, i'm thinking of client-processing the form vars/vals into the form action in URI format using jQuery.
will post an update here later when done.
taking a look at the user_guide :
$this->uri->assoc_to_uri()
Takes an associative array as input
and generates a URI string from it.
The array keys will be included in the
string. Example:
$array = array('product' => 'shoes', 'size' => 'large', 'color' => 'red');
$str = $this->uri->assoc_to_uri($array);
// Produces: product/shoes/size/large/color/red
and i think if your form is this:
<form action="http://domain/class/index/search">
<input name="product" value="shoes">
<input name="size" value="large">
<input name="color" value="red">
<input type="submit">
</form>
then somewhere in the search controller do this $this->uri->assoc_to_uri($data); IMHO will produce product/shoes/size/large/color/red
hey guys, thanks for replying and discussing, I think imma go with flow:
View --> form --> jquery, on form submit: replace action attribute with form params --> controller with uri string --> rest of the process
the jquery part would be something like this
$("#searchFormID").submit(function(){
// $(this).serialize() outputs param1=value1&param2=value2 string
// var.replace(regex, string) outputs param1/value1/param2/value2 string
// newact would be http://localhost/class/index/param1/value1/param2/value2
var newact = $(this).attr("action") + "/" + $(this).serialize().replace(/&|=/g,"/");
$(this).attr("action", newact); // or $(this).attr("target", newact);
return true;
});
notes:
add an id attribute to the form -> for the form selector in jquery
use post method in the form (this is default in codeigniter) -> so action url will not be populated with the GET string
You may want to enable query strings and use $_GET. IMO, this is a perfect example what the query string is intended for.
Make sure to change your form to <form method="get" action="http://domain/class/index">
You will then have a query string in your URL like ?searchvar1=value1&searchvar2=value2
You can access parts of the string like this: $this->input->get('searchvar1')
With the method you are currently using, if a user searches for any characters that are not allowed in your $config['permitted_uri_chars'], you will have to do a lot of encoding and decoding yourself to make sure the string is safe/readable in your URL. The CI Input class takes care of this for you, so it is my recommendation.
Another disadvantage to URI segment based search params is that there is no proper way to express an array like ?values[]=one&values[]=two&values[]=three. There are hacks to work around this, but they are all exactly that: hacks. you will eventually run into trouble.
Using $_POST is very tedious and forces the use of form submits for paginated results and links, and also ensures that you cannot link to the search results or use the back button properly.
If you must use this method, simply have the form post to your controller, read the input, and then redirect() to the url that you construct from it. littlechad has the right idea for this method in his answer
// This URL:
http://domain/class/index/searchvar1/searcvar1val/searchvar2/searchvar2val
// With this:
$search = $this->uri->uri_to_assoc();
// Produces this:
array(
'searchvar1' => 'searchvarval1',
'searchvar2' => 'searchvarval2',
);
// And you can use it like this:
$arg1 = $search['searchvar1'];
$arg2 = $search['searchvar2'];
To get TO this url, you can do something like this with your form post (in the controller after post):
$var1 = $this->input->post('searchvar1');
$var2 = $this->input->post('searchvar2');
redirect('searchvar1/'.urlencode($var1).'/searchvar2/'.urlencode($var2));
I'm sure you can see how much more work this is than just using the tried-and-true query string...

Categories