0

I am using Agile Toolkit for some development and would like to extend the existing Grid Control so that each row contains the data (as it does right now) but also links to a page with a query string that contains the ID. I want to be able to do something like:

$this->add('Grid', 'short-name', 'template-tag', array('page?id=', 'id'))->setModel('mydatasource');

I can currently use the following:

$this->add('Grid', 'short-name', 'template-tag')->setModel('mydatasource');

But I would like to be able to specify the page I'm linking to as a format with the field I want to pass so that clicking on anywhere on the second row:

1     Jack Johnson     Clerk
2     John Doe         Executive

Takes me to: myapp.com/page?id=2

How would I go about extending the Grid element to do that? Or do I need to extend all the way down from AbstractView or Lister?

Thanks!

Full working solution:

precacheTemplate removed the reference from row_t for the variable I defined in the html template. So I followed the existing practice, added another reset of the variable (i.e. where it sets the to ) of to - that way it stays in memory as a reference to go back to the template field inside the generic formatRow which is being overloaded from Basic Grid.

Roman had mentioned some of this before but i finally got the missing link where i had to reset.

Best way to understand is to compare line-by-line my grid and the Basic Grid (yes I know I extend from Advanced).

Hopefully that helps anyone else that has the exact same question.

On the page

$this->add('ExtendedUI_GridLinkedRow', array('dest_page'=>'home', 'name'=>'assessments'), 'assessments')
    ->setModel('GrantAssessment')
    ->addCondition('uid', 1);

GridLinkedRow.php

    <?php

class ExtendedUI_GridLinkedRow extends Grid_Advanced {

    function init(){
        parent::init();
    }

    function defaultTemplate(){
        return array('ExtendedUI/grid_linked_row');
    }

    function precacheTemplate(){
        // pre-cache our template for row
        // $full=false used for certain row init
        $row = $this->row_t;
        $col = $row->cloneRegion('col');

        // tbody -> column
        $row->setHTML('row_id','<?$id?>');
        $row->trySetHTML('odd_even','<?$odd_even?>');
        $col->setHTML('dest_link','<?$page_link?>');
        $row->del('cols');

        // thead -> column
        $header = $this->template->cloneRegion('header');
        $header_col = $header->cloneRegion('col');
        $header_sort = $header_col->cloneRegion('sort');

        // Totals -> column
        if($t_row = $this->totals_t){
            $t_col = $t_row->cloneRegion('col');
            $t_row->del('cols');
        }

        $header->del('cols');

        foreach($this->columns as $name=>$column){
            $col->del('content');
            $col->setHTML('content','<?$'.$name.'?>');

            if(isset($t_row)){
                $t_col->del('content');
                $t_col->setHTML('content','<?$'.$name.'?>');
                $t_col->trySetHTML('tdparam','<?tdparam_'.$name.'?>style="white-space: nowrap"<?/?>');
                $t_row->appendHTML('cols',$t_col->render());
            }

            // some types needs control over the td

            $col->setHTML('tdparam','<?tdparam_'.$name.'?>style="white-space: nowrap"<?/?>');

            $row->appendHTML('cols',$col->render());

            $header_col->set('descr',$column['descr']);
            $header_col->trySet('type',$column['type']);

            // TODO: rewrite this (and move into Advanced)
            if(isset($column['sortable'])){
                $s=$column['sortable'];
                // calculate sortlink
                $l = $this->api->getDestinationURL(null,array($this->name.'_sort'=>$s[1]));

                $header_sort->trySet('order',$column['sortable'][0]);
                $header_sort->trySet('sorticon',$this->sort_icons[$column['sortable'][0]]);
                $header_sort->set('sortlink',$l);
                $header_col->setHTML('sort',$header_sort->render());
            }else{
                $header_col->del('sort');
                $header_col->tryDel('sort_del');
            }

            if($column['thparam']){
                $header_col->trySetHTML('thparam',$column['thparam']);
            }else{
                $header_col->tryDel('thparam');
            }

            $header->appendHTML('cols',$header_col->render());

        }
        $this->row_t = $this->api->add('SMlite');
        $this->row_t->loadTemplateFromString($row->render());

        if(isset($t_row)){
            $this->totals_t = $this->api->add('SMlite');
            $this->totals_t->loadTemplateFromString($t_row->render());
        }

        $this->template->setHTML('header',$header->render());
    }

