### UI Create Button Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dynamicsource/settings.html An example of a 'create' button component used to add new items, featuring a plus icon and a specific width. ```html ``` -------------------------------- ### UI Input Component Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dynamicsource/settings.html Demonstrates the usage of the 'ui-component' with the 'input' name for capturing 'name' and 'id' fields. It includes configuration for required fields and default values. ```html @(Name) @(Value) ``` -------------------------------- ### UI Create Button Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/accordion/settings.html Displays a 'Create' button styled with a plus icon, intended for initiating a creation process. The button has a specific width and a green color for the icon. ```HTML ``` -------------------------------- ### UI Input Component Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/accordion/settings.html Demonstrates the usage of the 'input' UI component for capturing text input. It includes configuration for making the field required and setting a default empty string value. ```HTML Name ``` -------------------------------- ### App Layout Component Implementation (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/applayout/render.html This JavaScript code defines the 'applayout' component for Total.js UIBuilder. It handles rendering the layout using a template, managing button outputs, and responding to click events for navigation and toolbar actions. Dependencies include jQuery for DOM manipulation. ```javascript exports.id = 'applayout'; exports.outputs = []; exports.make = function(instance, config, element, cls) { var cls2 = '.' + cls; var render = function() { var template = instance.maketemplate(instance.component.html); var output = template({ value: config.buttons, name: config.name.encode(), backnav: config.backnav ? true : false }); element.html(output); instance.outputs = []; if (config.buttons && config.buttons.length) { for (let m of config.buttons) { instance.outputs.push({ id: m.id, name: m.name }); } } }; element.on('click', '.toolbar > button', function(e) { var el = $(this); var id = el.attrd('id'); instance.output(id, instance.get() || {}); }); element.on('click', '.CLASS_backbtn', function(e) { var el = $(this); var arr = instance.app.breadcrumb; arr[0].navigate(arr.slice(-2, -1)[0]); }); render(); }; ``` -------------------------------- ### HTML Template Structure for App Layout Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/applayout/render.html This HTML snippet represents the template structure used by the App Layout component. It includes conditional rendering for a back navigation button and iterates through a list of buttons for the toolbar. The `{{ }}` syntax indicates Total.js templating. ```html {{ if backnav }} {{ fi }} {{ foreach m in value }} {{ m.name }} {{ end }} ``` -------------------------------- ### CSS for UIBuilder App Layout Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/applayout/render.html This CSS defines the styling for the UIBuilder App Layout component. It includes styles for the header, labels, components area, toolbar, and a back button, ensuring a consistent and visually appealing interface. ```css .CLASS_header { height: 60px; border-bottom: 1px solid #E0E0E0; padding: 0 20px; display: flex; align-items: center; } .CLASS_header label { line-height: 59px; font-weight: bold; } .CLASS_components { padding: 20px; } .CLASS_header .toolbar { margin-left: auto; } .CLASS_header .CLASS_backbtn { margin-right: 20px; border: 0; border-radius: var(--radius); width: 30px; height: 30px; } ``` -------------------------------- ### Redirect Component Datasource Example (JSON) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/redirect/editor.html Illustrates the expected format for the datasource used by the Redirect component. Each item in the array should have an `id` and a `url` property, where `url` specifies the target URL for redirection. ```json [ { "id": 1, "url": "https://www.totaljs.com/" }, { "id": 2, "url": "https://www.totaljs.com/" }, { "id": 3, "url": "https://www.totaljs.com/" } ] ``` -------------------------------- ### UI Checkbox Component Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/accordion/settings.html Illustrates the use of the 'input' UI component configured as a checkbox. This component is used to toggle a boolean value, represented here by 'Apply padding'. ```HTML Apply padding ``` -------------------------------- ### Floor Plan Component Initialization and Upload Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/fbfloorplan/editor.html This JavaScript code initializes the Floor Plan component for Total.js UIBuilder. It sets up the component's metadata, including its ID, group, name, icon, author, and configuration. The `render` function handles the component's UI, including an upload button and an area to display the floor plan image. It also includes logic for uploading new images and updating the background display with the uploaded image's dimensions. ```javascript exports.id = 'fbfloorplan'; exports.group = 'Flowboard'; exports.name = 'Floor plan'; exports.icon = 'ti ti-object-group'; exports.author = 'Total.js'; exports.config = { url: '' }; exports.render = 'auto'; exports.version = '1'; exports.hidden = true; exports.type = ['flowboard']; exports.make = function(instance, config, element) { var cls = instance.component.cls; var cls2 = '.' + cls; element.append('
Upload new plan
'.format(cls)); var bg = element.find(cls2 + '-image'); var update = function() { var url = config.url || FUNC.makeimage(1000, 600, '#F0F0F0'); bg.css('background', 'url({0}) no-repeat 0 0'.format(url)); var img = new Image(); img.src = url; img.onload = function() { config.height = img.height || 600; config.width = img.width; bg.css({ 'min-height': WH - element.offset().top, 'padding-top': config.height + 20 }); }; }; element.find(cls2 + '-upload').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var opt = {}; opt.type = 'image/*'; opt.multiple = false; FUNC.upload(opt, function(response) { config.url = response.url; update(); }); }); update(); }; ``` -------------------------------- ### UI Validation Component Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dynamicsource/settings.html Shows how to implement a validation component with save, remove, and cancel buttons. The save button is initially disabled and requires valid input. ```html ``` -------------------------------- ### Total.js Toolbar Component Initialization Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/toolbar/editor.html Initializes the Total.js UIBuilder Toolbar component. It defines the component's metadata, configuration options, and the `make` function responsible for rendering the toolbar based on provided configuration and template. ```javascript exports.id = 'toolbar'; exports.name = 'Toolbar'; exports.group = 'Controls'; exports.icon = 'ti ti-wrench'; exports.author = 'Total.js'; exports.config = { border: false, padding: false }; exports.render = 'auto'; exports.settings = 'auto'; exports.version = '1'; exports.follow = true; exports.make = function(instance, config, element, cls) { var render = function() { var template = instance.maketemplate(instance.component.html); var output = template({ value: config.items, name: config.name.encode() }); element.html(output); element.tclass(cls + '_border', config.border); element.tclass(cls + '_padding', config.padding); }; instance.on('configure', render); render(); }; ``` -------------------------------- ### Configure Floor Plan Component Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/fbfloorplan/render.html This JavaScript code defines a Total.js UI Builder component for a floor plan. It sets up the component's ID, makes it, and configures its HTML structure, including a background image with specified URL, height, and width. ```javascript exports.id = 'fbfloorplan'; exports.make = function(instance, config, element) { var cls = instance.component.cls; var cls2 = '.' + cls; element.html(instance.component.html); element.find('{0}_content'.format(cls2)).append('
'.format(cls)); var bg = element.find(cls2 + '_image'); var url = config.url; bg.css({ background: 'url({0}) no-repeat 0 0'.format(url), 'min-height': config.height, 'min-width': config.width }); }; ``` -------------------------------- ### UI Navigation Buttons Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dropdown/settings.html Provides examples of navigation buttons (up, down, remove) within a UI component, typically used for managing lists or items. These buttons include icons for visual representation. ```HTML ``` -------------------------------- ### Initialize and Configure DataGrid Component Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/datagrid/render.html This JavaScript code snippet demonstrates the initialization and configuration of a DataGrid component within the Total.js UIBuilder framework. It sets up various properties such as height, margins, borders, selection behavior, and dynamic data fetching. It also defines how columns are rendered and handles click events. ```javascript exports.id = 'datagrid'; exports.inputs = [{ id: 'rows', name: 'Rows' }]; exports.outputs = [{ id: 'row', name: 'On row' }, { id: 'button', name: 'On button' }]; exports.make = function(instance, config, element) { var cfg = []; var path = 'uibuildercom_' + instance.id; var pathfn = path + '_exec'; var pathclick = path + '_click'; var isdynamic = config.dynamic && config.datasource && config.datasource.charAt(0) === '#' ? true : false; var allowselecting = false; if (typeof(config.height) === 'string' && config.height === 'parent') config.height += '1'; cfg.push('height:' + (config.height || 'parent1')); if (config.margin) cfg.push('margin:' + config.margin); if (config.parent) cfg.push('parent:' + config.parent); if (config.minheight) cfg.push('minheight:' + config.minheight); if (!config.border) cfg.push('noborder:1'); if (config.autoselect) cfg.push('autoselect:1'); if (config.dynamic) cfg.push('exec:' + pathfn); if (!config.numbering) cfg.push('numbering:false'); if (config.action) cfg.push('dblclick:' + pathdblclick); cfg.push('checkbox:' + (config.checkbox ? 1 : 0)); W[pathclick] = function(row) { if (row && (allowselecting || config.autoselect)) instance.output('row', row); }; if (isdynamic) { W[pathfn] = function(type, filter, sort, page) { if (!filter) filter = {}; filter.sort = sort; filter.page = page; instance.view(config.datasource, filter, function(response) { if (!response) response = { page: 1, pages: 0, items: [], count: 0 }; else if (response instanceof Array) response = { page: 1, pages: 1, items: response, count: response.length }; SET(path, response); }); }; } var columns = []; if (config.columns) { for (var i = 0; i < config.columns.length; i++) { var col = config.columns[i]; var tmp = {}; tmp.text = col.name; if (!tmp.text) tmp.text = DEF.empty; tmp.name = col.path.replace('?.', ''); tmp.hide = col.hidden; if (col.type) tmp.type = col.type; if (!col.format && col.type === 'date') col.format = '[date]'; if (col.filter === false) tmp.filter = false; if (col.sort === false) tmp.sort = false; if (col.format) tmp.format = col.format; if (col.align) tmp.align = col.align; if (col.title) tmp.title = col.title; if (col.width) tmp.width = col.width; if (col.template) tmp.template = col.template; if (col.colorize) tmp.colorize = true; columns.push(tmp); } } element.html(('{2}').format(path, cfg.join(';'), JSON.stringify(columns), pathclick)); if (!isdynamic) { config.datasource && instance.on('ready', function() { instance.datasource(config.datasource, function(response) { SET(path, response); }); }); instance.input('rows', function(value) { SET(path, value); }); } instance.on('ready', function() { setTimeout(() => allowselecting = true, 500); }); instance.on('destroy', function() { delete W[path]; delete W[pathclick]; delete W[pathfn]; }); }; ``` -------------------------------- ### Initialize and Configure Map Component Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/map/render.html This snippet demonstrates the initialization of the UIBuilder Map component. It sets up the map container, tile layer, and event listeners for map movements and marker interactions. It also includes functionality for searching locations and handling component lifecycle events like 'destroy' and 'value' changes. ```javascript exports.id = 'map'; exports.import = ['https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.min.css', 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.8.0/leaflet.min.js']; exports.inputs = [{ id: 'gps', name: 'Load GPS' }]; exports.make = function(instance, config, element) { var skipmove = false; var meta = { markers: [] }; element.append('
'); meta.container = element.find('div')[0]; $(meta.container).css('height', config.height); meta.map = L.map(meta.container); meta.tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: config.maxzoom, attribution: '© OpenStreetMap' }).addTo(meta.map); var search = function(name, callback) { AJAX('GET https://nominatim.openstreetmap.org/search?format=json&q=' + encodeURIComponent(name), function(response) { if (response instanceof Array) { for (var item of response) { item.pos = item.lat + ',' + item.lon; item.name = item.display_name; item.id = item.place_id; } } callback(response); }); }; var onmove = function() { if (instance.state.disabled) return; if (skipmove) { skipmove = false; return; } if (config.move) { var pos = meta.map.getCenter(); instance.set('value', pos.lat + ',' + pos.lng, 'nobind'); } }; var marker = function(pos) { if (meta.marker) { meta.marker.setLatLng(pos); return; } var opt = {}; if (config.draggable) opt.draggable = true; meta.marker = L.marker(pos, opt); meta.marker.addTo(meta.map); meta.markers.push(meta.marker); meta.marker.on('moveend', function(e) { var pos = e.target._latlng; instance.set('value', pos.lat + ',' + pos.lng, 'nobind'); }); }; meta.map.on('moveend', onmove); meta.map.on('zoomend', onmove); var parse = function(pos, callback) { if (!pos) return; if ((/[a-z]/i).test(pos)) { search(pos, response => instance.set('value', response[0].pos)); return } var tmp = pos.split(',').trim(); tmp[0] = parseFloat(tmp[0]); tmp[1] = parseFloat(tmp[1]); tmp[2] = tmp[2] ? parseInt(tmp[2]) : config.zoom; callback(tmp); }; var center = function(pos) { parse(pos, gps => meta.map.setView(gps.slice(0, 2), gps[2])); }; instance.on('destroy', function() { for (var m of meta.markers) m.remove(); meta.map.off(); meta.map.remove(); meta.markers = null; meta.map = null; meta.marker = null; }); instance.on('value', function(value, kind) { if (kind === 'nobind') return; parse(value, function(pos) { meta.map.setView(pos.slice(0, 2), pos[2]); marker(pos); }); }); instance.input('gps', function(value) { if (value) { if (typeof(value) === 'object') instance.set('value', value.lat + ', ' + (value.lng || value.long)); else parse(value, val => instance.set('value', val)); } }); instance.on('ready', function() { if (config.default && !instance.state.value) parse(config.default, val => instance.set('value', val)); }); }; ``` -------------------------------- ### UI Validation Component Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/accordion/settings.html Shows the 'validate' UI component, which is used to group validation and action buttons. It includes 'Save', 'Remove', and 'Cancel' buttons, with the 'Save' button initially disabled. ```HTML ``` -------------------------------- ### Radio Button Data Source Example (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/radiobutton/editor.html This snippet shows the expected data structure for populating the options of a Radio Button component in Total.js UIBuilder. Each item in the array should have an 'id' and a 'name' property. ```javascript [ { id: 1, name: 'Ruby' }, { id: 2, name: 'PHP' }, { id: 3, name: 'Node' }, { id: 4, name: 'Python' } ] ``` -------------------------------- ### Checkboxlist Data Source Format (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/checkboxlist/editor.html This example demonstrates the required data structure for the Checkboxlist component. The `data-source` should be an array of objects, where each object has an `id` and a `name` property, representing the unique identifier and display text for each checkbox option. ```javascript [ { id: 1, name: 'Ruby' }, { id: 2, name: 'PHP' }, { id: 3, name: 'node.js' }, { id: 4, name: 'Python', } ] ``` -------------------------------- ### Basic Component Structure Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dynamicsource/settings.html Illustrates the basic HTML structure for a UI component item, including a removable element and a display name. ```html
{{ name }}
``` -------------------------------- ### Listview Component Definition and Rendering Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/listview/editor.html Defines the Listview component's metadata (ID, name, group, author, icon, config, version, follow, outputs) and its rendering logic. The `make` function handles component configuration and rendering, including generating HTML placeholders and labels based on provided configuration. It emits a 'configure' event to trigger the rendering process. ```javascript exports.id = 'listview'; exports.name = 'Listview'; exports.group = 'List'; exports.author = 'Total.js'; exports.icon = 'ti ti-list-alt'; exports.config = { required: false, background: false, nolabel: false }; exports.settings = 'auto'; exports.render = 'auto'; exports.version = '1'; exports.follow = true; exports.outputs = [{ id: 'click', name: 'Click' }]; exports.make = function(instance, config, element, cls) { var options = { name: instance.component.id, count: 3 }; instance.on('configure', function() { options.background = config.background ? true : false; var html = FUNC.placeholder(options); var label = instance.maketemplate(''); config.nolabel ? element.html(html) : element.html(label(config) + html); }); instance.emit('configure'); }; ``` -------------------------------- ### UIBuilder Slider Component Creation Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/slider/render.html This JavaScript code defines the creation of a slider component within the Total.js UIBuilder framework. It handles the initial setup, event binding, and state management for the slider, including its visual representation and user interaction. ```javascript exports.id = 'slider'; exports.make = function(instance, config, element, cls) { instance.state.bind = true; var cls2 = '.' + cls; var events = {}; var thumb, track, rail, valuelabel; var percentage = null; var timeout = null; var template = instance.maketemplate(); var icon = config.icon ? ''.format(config.icon) : ''; var label = ''.format(config.name, icon); element.html(label + template()); thumb = element.find(cls2 + '\_thumb'); track = element.find(cls2 + '\_track'); rail = element.find(cls2 + '\_rail'); valuelabel = element.find(cls2 + '\_value'); thumb.css('left', (config.value || 50) + '%'); track.css('width', (config.value || 50) + '%'); valuelabel.text((config.value || 50) + '%'); var update = function(x) { thumb.css('left', x); track.css('width', x); events.p = Math.ceil(((events.width - (events.width - track.width())) * 100) / events.width); valuelabel.text(events.p + '%'); timeout && clearTimeout(timeout); timeout = setTimeout(function() { instance.set('value', events.p); },200); }; events.mup = function() { $(W).off('mousemove', events.mmove).off('mouseup', events.mup); element.rclass(cls + '\_moved'); instance.set('touched', true); instance.set('modified', true); }; events.mmove = function(e) { var x = events.offset + (e.pageX - events.x); if (x > events.width) x = events.width; else if (x < 0) x = 0; element.aclass(cls + '\_moved'); timeout && clearTimeout(timeout); timeout = setTimeout(function() { instance.set('value', events.p); },200); update(x); }; events.mdown = function(e) { if (instance.state.disabled) return; e.preventDefault(); var target = e.target; var offset = element.offset(); events.offset = (thumb.css('left') || '').parseInt(); events.x = e.pageX; events.w = thumb.width(); events.width = rail.width(); if (target === track[0] || target === rail[0]) { var x = ((e.pageX - offset.left) - (events.w / 2)) >> 0; update(x); } else $(W).on('mousemove', events.mmove).on('mouseup', events.mup); }; element.on('mousedown', events.mdown); element.tclass('UI_required', config.required == true); instance.validate = function() { var value = instance.state.value; return config.required ? !!value : true; }; instance.default = function() { return ''; }; instance.on('reset', function() { instance.set('touched', false); instance.set('modified', false); }); instance.on('set', function(type, value, kind) { if (kind === 'nobind') return; switch (type) { case 'value': if (value <= 100) { thumb.css('left', value + '%'); track.css('width', value + '%'); valuelabel.text(value + '%'); } break; } }); instance.on('ready', function() { instance.check(); }); }; ``` -------------------------------- ### External Image Component Configuration and Rendering (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/externalimage/editor.html This JavaScript code defines the configuration and rendering logic for the External Image component in Total.js UIBuilder. It handles component setup, image source, dimensions, linking, and updates the element based on configuration changes. ```javascript exports.id = 'externalimage'; exports.group = 'Content'; exports.name = 'External image'; exports.icon = 'ti ti-image'; exports.author = 'Total.js'; exports.config = { src: 'https://cdn.totaljs.com/logo.png', rounded: true, width: '', height: '', link: false, url: '', newtab: true }; exports.render = 'auto'; exports.settings = 'auto'; exports.version = '1'; exports.make = function(instance, config, element) { var template = instance.maketemplate(instance.component.html); instance.on('configure', () => element.html(template(config))); instance.emit('configure'); }; ``` -------------------------------- ### Initialize DataView Component Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dataview/render.html Initializes the DataView component for Total.js UIBuilder. It sets up data loading, request handling, and event listeners based on the provided configuration. ```javascript exports.id = 'dataview'; exports.make = function(instance, config, element) { var interval = null; var query = {}; var querykeys = config.query ? config.query.split(',').trim() : null; var binded = false; var timeout = null; var load = function(data) { if (config.read) data = instance.read(data, config.read); instance.set('value', data); }; var requestforce = function() { timeout = null; if (config.path && !binded) return; instance.app.view(config.id, query, ERROR(load)); if (config.interval) interval = setTimeout(request, config.interval * 1000); }; var request = function() { timeout && clearTimeout(timeout); timeout = setTimeout(requestforce, 100); }; instance.on('destroy', function() { if (interval) { clearTimeout(interval); interval = null; } }); config.model && instance.watch(config.model, function(value) { if (!value || typeof(value) !== 'object') return; if (querykeys) { for (var key of querykeys) query[key] = value[key]; } else query = value; binded = true; request(); }); if (!config.model) instance.on('ready', request); }; ``` -------------------------------- ### Line Chart Component Initialization and Rendering (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/linechart/render.html This snippet demonstrates how to initialize and render a line chart using the Total.js UIBuilder framework and the ApexCharts library. It includes setting up the chart options, handling data updates, and configuring date formatting based on the 'datetype' property. ```javascript exports.id = 'linechart'; exports.import = ['https://cdnjs.cloudflare.com/ajax/libs/apexcharts/3.36.3/apexcharts.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/apexcharts/3.36.3/apexcharts.min.css']; exports.make = function(instance, config, element, cls) { var container = '
'.format(cls); var dateformat = ''; var chart = null; var options = {}; var timeout = null; element.append(container); switch (config.datetype) { case 'full': dateformat = '[date]'; break; case 'years': dateformat = 'yyyy'; break; case 'months': dateformat = 'MMM'; break; case 'days': dateformat = 'ddd'; break; case 'hours': dateformat = 'HH:mm'; break; } var options = { chart: { type: 'line', toolbar: { show: false, tools: { zoom: false } } }, plotOptions: { bar: { horizontal: true } }, stroke: { curve: 'smooth' || config.stroke, width: 3 }, legend: { show: true, position: 'bottom', fontSize: '11px', itemMargin: { vertical: 5 } }, noData: { text: 'No data' }, xaxis: { type: 'datetime', labels: { formatter: function(value, timestamp) { return new Date(timestamp).format(dateformat); }, style: { fontSize: '11px' } } }, yaxis: { max: max => (config.max ? config.max : max), min: min => (config.min ? config.min : min), labels: { formatter: value => value.format(config.decimals) + ' ' + config.unit } }, dataLabels: { enabled: false } }; var render = function(response) { for (var item of response) { if (item.value && item.value.length) { item.data = item.value; delete item.value; } } if (chart) { chart.updateSeries(response); } else { options.series = response; if (!config.unit && response.length) config.unit = response[0].unit; if (!config.decimals && response.length) config.decimals = response[0].decimals; chart = new ApexCharts(element.find('.{0}_linechart_apex'.format(cls))[0], options); chart.render(); } }; instance.on('value', function(response) { timeout && clearTimeout(timeout); timeout = setTimeout(render, 200, response); }); }; ``` -------------------------------- ### JavaScript WebSocket Integration for UI Components Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/wsreceiver/render.html This snippet demonstrates the core logic for integrating UI components with a WebSocket. It handles establishing a connection, receiving messages, updating component states based on incoming data, and sending component state changes back to the server. It includes features like automatic reconnection and configurable data sending. ```JavaScript exports.scope = true; exports.make = function(instance, config, element, cls) { instance.state.value = {}; var children = null; var skip = false; var socket; element.append('
'); var reconnect = function() { var url = config.endpoint; if (url.charAt(0) === '/') url = location.origin.replace(/^http/, 'ws') + url; socket = new WebSocket(url); socket.onclose = function() { socket = null; setTimeout(reconnect, 1000); }; socket.onmessage = onmessage; }; var onmessage = function(e) { var data; try { data = PARSE(e.data); } catch (e) { console.warn('WebSocket "{0}": {1}'.format(config.endpoint, e.toString())); return; } var value = instance.state.value; for (var m of children) { if ((m.state.bind || config.bindtoall) && m.config.path && m.config.path.charAt(0) !== '@') { var val = instance.read(data, m.config.path); if (val != undefined) m.set('value', val, 'noemitstate'); } } for (var key in data) value[key] = data[key]; instance.set('value', value); }; instance.on('ready', function() { children = instance.family(); reconnect(); }); instance.on('state', function(e) { e.stopPropagation(); if (!children || skip || !e.changes.value) return; var target = e.instance; if (!target.config.path || target.config.path.charAt(0) === '@') return; var value = target.state.value; var path = target.config.path; if (config.sendall) { instance.write(instance.state.value, path, value); socket && socket.send(STRINGIFY(instance.state.value)); } else { var obj = {}; instance.write(instance.state.value, path, value); target.write(obj, path, value); socket && socket.send(STRINGIFY(obj)); } skip = true; instance.set('value', instance.state.value); skip = false; }); }; ``` -------------------------------- ### Toggle Group Data Source Example Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/togglegroup/editor.html This JavaScript code snippet demonstrates the required data structure for the Toggle Group component's data source. It should be an array of objects, where each object represents a toggle option. Each option must have an `id` and a `name`. An optional `icon` property can be included to display an icon next to the option name. ```javascript [ { id: 1, name: 'Ruby', icon: 'ti ti-totaljs' // optional }, { id: 2, name: 'PHP', }, { id: 3, name: 'Node' }, { id: 4, name: 'Python' } ] ``` -------------------------------- ### Dynamic Source Component Configuration and Rendering (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dynamicsource/editor.html This JavaScript code defines the configuration and rendering logic for the 'Dynamic source' component in Total.js UIBuilder. It specifies component metadata, configuration options like 'id', 'text', and 'url', and a 'make' function that handles the component's rendering and event handling, specifically the 'configure' event to update the element's HTML. ```JavaScript exports.id = 'dynamicsource'; exports.name = 'Dynamic source'; exports.group = 'Data'; exports.author = 'Total.js'; exports.icon = 'ti ti-project-diagram'; exports.render = 'auto'; exports.settings = 'auto'; exports.version = '1'; exports.config = { id: 'id', text: 'name', name: 'Custom datasource', url: 'https://hostname.com/cities/{value}', items: [] }; exports.follow = true; exports.make = function(instance, config, element, cls) { element.aclass('UI_special m'); instance.on('configure', function() { element.html(''.format(instance.component.icon).args(config, 'escape')); }); instance.emit('configure'); }; ``` -------------------------------- ### Get and Watch GPS Position Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/datagps/render.html This JavaScript code snippet retrieves the current GPS position using `navigator.geolocation.getCurrentPosition` and optionally watches for position changes using `navigator.geolocation.watchPosition`. It processes the position data, formats it into an object with latitude, longitude, speed, altitude, and accuracy, and updates the UI component's value. It also includes a caching mechanism to avoid unnecessary updates if the position hasn't changed. ```javascript exports.id = 'datagps'; exports.make = function(instance, config, element) { var cache = ''; var position = function(pos) { var coords = pos.coords; var obj = {}; obj.lat = coords.latitude.floor(6); obj.lng = coords.longitude.floor(6); obj.speed = coords.speed; obj.altitude = coords.altitude; obj.accuracy = coords.accuracy; if (obj.speed) obj.speed = obj.speed.floor(1); if (obj.altitude) obj.altitude = obj.altitude.floor(2); if (obj.accuracy) obj.accuracy = obj.accuracy.floor(2); obj.pos = obj.lat + ',' + obj.lng; var key = obj.pos + ',' + (obj.speed || '0') + ',' + (obj.altitude || '0'); if (cache && cache === key) return; cache = key; instance.set('value', obj); }; var geo = navigator.geolocation; geo.getCurrentPosition(position); config.watcher && geo.watchPosition(position); }; ``` -------------------------------- ### Initialize UIBuilder Component with Data Fetching (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/dynamicsource/render.html This JavaScript code initializes a UIBuilder component. It can set an initial 'value' from configuration or fetch data using AJAX. The data fetching is configurable with URL, data mapping (id, text), and can be triggered by 'notify' events or on initialization. ```javascript exports.make = function(instance, config) { // Internal flag instance.state.notify = true; // Set initial value if items are provided in config if (config.items && config.items.length) { instance.set('value', config.items); return; } // Function to fetch data var fetchdata = function(value) { // If path is configured but no value is provided, reset value to empty array if (config.path && !value) { instance.set('value', []); return; } // Construct URL with arguments var url = config.url.args({ value: value || '' }); // Perform AJAX GET request AJAX('GET ' + url, function(response, err) { if (err) return; var arr = []; // Map response data to desired format for (var m of response) { var obj = {}; obj.id = m[config.id]; obj.name = m[config.text]; arr.push(obj); } // Set the fetched and mapped value instance.set('value', arr); }); }; // Attach fetchdata to 'notify' event if path is configured, otherwise call fetchdata immediately if (config.path) instance.on('notify', fetchdata); else fetchdata(); }; ``` -------------------------------- ### Stylebox Component Implementation (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/stylebox/render.html This JavaScript code defines the 'stylebox' component for Total.js UIBuilder. The `make` function takes an instance, configuration, element, and class name to dynamically apply styles (background, padding, border, radius, shadow) to the element by adding corresponding CSS classes. It also injects a container div with a nested UI component placeholder. ```javascript exports.id = 'stylebox'; exports.make = function(instance, config, element, cls) { var builder = []; config.background && builder.push(cls + '_bg'); config.padding && builder.push(cls + '_padding'); config.border && builder.push(cls + '_border'); config.radius && builder.push(cls + '_radius'); config.shadow && builder.push(cls + '_shadow'); builder.length && element.aclass(builder.join(' ')); element.html('
'.format(cls)); }; ``` -------------------------------- ### UI Input Component Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/applayout/settings.html Demonstrates the usage of the 'ui-component' with the 'input' type for various fields like ID, Name, Icon, and Color. It shows how to set configurations such as 'required', 'type', and default values. ```HTML ID Name Icon Icon color ``` -------------------------------- ### DataGrid Component Configuration and Rendering Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/datagrid/editor.html This snippet defines the configuration, inputs, outputs, and rendering logic for the DataGrid component. It includes properties for datasource, styling, and event handling, along with a `make` function to render the component's HTML and handle configuration updates. ```javascript exports.id = 'datagrid'; exports.name = 'DataGrid'; exports.group = 'List'; exports.icon = 'ti ti-table-alt'; exports.author = 'Total.js'; exports.config = { datasource: '', border: true, icon: 'ti ti-totaljs', columns: [], margin: 0, height: '500', minheight: 300, numbering: true, checkbox: false, autoselect: false, dynamic: false }; exports.render = 'auto'; exports.settings = 'auto'; exports.version = '1'; exports.inputs = [ { id: 'rows', name: 'Rows' } ]; exports.outputs = [ { id: 'row', name: 'On row' }, { id: 'button', name: 'On button' } ]; exports.make = function(instance, config, element) { element.html('
{0}
'.format(config.type).args(instance.name)); instance.on('configure', function() { var builder = []; for (var m of config.columns) builder.push('
{0} {1}
'.format(m.name, m.type || 'string')); element.find('.UI_special > div').html(builder.join('')); element.find('label').text(config.name); }); instance.emit('configure'); }; ``` -------------------------------- ### Show Component Definition (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/show/editor.html Defines the 'Show' component for Total.js UIBuilder. It includes properties like ID, name, group, icon, configuration options, and a render function. The render function sets up the component's HTML structure and handles updates when the component is configured. ```javascript exports.id = 'show'; exports.name = 'Show components'; exports.group = 'Logical'; exports.icon = 'ti ti-eye'; exports.author = 'Total.js'; exports.config = { border: true, type: 'show', condition: 'positive', value: '' }; exports.render = 'auto'; exports.settings = 'auto'; exports.version = '1'; exports.gap = true; exports.make = function(instance, config, element) { element.html('
{0}
'.format(config.name.encode()).args(instance.component)); instance.on('configure', function() { element.find('> .UI_label span').text(config.name); }); }; ``` -------------------------------- ### UIBuilder Part Component Implementation (JavaScript) Source: https://github.com/totaljs/uibuildercomponents/blob/main/components/part/editor.html This snippet defines a 'Part' component for Total.js UIBuilder. It includes metadata like ID, name, group, author, and icon. The configuration allows for border and visibility checks, and specifies the component's URL. The `render` function sets up the component's HTML structure and handles the 'configure' event to update the displayed label and URL. ```javascript exports.id = 'part'; exports.name = 'Part'; exports.group = 'Parts'; exports.author = 'Total.js'; exports.config = { border: false, checkvisible: true, url: '' }; exports.render = 'auto'; exports.settings = 'auto'; exports.type = ['app', 'dashboard', 'mobile', 'uicomponent']; exports.version = '1'; exports.make = function(instance, config, element) { element.aclass('UI_special').html('
'.format(instance.component.icon)); instance.on('configure', function() { element.find('label').text(config.name); var name = DEF.cl.apps.findValue('id', config.url, 'name', ''); element.find('div').text(name || config.url); }); instance.emit('configure'); }; ```