CakePHP 2.x HABTM saveAll with Add view associated model optgroups - cakephp

I have a CakePHP Add Photo View that is using optgroups so that the HABTM related Tag model's data is shown in grouped fashion in the view. In the Photo controller I send the related Tag model data as follows to get the optgroups grouping of Tags by Tag Category:
//fields shown to create optgroups eg group tags by category
$this->set('tags', $this->Photo->Tag->find('list', array(
'fields' => array('Tag.id', 'Tag.tagname', 'Tag.category'),
'conditions' => array(
'Tag.account_id' => $this->Session->read('Auth.User.account_id')))));
}
The view shows the Tags nicely grouped by Category. So that part works perfectly.
However, after adding a new Photo and selecting one or more Tags to assign to it, it does save the Photo properly but not the assigned Tags.
I believe that CakePHP saveAll is expecting a data array as would be delivered without the optgroup Category > Tag hierarcy, and is therefore not saving Tag data when new Photo is added and Tags are assigned to the Photo.
What do I need to do to give it the proper array to save the related Tags? Will it be in the controller after Create() where I 'remove' the Category grouping?
A bit of background on this from CakePHP http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html
"If you would like to generate a select with optgroups, just pass data in hierarchical format. This works on multiple checkboxes and radio buttons too, but instead of optgroups wraps elements in fieldsets:"
$options = array(
'Group 1' => array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
),
'Group 2' => array(
'Value 3' => 'Label 3'
)
);
echo $this->Form->select('field', $options);
Output:
<select name="data[User][field]" id="UserField">
<optgroup label="Group 1">
<option value="Value 1">Label 1</option>
<option value="Value 2">Label 2</option>
</optgroup>
<optgroup label="Group 2">
<option value="Value 3">Label 3</option>
</optgroup>
</select>

Ok so this problem had nothing to do with the array structure.
It turns out I had 'Photo.Tag' instead of just 'Tag' in the Add Photo View. Here is the old Add Photo View code that didn't work:
<div class="photos form">
<p><?php echo $this->element('admin_nav'); ?></p>
<?php echo $this->Form->create('Photo'); ?>
<fieldset>
<legend><?php echo __('Add Photo'); ?></legend>
<?php
echo $this->Form->input('account_id', array('type'=>'hidden'));
//echo $this->Form->input('filename', array('type'=>'hidden'));
echo $this->Form->input('filename', array('type' => 'file', 'label' => 'Upload photo'));
echo $this->Form->input('desc');
echo $this->Form->input('Photo.Tag' , array('label'=>'Tags', 'multiple'=>'checkbox'));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
Here is the new Add Photo View code which now saves the new photo with the tags selected:
<div class="photos form">
<p><?php echo $this->element('admin_nav'); ?></p>
<?php echo $this->Form->create('Photo'); ?>
<fieldset>
<legend><?php echo __('Add Photo'); ?></legend>
<?php
echo $this->Form->input('account_id', array('type'=>'hidden'));
//echo $this->Form->input('filename', array('type'=>'hidden'));
echo $this->Form->input('filename', array('type' => 'file', 'label' => 'Upload photo'));
echo $this->Form->input('desc');
echo $this->Form->input('Tag' , array('label'=>'Tags', 'multiple'=>'checkbox'));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
</div>
While the Cakephp documentation on Saving Data makes references to how the array should be formatted, this appears to refer to all of the other relationships excluding HABTM. HABTM relationships can be saved in one action with the save on the parent model, in this case the Photo model eg:
$this->Photo->save($this->request->data)
will save the new Photo being added, plus any of the selected Tags, and they will be saved in the join table photostags.
What is a bit unusual, is that $this->Photo->save($this->request->data) appears to work same as $this->Photo->saveAll($this->request->data).

Related

CakePHP 2 output checkbox array inside loop

