Extend admin/module/edit page

edited April 2012 in Modules
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

  • edited April 2012
    I've done this a few times with the custom form field type (and the func option) and pointed it at a method in the model to get and format the data.

    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.
  • Hey Lance, if you want to fork me that code that would be awesome. Cheers!
  • edited April 2012
    It's not git'd unfortunatly and I may have forgotten about this last night.. sorry!

    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>&copy; 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. }
  • Thanks Lance, that does look similar to what I'm doing - basically just querying for the shifts and adding them via form-fields.

    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!
  • edited 4:15PM
    No problem.

    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.
  • edited 4:15PM
    Hi Lance, I was curious if you could share some more information about the process you took to customize the Fuel interface that you have shown in those 2 screen grabs you referenced.

    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
  • edited 4:15PM
    Sorry for the delay Erik, I missed your message.

    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.
Sign In or Register to comment.