Back to Blog Tutorial

Putting It Together: HTML Structure, SQL, and Dvl-epr Components

Wondering how the list, table, and forms from this arc actually come together on one page? See how simple it is.

Aug 2005·8 min read·Post 8 of 8

Module was briefly introduced in post 2 — it's a required XML file, and it forms the non-static part of the page. A module consists of Dvl'epr components, HTML structure for the UI, and SQL where it's needed. Here's a brief overview of how the module file pulls it together.

1 The module, wiring it all together

Every BizCore module follows one fixed skeleton, regardless of what it contains: a <Module> root, a <Layout> with an exact contentcontent-innerpage1page1a nesting, and one firm rule — every form='Y' registration lives inside the modal-overlay's id='bcmodal' container, never mixed in with ordinary page content. Here's that skeleton filled in with the four pieces from this arc:

emxml_modManagerContacts.xml
<Module menu='no' navbar='no'>
    <n>modManagerContacts</n>
    <Scripts></Scripts>
    <Links></Links>
    <NavBar><Attributes><Attribute><n>id</n><Value>navbar</Value></Attribute></Attributes></NavBar>
    <ModuleMenu></ModuleMenu>
    <SubModMenu></SubModMenu>
    <Layout>

        <Element type='inlinecontainer' tag='div'>
            <Attributes class='content' />
            <Element type='inlinecontainer' tag='div'>
                <Attributes class='content-inner' />

                <!-- 1. MODAL OVERLAY — every form='Y' registration MUST live here -->
                <Element type='inlinecontainer' tag='div'>
                    <Attributes class='modal-overlay' id='bcmodaloverlay' />
                    <Element type='ajaxcontainer' tag='div'>
                        <Attributes class='modal modal-lg' id='bcmodal' />

                        <!-- the form from posts 6 & 7 -->
                        <Element type='HTML' name='addcontactform'>
                            <Attributes id='addcontactform' form='Y' modal='Y'
                                        app='formsapp' submod='newcontactform'
                                        responseid='CONTACTADDED' template='tmp1'
                                        cbtmplt='emxml_ScrFPWSforms.xml'
                                        onsuccess="bcModal.close('bcmodaloverlay'); getcontactslist(); toast_message(sArg.successMessage[0].Message);" />
                        </Element>

                    </Element>
                </Element>
                <!-- /modal overlay -->

                <!-- 2. PAGE CONTENT — header, list/table pane, and detail pane from posts 3, 4 & 5 -->
                <Element type='inlinecontainer' tag='div'>
                    <Attributes id='page1' />
                    <Element type='ajaxcontainer' tag='div'>
                        <Attributes id='page1a' />

                        <!-- page header: title, List/Table tabs, Add Contact button -->
                        <Element type='inlinecontainer' tag='div'>
                            <Attributes class='page-header' />
                            <Element type='htmlitem' tag='div'>
                                <Attributes class='page-title' />
                                <Text>Contacts</Text>
                            </Element>
                            <Element type='htmlitem' tag='div'>
                                <Attributes class='view-toggle' />
                                <Element type='htmlitem' tag='span'>
                                    <Attributes class='active' onclick='getcontactslist()' />
                                    <Text>List</Text>
                                </Element>
                                <Element type='htmlitem' tag='span'>
                                    <Attributes onclick='getcontactstable()' />
                                    <Text>Table</Text>
                                </Element>
                            </Element>
                            <Element type='htmlitem' tag='button'>
                                <Attributes class='add-btn' onclick='getaddcontactform()' />
                                <Text>+ Add Contact</Text>
                            </Element>
                        </Element>

                        <Element type='inlinecontainer' tag='div'>
                            <Attributes class='split' />

                            <!-- list/table pane — List renders by default; the Table tab above
                                 re-fetches the SAME container with post 4's file instead -->
                            <Element type='ajaxcontainer' tag='div'>
                                <Attributes id='contactsViewPane' />
                                <Element type='block' name='contactslist' file='emxml_blkContactsList.xml' />
                            </Element>

                            <!-- detail pane, rendered on page load for the first contact -->
                            <Element type='ajaxcontainer' tag='div'>
                                <Attributes id='contactDetailPane' />
                                <Element type='block' name='contactdetail' file='emxml_blkContactDetail.xml' />
                            </Element>

                        </Element>

                        <!-- AJAX refresh registrations — generate getcontactslist() / getcontactstable() / getcontactdetail(id) -->
                        <Element type='HTML' name='contactslist'>
                            <Attributes updatelist='N' form='N' for='contactsViewPane' parm='0'
                                        app='ajaxblocks' submod='getcontactslist' />
                        </Element>
                        <Element type='HTML' name='contactstable'>
                            <Attributes updatelist='N' form='N' for='contactsViewPane' parm='0'
                                        app='ajaxblocks' submod='getcontactstable' />
                        </Element>
                        <Element type='HTML' name='contactdetail'>
                            <Attributes updatelist='N' form='N' for='contactDetailPane' parm='1'
                                        app='ajaxblocks' submod='getcontactdetail' />
                            <Parameters p1='contact_id' />
                        </Element>

                    </Element>
                </Element>

            </Element>
        </Element>

    </Layout>
    <SQL></SQL>
