Following my previous virtual keyboard project, I’ve now created an image gallery template.
msg.payload contains the directory path
msg.list contains the filenames
You can add any desired logic in the function node before this template to customize it further for your use case.
[
{
"id": "7e6c49405a786bd3",
"type": "ui-template",
"z": "7a34447ee27b9d6b",
"group": "23fac572cb3ab8c8",
"page": "",
"ui": "",
"name": "picture gallery",
"order": 1,
"width": "3",
"height": "2",
"head": "",
"format": "<template>\n \t<div class=\"text-center pa-4\">\n\t\t<!-- open dialog button -->\n\t\t<v-btn class=\"spaced-btn\" color=\"primary\" @click=\"openDialog\">\n\t\t\timage gallery\n\t\t</v-btn>\n\n\t\t<!-- dialog -->\n\t\t<v-dialog v-model=\"dialog\" max-width=\"1200\">\n\t\t\t<v-card>\n\t\t\t\t<v-card-title class=\"headline\">image gallery</v-card-title>\n\t\t\t\t<v-card-text>\n\t\t\t\t\t<v-row>\n\t\t\t\t\t\t<!-- computed imageAddresses -->\n\t\t\t\t\t\t<v-col\n\t\t\t\t\t\tv-for=\"(img, index) in imageAddresses\"\n\t\t\t\t\t\t:key=\"index\"\n\t\t\t\t\t\tclass=\"d-flex child-flex\"\n\t\t\t\t\t\tcols=\"4\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<v-img\n\t\t\t\t\t\t\t\t:src=\"img\"\n\t\t\t\t\t\t\t\taspect-ratio=\"1\"\n\t\t\t\t\t\t\t\tclass=\"bg-grey-lighten-2\"\n\t\t\t\t\t\t\t\tcontain\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<template v-slot:placeholder>\n\t\t\t\t\t\t\t\t\t<v-row align=\"center\" class=\"fill-height ma-0\" justify=\"center\">\n\t\t\t\t\t\t\t\t\t\t\t<v-progress-circular\n\t\t\t\t\t\t\t\t\t\t\tindeterminate\n\t\t\t\t\t\t\t\t\t\t\tcolor=\"grey lighten-5\"\n\t\t\t\t\t\t\t\t\t\t\t></v-progress-circular>\n\t\t\t\t\t\t\t\t\t</v-row>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t<template v-slot:error>\n\t\t\t\t\t\t\t\t\t<v-row align=\"center\" class=\"fill-height ma-0\" justify=\"center\">\n\t\t\t\t\t\t\t\t\t\t<span>Error loading image</span>\n\t\t\t\t\t\t\t\t\t</v-row>\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</v-img>\n\t\t\t\t\t\t</v-col>\n\t\t\t\t\t</v-row>\n\t\t\t\t</v-card-text>\n\t\t\t\t<v-card-actions>\n\t\t\t\t\t<v-spacer></v-spacer>\n\t\t\t\t\t<v-btn color=\"primary\" text @click=\"closeDialog\">Close</v-btn>\n\t\t\t\t</v-card-actions>\n\t\t\t</v-card>\n\t\t</v-dialog>\n \t</div>\n</template>\n\n<script>\nexport default \n{\n \tname: \"MultiImageGalleryDialog\",\n\tprops: ['msg'],\n\tdata() \n\t{\n\t\treturn {\n\t\t\tdialog: false\n\t\t};\n\t},\n\tcomputed: \n\t{\n\t\timageAddresses() \n\t\t{\n\t\t\treturn (this.msg && Array.isArray(this.msg.payload)) ? this.msg.payload : [];\n\t\t}\n\t},\n\tmethods: \n\t{\n\t\topenDialog() \n\t\t{\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.dialog = true;\n\t\t\t\tif (typeof this.send === \"function\") \n\t\t\t\t{\n\t\t\t\t\tthis.send({ payload: \"open\" });\n\t\t\t\t}else \n\t\t\t\t{\n\t\t\t\t\tthis.$emit(\"input\", { payload: \"open\" });\n\t\t\t\t}\n\t\t\t}, 1000);\n\t\t},\n\t\tcloseDialog() \n\t\t{\n\t\t\tthis.dialog = false;\n\t\t\tif (typeof this.send === \"function\") \n\t\t\t{\n\t\t\t\tthis.send({ payload: \"close\" });\n\t\t\t} else \n\t\t\t{\n\t\t\t\tthis.$emit(\"input\", { payload: \"close\" });\n\t\t\t}\n\t\t}\n\t}\n};\n</script>\n\n<style scoped>\n.spaced-btn {\n\tfont-size: 20px;\n\tpadding: 16px 24px;\n\tmargin: 10px;\n}\n</style>\n",
"storeOutMessages": true,
"passthru": true,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 620,
"y": 240,
"wires": [
[]
]
},
{
"id": "8a52fb44cf5ec85d",
"type": "function",
"z": "7a34447ee27b9d6b",
"name": "function 107",
"func": "var imageDir = msg.payload;\nvar list = msg.list;\nvar address = [];\n\nfor (var i = 0; i < list.length; i++)\n{\n address[i] = imageDir + list[i];\n}\n\nmsg.payload = address;\n\nreturn msg;\n",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 410,
"y": 240,
"wires": [
[
"7e6c49405a786bd3"
]
]
},
{
"id": "23fac572cb3ab8c8",
"type": "ui-group",
"name": "image layout",
"page": "c109e0668d1fee3b",
"width": "12",
"height": "1",
"order": 1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false",
"groupType": "default"
},
{
"id": "c109e0668d1fee3b",
"type": "ui-page",
"name": "data",
"ui": "35e7e3e70a04a217",
"path": "/page4",
"icon": "monitor",
"layout": "grid",
"theme": "0d92c765bfad87e6",
"breakpoints": [
{
"name": "Default",
"px": "0",
"cols": "3"
},
{
"name": "Tablet",
"px": "576",
"cols": "6"
},
{
"name": "Small Desktop",
"px": "768",
"cols": "9"
},
{
"name": "Desktop",
"px": "1024",
"cols": "12"
}
],
"order": 1,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "35e7e3e70a04a217",
"type": "ui-base",
"name": "image gallery",
"path": "/dashboard",
"appIcon": "",
"includeClientData": true,
"acceptsClientConfig": [
"ui-control",
"ui-template",
"ui-gauge",
"ui-iframe",
"ui-text-input",
"ui-number-input",
"ui-file-input",
"ui-button",
"ui-button-group",
"ui-dropdown",
"ui-radio-group",
"ui-slider",
"ui-switch",
"ui-text",
"ui-table",
"ui-chart",
"ui-notification",
"ui-audio",
"ui-markdown",
"ui-form"
],
"showPathInSidebar": false,
"showPageTitle": true,
"navigationStyle": "icon",
"titleBarStyle": "fixed",
"showReconnectNotification": false,
"notificationDisplayTime": "1",
"showDisconnectNotification": false
},
{
"id": "0d92c765bfad87e6",
"type": "ui-theme",
"name": "Basic Blue Theme",
"colors": {
"surface": "#14549e",
"primary": "#336ba9",
"bgPage": "#eeeeee",
"groupBg": "#ffffff",
"groupOutline": "#cccccc"
},
"sizes": {
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px",
"density": "default"
}
}
]