验证资料/产生测试资料/表格显示 - day05

储存前,验证资料正确性

  • 当使用者输入资料後需要验证资料正确性,并提示给使用者。在VoK要做到这点非常的容易。请打开 Student.kt,加上栏位验证
data class Student(
    override var id: Long? = null,

    @field:NotNull
    @field:Size(min = 2, max = 10)
    var name: String? = null,

    @field:NotNull
    @field:Past
    var birthday: LocalDate? = null,
    var created: Date? = null,

    @field:NotNull
    var gender : Gender? = null,

    @field:NotNull
    @field:DecimalMin(value = "100.0")
    @field:DecimalMax(value = "200.0")
    var height: Double? = null,

    @field:NotNull
    @field:DecimalMin(value = "40.0")
    @field:DecimalMax(value = "150.0")
    var weight: Double? = null,

    var student_id : String? = null
): KEntity<Long>{
    companion object :Dao<Student, Long>(Student::class.java)
}

@Past表示日期需为过去的时间,多半用於生日
*请注意,文字长度不分中英文,若为栏位输入为中文字请特别留意

  • 接着,储存资料前验证资料。请打开 CreateStudentView.kt
            button("Save"){
                onLeftClick {
                    val student = Student()
                    if (binder.validate().isOk && binder.writeBeanIfValid(student)){
                        student.save()
                        StudentView.navigateTo(student.id!!)
                    }
                }
            }

binder.validate() 验证bean是否正确,若有误即在 bind 栏位下方出示错误原因,isOK方法回传验证的 boolan 值

执行结果如下 :
https://ithelp.ithome.com.tw/upload/images/20210920/20138680xNhu2M10DA.png

自订讯息

上图中可看到一个很奇怪的讯息 必须大於 or equal to 100.0,一般人不会这麽说话,我们改一下提示讯息,请打开Student.kt,更改身高提示文字

    @field:NotNull
    @field:DecimalMin(value = "100.0", message = "需至少100公分以上")
    @field:DecimalMax(value = "200.0")
    var height: Double? = null,

栏位提示文字

此例中,身高和体重栏位,使用者可能会对单位感到疑惑,到底是公分还是公尺、公斤还是磅,除了可以在身高/体重後面加上文字提示外,以此为例我们直接在栏位上加上提示文字,请打开 CreateStudentView.kt,在栏位上加上 placehoder

            numberField("身高"){
                bind(binder).bind(Student::height)
                placeholder = "公分"
            }
            numberField("体重"){
                bind(binder).bind(Student::weight)
                placeholder = "公斤"
            }

https://ithelp.ithome.com.tw/upload/images/20210920/20138680nIzLaQGV8G.png
这样就完成了

显示全部学生资料

  • 新增学生资料後,需要一个能够显示所有学生资料的画面,新增 AllStudentsView.kt
package com.example.vok

import com.github.mvysny.karibudsl.v10.*
import com.github.vokorm.dataloader.dataLoader
import com.vaadin.flow.component.button.Button
import com.vaadin.flow.component.grid.Grid
import com.vaadin.flow.router.AfterNavigationEvent
import com.vaadin.flow.router.AfterNavigationObserver
import com.vaadin.flow.router.Route
import eu.vaadinonkotlin.vaadin10.vokdb.setDataLoader
import java.util.*

@Route("students", layout = MainLayout::class)
class AllStudentsView: KComposite(), AfterNavigationObserver {
    private lateinit var grid: Grid<Student>
    private val root = ui {
        verticalLayout {
            setSizeFull()
            h1("学生资料")
            grid = grid {
                isExpand = true
                setDataLoader(Student.dataLoader)
                addColumnFor(Student::id)
                addColumnFor(Student::name)
                addColumnFor(Student::gender).
                addColumnFor(Student::birthday)
                addColumnFor(Student::height)
                addColumnFor(Student::weight).
            }
        }
    }

    override fun afterNavigation(event: AfterNavigationEvent?) {
        grid.refresh()
    }
}

执行後开启 http://localhost:8080/students 可显示所有学生资料。这里使用 Grid 元件显示,Grid 支援 paging、lazy-loading,还能够排序和过滤资料,是个功能强大的元件。

产生测试资料

由於范例使用的 H2 database,重新启动资料就消失了,确实有点困扰。这里我们使用 JavaFaker 来产生测试资料。 请在 web/build.gradle.kts 加入依赖

dependencies {
    implementation("com.github.javafaker:javafaker:1.0.2")
}
  • 开启档案 AllStucentsView.kt,在 grid 上方加个 button
    button("Generate testing data"){
        onLeftClick {
            val faker = Faker(Locale("zh-TW"))
            (1..20).forEach { i ->
                Student(
                    name = faker.name().fullName(),
                    birthday = LocalDateToDateConverter().convertToPresentation(faker.date().birthday(20, 21), null), 
                    gender = Gender.values().random(),
                    height = faker.number().randomDouble(1, 155, 190),
                    weight = faker.number().randomDouble(1, 45, 80)
                ).save()
            }
            grid.refresh()
        }
    }

第3行,初始化Faker时指定语言,台湾使用之语言代码为 zh-TW
第4行,产生20笔测试资料
第7行,使用Vaadin提供的方法 LocalDateToDateConverter().convertToPresentation() 做资料型态转换,将faker 产生的 Date 转换成 Student 需要的 LocalDate
第8行,性别直接取 Gender enum 随机值
第9~10行,给予适当区间取小数一位的随机值
第11行,最後别忘了储存Student Entity
第13行,待资料产生後,更新grid

资料表格改标题文字

最後,再给资料加上标题。开启 AllStucentsView.kt,加上setHeader() method chaining,最後会回传加上标题文字的column。

                addColumnFor(Student::id).setHeader("序号")
                addColumnFor(Student::name).setHeader("姓名")
                addColumnFor(Student::gender).setHeader("性别")
                addColumnFor(Student::birthday).setHeader("生日")
                addColumnFor(Student::height).setHeader("身高")
                addColumnFor(Student::weight).setHeader("体重")

执行结果

执行结果如下。画面中可看到标题旁有上下三角图符号,点选符号可用该列资料排序。下图采身高由高而低排序:
https://ithelp.ithome.com.tw/upload/images/20210920/20138680DNqD2djuVM.png

本日范例程序已上传 Github


<<:  Day 19:非 GUI 类工具之 juce::String

>>:  Vue.js 从零开始:箭头函式

Day12:今天来谈一下Microsoft-Defender-for-Endpoint的设定及管理自动化

在Microsoft Defender for Endpoint中有提供自动化调查和补救功能。 自动...

大共享时代系列_008_共享居家照护

照顾...是谁的工作? 当我病痛衰弱时,谁可以照顾我? 家人?朋友?爱人? 但照顾者不需要休息跟喘息...

04 - Uptime - 掌握系统的生命徵象 (2/4) - 使用 Heartbeat 收集系统生命徵象数据

Uptime - 掌握系统的生命徵象 系列文章 (1/4) - 我们要观测的生命徵象是什麽? (2/...

Day-27 图论(Graph)基本概念

图(Graph)的表示 图(Graph) 图,是一种记录节点和节点之间关连的表示法。对於图,表示是由...

设计安全考虑最少

-如何将 Cisco IOS 复制到 TFTP 服务器 TFTP 以其不需要身份验证和访问控制的简...