# Select List

#### Select List 형 위젯은 텍스트와 텍스트 입력 창, 혹은 선택 버튼을 함께 사용할 수 있는 UI입니다.

활용 예 ) 탑승 앱, 찌르기 앱, 아바타 특수 효과 앱

#### Image

![](/files/NYRqkWXk93uYcqPFcVQO)

####

#### Example

{% file src="/files/14laQzAmRS4hpdf6ksOM" %}

```javascript
// Editable fields. Used for validation.
const RequiredFields = {
    password: "string",
    lock: "boolean"
};

const SELECT_ITEM_DATA = {
    Select_1: {
        id: 1,
        order: 1, // Item sorting order
        displayName: "Item 1", // Item display name
        password: "password", // password
        lock: false, // lock(boolean)
    },
    Select_2: {
        id: 2,
        order: 2,
        displayName: "Item 2",
        password: "password",
        lock: false,
    },
    Select_3: {
        id: 3,
        order: 3,
        displayName: "Item 3",
        password: "password",
        lock: false,
    },
    Select_4: {
        id: 4,
        order: 4,
        displayName: "Item 4",
        password: "password",
        lock: false,
    },
    Select_5: {
        id: 5,
        order: 5,
        displayName: "Item 5",
        password: "password",
        lock: false,
    },
    Select_6: {
        id: 6,
        order: 6,
        displayName: "Item 6",
        password: "password",
        lock: false,
    },
    Select_7: {
        id: 7,
        order: 7,
        displayName: "Item 7",
        password: "password",
        lock: false,
    },
    Select_8: {
        id: 8,
        order: 8,
        displayName: "Item 8",
        password: "password",
        lock: false,
    },
};


App.onStart.Add(() => {
    init();
});

App.onJoinPlayer.Add(function (player) {
    player.tag = {};
});

App.onSidebarTouched.Add(function (player) {
    showMainWidget(player);
})

function init() {
    // ensureStorageInitialized
    if (!App.storage) {
        App.storage = "{}";
        App.save();
    }
    const appStorage = JSON.parse(App.storage);

    // updateItemDataFromStorage
    if (appStorage.setting) {
        for (let key in SELECT_ITEM_DATA) {
            if (appStorage.setting.hasOwnProperty(key)) {
                SELECT_ITEM_DATA[key] = Object.assign({}, SELECT_ITEM_DATA[key], appStorage.setting[key]);
            } else {
                SELECT_ITEM_DATA[key] = Object.assign({}, SELECT_ITEM_DATA[key]);
            }
        }
    }
}

function showMainWidget(player) {
    App.getStorage(() => {
        const appStorage = JSON.parse(App.storage);
        if (player.tag.widget) {
            player.tag.widget.destroy();
            player.tag.widget = null;
        }
        if (player.isMobile) {
            player.tag.widget = player.showWidget("SelectList.html", "sidebar", 0, 0);
        } else {
            player.tag.widget = player.showWidget("SelectList.html", "bottomleft", 0, 0);
        }

        let selectItemData = SELECT_ITEM_DATA;
        if (appStorage.setting) {
            let newList = {};
            for (let key in selectItemData) {
                if (appStorage.setting.hasOwnProperty(key)) {
                    newList[key] = Object.assign({}, selectItemData[key], appStorage.setting[key]);
                } else {
                    newList[key] = Object.assign({}, selectItemData[key]);
                }
            }
            selectItemData = newList;
        }

        player.tag.widget.sendMessage({
            type: "init",
            isMobile: player.isMobile,
            isAdmin: isAdmin(player),
            selectItemData: selectItemData,
        });

        player.tag.widget.onMessage.Add(function (sender, msg) {
            switch (msg.type) {
                case "close":
                    if (sender.tag.widget) {
                        sender.tag.widget.destroy();
                        sender.tag.widget = null;
                    }
                    break;
                case "requestSaveSetting":
                    const result = validateDatabase(msg.editData);
                    if (!result) {
                        sender.showAlert("Invalid Input");
                        return;
                    }
                    App.getStorage(() => {
                        const appStorage = JSON.parse(App.storage);
                        appStorage.setting = result;
                        App.setStorage(JSON.stringify(appStorage));

                        if (sender.tag.widget) {
                            sender.tag.widget.sendMessage({
                                type: "responseSaveSetting",
                            });
                        }

                        let selectItemData = {};
                        for (let key in SELECT_ITEM_DATA) {
                            if (appStorage.setting.hasOwnProperty(key)) {
                                selectItemData[key] = Object.assign({}, SELECT_ITEM_DATA[key], appStorage.setting[key]);
                                SELECT_ITEM_DATA[key] = selectItemData[key];
                            } else {
                                SELECT_ITEM_DATA[key] = Object.assign({}, SELECT_ITEM_DATA[key]);
                            }
                        }
                        if (selectItemData == {}) {
                            selectItemData = SELECT_ITEM_DATA;
                        }
                        handleUpdateSetting(selectItemData);
                    });

                    break;
            }
        });
    });

}

function handleUpdateSetting(selectItemData) {
    for (const player of App.players) {
        if (!player) continue;
        if (player.tag.widget) {
            player.tag.widget.sendMessage({
                type: "update",
                selectItemData: selectItemData,
            });
        }
    }
}

function validateDatabase(database) {
    let newDB = {};
    for (let key in database) {
        let item = database[key];
        newDB[key] = {};
        for (let field in RequiredFields) {
            // validateFields
            if (!item.hasOwnProperty(field) || typeof item[field] !== RequiredFields[field]) {
                return false;
            }
            if (field === "password" && (!item[field] && item["lock"])) {
                return false;
            }

            newDB[key][field] = item[field];
        }
    }
    return newDB;
}

function isAdmin(player) {
    return player.role >= 3000;
}

```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-kr.zep.us/creator/tutor/undefined/select-list.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
