hello guys I'm a new member and I'd like to share with you my idea which discussed in this topic :
/topic/1260-no-cms-and-grocery-crud-master-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 :D
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 :lol:
so we need to implement some styles for our new feature :D
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 :D
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 :rolleyes: