Another Model Widget Using ListView Item Without view

Ok here’s the problem

Lets say a User has Posts what’s the easiest way to display user/posts cleanly. We want to use Listview

  • Calling the POSTS model from user/posts (controller code in a different place)

  • redirecting to posts/userindex (messy, what if we need to auth User)

  • create a widget and open it from user/posts view file. ( This looks like the best idea so far)

  1. Create a Widget for Posts and put it in posts/views/widgets/userPosts






class UserPosts extends Widget

{


    public $dataProvider;


    public function init()

    {

		

    $query = Posts::find();

								    

    $this->dataProvider = new ActiveDataProvider([

			'query' => $query,

			'pagination' => [

				'pageSize' => 20,

			]

		   ]);


    }


    public function run()

    {


		return ListView::widget([

			'dataProvider' => $this->dataProvider,

			'class' => 'list-group',

			'itemView' => function ($model,$key,$index,$widget) {   # <---- VIEW

							return $this->itemView($model,$key,$index,$widget);

						 },

		]);	

		

		

	}

	


}




  1. Now we have a widget. But usually item view is a view file and pointing back to the parent controller. It might be really confusing searching for a view in posts rather than user and it’s only a few lines of code. So why not we just put it in the widget itself.

  2. Create a internal function




itemView($model,$key,$index,$widget);



This allows us to cleanly write code without disturbing the messy array structure.





private function itemView($model,$key,$index,$widget) {

		

return <<<EOD

		<div class='list-group-item '> 

			<div class="col-xs-4 col-sm-3">{$model->id} </div>;

			<div class="col-xs-4 col-sm-3">{$model->datetimeCreate}</div>

			<div class="col-xs-4 col-sm-3">{$model->total}</div>

		</div>

EOD;


}







Using the <<<EOD allows us to write the entire piece as a string, commenting out the variables. Neat and tidy.

If there are changers to Posts we can look for it in the Widgets folder in view.