Valery  Kulikov
Valery Kulikov

Reputation: 319

How to bind ItemViewModel to the combobox and to the entire form?

I have class User and ItemViewModel for it.

class User(name: String, type: Int, isAdmin: Boolean) {

    var name by property<String>(name)
    fun nameProperty() = getProperty(User::name)

    var type by property<Int>(type)
    fun typeProperty() = getProperty(User::type)

    var isAdmin by property<Boolean>(isAdmin)
    fun isAdminProperty() = getProperty(User::isAdmin)

}

class UserModel : ItemViewModel<User>() {
    val name = bind { item?.nameProperty() }
    val type = bind { item?.typeProperty() }
    val isAdmin = bind { item?.isAdminProperty() }
}

In addition i have View with Form and Controller

class ChooseUserView : View() {

    val ctrl: ChooseUserCtrl by inject()

    override val root = form {

        fieldset("Choose user") {

            field("Name") {
                combobox<User> {
                    items = ctrl.users
                    selectionModel.select(0)
                }
            }

            field("Psw") {
                textfield {
                    whenVisible {
                        ctrl.model.isAdmin
                    }
                }
            }
        }
    }

}

class ChooseUserCtrl : Controller() {

    val view: ChooseUserView by inject()

    val users = FXCollections.observableArrayList<User>()
    val model = UserModel()

    init {
        users.add(User("disp", 1, false))
        users.add(User("admin", 2, true))
    }

}

I'd like to bind user list to form so

  1. In combobox i wanna see names, not addresses like these image
  2. When combobox index is changing i'd like to see bind enabling of textfield("Psw") based on boolean property isAdmin.

Upvotes: 2

Views: 943

Answers (1)

Valery  Kulikov
Valery Kulikov

Reputation: 319

Here is the answer from tornadofx author:


Here you go:

class User() {
    constructor(name: String, type: Int, isAdmin: Boolean): this() {
        this.name = name
        this.type = type
        this.isAdmin = isAdmin
    }

    val nameProperty = SimpleStringProperty()
    var name by nameProperty

    val typeProperty = SimpleIntegerProperty()
    var type by typeProperty

    val isAdminProperty = SimpleBooleanProperty()
    var isAdmin by isAdminProperty

    val passwordProperty = SimpleStringProperty()
    var password by passwordProperty
}

class UserModel(user: User? = null) : ItemViewModel<User>(user) {
    val name = bind(User::nameProperty)
    val type = bind(User::typeProperty)
    val isAdmin = bind(User::isAdminProperty)
    val password = bind(User::passwordProperty)
}


class ChooseUserView : View() {
    val ctrl: ChooseUserCtrl by inject()
    val selectedUser = UserModel(ctrl.users.first())

    override val root = form {
        fieldset("Choose user") {
            field("Name") {
                combobox(selectedUser.itemProperty, ctrl.users) {
                    cellFormat {
                        text = it.name
                    }
                }
            }

            field("Psw") {
                visibleWhen(selectedUser.isAdmin)
                textfield(selectedUser.password)
            }
        }
    }

}

class ChooseUserCtrl : Controller() {
    val users = FXCollections.observableArrayList<User>()

    init {
        users.add(User("disp", 1, false))
        users.add(User("admin", 2, true))
    }
}

Upvotes: 3

Related Questions