Extend admin/module/edit page
I have a custom module that contains a number of tables (and associated models) linked by foreign keys, including an events table and a shifts table. I'd like all of the shifts associated with an event's record to be visible and editable via the fuel admin interface when that event record is being edited. My best current idea for this is to query for the shifts inside the events_model, pass the data to the form_fields() function, and then use the $_POST array in the on_after_post() hook to update the shifts table. This feels like a bit of a hack. Is there a more erudite way to accomplish this?
Comments
Two examples, product options:
http://redgemmedia.co.nz/assets/grab.jpg
Images for a gallery:
http://redgemmedia.co.nz/assets/grab1.jpg
I don't have access to the code for those examples right now (at work) but I'll post tonight. Hopefully puts you on the right track.
The model for that second example with the images:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); require_once(FUEL_PATH.'models/base_module_model.php'); class Gallery_albums_model extends Base_module_model { public $required = array('title', 'excerpt'); public $linked_fields = array('permalink' => array('title' => 'url_title')); public $unique_fields = array('permalink'); function __construct() { parent::__construct('gallery_albums'); } public function form_fields($values = array()) { $fields = parent::form_fields(); $fields['album_image'] = array( 'type' => 'custom', 'class' => '', 'func' => 'ckf_single_img', 'ckfinder' => 'album_image', 'required' => true ); $this->load->module_model('gallery', 'gallery_images_model'); $has_images = false; # Images if ( ! empty($this->normalized_save_data['images'])) { # Had some already - failed edit (form validation) $image_fields = $this->_set_images($this->normalized_save_data['images']); $has_images = true; } else if ( ! empty($values['id'])) { # Get from Database if ($images = $this->gallery_images_model->find_all('gallery_id = '.$values['id'])) { $image_fields = $this->_set_images($images); $has_images = true; } } if ( ! $has_images) { # No images, just a static message $image_fields['no_images'] = array( 'label' => ' ', 'value' => '<h4>There are no images yet.</h4>', 'displayonly' => true ); } # Merge image fields into main fields $fields = array_merge($fields, $image_fields); unset($fields['album_image_upload']); return $fields; } # Create a place holder field for each image to be rendered private function _set_images($data) { $order = 10; foreach ($data as $key => $row) { if (empty($row['id'])) $row['id'] = $key; # Create a placeholder field to store the image fields $image_fields['images['.$row['id'].']'] = array( 'type' => 'custom', 'value' => $row, # The row for an image 'func' => array(&$this, 'image'), 'order' => $order, 'label' => ' ' ); $order++; } return $image_fields; } # The custom render method for each image row a gallery has public function image($field) { # Slight shortcut $v = $field['value']; $return[] = '<table><tr>'; $return[] = '<td rowspan="2"><a href="'.$v['image'].'" rel="lightbox">'.img(array('src'=>$v['image'], 'width'=>80, 'class'=>'img')).'</a></td>'; $return[] = '<td>Race #: '.$this->form->text('images['.$v['id'].'][race_number]', $v['race_number']).'</td></tr>'; $return[] = '<tr><td>© info: '.$this->form->text('images['.$v['id'].'][title]', $v['title']).$this->form->hidden('images['.$v['id'].'][thumb]', $v['thumb']).$this->form->hidden('images['.$v['id'].'][image]', $v['image']).'</td>'; $return[] = '</tr></table><hr class="img-split">'; return join($return); } public function on_after_save($values) { # Orginal save data $saved_data = $this->normalized_save_data; # Got images if ( ! empty($saved_data['images'])) { # Load model $this->load->module_model('gallery', 'gallery_images_model'); # Iterate over and update the editable fields foreach ($saved_data['images'] as $id => $row) { $this->gallery_images_model->update($row, array('id' => $id)); } } } } The image function there could do with with being in a helper or something. Not a fan of html in models.. One way to do it anyway, hope it helps. }
A slightly unrelated question: Is there a way to add an arbitrary attribute to a form field.... I need some data attributes to work my js magic...
Thanks again!
On a custom field like the above $fields['album_image'] field you'll see the ckfinder attribute I stuck in there so with custom fields the new attribute is still available for you to render.
I've not tried it with 'normal' field types. I don't think $form_builder::_normalize_value() will strip them out but the render methods won't output them either.
I guess at this time your best bet is the class attribute for normal field types.
I would love to feel safe doing this for my projects as well, but as I have not yet tried to dabble in trying to change Fuel's look-and-feel.
Thanks!
Erik
No real process, just hacked at it!
I made a few minor (structure) changes in the header and the rest is just css. I loaded in an extra css file with my custom changes in there.
I did make the menus slide which was a change in the base controller.
To be honest I just wanted to play around with it. The changes I've made are probably quite safe with minor upgrades, I wouldn't think there would be big changes to the header in minor releases. That's an assumption on my part but with the next major release knocking on the door it's fair.
Happy to share.