2021-09-07 17:36:50 +03:00
|
|
|
package rui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2022-08-31 22:22:19 +03:00
|
|
|
// DropDownEvent is the constant for "drop-down-event" property tag.
|
2024-09-18 13:50:06 +03:00
|
|
|
//
|
|
|
|
// Used by `DropDownList`.
|
|
|
|
// Occur when a list item becomes selected.
|
|
|
|
//
|
|
|
|
// General listener format:
|
|
|
|
// `func(list rui.DropDownList, index int)`.
|
|
|
|
//
|
|
|
|
// where:
|
|
|
|
// list - Interface of a drop down list which generated this event,
|
|
|
|
// index - Index of a newly selected item.
|
|
|
|
//
|
|
|
|
// Allowed listener formats:
|
2021-09-07 17:36:50 +03:00
|
|
|
const DropDownEvent = "drop-down-event"
|
|
|
|
|
2024-09-12 14:05:11 +03:00
|
|
|
// DropDownList represent a DropDownList view
|
2021-09-07 17:36:50 +03:00
|
|
|
type DropDownList interface {
|
|
|
|
View
|
|
|
|
getItems() []string
|
|
|
|
}
|
|
|
|
|
|
|
|
type dropDownListData struct {
|
|
|
|
viewData
|
|
|
|
items []string
|
2022-07-26 18:36:00 +03:00
|
|
|
disabledItems []any
|
2024-09-03 19:55:14 +03:00
|
|
|
itemSeparators []any
|
2023-04-23 18:07:01 +03:00
|
|
|
dropDownListener []func(DropDownList, int, int)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewDropDownList create new DropDownList object and return it
|
|
|
|
func NewDropDownList(session Session, params Params) DropDownList {
|
|
|
|
view := new(dropDownListData)
|
2022-09-01 11:04:50 +03:00
|
|
|
view.init(session)
|
2021-09-07 17:36:50 +03:00
|
|
|
setInitParams(view, params)
|
|
|
|
return view
|
|
|
|
}
|
|
|
|
|
|
|
|
func newDropDownList(session Session) View {
|
|
|
|
return NewDropDownList(session, nil)
|
|
|
|
}
|
|
|
|
|
2022-09-01 11:04:50 +03:00
|
|
|
func (list *dropDownListData) init(session Session) {
|
|
|
|
list.viewData.init(session)
|
2021-09-07 17:36:50 +03:00
|
|
|
list.tag = "DropDownList"
|
2024-04-23 18:24:51 +03:00
|
|
|
list.hasHtmlDisabled = true
|
2021-09-07 17:36:50 +03:00
|
|
|
list.items = []string{}
|
2022-07-26 18:36:00 +03:00
|
|
|
list.disabledItems = []any{}
|
2024-09-03 19:55:14 +03:00
|
|
|
list.itemSeparators = []any{}
|
2023-04-23 18:07:01 +03:00
|
|
|
list.dropDownListener = []func(DropDownList, int, int){}
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2022-05-22 12:54:02 +03:00
|
|
|
func (list *dropDownListData) String() string {
|
2024-05-02 15:07:57 +03:00
|
|
|
return getViewString(list, nil)
|
2022-05-22 12:54:02 +03:00
|
|
|
}
|
|
|
|
|
2022-01-15 01:20:04 +03:00
|
|
|
func (list *dropDownListData) Focusable() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
func (list *dropDownListData) Remove(tag string) {
|
|
|
|
list.remove(strings.ToLower(tag))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (list *dropDownListData) remove(tag string) {
|
|
|
|
switch tag {
|
|
|
|
case Items:
|
|
|
|
if len(list.items) > 0 {
|
|
|
|
list.items = []string{}
|
2021-11-20 11:15:28 +03:00
|
|
|
if list.created {
|
|
|
|
updateInnerHTML(list.htmlID(), list.session)
|
|
|
|
}
|
|
|
|
list.propertyChangedEvent(tag)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2022-05-04 22:35:54 +03:00
|
|
|
case DisabledItems:
|
|
|
|
if len(list.disabledItems) > 0 {
|
2022-07-26 18:36:00 +03:00
|
|
|
list.disabledItems = []any{}
|
2022-05-04 22:35:54 +03:00
|
|
|
if list.created {
|
|
|
|
updateInnerHTML(list.htmlID(), list.session)
|
|
|
|
}
|
|
|
|
list.propertyChangedEvent(tag)
|
|
|
|
}
|
|
|
|
|
2024-09-03 19:55:14 +03:00
|
|
|
case ItemSeparators, "separators":
|
|
|
|
if len(list.itemSeparators) > 0 {
|
|
|
|
list.itemSeparators = []any{}
|
|
|
|
if list.created {
|
|
|
|
updateInnerHTML(list.htmlID(), list.session)
|
|
|
|
}
|
|
|
|
list.propertyChangedEvent(ItemSeparators)
|
|
|
|
}
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
case DropDownEvent:
|
|
|
|
if len(list.dropDownListener) > 0 {
|
2023-04-23 18:07:01 +03:00
|
|
|
list.dropDownListener = []func(DropDownList, int, int){}
|
2021-11-20 11:15:28 +03:00
|
|
|
list.propertyChangedEvent(tag)
|
|
|
|
}
|
|
|
|
|
|
|
|
case Current:
|
2022-08-31 22:17:46 +03:00
|
|
|
oldCurrent := GetCurrent(list)
|
2021-11-20 11:15:28 +03:00
|
|
|
delete(list.properties, Current)
|
|
|
|
if oldCurrent != 0 {
|
|
|
|
if list.created {
|
2022-11-02 20:10:19 +03:00
|
|
|
list.session.callFunc("selectDropDownListItem", list.htmlID(), 0)
|
2021-11-20 11:15:28 +03:00
|
|
|
}
|
2023-04-23 18:07:01 +03:00
|
|
|
list.onSelectedItemChanged(0, oldCurrent)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
list.viewData.remove(tag)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (list *dropDownListData) Set(tag string, value any) bool {
|
2021-09-07 17:36:50 +03:00
|
|
|
return list.set(strings.ToLower(tag), value)
|
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (list *dropDownListData) set(tag string, value any) bool {
|
2022-05-04 22:35:54 +03:00
|
|
|
if value == nil {
|
|
|
|
list.remove(tag)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
switch tag {
|
|
|
|
case Items:
|
|
|
|
return list.setItems(value)
|
|
|
|
|
2022-05-04 22:35:54 +03:00
|
|
|
case DisabledItems:
|
2024-09-03 19:55:14 +03:00
|
|
|
items, ok := list.parseIndicesArray(value)
|
|
|
|
if !ok {
|
|
|
|
notCompatibleType(tag, value)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
list.disabledItems = items
|
|
|
|
if list.created {
|
|
|
|
updateInnerHTML(list.htmlID(), list.session)
|
|
|
|
}
|
|
|
|
list.propertyChangedEvent(tag)
|
|
|
|
return true
|
|
|
|
|
|
|
|
case ItemSeparators, "separators":
|
|
|
|
items, ok := list.parseIndicesArray(value)
|
|
|
|
if !ok {
|
|
|
|
notCompatibleType(ItemSeparators, value)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
list.itemSeparators = items
|
|
|
|
if list.created {
|
|
|
|
updateInnerHTML(list.htmlID(), list.session)
|
|
|
|
}
|
|
|
|
list.propertyChangedEvent(ItemSeparators)
|
|
|
|
return true
|
2022-05-04 22:35:54 +03:00
|
|
|
|
2021-11-20 11:15:28 +03:00
|
|
|
case DropDownEvent:
|
2023-04-23 18:07:01 +03:00
|
|
|
listeners, ok := valueToEventWithOldListeners[DropDownList, int](value)
|
2022-07-27 20:31:57 +03:00
|
|
|
if !ok {
|
|
|
|
notCompatibleType(tag, value)
|
|
|
|
return false
|
|
|
|
} else if listeners == nil {
|
2023-04-23 18:07:01 +03:00
|
|
|
listeners = []func(DropDownList, int, int){}
|
2022-07-27 20:31:57 +03:00
|
|
|
}
|
|
|
|
list.dropDownListener = listeners
|
|
|
|
list.propertyChangedEvent(tag)
|
|
|
|
return true
|
2021-11-20 11:15:28 +03:00
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
case Current:
|
2022-08-31 22:17:46 +03:00
|
|
|
oldCurrent := GetCurrent(list)
|
2021-09-07 17:36:50 +03:00
|
|
|
if !list.setIntProperty(Current, value) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-08-31 22:17:46 +03:00
|
|
|
if current := GetCurrent(list); oldCurrent != current {
|
2021-11-20 11:15:28 +03:00
|
|
|
if list.created {
|
2022-11-02 20:10:19 +03:00
|
|
|
list.session.callFunc("selectDropDownListItem", list.htmlID(), current)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
2023-04-23 18:07:01 +03:00
|
|
|
list.onSelectedItemChanged(current, oldCurrent)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return list.viewData.set(tag, value)
|
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (list *dropDownListData) setItems(value any) bool {
|
2024-05-18 18:57:41 +03:00
|
|
|
items, ok := anyToStringArray(value)
|
|
|
|
if !ok {
|
|
|
|
notCompatibleType(Items, value)
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
list.items = items
|
|
|
|
if list.created {
|
|
|
|
updateInnerHTML(list.htmlID(), list.session)
|
|
|
|
}
|
|
|
|
|
|
|
|
list.propertyChangedEvent(Items)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func intArrayToStringArray[T int | uint | int8 | uint8 | int16 | uint16 | int32 | uint32 | int64 | uint64](array []T) []string {
|
|
|
|
items := make([]string, len(array))
|
|
|
|
for i, val := range array {
|
|
|
|
items[i] = strconv.Itoa(int(val))
|
|
|
|
}
|
|
|
|
return items
|
|
|
|
}
|
|
|
|
|
|
|
|
func anyToStringArray(value any) ([]string, bool) {
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
switch value := value.(type) {
|
|
|
|
case string:
|
2024-05-18 18:57:41 +03:00
|
|
|
return []string{value}, true
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
case []string:
|
2024-05-18 18:57:41 +03:00
|
|
|
return value, true
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
case []DataValue:
|
2024-05-18 18:57:41 +03:00
|
|
|
items := make([]string, 0, len(value))
|
2021-09-07 17:36:50 +03:00
|
|
|
for _, val := range value {
|
|
|
|
if !val.IsObject() {
|
2024-05-18 18:57:41 +03:00
|
|
|
items = append(items, val.Value())
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
}
|
2024-05-18 18:57:41 +03:00
|
|
|
return items, true
|
2021-09-07 17:36:50 +03:00
|
|
|
|
|
|
|
case []fmt.Stringer:
|
2024-05-18 18:57:41 +03:00
|
|
|
items := make([]string, len(value))
|
|
|
|
for i, str := range value {
|
|
|
|
items[i] = str.String()
|
|
|
|
}
|
|
|
|
return items, true
|
|
|
|
|
|
|
|
case []Color:
|
|
|
|
items := make([]string, len(value))
|
|
|
|
for i, str := range value {
|
|
|
|
items[i] = str.String()
|
|
|
|
}
|
|
|
|
return items, true
|
|
|
|
|
|
|
|
case []SizeUnit:
|
|
|
|
items := make([]string, len(value))
|
|
|
|
for i, str := range value {
|
|
|
|
items[i] = str.String()
|
|
|
|
}
|
|
|
|
return items, true
|
|
|
|
|
|
|
|
case []AngleUnit:
|
|
|
|
items := make([]string, len(value))
|
2021-09-07 17:36:50 +03:00
|
|
|
for i, str := range value {
|
2024-05-18 18:57:41 +03:00
|
|
|
items[i] = str.String()
|
|
|
|
}
|
|
|
|
return items, true
|
|
|
|
|
|
|
|
case []float32:
|
|
|
|
items := make([]string, len(value))
|
|
|
|
for i, val := range value {
|
|
|
|
items[i] = fmt.Sprintf("%g", float64(val))
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
2024-05-18 18:57:41 +03:00
|
|
|
return items, true
|
|
|
|
|
|
|
|
case []float64:
|
|
|
|
items := make([]string, len(value))
|
|
|
|
for i, val := range value {
|
|
|
|
items[i] = fmt.Sprintf("%g", val)
|
|
|
|
}
|
|
|
|
return items, true
|
|
|
|
|
|
|
|
case []int:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []uint:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []int8:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []uint8:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []int16:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []uint16:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []int32:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []uint32:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []int64:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []uint64:
|
|
|
|
return intArrayToStringArray(value), true
|
|
|
|
|
|
|
|
case []bool:
|
|
|
|
items := make([]string, len(value))
|
|
|
|
for i, val := range value {
|
|
|
|
if val {
|
|
|
|
items[i] = "true"
|
|
|
|
} else {
|
|
|
|
items[i] = "false"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return items, true
|
2021-09-07 17:36:50 +03:00
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
case []any:
|
2022-05-04 22:35:54 +03:00
|
|
|
items := make([]string, 0, len(value))
|
2021-09-07 17:36:50 +03:00
|
|
|
for _, v := range value {
|
|
|
|
switch val := v.(type) {
|
|
|
|
case string:
|
|
|
|
items = append(items, val)
|
|
|
|
|
|
|
|
case fmt.Stringer:
|
|
|
|
items = append(items, val.String())
|
|
|
|
|
|
|
|
case bool:
|
|
|
|
if val {
|
|
|
|
items = append(items, "true")
|
|
|
|
} else {
|
|
|
|
items = append(items, "false")
|
|
|
|
}
|
|
|
|
|
|
|
|
case float32:
|
|
|
|
items = append(items, fmt.Sprintf("%g", float64(val)))
|
|
|
|
|
|
|
|
case float64:
|
|
|
|
items = append(items, fmt.Sprintf("%g", val))
|
|
|
|
|
|
|
|
case rune:
|
|
|
|
items = append(items, string(val))
|
|
|
|
|
|
|
|
default:
|
|
|
|
if n, ok := isInt(v); ok {
|
|
|
|
items = append(items, strconv.Itoa(n))
|
|
|
|
} else {
|
2024-05-18 18:57:41 +03:00
|
|
|
return []string{}, false
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-18 18:57:41 +03:00
|
|
|
return items, true
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
2021-11-20 11:15:28 +03:00
|
|
|
|
2024-05-18 18:57:41 +03:00
|
|
|
return []string{}, false
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2024-09-03 19:55:14 +03:00
|
|
|
func (list *dropDownListData) parseIndicesArray(value any) ([]any, bool) {
|
2022-05-04 22:35:54 +03:00
|
|
|
switch value := value.(type) {
|
|
|
|
case []int:
|
2024-09-03 19:55:14 +03:00
|
|
|
items := make([]any, len(value))
|
2022-05-04 22:35:54 +03:00
|
|
|
for i, n := range value {
|
2024-09-03 19:55:14 +03:00
|
|
|
items[i] = n
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
2024-09-03 19:55:14 +03:00
|
|
|
return items, true
|
2022-05-04 22:35:54 +03:00
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
case []any:
|
2024-09-03 19:55:14 +03:00
|
|
|
items := make([]any, len(value))
|
2022-05-04 22:35:54 +03:00
|
|
|
for i, val := range value {
|
|
|
|
if val == nil {
|
2024-09-03 19:55:14 +03:00
|
|
|
return nil, false
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
switch val := val.(type) {
|
|
|
|
case string:
|
|
|
|
if isConstantName(val) {
|
2024-09-03 19:55:14 +03:00
|
|
|
items[i] = val
|
2022-05-04 22:35:54 +03:00
|
|
|
} else {
|
|
|
|
n, err := strconv.Atoi(val)
|
|
|
|
if err != nil {
|
2024-09-03 19:55:14 +03:00
|
|
|
return nil, false
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
2024-09-03 19:55:14 +03:00
|
|
|
items[i] = n
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
if n, ok := isInt(val); ok {
|
2024-09-03 19:55:14 +03:00
|
|
|
items[i] = n
|
2022-05-04 22:35:54 +03:00
|
|
|
} else {
|
2024-09-03 19:55:14 +03:00
|
|
|
return nil, false
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2024-09-03 19:55:14 +03:00
|
|
|
return items, true
|
2022-05-04 22:35:54 +03:00
|
|
|
|
|
|
|
case string:
|
|
|
|
values := strings.Split(value, ",")
|
2024-09-03 19:55:14 +03:00
|
|
|
items := make([]any, len(values))
|
2022-05-04 22:35:54 +03:00
|
|
|
for i, str := range values {
|
|
|
|
str = strings.Trim(str, " ")
|
|
|
|
if str == "" {
|
2024-09-03 19:55:14 +03:00
|
|
|
return nil, false
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
if isConstantName(str) {
|
2024-09-03 19:55:14 +03:00
|
|
|
items[i] = str
|
2022-05-04 22:35:54 +03:00
|
|
|
} else {
|
|
|
|
n, err := strconv.Atoi(str)
|
|
|
|
if err != nil {
|
2024-09-03 19:55:14 +03:00
|
|
|
return nil, false
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
2024-09-03 19:55:14 +03:00
|
|
|
items[i] = n
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
}
|
2024-09-03 19:55:14 +03:00
|
|
|
return items, true
|
2022-05-04 22:35:54 +03:00
|
|
|
|
|
|
|
case []DataValue:
|
2024-09-03 19:55:14 +03:00
|
|
|
items := make([]any, 0, len(value))
|
2022-05-04 22:35:54 +03:00
|
|
|
for _, val := range value {
|
|
|
|
if !val.IsObject() {
|
2024-09-03 19:55:14 +03:00
|
|
|
items = append(items, val.Value())
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
}
|
2024-09-03 19:55:14 +03:00
|
|
|
return list.parseIndicesArray(items)
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
|
2024-09-03 19:55:14 +03:00
|
|
|
return nil, false
|
2022-05-04 22:35:54 +03:00
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (list *dropDownListData) Get(tag string) any {
|
2021-09-07 17:36:50 +03:00
|
|
|
return list.get(strings.ToLower(tag))
|
|
|
|
}
|
|
|
|
|
2022-07-26 18:36:00 +03:00
|
|
|
func (list *dropDownListData) get(tag string) any {
|
2021-09-07 17:36:50 +03:00
|
|
|
switch tag {
|
|
|
|
case Items:
|
|
|
|
return list.items
|
|
|
|
|
2022-05-04 22:35:54 +03:00
|
|
|
case DisabledItems:
|
|
|
|
return list.disabledItems
|
|
|
|
|
2024-09-03 19:55:14 +03:00
|
|
|
case ItemSeparators:
|
|
|
|
return list.itemSeparators
|
|
|
|
|
2021-09-07 17:36:50 +03:00
|
|
|
case Current:
|
|
|
|
result, _ := intProperty(list, Current, list.session, 0)
|
|
|
|
return result
|
|
|
|
|
|
|
|
case DropDownEvent:
|
|
|
|
return list.dropDownListener
|
|
|
|
}
|
|
|
|
|
|
|
|
return list.viewData.get(tag)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (list *dropDownListData) getItems() []string {
|
|
|
|
return list.items
|
|
|
|
}
|
|
|
|
|
|
|
|
func (list *dropDownListData) htmlTag() string {
|
|
|
|
return "select"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (list *dropDownListData) htmlSubviews(self View, buffer *strings.Builder) {
|
|
|
|
if list.items != nil {
|
2022-08-31 22:17:46 +03:00
|
|
|
current := GetCurrent(list)
|
|
|
|
notTranslate := GetNotTranslate(list)
|
|
|
|
disabledItems := GetDropDownDisabledItems(list)
|
2024-09-03 19:55:14 +03:00
|
|
|
separators := GetDropDownItemSeparators(list)
|
2021-09-07 17:36:50 +03:00
|
|
|
for i, item := range list.items {
|
2022-05-04 22:35:54 +03:00
|
|
|
disabled := false
|
|
|
|
for _, index := range disabledItems {
|
|
|
|
if i == index {
|
|
|
|
disabled = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if disabled {
|
|
|
|
buffer.WriteString("<option disabled>")
|
|
|
|
} else if i == current {
|
2021-09-07 17:36:50 +03:00
|
|
|
buffer.WriteString("<option selected>")
|
|
|
|
} else {
|
|
|
|
buffer.WriteString("<option>")
|
|
|
|
}
|
|
|
|
if !notTranslate {
|
|
|
|
item, _ = list.session.GetString(item)
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer.WriteString(item)
|
|
|
|
buffer.WriteString("</option>")
|
2024-09-03 19:55:14 +03:00
|
|
|
for _, index := range separators {
|
|
|
|
if i == index {
|
|
|
|
buffer.WriteString("<hr>")
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (list *dropDownListData) htmlProperties(self View, buffer *strings.Builder) {
|
|
|
|
list.viewData.htmlProperties(self, buffer)
|
|
|
|
buffer.WriteString(` size="1" onchange="dropDownListEvent(this, event)"`)
|
|
|
|
}
|
|
|
|
|
2023-04-23 18:07:01 +03:00
|
|
|
func (list *dropDownListData) onSelectedItemChanged(number, old int) {
|
2021-09-07 17:36:50 +03:00
|
|
|
for _, listener := range list.dropDownListener {
|
2023-04-23 18:07:01 +03:00
|
|
|
listener(list, number, old)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
2021-11-20 11:15:28 +03:00
|
|
|
list.propertyChangedEvent(Current)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (list *dropDownListData) handleCommand(self View, command string, data DataObject) bool {
|
|
|
|
switch command {
|
|
|
|
case "itemSelected":
|
|
|
|
if text, ok := data.PropertyValue("number"); ok {
|
|
|
|
if number, err := strconv.Atoi(text); err == nil {
|
2022-08-31 22:17:46 +03:00
|
|
|
if GetCurrent(list) != number && number >= 0 && number < len(list.items) {
|
2023-04-23 18:07:01 +03:00
|
|
|
old := GetCurrent(list)
|
2021-09-07 17:36:50 +03:00
|
|
|
list.properties[Current] = number
|
2023-04-23 18:07:01 +03:00
|
|
|
list.onSelectedItemChanged(number, old)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ErrorLog(err.Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
return list.viewData.handleCommand(self, command, data)
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2022-08-31 22:17:46 +03:00
|
|
|
// GetDropDownListeners returns the "drop-down-event" listener list. If there are no listeners then the empty list is returned.
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
2023-04-23 18:07:01 +03:00
|
|
|
func GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int) {
|
|
|
|
return getEventWithOldListeners[DropDownList, int](view, subviewID, DropDownEvent)
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
|
2022-08-31 22:17:46 +03:00
|
|
|
// GetDropDownItems return the DropDownList items list.
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
func GetDropDownItems(view View, subviewID ...string) []string {
|
|
|
|
if len(subviewID) > 0 && subviewID[0] != "" {
|
|
|
|
view = ViewByID(view, subviewID[0])
|
2021-09-07 17:36:50 +03:00
|
|
|
}
|
|
|
|
if view != nil {
|
|
|
|
if list, ok := view.(DropDownList); ok {
|
|
|
|
return list.getItems()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return []string{}
|
|
|
|
}
|
2022-05-04 22:35:54 +03:00
|
|
|
|
2024-09-03 19:55:14 +03:00
|
|
|
func getIndicesArray(view View, tag string) []int {
|
2022-05-04 22:35:54 +03:00
|
|
|
if view != nil {
|
2024-09-03 19:55:14 +03:00
|
|
|
if value := view.Get(tag); value != nil {
|
2022-07-26 18:36:00 +03:00
|
|
|
if values, ok := value.([]any); ok {
|
2022-05-04 22:35:54 +03:00
|
|
|
count := len(values)
|
|
|
|
if count > 0 {
|
|
|
|
result := make([]int, 0, count)
|
|
|
|
for _, value := range values {
|
|
|
|
switch value := value.(type) {
|
|
|
|
case int:
|
|
|
|
result = append(result, value)
|
|
|
|
|
|
|
|
case string:
|
|
|
|
if value != "" && value[0] == '@' {
|
|
|
|
if val, ok := view.Session().Constant(value[1:]); ok {
|
|
|
|
if n, err := strconv.Atoi(val); err == nil {
|
|
|
|
result = append(result, n)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return []int{}
|
|
|
|
}
|
2024-09-03 19:55:14 +03:00
|
|
|
|
|
|
|
// GetDropDownDisabledItems return an array of disabled(non selectable) items indices of DropDownList.
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
func GetDropDownDisabledItems(view View, subviewID ...string) []int {
|
|
|
|
if len(subviewID) > 0 && subviewID[0] != "" {
|
|
|
|
view = ViewByID(view, subviewID[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
return getIndicesArray(view, DisabledItems)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetDropDownItemSeparators return an array of indices of DropDownList items after which a separator should be added.
|
|
|
|
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
|
|
|
func GetDropDownItemSeparators(view View, subviewID ...string) []int {
|
|
|
|
if len(subviewID) > 0 && subviewID[0] != "" {
|
|
|
|
view = ViewByID(view, subviewID[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
return getIndicesArray(view, ItemSeparators)
|
|
|
|
}
|