Forums / Developer / Enhanced matrix datatype

Enhanced matrix datatype

Author Message

Felix Laate

Friday 05 October 2007 3:41:19 am

Hi all!

the matrix datatype is a very practical datatype, but it has its limitations. It's more like a textual table than a real matrix between objects. But it is obviously possible to store links or e.g. object_ids as text in the cells. This brings me to my question (did I hear a "finally"?):

Has anyone extended/enhanced the matrix datatype so that one can decide the datatype of a column? The ezMatrix datatype lets you write a name and an identifier for each column. Now what I think would be a real enhancement, would be the possibility to decide the datatype of each column as well as the above.

Let me sketch an example:

Say you have a class named <i>playlist</i>. The class has the attributes <i>title</i> and <i>description</i> in addition to a <i>enhanced_matrix</i> attribute. The <i>enhanced_matrix</i> has in addition to a <i>name</i>-column, an <i>artist<i/>-column of datatype objectrealtion and a <i>song<i/>-column also of datatype objectrealtion.

If the matrix would ony consist of attributes that could be gotten directly from the <i>song</i>, then obviously a normal objectrelations datatype would do the trick.

But here the matrix consists of more than 1 relation pr item.

Another thing is that if you would like to, say make a new datatype that e.g. looked the song up in a external database and returned a link, it would be great to add i directly in the matrix.

Just some thaughts :-)

Felix

 

Publlic Relations Manager
Greater Stavanger
www.greaterstavanger.com

André R.

Friday 05 October 2007 4:27:08 am

Your example couild more easily and more efficiently be replicated like this:

Artist Container class
Album Contaner class (permission restricted to parent: Artist)
Song class (permission restricted to parent: Album)

Playlist class:
Name
......
Object ralations ( allowed classes: Song)

eZ Online Editor 5: http://projects.ez.no/ezoe || eZJSCore (Ajax): http://projects.ez.no/ezjscore || eZ Publish EE http://ez.no/eZPublish/eZ-Publish-Enterprise-Subscription
@: http://twitter.com/andrerom

Felix Laate

Friday 05 October 2007 5:25:03 am

Hi André,

you're right off course, but doesn't it get a bit cumbersome?

One thing to set t up, but the final usage seems to be a bit demanding.

But again, I see your point.

Felix

Publlic Relations Manager
Greater Stavanger
www.greaterstavanger.com

Stefan de Bruijn

Thursday 01 November 2007 4:05:24 pm

Hi Felix,

I wanted something similar for a site i'm developing (but not for a playlist).

To achieve this i didn't enhance the datatype but made an override in /design/admin/override/templates/content/datatype/edit/ezmatrix.tpl.

If i now add 'matrix_related_node_ID' (where ID is the ID of a node) to the identifier of a matrix column in the class definition, i have a pull down menu of all items in the specified node when creating/editing an object.

Example: if you have your artists in node 156, then add a matrix in class playlist, then name the column for artist as follows:
Columns
Matrix column Identifier
Artist artist_matrix_related_node_156

Complete override template:

{* Override for matrix datatype. *}
{* if the class-attribute-identifier contains the string: 'matrix_related_node_',
the matrix will show a list of related obects in the node_id following the
matrix_related_node_
Example:         For the class 'report' a property of type 'matrix' is added.
        The identifier of the first column is: mepper_matrix_related_node_156
        The first clumn of the matrix will now show a pull-downmenu of the objects in node 156.
*}
{default attribute_base=ContentObjectAttribute}
{let matrix=$attribute.content}
{* dbcc *} {def $related_node_ids=array()}

{* Matrix. *}
{section show=$matrix.rows.sequential}