I've read CakePHP multiple checkbox array HTML the right way but getting strange results. I have a list of tags (from a Model called Tag). I want to loop through these and output checkboxes for them in a View.
So I have obtained the Tag data in my Controller with:
$tags = $this->Tag->find('list', ['order' => ['name' => 'ASC']]);
$this->set('tags',$tags);
When I loop through it in my View I am trying to output the checkboxes in between Bootstrap markup:
<?php echo $this->Form->create('GroupTag'); ?>
<?php foreach ($tags as $tag_id => $tag): ?>
<div class="checkbox">
<label>
<?php echo $this->Form->checkbox('tag_id[]', array( 'value'=> $tag_id)); ?>
<?php echo $tag; ?>
</label>
</div>
<?php endforeach; ?>
I copied the syntax for tag_id[] from the post I linked to.
But when I inspect the markup it's producing the following as the name attribute for each <input type="checkbox">:
data[GroupTag][tag_id[]]
Should this not be
data[GroupTag][tag_id][]
?
The idea is that I have multiple checkboxes with a name attribute tag_id[] and then in the Controller I can loop through what has been checked.
Please can someone advise on this as I can't get it working and have looked into examples provided on here/docs.
Try this
$this->Form->checkbox('tag_id.', array( 'value'=> $tag_id))
You can also do this:
$this->Form->input('GroupTag.tag_id', [
'type' => 'select',
'multiple' => 'checkbox',
'options' => $tag_id
]);
FormHelper::select(string $fieldName, array $options, array $attributes)
Example:
$options = array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
);
echo $this->Form->select('Model.field', $options, array(
'multiple' => 'checkbox'
));
Output:
<div class="input select">
<label for="ModelField">Field</label>
<input name="data[Model][field]" value="" id="ModelField"
type="hidden">
<div class="checkbox">
<input name="data[Model][field][]" value="Value 1"
id="ModelField1" type="checkbox">
<label for="ModelField1">Label 1</label>
</div>
<div class="checkbox">
<input name="data[Model][field][]" value="Value 2"
id="ModelField2" type="checkbox">
<label for="ModelField2">Label 2</label>
</div>
</div>

User doesn't have user id after login

I can log in a user using Auth->login($this->data). Debugging the Auth->user() after login all I see is the username and password. Is the Id supposed to be auto populated or do I need a way to manually set it? By going off a few tutorials it seem like the ID should already be there.
What is debugged:
\app\Controller\UsersController.php (line 90)
array(
'User' => array(
'password' => '*****',
'username' => 'LittleRy'
)
)
As ndm comment, I changed the call to Auth->login() so it should be grabbing the request info. With this change login() is always returning false. Below is the login form. I believe everything is being passed in correctly.
<div class="users form">
<?php echo $this->Session->Flash('auth');
?>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend>
<?php echo __('Please enter your username and password'); ?>
</legend>
<?php echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>
try this $this->Auth->user('id'); to get user id.

Form submit button losing value attribute in CakePHP

We have baked a crud with validations. All seems ok.
However, when we hit the submit button,
<?php echo $this->Form->submit('go for it'); ?>
and if we get validation errors, the HTML submit button loses is value attribute.
Before hitting submit we get this output:
<input type="submit" value="go for it"/>
After hitting submit we get this output:
<input type="submit" value></input>
Here's the full ctp code:
<?php echo $this->Form->create('ScheduleAccess'); ?>
<?php echo $this->Form->input('id'); ?>
<fieldset class="short">
<legend>Bla bla</legend>
<?php echo $this->Form->input('schedule_es', array('label' => 'Bla bla (es)')); ?>
<?php echo $this->Form->input('schedule_en', array('label' => 'Ble ble (en)')); ?>
</fieldset>
<fieldset class="short">
<legend>Last Bla bla</legend>
<?php echo $this->Form->input('last_entry', array(
'dateFormat' => 'YMD',
'timeFormat' => '24',
'label'=>'until:'
)); ?>
</fieldset>
<fieldset class="full">
<legend>terms</legend>
<div class="medium wysihtml5">
<?php echo $this->Form->input('free_entry_day_time_es', array('label' => 'Things (es)')); ?>
<?php echo $this->Form->input('free_entries_and_discounts_es', array('label' => 'More things (es)')); ?>
</div>
<div class="medium wysihtml5">
<?php echo $this->Form->input('free_entry_day_time_en', array('label' => 'Things (en)')); ?>
<?php echo $this->Form->input('free_entries_and_discounts_en', array('label' => 'More things (en)')); ?>
</div>
</fieldset>
<?php //echo $this->Element('admin/save'); ?>
<?php echo $this->Form->submit('go for it'); ?>
<?php echo $this->Form->end(); ?>
Has anyone found a similar issue?
just for grin's try this
<?php echo $this->Form->end('Go for it'); ?>
end can provide the submit button. If this works then you probably have something overwriting the value of the submit. I'd start looking in your $this->request->data to see what its sending over to the view.
Hope this helps.

