2

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.

2 Answers 2

2

If you know the content of the array

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.

If the array is dynamic

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.

Sign up to request clarification or add additional context in comments.

6 Comments

This is no real solutions for my problem since the attributes to be displayed have to specified explicitly in DetailView. I need an arbitrary number of Key/Values in the array to be displayed in the view.
@WeSee Updated my answer.
thanks. that leads in the right directiony. in my solution there are labels handled, too. How can this be done in your solution?
@WeSee In which way do/should they get handled?
please see my solution. each array should have a text label ‚label-key‘ which can be handled by Yii::t(...)
|
0

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)',
];

3 Comments

IMHO it would be nice to make a callback function defining the labels. This would avoid subclassing the DynamicModel.
using ArrayDataProvider with gridview would be a simple and easy way to do it.
Ok, but a DetailView requires a model as data source AFAIK. How to bring this together?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.