</Module>

As you can see, a module is an XML document like all the others in this arc. The Layout element contains the HTML structure — the tag attribute is where it shows through — and the type attribute is what identifies each Dvl'epr component. SQL gets its own element, same as in earlier posts. Here's a brief rundown of the type values used above:

  • type='inlinecontainer' — has child elements
  • type='ajaxcontainer' — has child elements; the ones without a tag attribute are the ones loaded via AJAX calls
  • type='HTML' — two flavors: as a child of an ajaxcontainer, Dvl'epr generates the JS needed to load it via AJAX; anywhere else, it holds actual HTML

Every form and component this module uses is registered right here, in one place — which means anyone can see exactly what belongs to this page just by scanning the registrations, without digging through rendered output to work it out.

And if you look at the rendered version further down, every piece of HTML you see there traces straight back to something in the module file above.

2 Where this sits in the five-layer chain

From post 2 — every screen on the platform resolves through the same five layers. Here's where each piece from this arc actually lives:

APP
emxml_appManager.xml
The Manager role shell
SITE
emxml_siteManager.xml
Header & nav incl. Contacts
PAGE
emxml_pageContacts.xml
Registers the module below
MODULE
emxml_modManagerContacts.xml
The wiring shown above
BLOCKS
blkContactsList / Table / Detail, ajxInpFcontact
The four files this arc built
3 Rendered live — the whole thing
app.example.com/manager/contacts
S
Sarah Whitfield
Operations Manager
D
David Okonkwo
Procurement Lead
M
Maria Santos
Finance Controller
P
Priya Anand
Customer Service
Sarah Whitfield
Operations Manager · Operations
Emails.whitfield@example.com
Phone+44 1895 700 142
Open Orders3
Customer SinceMar 2023
Click a row, getcontactdetail(id) refreshes the right-hand pane. Click Add Contact, the form from post 6 opens and, on save, getcontactslist() refreshes the left-hand list. Two generated function calls are doing all of the interactivity on this page.

What actually got built across this arc

  • A list (post 3) — dynamiclist, free-form rows, one query.
  • A table (post 4) — dynamiclisttable, the structured alternative, same data.
  • A detail screen (post 5) — block-level SQL, single row, no row template.
  • A form (post 6) — validation, submit wiring, all generated from one registration.
  • A processor (post 7) — an insert, a response, an onsuccess handler with nothing left to hand-wire.
  • This page (post 8) — the same five-layer chain from post 2, holding all of it together.

Every piece here is real, working XML and SQL — not a simplified teaching example bearing only a passing resemblance to what you'd actually ship. This is what a small feature looks like on Dvl'epr, start to finish, in eight posts and considerably less code than it would have taken to hand-write the equivalent AJAX, validation, and DOM wiring yourself.

That's the full loop.

Read, browse, drill in, write back — the same handful of element types cover almost everything a business application needs to do. If you've followed this arc from post 1, you've now seen the platform's actual mechanics, not just the pitch for them.