#Introduction

In this lab you'll change the detail view to be a tab panel,
then use the `vdom` property to render content. 

#Steps

??Change the details container to be a tab container

Import `src/tab/Container.mjs` and Import `src/component/Base.mjs`.

Change the view to extend tab container. 

Code an items array. Since we'll be needing references to the 
two items, each has a `reference`. Note the `vdom` and padding 
on the first item. You'll be dynamically updating the vdom 
in the `afterSetBusiness()` method.

    items: [{
        module: Component,
        reference: 'view',
        header: {
            text: 'View'
        },
        style: {
            padding: '8px'
        },    
        vdom: {
            cn: [{
                tag : 'h2',
                html: 'foo'
            }]
        }
    }, {
        reference: 'form',
        header: {
            text: 'Edit'
        }
    }]

Save and refresh, and you should see the _foo_ in the detail container.

??Update the field when a record is set

Change the detail view's `afterSetBusiness()` method to update the `vdom`.

    afterSetBusiness(business){
        if (!business) return;
        const view = this.getReference('view');
        view.vdom.cn[0].html = business.title;
        view.update();
    }

<b>Important: </b>The `update()` method tells Neo to apply vdom changes to the DOM.
Any time you change a set of vdom properties you need to run `update()`.

You don't need the first item's `html:'foo'` property any more, so you can 
remove that from the first item's config.

Save, refresh, and confirm that the title is shown as the business is set.

??Use a convenience function

Neo has a convenience method that lets you abstract the vdom a little.

Edit the detail view's first item, and add a `id` to the element showing the title.

    vdom: {
        cn: [{
            tag: 'h2',
            id: 'title'
        }]
    }

The util method lets you find the node using the id (or using a more complex selector).
Use the utility method, replacing the statement referencing the vdom hierarchy.

<pre>
    <s>view.vdom.cn[0].html = business.title;</s>
    Neo.util.VDom.find(view.vdom, 'title').vdom.html = business.title;
</pre>


We'll be updating several vdom nodes, so we can create a more convenient way of 
calling the function.

Code a new class member.

    find = Neo.util.VDom.find

Then use it in the after set method. Here's how that part of the code will look afterwards.

<pre style="color:gray; padding: 8px; border: thin solid lightgray;">
find = Neo.util.VDom.find;

afterSetBusiness(business){
    if (!business) return;
    const view = this.getReference('view');
    this.find(view.vdom, 'title').vdom.html = business.title;
    view.update();
}
</pre>

??Add the thumbnail

The Yelp businesses store doesn't have a field value for the image. Add this
to the main view model _businesses_ store `fields:[]`.

    {
        name: 'imageUrl',
        mapping: 'image_url'
    }

Then back in the details view, update the vdom as follows.

    vdom: {
        tag: 'div',
        cn: [{
            tag: 'h2',
            id: 'title'
        }, {
            tag: 'img',
            id: 'thumbnail',
            style: {
                width: '100%'
            }
        }]
    }

Then modify the `afterSetBusiness()` method to update the element's `src`.

    this.find(view.vdom, 'thumbnail').vdom.src = business.imageUrl;

??Add the address

Depending on how you left the store's `address` config, you may need to change two things.

First, in the businesses store config and make sure the address field is defined like this.

    {
        name: 'address',
        mapping: 'location.display_address'
    }, 

Second, look at the address column in the table and make sure it uses a renderer.

    {
        text: 'Address',
        dataField: 'address',
        renderer: data => data.value.join(', ')
    }

Now edit the details view and a `vdom` child element between the _h2_ and the _img_ to 
be a div that shows the address. 

    vdom: {
        tag: 'div',
        cn: [{
            tag: 'h2',
            id: 'title'
        }, {
            tag: 'div',
            id: 'address',
            cn: []
        }, {
            tag: 'img',
            id: 'thumbnail',
            style: {
                width: '100%' // It would be better to do this via css
            }
        }]
    }

Then modify the `afterSetBusiness()` method to update the _address_ element's
`cn` to be an array of items, one per item in the address array. Each item should
be a _div_ with its `html` set to that part of the address.

Hint: The business record's `address` property is an array, and the `cn` is 
also an array. Maybe there's a easy way to map the address array into a new
array you assign to `cn`? How would you code it? Give it a few minutes
of thought and try it. If you get stuck, that code is given in the next lab step.

??Here's the code for showing the address

Here's one way to code it. How does this compare to your solution?

    this.find(view.vdom, 'address').vdom.cn = business
        .address
        .map(item => ({tag: 'div', html: item}));

??One last point...

The view tab will become more and more complicated as we add content.
It should be refactored into its own view class to isolate that complexity.
We won't bother, but on a project that would be the right thing to do.
