Extending the question asked a few days ago, how can I handle 1:[1,0]
relationships?
Assume I have a master table with some information and a details table
that may or may not
have optional info, but at most one row.

In the minimal example below I can teach my form
to display this optional info, but by default, if I enter new optional
info, and move
forward and back through the masters dataset, the entered information is lost.

I added a onValueChanged handler which creates a new details row if
there is none, but
this seems not practical for two reason. First, if I enter a new
optional info and
*directly* move to the next master's row (by hitting next) and then back, the
information is still lost. Second, in my real form I have several data
controls for
the "details" table and it seems too tedious to add a event handler
for each of these
controls.

Do you have another suggestion on how to handle this situation?

Kind regards,
Karsten.

---------
#!/usr/bin/env python
# -*- coding: iso8859_15 -*-

"""Example how to model a 1:[0,1] relationship."""

version = dict(version="0.1", revision="1", stage="development")

import dabo
import dabo.dEvents as ev
dabo.ui.loadUI("wx")
import datetime
from dabo.dLocalize import _

class BizMaster(dabo.biz.dBizobj):
    def initProperties(self):
        self.Caption = _("BizObj for table 'master'")
        self.DataSource = "master"
        self.KeyField = "id"
        self.AutoPopulatePK = True
        self.DataStructure = (
                ("id", "I", True, "master", "id"),
                ("info", "C", False, "master", "info"),
        )
        self.DefaultValues = {}
        self.addFrom("master")
        self.addField("id")
        self.addField("info")

class BizDetails(dabo.biz.dBizobj):
    def initProperties(self):
        self.Caption = _("BizObj for table 'details'")
        self.DataSource = "details"
        self.KeyField = "id"
        self.AutoPopulatePK = True
        self.DataStructure = (
                ("id", "I", True, "details", "id"),
                ("master_fk", "I", False, "details", "master_fk"),
                ("optional_info", "C", False, "details", "optional_info"),
        )
        self.DefaultValues = {}
        self.addFrom("details")
        self.addField("id")
        self.addField("optional_info")
        self.addField("master_fk")

class FrmOneToNullOne(dabo.ui.dForm):
    def afterInit(self):
        """This is the place to insert all data controls into the form."""

        self.Sizer = dabo.ui.dSizer("v")

        # put a panel in the back. This enables Tab/Shift-Tab functionality
        # between the controls.
        panel = dabo.ui.dPanel(self)
        self.Sizer.append1x(panel)
        panel.Sizer = dabo.ui.dSizer("v")

        # display the id
        ui = self.addObject(dabo.ui.dTextBox, RegID="tbId",
DataSource="master", DataField="id", Enabled=False)
        panel.Sizer.append(ui, halign="Center", border=5)

        # info textbox
        ui = dabo.ui.dTextBox(panel, RegID="tbInfo",
DataSource="master", DataField="info")
        panel.Sizer.append(ui, halign="Center", border=5)

        # optional info textbox
        ui = dabo.ui.dTextBox(panel, RegID="tbOptionalInfo",
DataSource="details", DataField="optional_info")
        panel.Sizer.append(ui, halign="Center", border=5)

        # some buttons to navigate
        hsz = dabo.ui.dSizer("h")
        ui = panel.addObject(dabo.ui.dButton, Caption=_("Prev"))
        ui.bindEvent(ev.Hit, lambda ev: self.prior())
        hsz.append(ui)
        ui = panel.addObject(dabo.ui.dButton, Caption=_("Next"))
        ui.bindEvent(ev.Hit, lambda ev: self.next())
        hsz.append(ui)
        ui = panel.addObject(dabo.ui.dButton, Caption=_("New"))
        ui.bindEvent(ev.Hit, lambda ev: self.new())
        hsz.append(ui)
        ui = panel.addObject(dabo.ui.dButton, Caption=_("Save"))
        ui.bindEvent(ev.Hit, lambda ev: self.save())
        hsz.append(ui)
        ui = panel.addObject(dabo.ui.dButton, Caption=_("Delete"))
        ui.bindEvent(ev.Hit, lambda ev: self.delete())
        hsz.append(ui)
        ui = panel.addObject(dabo.ui.dButton, Caption=_("Requery"))
        ui.bindEvent(ev.Hit, lambda ev: self.requery())
        hsz.append(ui)
        panel.Sizer.append(hsz, halign="Center", border=5)

        self.fitToSizer()

    def createBizobjs(self):
        """This is the place to create all bizobjs for the application."""
        conn = self.Application.getConnectionByName("myconn")
        master = BizMaster(conn)
        details = BizDetails(conn)

        # link details to master
        details.LinkField = "master_fk"
        details.NewRecordOnNewParent = False
        details.FillLinkFromParent = True
        master.NewChildOnNew = False
        master.addChild(details)

        self.addBizobj(master) # the first added bizobj is the PrimaryBizobj
        self.addBizobj(details)

    def afterInitAll(self):
        self.requery()

    def onValueChanged_tbOptionalInfo(self, evt):
        print "onValueChanged_tbOptionalInfo"
        val = self.tbOptionalInfo.Value
        print "   Value=", val
        biz = self.getBizobj("details")
        if biz.RowCount == 0:
            biz.new()
            biz.setFieldVal("optional_info", val)
        print "   getDataSet=", biz.getDataSet()
        self.update()

if __name__ == "__main__":
    from dabo.dApp import dApp
    from dabo.dLocalize import _
    from dabo.db.dConnectInfo import dConnectInfo

    app = dApp()

    # Manages how preferences are saved
    app.BasePrefKey = "dabo.app.minimal.FrmOneToNullOne"
    dabo.settings.MDI = False
    app.MainFormClass = FrmOneToNullOne

    ## The following information can be used in various places in your app:
    app.setAppInfo("appShortName", _("FrmOneToNullOne Form"))
    app.setAppInfo("appName", _("Dabo Minimal Example: FrmOneToNullOne"))
    app.setAppInfo("appDescription", _("Dabo demo program
demonstrating how to handle 1:[1,0] relationships."))

    ## Set appVersion and appRevision from __version__.py:
    app.setAppInfo("appVersion", version["version"])
    app.setAppInfo("appRevision", version["revision"])

    ## Connections:
    if version["stage"] == "development":
        dbFileName = ":memory:"
        connInfo = dConnectInfo(Name="myconn", DbType="SQLite",
Database=dbFileName)
        app.addConnectInfo(connInfo)

    ## create database on the fly:
    # this is uncommon for real applications, as you will usually connect to
    # a populated database.
    conn = app.getConnectionByName("myconn")
    curs= conn.getDaboCursor()
    # create tables and testdata
    scriptList = """
        create table master (
            id integer primary key autoincrement not null,
            info text
        );
        create table details (
            id integer primary key autoincrement not null,
            master_fk integer,
            optional_info text
        );
        insert into master (id, info) values (1, 'spring');
        insert into master (id, info) values (2, 'summer');
        insert into master (id, info) values (3, 'autumn');
        insert into details (id, master_fk, optional_info) values (1,
3, 'rainy');
        insert into details (id, master_fk, optional_info) values (2,
2, 'sunny');
        """.split(";")
    for stmt in scriptList:
        if stmt.strip():
            curs.execute(stmt)
            dabo.infoLog.write(stmt)

    ## start the app
    app.setup()
    app.start()


_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users
Searchable Archives: http://leafe.com/archives/search/dabo-users
This message: http://leafe.com/archives/byMID/[EMAIL PROTECTED]

Reply via email to