hello guys I'm a new member and I'd like to share with you my idea which discussed in this topic :
http://www.grocerycr...er-detail-form/
this was a very long time ago and I have no idea if you guys already fix this or not but what I've done is I fix this issue and I would like to share my code with you .
so just to remind you guys this discussion is about implementing master-detail 1_n relation inside tables, for example:
if you have a customers table and each customer has multiple phone numbers
in this case you might want to add the phone number inside the add customer form like this :
as you can see we can add and remove rows easily by pressing the buttons shown in the figure above !
so please follow my instructions :
first create phone_numbers table in your database :
CREATE TABLE `phone_numbers` ( `id` int(11) NOT NULL, `customer_id` int(11) NOT NULL, `phone_type` varchar(255) NOT NULL, `phone_number` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
then inside the customers controller define a new field and call it for example : phone_number like this :
$crud->fields('first_name', 'last_name', 'email', 'gender', 'birth_date', 'phone_number');
note : phone_number field isn't exist inside customers table in the database !!.
after this we add callback for our new field like this :
$crud->callback_add_field('phone', array($this, 'phone_number'));
and then we define our new callback inside our class like this :
function phone_number($value = '', $primary_key = null){ $this->db->where('customer_id', $primary_key); $numbers = $this->db->get('phone_numbers')->result_array(); $numbers[1] = array(); $html = ' <table id="phone_number"> <tr> <th>type</th><th>Phone number</th> </tr>'; foreach ($numbers as $number){ if (!empty($number["phone_number"]) ) $html.= '<tr><td><input name="phone_types[]" type="text" value="'.$number["phone_type"].'" ></td><td><input name="phone_numbers[]" type="text" value="'.$number["phone_number"].'" ></td><td><button class="remove_number btn btn-danger">remove</button></td></tr>'; } $html .=' <tr><td><input name="phone_types[]" type="text" ></td><td><input name="phone_numbers[]" type="text" ></td><td><button class="remove_number btn btn-danger">remove</button></td></tr> </table> <button type="button" id="add_number" class="btn btn-info" style="width: 100px; margin:20px 0px; ">add</button> '; return $html; }
by doing all these steps we'll get a simple table inside our add customer form !
please keep in mind :
** don't use the same input field name inside the $html variable as the field name inside your grocery crud fields definition
example : inside $crud->fields function we pass phone_number variable and inside $html variable in the phone_number call back we use phone_numbers[]
(different name)
so now we should see a static table as mentioned before so now we need to bring it to live
inside your custom Javascript file put this :
jQuery(document).ready(function(){ // Sales chart jQuery(' #add_number').on('click', function(e){ e.preventDefault(); var row = '<tr><td><input name="phone_types[]" type="text" ></td><td><input name="phone_numbers[]" type="text" ></td><td><button class="remove_number btn btn-danger">remove</button></td></tr>'; jQuery('#phone_number tr:last').after(row); register_remove_event(); }); function register_remove_event(){ jQuery('#phone_number button.remove_number').on('click', function (e) { e.preventDefault(); if (jQuery('#phone_number tr').length > 2){ jQuery(this).parents('tr').remove(); } }); } register_remove_event(); });
the code above does nothing more than removing and adding rows in the table !
now we want to save the inserted phone numbers to the database
easy !!
use another 2 callbacks inside your class
$crud->callback_before_insert(array($this, 'save_phone_number')); $crud->callback_before_update(array($this, 'save_phone_number'));
the first one fire for new inserted customers
the second one fires when we update an existing customer
they both invoke the same callback save_phone_number
so we need to define it
function save_phone_number($post_array, $primary_key){ //first we delete all the old records since we're going to re-insert them back! $this->db->delete('phone_numbers', array('customer_id' => $primary_key)); $i = 0; $data = array(); while (!empty($post_array["phone_numbers"][$i]) ){ $phone = array( 'phone_type' => $post_array["phone_types"][$i], 'phone_number' => $post_array["phone_numbers"][$i], 'customer_id' => $primary_key ); array_push($data, $phone); $i++; } $this->db->insert_batch('phone_numbers', $data); }
the code above defines the save_phone_number call back
so what that code does is it deletes all previous phone numbers and insert the new ones !
now as we can see we've finished our solution but it looks so stupid
like miss miss colombia without makeup
so we need to implement some styles for our new feature
so put the following code inside your css file :
/*everything below this line is custom */ table#phone_number{ border-collapse: collapse; width: 100%; } table#phone_number th, td { text-align: left; padding: 8px; } table#phone_number tr:nth-child(even){background-color: #f2f2f2} table#phone_number th { background-color: #46bfeb; color: white; } table#phone_number th:first-child { -webkit-border-radius:5px 0 0 0; border-left:none} table#phone_number th:last-child{ -webkit-border-radius:0 5px 0 0;border-right:none } table#phone_number tfoot td:first-child{ -webkit-border-radius:0 0 0 5px ;} table#phone_number tfoot td:last-child{ -webkit-border-radius:0 0 5px 0;} table#phone_number input{ border: solid 1px lightgrey; padding: 5px; width: 80%; min-width: 40px; -webkit-border-radius: 7px; -moz-border-radius: 5px; border-radius: 5px; }
and here we can see this amazing table inside our customer insertion page
ok guys so now we finish all this,
anyway if I see any support or interests on this topic then I'll release a nice implementation on github which requires less code and time from you