Reputation: 2531
In my cake app I have a model called faqs, controller called faqs_controller & view called faqsindex.php.
I'm making a CMS so users can change the FAQs. The db table 'faqs' has 5 columns id, category, question, answer and number. "Number" is the order in which the FAQ's will appear.
The loop that lists all of the FAQs looks more or less like this:
<?php
foreach ($faqs as $faq):
<tr>
<td><?php echo $faq['Faq']['category']; ?></td>
<td><?php echo $faq['Faq']['number']; ?></td>
<td><?php echo $faq['Faq']['question']; ?></td>
<td><?php echo $faq['Faq']['answer']; ?></td>
</tr>
<?php endforeach; ?>
I want to make it so that the user can change the "number" cell from this screen, instead of going into a separate edit screen for each row and changing the number there.
You know, like how netflix's queue works, where the user can reorder it from the list, you don't have to click on the movie you want to see to change its order in your queue.
EDIT I set up edit in faqs_controller.php like this:
function edit() {
if(!empty($this->data)) {
$this->Faq->saveAll($this->data['Faq']);
}
else {
$this->data['Faq'] = Set::combine($this->Faq->find('all'), '{n}.Faq.id', '{n}.Faq');
}
}
and in the index view I made a foreach that looks like this:
echo $form->create('Faq', array('action'=>'edit'));
foreach($this->viewVars['faqs'] as $key => $value) {
echo 'id:'.$value['Faq']['id'];
echo '<br/>question:'.$value['Faq']['question'];
echo $form->input('Faq.'.$key.'.number');
}
In this case the foreach goes round 8 times because there are 8 rows. If I submit them, I create 8 new rows & can't update existing rows.
-EDIT-
I changed the form echo here:
echo $form->input('Faq.'.$key.'.question',array('value'=>$value['Faq']['question']));
to prepopulate the form. What I can't figure out is how to update the proper row. If I submit the form I get 8 mysql queries like this:
INSERT INTO faqs
(question
) VALUES ('THE NEW QUESTION I JUST ADDED?') when I don't want an insert but an update.
Upvotes: 1
Views: 4273
Reputation: 60506
Put each faq id inside your form?
echo $form->create('Faq', array('action'=>'edit'));
foreach($this->viewVars['faqs'] as $key => $value) {
echo 'id:'.$value['Faq']['id'];
echo '<br/>question:'.$value['Faq']['question'];
echo $form->hidden('Faq.'.$key.'.id', array('value' => $value['Faq']['id']));
echo $form->input('Faq.'.$key.'.number');
}
Upvotes: 4
Reputation: 7853
If you're wanting to update a specific row with Cake it is as simple as setting the appropriate row ID in your saveAll()
query.
function edit() {
if (!empty($this->data)) {
$this->Faq->saveAll($this->data['Faq'], array('conditions' => array('Faq.id' => $yourId)));
}
...
}
This is telling Cake's ORM to save the information into the row only where Faq.id
is equal to $yourId
. If $yourId
matches an existing ID in your table then that row should be updated.
Edit
You can put the id
field into a hidden form element using CakePHP's FormHelper.
$this->Form->hidden('id', array('value' => $value['Faq']['id']));
Upvotes: 1
Reputation: 5481
if you are using jquery: http://jqueryui.com/demos/sortable/ All the ordering is done on client side, you put the order value into hidden input and use javascript to change them according to user interaction. There's nothing to change on the server side script.
Edit:
echo $form->create('Faq', array('action'=>'edit')); foreach($this->data['Faq'] as $key => $value) { echo 'id:'.$value['Faq']['id']; echo '<br/>question:'.$value['Faq']['question']; echo $form->input('Faq.'.$key.'.number'); echo $form->input('Faq.'.$key.'.id'); } echo $form->end('Save');
and the controller:
function edit() { if(!empty($this->data)) { $this->Faq->saveAll($this->data['Faq']); } $this->data['Faq'] = Set::combine($this->Faq->find('all'), '{n}.Faq.id', '{n}.Faq'); }
unless you redirect them somewhere else after saving.
Upvotes: 3