You are here: cakephp » using checkboxes for a one to many relationship
Using checkboxes for a one to many relationship
- Written By
- Shadow
- Submitted At
- 2010-10-05 13:50:37
- Num Views
- 722
- Category
- CakePHP
|
I am currently busy with a program for the showing of horses. Now, a horse can be registered and can enter into many different classes. I used checkboxes to enable the user to choose the classes. The classes are named "class 1 - class 139" I just want to know how do I submit the form and write to the different databases simultaneously? All the classes have exactly the same fields in the database... By Shadow @ 2010-10-05 13:50:37
|
|
I've had many problems with this. Could you paste your view file here? By Admin @ 2010-10-05 14:01:41
|
|
View file: <form action="<?=$html->url('/entries/index')?>" method="post" id="index"> <fieldset> <legend>Horse registration form:</legend> <p class="footer">All fields are required</p> <ul id="registration_list"> <!--when the form is submitted the 'Entry(model name).id(fieldname) etc' will be sent to the 'Entry.php' model and verify the information before it is sent to the database and stored--> <li><?=$form->input('Entry.horse_number', array('label' => 'Horse Number:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.horse_breeder', array('label' => 'Horse Breeder :<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.horse_name', array('label' => 'Horse Name :<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.registration_number', array('label' => 'Registration Number:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.dob', array('label' => 'Date of Birth:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.sire', array('label' => 'Sire:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.owner', array('label' => 'Owner:<br />','cols' => '40', 'rows' => '1'))?></li><br /> </ul> <div class="checkbox"> <h2>Breeding Classes</h2> <h3>Foal Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class1' => '1. Mare Fillies Under 12 months', 'class2' => '2. Colt Fillies Under 12 months', ))); ?> <h3>Traditional Junior Breeding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class3' => '3. Traditional Mare 1-2 Years', 'class4' => '4. Traditional Colt 1-2 Years', 'class5' => '5. Traditional Mare 2-3 Years', 'class6' => '6. Traditional Colt 2-3 Years', ))); ?> <h3>Traditional Senior Breeding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class9' => '9. Traditional CHAMPION Gelding Any Age', 'class10' => '10. Traditional Mare 3-4 Years', 'class11' => '11. Traditional Stallion 3-4 Years', 'class12' => '12. Traditional Mare 4 Years and Older', 'class13' => '13. Traditional Mare 4 Years and Older', ))); ?> <h3>Universal Junior Breeding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class18' => '18. Universal Mare 1-2 Years', 'class19' => '19. Universal Colt 1-2 Years', 'class20' => '20. Universal Mare 2-3 Years', 'class21' => '21. Universal Colt 2-3 Years', ))); ?> <h3>Universal Senior Breeding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class24' => '24. Universal CHAMPION Gelding Any Age', 'class25' => '25. Universal Mare 3-4 Years', 'class26' => '26. Universal Stallion 3-4 Years', 'class27' => '27. Universal Mare 4 Years and Older', 'class28' => '28. Universal Mare 4 Years and Older', ))); ?> <h3>Group Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class33' => '33. Group of 3 Any Age or Sex Property of 1 owner', 'class34' => '34. Group of 3 Progeny of 1 Stallion or Mare, Any Age or Sex not necessarily the property of 1 owner', ))); ?><br /> <h2>Tradiotional Riding Classes</h2> <h3>Traditional Three Gaited Riding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class35' => '35. Traditional Stallion for the Breeding of Riding Horses Under Saddle', 'class36' => '36. Traditional Mare for the Breeding of Riding Horses Under Saddle', 'class37' => '37. Traditional 3-Gaited Riding Horse Mares', 'class38' => '38. Traditional 3-Gaited Riding Horse Geldings', 'class39' => '39. Traditional Novice 3-Gaited Riding Horse', 'class40' => '40. Traditional 3-Gaited Riding Horse Under 4 Years', 'class41' => '41. Traditional 3-Gaited Riding Horse Stallions', 'class42' => '42. Traditional Ladies 3-Gaited Riding Horse', 'class43' => "43. Traditional Gentleman's 3-Gaited Riding Horse", 'class44' => '44. Traditional Pleasure Horse', 'class125' => '125. Best Schooled Traditional Horse', ))); ?> <h3>Traditional Five Gaited Riding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class59' => '59. Five Gaited Stallion', 'class60' => '60. Five Gaited Pleasure Horse - AUTOMATIC CHAMPIONSHIP', 'class112' => '112. Five Gaited Mare or Gelding', 'class114' => '114. Five Gaited Novice Riding Horse', ))); ?> <h2>Universal Riding Classes</h2> <h3>Universal Three Gaited Riding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class46' => '46. Universal Stallion for the Breeding of Riding Horses Under Saddle', 'class47' => '47. Universal Mare for the Breeding of Riding Horses Under Saddle', 'class48' => '48. Universal 3-Gaited Riding Horse Mares', 'class49' => '49. Universal 3-Gaited Riding Horse Geldings', 'class50' => '50. Universal Novice 3-Gaited Riding Horse', 'class51' => '51. Universal 3-Gaited Riding Horse Under 4 Years', 'class52' => '52. Universal 3-Gaited Stallions', 'class53' => '53. Universal Ladies 3-Gaited Riding Horse', 'class54' => "54. Universal Gentleman's 3-Gaited Riding Horse", 'class55' => '55. Universal 3-Gaited Pleasure Horse', ))); ?> <h2>Harness Classes</h2> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class66' => '66. Single Harness Stallions', 'class67' => '67. Single Harness Novice', 'class68' => '68. Ladies Single Harness', 'class69' => '69. Single Harness Best Schooled Horse', 'class71' => '71. Fine Harness - AUTOMATIC CHAMPIONSHIP', 'class72' => '72. Universal Single Harness - AUTOMATIC CHAMPIONSHIP', 'class113' => '113. Single Harness Mare or Gelding', 'class136' => '136. Best Single Harness Under 4 Years - AUTOMATIC CHAMPIONSHIP', ))); ?> <h2>Utility Classes</h2> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class103' => '103. Utility Novice Riding Horse - Rider Any Age', 'class105' => '105. Utility Riding Horse - Rider Under 15 Years', 'class106' => '106. Utility Riding Horse - Rider Under 19 Years', 'class107' => '107. Utility Riding Horse - Adults - Rider 19 Years and Older', 'class111' => '111. Show Hunter', ))); ?> <h2>Rider Classes</h2> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class75' => '75. Best Ladies Rider - 19 Years and Older', 'class76' => '76. Best Gentlemans Rider - 19 Years and Older', ))); ?> <h2>Children's Classes</h2> <h3>Children's Riding Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class81' => '81. Universal CHAMPION 3-Gaited Riding Horse - Rider Under 11 Years', 'class84' => '84. Universal CHAMPION 3-Gaited Riding Horse - Rider Under 15 Years', 'class87' => '87. Universal CHAMPION 3-Gaited Riding Horse - Rider Under 19 Years', 'class90' => '90. Traditional CHAMPION 3-Gaited Riding Horse - Rider Under 11 Years', 'class93' => '93. Traditional CHAMPION 3-Gaited Riding Horse - Rider Under 15 Years', 'class96' => '96. Traditional CHAMPION 3-Gaited Riding Horse - Rider Under 19 Years', ))); ?> <h3>Children's Rider Classes</h3> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class129' => '129. Traditional and Universal Rider Under 11 Years - AUTOMATIC CHAMPIONSHIPS', 'class130' => '130. Traditional and Universal Rider Under 15 Years - AUTOMATIC CHAMPIONSHIPS', 'class131' => '131. Traditional and Universal Rider Under 19 Years - AUTOMATIC CHAMPIONSHIPS', ))); ?> <h2>Fun Classes</h2> <?=$form->input('Entry.class', array('type' => 'select', 'multiple' => 'checkbox','options' => array( 'class109' => '109. Ladies Side Saddle in Costume', 'class110' => '110. Development Class', 'class78' => '78. Rider Under 7 years - Lead Rein Class', 'class127' => '127. Best Trotter', 'class126' => '126. Best Trippler', 'class137' => '137. Fastest SA Boerperd over 100 meters - Against Time', 'class138' => '138. Veteran Rider - Above 55 Years of Age', 'class139' => '139. Costume Class', ))); ?> </div> </fieldset> <fieldset> <legend>Handler / Rider info:</legend> <fieldset> <ul> <li><?=$form->input('Entry.handler', array('label' => 'Handler:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.id_number', array('label' => 'ID Number:<br />','cols' => '40', 'rows' => '1'))?></li> </ul> </fieldset> <fieldset> <ul> <li><?=$form->input('Entry.rider1', array('label' => 'Rider #1:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.id_number1', array('label' => 'ID Number:<br />','cols' => '40', 'rows' => '1'))?></li> </ul> </fieldset> <fieldset> <ul> <li><?=$form->input('Entry.rider2', array('label' => 'Rider #2:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.id_number2', array('label' => 'ID Number:<br />','cols' => '40', 'rows' => '1'))?></li> </ul> </fieldset> <input type="submit" name="submit" value="Submit" /> <? 'debug'; ?> </fieldset> </form> By Shadow @ 2010-10-05 14:06:28
|
|
The debug at the bottom is not supposed to be there, just did it now and took it out again By Shadow @ 2010-10-05 14:07:20
|
|
Ok, so from what I can see your main table is called "Entry" I apologize if the following information is redundant, but I don't know what tables you have or don't have Step 1: Create a database table called "types" (if you don't have it already) Table:types Fields: id, name Step 1.2: Add all the classes into table types, with the ID being the class id and the name being the description, example: ID: 1. NAME: 1. Mare Fillies Under 12 months Step 2: Create a database table called "entries_types" (if you don't have it already) Table: entries_types Fields: type_id, entry_id Step 3: Use the following view file <form action="<?=$html->url('/entries/index')?>" method="post" id="index"> <fieldset> <legend>Horse registration form:</legend> <p class="footer">All fields are required</p> <ul id="registration_list"> <!--when the form is submitted the 'Entry(model name).id(fieldname) etc' will be sent to the 'Entry.php' model and verify the information before it is sent to the database and stored--> <li><?=$form->input('Entry.horse_number', array('label' => 'Horse Number:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.horse_breeder', array('label' => 'Horse Breeder :<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.horse_name', array('label' => 'Horse Name :<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.registration_number', array('label' => 'Registration Number:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.dob', array('label' => 'Date of Birth:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.sire', array('label' => 'Sire:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.owner', array('label' => 'Owner:<br />','cols' => '40', 'rows' => '1'))?></li><br /> </ul> <div class="checkbox"> <h2>Breeding Classes</h2> <h3>Foal Classes</h3> <?php foreach($types as $id => $type){ ?> <input type="checkbox" name="data[Type][Type][]" value="<?php echo $id; ?>" <?php if(in_array($id,$selectedTypes))echo 'checked="checked"';?> /> <?php echo $type; ?> <br /> <?php } ?> </div> </fieldset> <fieldset> <legend>Handler / Rider info:</legend> <fieldset> <ul> <li><?=$form->input('Entry.handler', array('label' => 'Handler:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.id_number', array('label' => 'ID Number:<br />','cols' => '40', 'rows' => '1'))?></li> </ul> </fieldset> <fieldset> <ul> <li><?=$form->input('Entry.rider1', array('label' => 'Rider #1:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.id_number1', array('label' => 'ID Number:<br />','cols' => '40', 'rows' => '1'))?></li> </ul> </fieldset> <fieldset> <ul> <li><?=$form->input('Entry.rider2', array('label' => 'Rider #2:<br />','cols' => '40', 'rows' => '1'))?></li><br /> <li><?=$form->input('Entry.id_number2', array('label' => 'ID Number:<br />','cols' => '40', 'rows' => '1'))?></li> </ul> </fieldset> <?=$form->input('Entry.id',array('type'=>'hidden')); ?> <input type="submit" name="submit" value="Submit" /> <? 'debug'; ?> </fieldset> </form> Step 4: The model file for the table entry (app/models/entry.php) <?php class Entry extends AppModel{ var $name = 'Entry'; var $hasAndBelongsToMany = array('Type'); } ?> Step 5: The model file for the table type (app/models/type.php) - which will hold your classes <?php class Type extends AppModel{ var $name = 'Type'; } ?> Step 6: The controller file for entries (app/controllers/entries_controller.php) <?php class EntriesController extends AppController { function index(){ $this->loadModel('Type'); $types = $this->Type->find('list'); $this->set('types',$types); $this->set('selectedTypes',$this->data['Type']['Type']); if($this->data){ if($this->Entry->save($this->data)){ echo 'saved successfully'; $this->data['Entry']['id'] = $this->Entry->id; }else{ echo 'failed saving'; } } } } I did the following in your view file: * In your view file I replaced all the class1, class2, class3 with 1, 2, 3 * In your view file I replaced Entry.class with Type.Type and also took it out of cake's way to handle checkboxes as in your case this wont work too well (we are changing Class to Type as Class is a reserved keyword and going to break things, you might also think why Type.Type, do it twice? yes it is right, weird but it is right) By Admin @ 2010-10-05 16:05:52
|
|
Ok as you mentioned this now works for you. So now to add the headings back. You can just follow these steps. Step 1: Create a database table called type_headings Table: type_headings Fields: id, name Step 2: Add all your headings into this database table with the id being whatever you want and the heading in the name field Model file for type_headings (app/models/type_heading.php) <?php class TypeHeading extends AppModel{ var $name = 'TypeHeading'; } ?> Step 3: Add a column to your Types table called type_heading_id Step 4: Now use the id's from the type_heading table and add them to the type table under the newly created column Step 5: Update your Type model to link with your type headings table class Type extends AppModel{ var $name = 'Type'; var $belongsTo = array('TypeHeading'); } Step 6: Now change your select for the types: From this: $types = $this->Type->find('list'); To this: $types = $this->Type->find('all',array('order'=>'Type.type_heading_id')); Step 7: Now you have a different data set in $types in your view so we need to change the view: From this: <?php foreach($types as $id => $type){ ?> <input type="checkbox" name="data[Type][Type][]" value="<?php echo $id; ?>" <?php if(in_array($id,$selectedTypes))echo 'checked="checked"';?> /> <?php echo $type; ?> <br /> <?php } ?> To this: <?php $currentHeadingId = ''; foreach($types as $type){ //saves the last used heading id so that you can check if it has changed next time it loops $currentHeadingId = $type['Type']['type_heading_id']; //if it is a new heading then print out the heading if($currentHeadingId != $type['Type']['type_heading_id']){ echo '<h3>'.$type['Type']['TypeHeading']['name'].'</h3>'; } ?> <input type="checkbox" name="data[Type][Type][]" value="<?php echo $type['Type']['id']; ?>" <?php if(in_array($type['Type']['id'],$selectedTypes))echo 'checked="checked"';?> /> <?php echo $type['Type']['name']; ?> <br /> <?php } ?> That should do it. Let me know if this does not work for you. By PHPin24 @ 2010-10-06 20:43:03
|
|
Um... I don't know if I broke something, but here's the error I get: Warning (2): in_array() expects parameter 2 to be array, null given [APP\views\entries\index.ctp, line 30] The headings also don't want to work yet, but I will try and figure out why. And here follows my controller (app\controllers\entries_controller.php) : <?php class EntriesController extends AppController { public $name = 'Entries'; public $helpers = array('Html', 'Form'); function index(){ $this->loadModel('Type'); $types = $this->Type->find('all',array('order'=>'Type.type_heading_id')); $this->set('types',$types); $this->set('selectedTypes',$this->data['Type']['Type']); if($this->data){ if($this->Entry->save($this->data)){ $this->Session->setFlash('The registration was saved'); $this->data['Entry']['id'] = $this->Entry->id; }else{ $this->Session->setFlash('There was a problem saving this information'); } } } public function accounts() { if (!empty($this->data)) { $this->loadModel('Account'); if ($this->Account->save($this->data)) { $this->Session->setFlash('The registration was saved'); $this->redirect(''); } else { $this->Session->setFlash('There was a problem saving this information'); } } } } ?> The accounts function is not done yet, just going to be a simple math function for people who made payments for various items, what the total amount is and what might still be outstanding. By Shadow @ 2010-10-06 22:56:45
|