    function formatRow(){

        if(!$this->columns)throw $this->exception('No columns defined for grid');

        foreach($this->columns as $tmp=>$column){
            $this->current_row[$tmp.'_original']=@$this->current_row[$tmp];

            $formatters = explode(',',$column['type']);
            foreach($formatters as $formatter){
                if(!$formatter)continue;
                if(method_exists($this,$m="format_".$formatter)){
                    $this->$m($tmp,$column);
                }else throw new BaseException("Grid does not know how to format type: ".$formatter);
            }
            // setting cell parameters (tdparam)
            $this->applyTDParams($tmp);
            if($this->current_row[$tmp]=='')$this->current_row[$tmp]=' ';
        }
        $this->row_t->setHTML('page_link', $this->api->url($this->dest_page, array('id'=>$this->current_id)));
        return $this->current_row;
    }

}

For the templates:

grid_linked_row.html

<?$Misc?>
<div id="<?$_name?>" class="atk-grid">
  <div class="atk-grid-panel">
    <?quick_search?><?/?>
    <div class="atk-buttons"><?grid_buttons?><?/?></div>
  </div>
  <table width="<?table_width?>100%<?/?>">
    <?header?>
    <thead class="ui-widget-header"><tr>
        <?cols?>
        <?col?>
        <th class="ui-widget-header" nowrap    <?$thparam?>><?sort?><i  style="float: left" class="ui-icon <?$sorticon?>"></i><a href="<?$sortlink?>"><?/sort?><?descr?>Customer<?/?><?sort_del?></a><?/?></th>
        <?/col?>
        <?/cols?>
    </tr></thead>
    <?/header?>

    <tbody class="grid_body">
      <?rows?>
      <?row?>
      <tr class="<?$odd_even?>" data-id="<?$row_id?>" rel="<?$row_id?>">
        <?cols?>
        <?col?>
        <td <?$tdparam?>><a href="<?$dest_link?>"><?$content?></a></td>
        <?/col?>
        <?/cols?>
      </tr>
      <?/row?>

      <?totals?>
      <tr class="atk-grid-totals">
        <?cols?>
        <?col?>
        <td <?$tdparam?>><?$content?></td>
        <?/col?>
        <?/cols?>
      </tr>
      <?/totals?>
      <?/rows?>


    </tbody>
    <?full_table?>
    <?/full_table?>
  </table>
  <?not_found?><div class="atk-grid-notfound ui-state-highlight ui-corner-all"><i class="ui-icon ui-icon-alert float-left"></i>No Records Found</div><?/not_found?>
  <div class="atk-paginator"><?paginator?><?/?></div>
  <?hidden_forms?><?/hidden_forms?>
</div>
Omar Mir
  • 1,500
  • 1
  • 19
  • 39

1 Answers1

0

If you want to wrap all the text values of your grid inside a link, you can use the following:

$this->add('MyGrid',array('dest_page'=>'page'), 'template-tag');


class MyGrid extends Grid {
    function format_text($field){
        parent::format_text($field);

        // Wrap the value inside a link
        $this->current_row_html[$field]='<a href="'.
            $this->api->url($this->dest_page, array('id'=>$this->current_id).'">'.
            ($this->current_row_html[$field]?:
             htmlspecialchars($this->current_row[$field],ENT_NOQUOTES,'UTF-8')).
            '</a>'
    }
}
romaninsh
  • 10,606
  • 4
  • 50
  • 70
  • Hi @romaninsh the id field is coming up blank in both the precachetemplate and init – Omar Mir Sep 08 '12 at 04:17
  • 1
    Try `this->current_id` if you are inside formatRow or format_XXX – romaninsh Sep 09 '12 at 21:13
  • Tried @romaninsh $this->setHTML('dest_link', $this->api->url($this->dest_page, array('id'=>$this->current_id))); inside formatRow but no dice - it has the url (and the id field) but I don't know what the template object is that i need to use. i.e. $this->template->setHTML..... or $this->setHTML.... – Omar Mir Sep 10 '12 at 04:52
  • I have updated my answer. It may contain some syntax errors, please amend it if necessary. The idea should be clear. – romaninsh Sep 10 '12 at 21:57
  • Thanks @romaninsh - I didn't use the exact solution you posted but I have finally gathered together a working solution from your tips that feels clean, i.e. I wanted to stay with the goal of your framework - I didn't directly modify any html directly. I have also posted my full working solution - please let me know if you think ok :) – Omar Mir Sep 11 '12 at 01:25
  • It's alright, I wouldn't go through the trouble of changing the whole template of a grid and would have the link in the PHP, so this question and answer provide two alternative solutions and readers will be able to pick the one they find more appropriate. Thanks for posting your solution. – romaninsh Sep 14 '12 at 10:21
  • Hi @romaninsh - I tried your solution and it works but it means overriding each individual format function which I didn't want to do. What I am doing is simulating tr onClick by: table .grid_body tr td a { display: block; width: 100%; height: 100%; padding: 0.67em; text-decoration: none; color: black; } For this to work each column and format needed to be wrapper with links, including boolean etc etc. – Omar Mir Sep 14 '12 at 18:04