<table class="list" cellspacing="0">
 <tr>
  <th class="tight">&nbsp;</th>
  {section var=ColumnNames loop=$matrix.columns.sequential}
{* dbcc *}  {if $ColumnNames.item.identifier|contains( 'matrix_related_node_' ) }
{* dbcc *}    {def $nameExploded= $ColumnNames.item.identifier|explode('matrix_related_node_' )|reverse }
{* dbcc *}    {set $related_node_ids= $related_node_ids|append( $nameExploded[0]) }  
{* dbcc *}    {if $related_nodes}
{* dbcc *}      {set $related_nodes=$related_nodes|merge(hash($ColumnNames.item.index, fetch( content, node, hash( node_id, $nameExploded[0]) ) ) )}  
{* dbcc *}    {else}
{* dbcc *}      {def $related_nodes=hash($ColumnNames.item.index, fetch( content, node, hash( node_id, $nameExploded[0]) ) ) }  
{* dbcc *}    {/if}
{* dbcc *}  {else}
{* dbcc *}    {set $related_node_ids= $related_node_ids|append( 0 ) }  
{* dbcc *}  {/if}
  <th>{$ColumnNames.item.name}</th>
  {/section}
 </tr>
 {section var=Rows loop=$matrix.rows.sequential sequence=array( bglight, bgdark )}
 <tr class="{$Rows.sequence}">
 
 {* Remove. *}
 <td><input id="ezcoa-{if ne( $attribute_base, 'ContentObjectAttribute' )}{$attribute_base}-{/if}{$attribute.contentclassattribute_id}_{$attribute.contentclass_attribute_identifier}_remove_{$Rows.index}" class="ezcc-{$attribute.object.content_class.identifier} ezcca-{$attribute.object.content_class.identifier}_{$attribute.contentclass_attribute_identifier}" type="checkbox" name="{$attribute_base}_data_matrix_remove_{$attribute.id}[]" value="{$Rows.index}" title="{'Select row for removal.'|i18n( 'design/standard/content/datatype' )}" /></td>
 
 {* Custom columns. *}
 {* dbcc *} {def $column_id=0}
 {section var=Columns loop=$Rows.item.columns}
 <td>      
 {* dbcc *}  {if gt($related_node_ids[$column_id] , 0 )}
 {* dbcc *}    <select id="ezcoa-{if ne( $attribute_base, 'ContentObjectAttribute' )}{$attribute_base}-{/if}{$attribute.contentclassattribute_id}_{$attribute.contentclass_attribute_identifier}_matrix_cell_{$Rows.index}"       class="ezcc-{$attribute.object.content_class.identifier} ezcca-{$attribute.object.content_class.identifier}_{$attribute.contentclass_attribute_identifier}" name="{$attribute_base}_ezmatrix_cell_{$attribute.id}[]">
 {* dbcc *}      {section show=$attribute.contentclass_attribute.is_required|not}
 {* dbcc *}        <option value="" {section show=eq( $attribute.data_int, '' )}selected="selected"{/section}>{'No relation'|i18n( 'design/standard/content/datatype' )}</option>
 {* dbcc *}      {/section}
 {* dbcc *}      {section var=Nodes loop=fetch( content, list, hash( parent_node_id, $related_nodes[$column_id].node_id, sort_by, $related_nodes[$column_id].sort_array ) )}
 {* dbcc *}        <option value="{$Nodes.item.contentobject_id}" {section show=eq( $Columns.item|wash( xhtml ), $Nodes.item.contentobject_id )}selected="selected"{/section}>{$Nodes.item.name|wash}</option>
 {* dbcc *}      {/section}
 {* dbcc *}    </select>
 {* dbcc *}  {else}
      <input id="ezcoa-{if ne( $attribute_base, 'ContentObjectAttribute' )}{$attribute_base}-{/if}{$attribute.contentclassattribute_id}_{$attribute.contentclass_attribute_identifier}_matrix_cell_{$Rows.index}" class="box ezcc-{$attribute.object.content_class.identifier} ezcca-{$attribute.object.content_class.identifier}_{$attribute.contentclass_attribute_identifier}" type="text" name="{$attribute_base}_ezmatrix_cell_{$attribute.id}[]" value="{$Columns.item|wash( xhtml )}" />
 {* dbcc *}  {/if}
 </td>
{* dbcc *}  {set $column_id=|inc($column_id)}
{/section}
 </tr>
{/section}
</table>
{section-else}
<p>{'There are no rows in the matrix.'|i18n( 'design/standard/content/datatype' )}</p>
{/section}
  {* Buttons. *}
{section show=$matrix.rows.sequential}
<input id="ezcoa-{if ne( $attribute_base, 'ContentObjectAttribute' )}{$attribute_base}-{/if}{$attribute.contentclassattribute_id}_{$attribute.contentclass_attribute_identifier}_remove_selected" class="button ezcc-{$attribute.object.content_class.identifier} ezcca-{$attribute.object.content_class.identifier}_{$attribute.contentclass_attribute_identifier}" type="submit" name="CustomActionButton[{$attribute.id}_remove_selected]" value="{'Remove selected'|i18n( 'design/standard/content/datatype' )}" title="{'Remove selected rows from the matrix.'|i18n( 'design/standard/content/datatype' )}" />
{section-else}
<input class="button-disabled" type="submit" name="CustomActionButton[{$attribute.id}_remove_selected]" value="{'Remove selected'|i18n( 'design/standard/content/datatype' )}" disabled="disabled" />
{/section}
&nbsp;&nbsp;
{let row_count=sub( 40, count( $matrix.rows.sequential ) ) index_var=0}
{section show=$row_count|lt( 1 )}
       {set row_count=0}
{/section}
 <select id="ezcoa-{if ne( $attribute_base, 'ContentObjectAttribute' )}{$attribute_base}-{/if}{$attribute.contentclassattribute_id}_{$attribute.contentclass_attribute_identifier}_add_count" class="matrix_cell ezcc-{$attribute.object.content_class.identifier} ezcca-{$attribute.object.content_class.identifier}_{$attribute.contentclass_attribute_identifier}" name="{$attribute_base}_data_matrix_add_count_{$attribute.id}" title="{'Number of rows to add.'|i18n( 'design/standard/content/datatype' )}" >
   <option value="1">1</option>
   {section loop=$row_count}
       {set index_var=$index_var|inc}
       {delimiter modulo=5}
          <option value="{$index_var}">{$index_var}</option>
       {/delimiter}
  {/section}
</select>
 <input id="ezcoa-{if ne( $attribute_base, 'ContentObjectAttribute' )}{$attribute_base}-{/if}{$attribute.contentclassattribute_id}_{$attribute.contentclass_attribute_identifier}_new_row" class="button ezcc-{$attribute.object.content_class.identifier} ezcca-{$attribute.object.content_class.identifier}_{$attribute.contentclass_attribute_identifier}" type="submit" name="CustomActionButton[{$attribute.id}_new_row]" value="{'Add rows'|i18n('design/standard/content/datatype')}" title="{'Add new rows to the matrix.'|i18n( 'design/standard/content/datatype' )}" />
{/let}
   {/let}
{/default}