Yii Framework Forum: Zii For Non-active Records - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Zii For Non-active Records Is it possible to use Zii widgets in 1.1 without active records? Rate Topic: -----

#1 User is offline   ssj 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 5
  • Joined: 04-March 10

Posted 05 March 2010 - 04:49 AM

I would like to use Zii widgets for generic data models represented as objects or arrays without a database table.

In an attempt to serve an array as a data model, I tried extending CDataProvider by creating an ArrayDataProvider component as follows:
class ArrayDataProvider extends CDataProvider
{
    /**
     * The array containing our data. Format is:
     * array (
     *      array('col1'=> 1, 'col2'=> 2, 'col3'=> 3, ...),   // Row 1
     *      array('col1'=> 1, 'col2'=> 2, 'col3'=> 3, ...),   // Row 2
     *      ...
     * );
     */
    public $dataArray;

    public function __construct($dataArray)
    {
        if(empty($dataArray))
            throw new CException('Empty Array given.');
        $this->dataArray = $dataArray;
        $this->setId(mt_rand(0, 10000));     // Without this CDataProvider expects $this->modelClass.
    }

    protected function fetchData()
    {
        return $this->dataArray;
    }

    protected function fetchKeys()
    {
        return empty($this->dataArray[0]) ? null : array_keys($this->dataArray[0]);
    }

    protected function calculateTotalItemCount()
    {
        return count($this->dataArray);
    }
}


In the controller I create some test data and pass it to the view:
    public function actionSearch()
    {
        //$dataProvider = new CActiveDataProvider('Inventory');
        $data = array(
            array('date' => '2010-01-19', 'itemID'=> '2', 'count'=> '5'),
            array('date' => '2010-01-20', 'itemID'=> '2', 'count'=> '5'),
            array('date' => '2010-01-21', 'itemID'=> '2', 'count'=> '5'),
            array('date' => '2010-01-22', 'itemID'=> '2', 'count'=> '5'),
            array('date' => '2010-01-23', 'itemID'=> '2', 'count'=> '5'),
            array('date' => '2010-01-24', 'itemID'=> '2', 'count'=> '5'),
            array('date' => '2010-01-25', 'itemID'=> '2', 'count'=> '5'),
            array('date' => '2010-01-26', 'itemID'=> '2', 'count'=> '5')
        );
        $dataProvider = new ArrayDataProvider($data);
        $this->render('search', array('dataProvider' => $dataProvider));
    }


The view uses CGridView:
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider
));


When I run this however, no data appears. The HTML output does contain column names but no data:
<div id="yw0" class="grid-view">
<div class="keys" style="display:none" title="/yii_app/index.php?r=mod/default/search"><span>date</span><span>itemID</span><span>count</span></div>
<div class="summary">Displaying 1-8 of 8 result(s).</div>
<table class="items">
<thead>
<tr>
</tr>
</thead>
<tbody>

<tr class="odd"></tr>
<tr class="even"></tr>
<tr class="odd"></tr>
<tr class="even"></tr>
<tr class="odd"></tr>
<tr class="even"></tr>
<tr class="odd"></tr>
<tr class="even"></tr>
</tbody>
</table>
<div class="pager"></div></div>


Am I missing something? Currently, it appears that Zii is coupled to active records by using CActiveDataProvider. Is it possible to use Zii widgets for data whose source is not a relational database, such as a web service, LDAP directory service, or a CSV file?


Thanks,
Sunpreet.

(PS: I have seen the CArrayDataProvider extension but it still requires active records.)
0

#2 User is offline   Doug Swain 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 28-December 09

Posted 06 March 2010 - 06:04 PM

I'm also really interested in this idea. I'm going to see if I can work with the idea posted above and get it to work. However, if there's a smarter way to do this or it's already been done, I'd love to hear it!
0

#3 User is offline   Doug Swain 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 28-December 09

Posted 06 March 2010 - 10:11 PM

So, I've made a little progress. Managed to get it to display some information. Using the class above as a skeleton, I modified to override the getData() and getKeys() methods, along with the setData() method. The reason is because since we need to use a separate var for storage in this class, I did not want to assume that CDataProvider::set/getData() would use the fetchKeys() and fetchData() methods. Overriding them seems to allow it to work... partially. Another issue that occurs is that when called zii.widgets.grid.CGridView, one must specify the columns to be displayed too. Code provided below:

class ArrayDataProvider extends CDataProvider {
    /**
     * The array containing our data. Format is:
     * array (
     *      array('col1'=> 1, 'col2'=> 2, 'col3'=> 3, ...),   // Row 1
     *      array('col1'=> 1, 'col2'=> 2, 'col3'=> 3, ...),   // Row 2
     *      ...
     * );
     */

    public $data;

    public function __construct( $dataArray ) {
        $this->setData( array( $dataArray ) );
        $this->setKeys( $this->fetchKeys() );
        $this->setId( mt_rand( 0, 10000 ) );     // Without this CDataProvider expects $this->modelClass.
    }

    protected function fetchData() {
        return $this->data;
    }

    protected function fetchKeys() {
        return empty( $this->data ) ? null : array_keys( $this->data );
    }

    protected function calculateTotalItemCount() {
        return count( $this->data );
    }

    public function getData( $refresh = false ) {
        return $this->fetchData();
    }

    public function getKeys( $refresh = false ) {
        return $this->fetchKeys();
    }

    public function setData( $array ) {
        $this->data = $array;
    }
}


To use:

<?php 
    $dp = new ArrayDataProvider( array( "some data" ) );
    $this->widget('zii.widgets.grid.CGridView', array(
	'dataProvider'=> $dp,
    'columns' => array(
        'col1',
        'col2',
    ),
)); ?>


Granted, specifying the columns is kind of annoying. It might just be a matter of overriding some tagging information. I'll update when I find out.
0

#4 User is offline   romanoza 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 117
  • Joined: 17-April 09
  • Location:Moscow, Russia

Posted 31 March 2010 - 04:12 AM

View PostDoug Swain, on 06 March 2010 - 10:11 PM, said:

Granted, specifying the columns is kind of annoying. It might just be a matter of overriding some tagging information. I'll update when I find out.



There is some mistake:
If you use for data array like this:
      array (
           array('col1'=> 1, 'col2'=> 2, 'col3'=> 3, ...),   // Row 1
           array('col1'=> 1, 'col2'=> 2, 'col3'=> 3, ...),   // Row 2
           ...
      );

you need to use
$this->setData( $dataArray );
, instead of
$this->setData( array( $dataArray ) );

I am not a wizard, i am just learning...
0

#5 User is offline   romanoza 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 117
  • Joined: 17-April 09
  • Location:Moscow, Russia

Posted 31 March 2010 - 05:58 AM

Next question for this, how to use sort for this?
I am not a wizard, i am just learning...
0

#6 User is offline   seniorandre 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 15-February 10

Posted 28 April 2010 - 03:12 AM

I`m using my CPdoDataProvider
This class execute SELECT and put result in CDataProvider. This is allow use SELECT query with CGridView and CListView
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users