aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Jaros <rjaros@finn.pl>2018-08-21 16:07:28 +0200
committerRobert Jaros <rjaros@finn.pl>2018-08-21 16:07:28 +0200
commit63691ce4536cbff24330e6d268343e343ee806fa (patch)
treecfa9b6e8c3a594a7756034bfd403ceb9311c72d7
parent561a9d5fdc0f8be67703e8d594148cda5d74f754 (diff)
downloadkvision-63691ce4536cbff24330e6d268343e343ee806fa.tar.gz
kvision-63691ce4536cbff24330e6d268343e343ee806fa.tar.bz2
kvision-63691ce4536cbff24330e6d268343e343ee806fa.zip
Internationalization support for built-in components.
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/KVManager.kt113
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/Form.kt41
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt29
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt3
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt3
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt3
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt3
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/i18n/I18n.kt2
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/Root.kt5
9 files changed, 168 insertions, 34 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt
index b762bc01..b0e9ea6f 100644
--- a/src/main/kotlin/pl/treksoft/kvision/KVManager.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/KVManager.kt
@@ -31,8 +31,11 @@ import com.github.snabbdom.propsModule
import com.github.snabbdom.styleModule
import org.w3c.dom.asList
import pl.treksoft.kvision.core.Component
+import pl.treksoft.kvision.i18n.I18n
import pl.treksoft.kvision.utils.isIE11
+import pl.treksoft.kvision.utils.obj
import kotlin.browser.document
+import kotlin.browser.window
import kotlin.dom.clear
/**
@@ -76,9 +79,6 @@ internal object KVManager {
}
private val bootstrapSelect = try {
require("bootstrap-select/dist/js/bootstrap-select.min.js")
- } catch (e: Throwable) {
- }
- private val bootstrapSelectI18n = try {
require("./js/bootstrap-select-i18n.min.js")
} catch (e: Throwable) {
}
@@ -88,6 +88,17 @@ internal object KVManager {
}
private val bootstrapSelectAjax = try {
require("ajax-bootstrap-select/dist/js/ajax-bootstrap-select.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.de-DE.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.es-ES.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.fr-FR.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.it-IT.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ja-JP.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ko-KR.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.nl-NL.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pl-PL.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.pt-BR.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.ru-RU.min.js")
+ require("../../js/js/locales/ajax-bootstrap-select/ajax-bootstrap-select.tr-TR.min.js")
} catch (e: Throwable) {
}
private val trixCss = try {
@@ -95,7 +106,26 @@ internal object KVManager {
} catch (e: Throwable) {
}
private val trix = try {
- require("trix")
+ val trix = require("trix")
+ window.asDynamic().Trix = trix
+ trix.config.languages = obj {}
+ trix.config.languages["en"] = obj {}
+ for (key in js("Object").keys(trix.config.lang)) {
+ trix.config.languages["en"][key] = trix.config.lang[key]
+ }
+ val orig = trix.config.toolbar.getDefaultHTML
+ trix.config.toolbar.getDefaultHTML = {
+ val config = if (trix.config.languages[I18n.language] != undefined) {
+ trix.config.languages[I18n.language]
+ } else {
+ trix.config.languages["en"]
+ }
+ for (key in js("Object").keys(trix.config.lang)) {
+ trix.config.lang[key] = config[key]
+ }
+ orig()
+ }
+ require("../../js/js/locales/trix/trix.pl.js")
} catch (e: Throwable) {
}
private val bootstrapDateTimePickerCss = try {
@@ -104,6 +134,45 @@ internal object KVManager {
}
private val bootstrapDateTimePicker = try {
require("bootstrap-datetime-picker/js/bootstrap-datetimepicker.min.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ar.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.az.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bg.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.bn.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ca.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.cs.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.da.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.de.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ee.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.el.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.es.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fi.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.fr.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.he.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hr.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hu.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.hy.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.id.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.is.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.it.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ja.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ko.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lt.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.lv.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.nl.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.no.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pl.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.pt.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ro.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.rs.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ru.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sk.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sl.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.sv.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.th.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.tr.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.ua.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.uk.js")
+ require("../../js/js/locales/bootstrap-datetime-picker/bootstrap-datetimepicker.zh.js")
} catch (e: Throwable) {
}
private val bootstrapTouchspinCss = try {
@@ -128,6 +197,42 @@ internal object KVManager {
}
private val bootstrapFileinput = try {
require("bootstrap-fileinput")
+ require("../../js/js/locales/bootstrap-fileinput/ar.js")
+ require("../../js/js/locales/bootstrap-fileinput/az.js")
+ require("../../js/js/locales/bootstrap-fileinput/bg.js")
+ require("../../js/js/locales/bootstrap-fileinput/ca.js")
+ require("../../js/js/locales/bootstrap-fileinput/cr.js")
+ require("../../js/js/locales/bootstrap-fileinput/cs.js")
+ require("../../js/js/locales/bootstrap-fileinput/da.js")
+ require("../../js/js/locales/bootstrap-fileinput/de.js")
+ require("../../js/js/locales/bootstrap-fileinput/el.js")
+ require("../../js/js/locales/bootstrap-fileinput/es.js")
+ require("../../js/js/locales/bootstrap-fileinput/et.js")
+ require("../../js/js/locales/bootstrap-fileinput/fa.js")
+ require("../../js/js/locales/bootstrap-fileinput/fi.js")
+ require("../../js/js/locales/bootstrap-fileinput/fr.js")
+ require("../../js/js/locales/bootstrap-fileinput/gl.js")
+ require("../../js/js/locales/bootstrap-fileinput/id.js")
+ require("../../js/js/locales/bootstrap-fileinput/it.js")
+ require("../../js/js/locales/bootstrap-fileinput/ja.js")
+ require("../../js/js/locales/bootstrap-fileinput/ka.js")
+ require("../../js/js/locales/bootstrap-fileinput/ko.js")
+ require("../../js/js/locales/bootstrap-fileinput/kz.js")
+ require("../../js/js/locales/bootstrap-fileinput/lt.js")
+ require("../../js/js/locales/bootstrap-fileinput/nl.js")
+ require("../../js/js/locales/bootstrap-fileinput/no.js")
+ require("../../js/js/locales/bootstrap-fileinput/pl.js")
+ require("../../js/js/locales/bootstrap-fileinput/pt.js")
+ require("../../js/js/locales/bootstrap-fileinput/ro.js")
+ require("../../js/js/locales/bootstrap-fileinput/ru.js")
+ require("../../js/js/locales/bootstrap-fileinput/sk.js")
+ require("../../js/js/locales/bootstrap-fileinput/sl.js")
+ require("../../js/js/locales/bootstrap-fileinput/sv.js")
+ require("../../js/js/locales/bootstrap-fileinput/th.js")
+ require("../../js/js/locales/bootstrap-fileinput/tr.js")
+ require("../../js/js/locales/bootstrap-fileinput/uk.js")
+ require("../../js/js/locales/bootstrap-fileinput/vi.js")
+ require("../../js/js/locales/bootstrap-fileinput/zh.js")
} catch (e: Throwable) {
}
private val bootstrapFileinputFa = try {
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt
index b1e08606..7d429c2e 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/Form.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/Form.kt
@@ -26,6 +26,7 @@ import kotlinx.serialization.Mapper
import kotlinx.serialization.json.JSON
import kotlinx.serialization.serializer
import pl.treksoft.kvision.form.upload.Upload
+import pl.treksoft.kvision.i18n.I18n.trans
import pl.treksoft.kvision.types.KDate
import pl.treksoft.kvision.types.KFile
import pl.treksoft.kvision.utils.getContent
@@ -37,6 +38,7 @@ import kotlin.reflect.KProperty1
*/
internal data class FieldParams<in F : FormControl>(
val required: Boolean = false,
+ val requiredMessage: String? = null,
val validatorMessage: ((F) -> String?)? = null,
val validator: ((F) -> Boolean?)? = null
)
@@ -51,7 +53,9 @@ private class FormMapWrapper<out V>(private val map: Map<String, V>) : Map<Strin
override fun toString(): String = map.toString()
override val size: Int get() = map.size
override fun isEmpty(): Boolean = map.isEmpty()
- override fun containsKey(key: String): Boolean = if (key.indexOf('.') != -1) map.containsKey(key) else !(map.containsKey("$key.time") || map.containsKey("$key.size"))
+ override fun containsKey(key: String): Boolean =
+ if (key.indexOf('.') != -1) map.containsKey(key) else !(map.containsKey("$key.time") || map.containsKey("$key.size"))
+
override fun containsValue(value: @UnsafeVariance V): Boolean = map.containsValue(value)
override fun get(key: String): V? = map[key]
override val keys: Set<String> get() = map.keys
@@ -105,12 +109,12 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
}
internal fun <C : FormControl> addInternal(
- key: KProperty1<K, *>, control: C, required: Boolean = false,
+ key: KProperty1<K, *>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): Form<K> {
this.fields[key.name] = control
- this.fieldsParams[key.name] = FieldParams(required, validatorMessage, validator)
+ this.fieldsParams[key.name] = FieldParams(required, requiredMessage, validatorMessage, validator)
return this
}
@@ -119,16 +123,17 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
* @param key key identifier of the control
* @param control the string form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form
*/
fun <C : StringFormControl> add(
- key: KProperty1<K, String?>, control: C, required: Boolean = false,
+ key: KProperty1<K, String?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): Form<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -136,16 +141,17 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
* @param key key identifier of the control
* @param control the boolean form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form
*/
fun <C : BoolFormControl> add(
- key: KProperty1<K, Boolean?>, control: C, required: Boolean = false,
+ key: KProperty1<K, Boolean?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): Form<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -153,16 +159,17 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
* @param key key identifier of the control
* @param control the number form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form
*/
fun <C : NumberFormControl> add(
- key: KProperty1<K, Number?>, control: C, required: Boolean = false,
+ key: KProperty1<K, Number?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): Form<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -170,16 +177,17 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
* @param key key identifier of the control
* @param control the date form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form
*/
fun <C : KDateFormControl> add(
- key: KProperty1<K, KDate?>, control: C, required: Boolean = false,
+ key: KProperty1<K, KDate?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): Form<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -187,16 +195,17 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
* @param key key identifier of the control
* @param control the files form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form
*/
fun <C : KFilesFormControl> add(
- key: KProperty1<K, List<KFile>?>, control: C, required: Boolean = false,
+ key: KProperty1<K, List<KFile>?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): Form<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -300,12 +309,12 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
val required = fieldsParams?.required ?: false
val requiredError = control.getValue() == null && required
if (requiredError) {
- control.validatorError = "Value is required"
+ control.validatorError = trans(fieldsParams?.requiredMessage) ?: "Value is required"
true
} else {
val validatorPassed = fieldsParams?.validator?.invoke(control) ?: true
control.validatorError = if (!validatorPassed) {
- fieldsParams?.validatorMessage?.invoke(control) ?: "Invalid value"
+ trans(fieldsParams?.validatorMessage?.invoke(control)) ?: "Invalid value"
} else {
null
}
@@ -315,7 +324,7 @@ class Form<K : Any>(private val panel: FormPanel<K>? = null, private val seriali
}.find { it }
val validatorPassed = validator?.invoke(this) ?: true
panel?.validatorError = if (!validatorPassed) {
- validatorMessage?.invoke(this) ?: "Invalid form data"
+ trans(validatorMessage?.invoke(this)) ?: "Invalid form data"
} else {
null
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt
index 88aed36b..a013c076 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/FormPanel.kt
@@ -203,7 +203,7 @@ open class FormPanel<K : Any>(
}
protected fun <C : FormControl> addInternal(
- key: KProperty1<K, *>, control: C, required: Boolean = false,
+ key: KProperty1<K, *>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): FormPanel<K> {
@@ -219,7 +219,7 @@ open class FormPanel<K : Any>(
}
}
super.add(control)
- form.addInternal(key, control, required, validatorMessage, validator)
+ form.addInternal(key, control, required, requiredMessage, validatorMessage, validator)
return this
}
@@ -228,16 +228,17 @@ open class FormPanel<K : Any>(
* @param key key identifier of the control
* @param control the string form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form panel
*/
open fun <C : StringFormControl> add(
- key: KProperty1<K, String?>, control: C, required: Boolean = false,
+ key: KProperty1<K, String?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): FormPanel<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -245,16 +246,17 @@ open class FormPanel<K : Any>(
* @param key key identifier of the control
* @param control the boolean form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form panel
*/
open fun <C : BoolFormControl> add(
- key: KProperty1<K, Boolean?>, control: C, required: Boolean = false,
+ key: KProperty1<K, Boolean?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): FormPanel<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -262,16 +264,17 @@ open class FormPanel<K : Any>(
* @param key key identifier of the control
* @param control the number form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form panel
*/
open fun <C : NumberFormControl> add(
- key: KProperty1<K, Number?>, control: C, required: Boolean = false,
+ key: KProperty1<K, Number?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): FormPanel<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -279,16 +282,17 @@ open class FormPanel<K : Any>(
* @param key key identifier of the control
* @param control the date form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form panel
*/
open fun <C : KDateFormControl> add(
- key: KProperty1<K, KDate?>, control: C, required: Boolean = false,
+ key: KProperty1<K, KDate?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): FormPanel<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
@@ -296,16 +300,17 @@ open class FormPanel<K : Any>(
* @param key key identifier of the control
* @param control the files form control
* @param required determines if the control is required
+ * @param requiredMessage optional required validation message
* @param validatorMessage optional function returning validation message
* @param validator optional validation function
* @return current form panel
*/
open fun <C : KFilesFormControl> add(
- key: KProperty1<K, List<KFile>?>, control: C, required: Boolean = false,
+ key: KProperty1<K, List<KFile>?>, control: C, required: Boolean = false, requiredMessage: String? = null,
validatorMessage: ((C) -> String?)? = null,
validator: ((C) -> Boolean?)? = null
): FormPanel<K> {
- return addInternal(key, control, required, validatorMessage, validator)
+ return addInternal(key, control, required, requiredMessage, validatorMessage, validator)
}
/**
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt
index 09d2fcdb..d802a111 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/select/AjaxOptions.kt
@@ -24,6 +24,7 @@ package pl.treksoft.kvision.form.select
import pl.treksoft.jquery.JQueryXHR
import pl.treksoft.kvision.KVManager.AJAX_REQUEST_DELAY
import pl.treksoft.kvision.KVManager.KVNULL
+import pl.treksoft.kvision.i18n.I18n
import pl.treksoft.kvision.utils.obj
/**
@@ -104,6 +105,7 @@ fun AjaxOptions.toJs(emptyOption: Boolean): dynamic {
processedData
}
}
+ val language = I18n.language
return obj {
this.ajax = obj {
this.url = url
@@ -121,5 +123,6 @@ fun AjaxOptions.toJs(emptyOption: Boolean): dynamic {
this.preserveSelected = false
this.requestDelay = requestDelay
this.restoreOnError = restoreOnError
+ this.langCode = language
}
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt
index 88cb3b86..c5d9a556 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/text/RichTextInput.kt
@@ -84,8 +84,9 @@ open class RichTextInput(value: String? = null, classes: Set<String> = setOf())
trixId = this.getElementJQuery()?.attr("trix-id")
if (trixId != null) {
value?.let {
- if (this.getElement().asDynamic().editor != undefined)
+ if (this.getElement().asDynamic().editor != undefined) {
this.getElement().asDynamic().editor.loadHTML(it)
+ }
}
}
})
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt
index 6ce4d0c3..1df8a082 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt
@@ -28,6 +28,7 @@ import pl.treksoft.kvision.core.StringPair
import pl.treksoft.kvision.core.Widget
import pl.treksoft.kvision.form.FormInput
import pl.treksoft.kvision.form.InputSize
+import pl.treksoft.kvision.i18n.I18n
import pl.treksoft.kvision.types.KDate
import pl.treksoft.kvision.types.toJS
import pl.treksoft.kvision.types.toKDateF
@@ -226,6 +227,7 @@ open class DateTimeInput(
val minView = if (format.contains("HH") || format.contains("mm")) 0 else 2
val maxView = if (format.contains("YY") || format.contains("M") || format.contains("D")) MAX_VIEW else 1
val startView = if (maxView < 2) maxView else 2
+ val language = I18n.language
getElementJQueryD()?.datetimepicker(obj {
this.format = datePickerFormat
this.startView = startView
@@ -239,6 +241,7 @@ open class DateTimeInput(
this.showMeridian = showMeridian
this.daysOfWeekDisabled = daysOfWeekDisabled
this.autoclose = true
+ this.language = language
})
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt
index 90dd21c4..0f8aaf4a 100644
--- a/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/form/upload/UploadInput.kt
@@ -29,6 +29,7 @@ import pl.treksoft.kvision.core.StringPair
import pl.treksoft.kvision.core.Widget
import pl.treksoft.kvision.form.FormInput
import pl.treksoft.kvision.form.InputSize
+import pl.treksoft.kvision.i18n.I18n
import pl.treksoft.kvision.types.KFile
import pl.treksoft.kvision.utils.obj
@@ -279,6 +280,7 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla
}
private fun getSettingsObj(): dynamic {
+ val language = I18n.language
return obj {
this.uploadUrl = uploadUrl
this.uploadExtraData = uploadExtraData ?: undefined
@@ -295,6 +297,7 @@ open class UploadInput(uploadUrl: String? = null, multiple: Boolean = false, cla
this.allowedFileTypes = allowedFileTypes?.toTypedArray()
this.allowedFileExtensions = allowedFileExtensions?.toTypedArray()
this.dropZoneEnabled = dropZoneEnabled
+ this.language = language
}
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/i18n/I18n.kt b/src/main/kotlin/pl/treksoft/kvision/i18n/I18n.kt
index 6d0b0bfa..9d2ee1db 100644
--- a/src/main/kotlin/pl/treksoft/kvision/i18n/I18n.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/i18n/I18n.kt
@@ -48,7 +48,7 @@ object I18n {
var language = defaultLanguage
set(value) {
field = value
- Root.roots.forEach { it.reRender() }
+ Root.roots.forEach { it.restart() }
}
private val cache = mutableMapOf<String, Jed>()
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
index fece65e2..24eff10f 100644
--- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
@@ -106,6 +106,11 @@ class Root(id: String, private val fixed: Boolean = false, init: (Root.() -> Uni
return this
}
+ internal fun restart() {
+ rootVnode = KVManager.patch(rootVnode, h("div"))
+ rootVnode = KVManager.patch(rootVnode, renderVNode())
+ }
+
override fun getRoot(): Root? {
return this
}