How to save multiple form in the same table like phpmyadmin

I'm working with CakePHP version 2.3
I've been wondering how to save a looped form like phpmyadmin does when you input multiple form for 1 table.
Let's say that I have a table products with id, name and content columns.
In order to save my data, I make a form with this 3 inputs multiplied by 3.
So that gives me something like this :
<?php echo $this->Form->create('Product'); ?>
<!-- Form for product 1 -->
<?php echo $this->Form->input('name', array('label' => "Name")); ?>
<?php echo $this->Form->input('content', array('label' => "Content")); ?>
<?php echo $this->Form->input('id'); ?>
<!-- Form for product 2 -->
<?php echo $this->Form->input('name', array('label' => "Name")); ?>
<?php echo $this->Form->input('content', array('label' => "Content")); ?>
<?php echo $this->Form->input('id'); ?>
<!-- Form for product 3 -->
<?php echo $this->Form->input('name', array('label' => "Name")); ?>
<?php echo $this->Form->input('content', array('label' => "Content")); ?>
<?php echo $this->Form->input('id'); ?>
<?php echo $this->Form->end('done'); ?>
Of course this can't work and I have no clue to how to get this done.
Does anybody could show me how it works?
Thank you very much for your help.
Do the following calls to input() method:
...
echo $this->Form->input('Product.0.name', array('label' => 'Name'));
echo $this->Form->input('Product.0.content', array('label' => 'Content'));
echo $this->Form->input('Product.1.name', array('label' => 'Name'));
echo $this->Form->input('Product.1.content', array('label' => 'Content'));
echo $this->Form->input('Product.2.name', array('label' => 'Name'));
echo $this->Form->input('Product.2.content', array('label' => 'Content'));
...
The previous code should output the following form elements
<input type="text" id="Product0name" name="data[Product][0][name]">
<input type="teaxtarea" id="Product0Content" name="data[Product][0][Content]">
<input type="text" id="Product1name" name="data[Product][1][name]">
<input type="teaxtarea" id="Product1Content" name="data[Product][1][Content]">
<input type="text" id="Product2name" name="data[Product][2][name]">
<input type="teaxtarea" id="Product2Content" name="data[Product][2][Content]">
which can posted and saved by your controller using saveAll() method very easily.
Also check out the CakePHP docs at: Field-naming-conventions

Show selected option in HTML Select menu after page has been reloaded in CakePHP

I'm building a non-javascript version of a website, as there are a number of customers who don't have javascript enabled. On this site, the customer selects what country they will be visiting and then displays the data related to that country accordingly.
I've managed to get this to work. They use a HTML drop down menu to select the country, click on Submit, and the page reloads with the data related to the selected country. However, it does not change the country displayed in the HTML drop down menu, so when the page reloads it reverts back to "Select A Country".
What I would like to have happen is that if you clicked on United Kingdom from the drop down box for example, when the page reloads the drop down should display United Kingdom.
Here is the code I am currently using for the view file:
<form name="countryselect" action="/selected-country/" method="post">
<select id="country-list" name="countryselected">
<?php foreach($countries as $coun) { ?>
<option value="<?php echo $coun['Tariff']['countryslug']; ?>"><?php echo $coun['Tariff']['countryname']; ?></option>
<?php } ?>
<input type="submit" value="Submit" />
</select>
</form>
And in my controller file I am using this:
$countries = $this->Tariff->find('all', array('conditions' => array('Tariff.gsmid' => '1')));
$this->set('countries', $countries);
if (!isset($_POST['countryselected'])) {
} else {
$countryselect = $_POST['countryselected'];
$tarcounselect = $this->Tariff->find('first', array('conditions' => array('Tariff.countryslug' => $countryselect)));
$this->set('tarcounselect', $tarcounselect);
}
Cheers!
If you use Cake, you should not build the form and the select manually but use the Cake FormHelper instead. It will then keep the selected country automatically:
Controller:
$this->set('countries', $this->Tariff->find('list', array('conditions' => array('Tariff.gsmid' => '1'), 'fields' => array('countryslug', 'countryname'))));
View:
<?php
echo $this->Form->create();
echo $this->Form->select('Tariff.countryslug', $countries);
echo $this->Form->end(__('Submit'));
?>
And then to retrieve the selected country in the controller:
if($this->request->is('post'))
{
$countryslug = $this->request->data['Tariff']['countryslug'];
}

Resources