Reputation: 3762
What is the easiest way to display an associative array in a table style?
The array is defined as
$data = [ 'name' => 'bert', 'age' => 42 ];
Input validation is not required. The output should look like a GridView (one key/value per line), but a GridView requires a model.
So I could use DynamicModel, ArrayDataProvider or other Yii2 stuff.
I tried a lot but there should be an easy way to get this done.
Upvotes: 2
Views: 3220
Reputation: 9718
You can do it this way and use the features of DetailView, esp. formating. I enhanced your data a little bit. Just copy the code into a view file to get a quick impression.
$myArray = [
'name' => 'bert',
'age' => 42,
'My email address' => '[email protected]', //no problems with spaces in the key
'html' => '<div style="font-size: 2em">asdf</div>',
];
echo \yii\widgets\DetailView::widget([
'model' => $myArray,
'attributes' => [
'name',
'age',
'My email address:email',
'html',
'html:html',
'html:html:Html with different label',
[
'label' => 'Html self defined',
'attribute' => 'html', // key in model
'format' => 'raw'
]
]
])
Attributes refers to keys of the model.
Look here how you can use attributes.
i.e. you don't know the content and get different kind of data, you can use the DetailView default formatting (what means format is 'text'). In its simplest way it is:
echo \yii\widgets\DetailView::widget([
'model' => $myArray,
'attributes' => array_keys($myArray),
]);
If you want to control the format more or less, use may want to use this, using format 'raw':
echo \yii\widgets\DetailView::widget([
'model' => $myArray,
'attributes' => array_map(function ($key) {
return "$key:raw";
// or build some logic for the right format
// e.g. use '$key:email' if key contains 'email'
}, array_keys($myArray)),
]);
Regarding the requirement in your answer of localizing the labels as well, you could do it this way (with default 'text' format):
echo \yii\widgets\DetailView::widget([
'model' => $myArray,
'attributes' => array_map(function ($key) {
return $key . ':text:' . Yii::t('app', 'label-' . $key);
}, array_keys($myArray)),
]);
However, note some further logic could be needed if the 'label-' . $key
does not exist. Otherwise label-somekey would be shown in the DetailView.
Upvotes: 2
Reputation: 3762
Found a solution that even works with attribute labels being translated, but is it "the easiest"?
In controller file:
class MyDynModel extends \yii\base\DynamicModel {
public function generateAttributeLabel($name) {
return Yii::t('app','label-'.$name);
}
}
class MyController extends Controller {
public function actionShow() {
$data = [ 'name' => 'bert', 'age' => 42 ];
$dataModel = new MyDynModel($data);
return $this->render('myview', ['dataModel'=>$dataModel]);
}
}
In view file "my/myview.php":
echo \yii\widgets\DetailView::widget(['model'=>$dataModel]);
In translation file "messages/en/app.php":
return [
'label-name' => 'Name',
'label-age' => 'Age (in Years)',
];
Upvotes: 0