Files
vvveb-cms/static/Vvvebjs/libs/builder/components-bootstrap5.js
2026-05-17 21:09:32 +08:00

1031 lines
30 KiB
JavaScript

/*
Copyright 2017 Ziadin Givan
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
https://github.com/givanz/Vvvebjs
*/
Vvveb.ComponentsGroup['Bootstrap 5'] =
["html/container", "html/gridrow", "html/btn", "html/btn-link", "html/buttongroup", "html/buttontoolbar", "html/alert", "html/card", "html/listgroup", "html/badge", "html/progress", "html/navbar", "html/breadcrumbs", "html/pagination"];
Vvveb.Components.extend("_base", "html/container", {
classes: ["container", "container-fluid"],
image: "icons/container.svg",
html: '<div class="container" style="min-height:150px;"><div class="m-5">Container</div></div>',
name: "Container",
properties: [
{
name: "Type",
key: "type",
htmlAttr: "class",
inputtype: SelectInput,
validValues: ["container", "container-fluid"],
data: {
options: [{
value: "container",
text: "Default"
},{
value: "container-fluid",
text: "Fluid"
}]
}
},{
name: "Background",
key: "background",
htmlAttr: "class",
validValues: bgcolorClasses,
inputtype: SelectInput,
data: {
options: bgcolorSelectOptions
}
},{
name: "Background Color",
key: "background-color",
htmlAttr: "style",
inputtype: ColorInput,
},{
name: "Text Color",
key: "color",
htmlAttr: "style",
inputtype: ColorInput,
}],
});
Vvveb.Components.extend("html/link", "html/btn", {
classes: ["btn"],
nodes: null,
name: "Button",
image: "icons/button.svg",
html: '<a class="btn btn-primary">Primary</a>',
properties: [{
name: "Background",
key: "background",
htmlAttr: "class",
inputtype: SelectInput,
validValues: ["btn-default", "btn-primary", "btn-info", "btn-success", "btn-warning", "btn-info", "btn-light", "btn-dark", "btn-outline-primary", "btn-outline-info", "btn-outline-success", "btn-outline-warning", "btn-outline-info", "btn-outline-light", "btn-outline-dark", "btn-link"],
data: {
options: [{
value: "btn-default",
text: "Default"
},{
value: "btn-primary",
text: "Primary"
},{
value: "btn btn-info",
text: "Info"
},{
value: "btn-success",
text: "Success"
},{
value: "btn-warning",
text: "Warning"
},{
value: "btn-info",
text: "Info"
},{
value: "btn-light",
text: "Light"
},{
value: "btn-dark",
text: "Dark"
},{
value: "btn-outline-primary",
text: "Primary outline"
},{
value: "btn btn-outline-info",
text: "Info outline"
},{
value: "btn-outline-success",
text: "Success outline"
},{
value: "btn-outline-warning",
text: "Warning outline"
},{
value: "btn-outline-info",
text: "Info outline"
},{
value: "btn-outline-light",
text: "Light outline"
},{
value: "btn-outline-dark",
text: "Dark outline"
},{
value: "btn-link",
text: "Link"
}]
}
},{
name: "Size",
key: "size",
htmlAttr: "class",
inputtype: SelectInput,
validValues: ["btn-lg", "btn-sm"],
data: {
options: [{
value: "",
text: "Default"
},{
value: "btn-lg",
text: "Large"
},{
value: "btn-sm",
text: "Small"
}]
}
},{
name: "Autofocus",
key: "autofocus",
htmlAttr: "autofocus",
inputtype: CheckboxInput,
inline:true,
col:6,
},{
name: "Disabled",
key: "disabled",
htmlAttr: "class",
inline:true,
col:6,
inputtype: ToggleInput,
validValues: ["disabled"],
data: {
on: "disabled",
off: null
}
},{
key: "link_options",
inputtype: SectionInput,
name:false,
data: {header:"Link"},
}]
});
Vvveb.Components.extend("_base", "html/buttongroup", {
classes: ["btn-group"],
name: "Button Group",
image: "icons/button_group.svg",
html: '<div class="btn-group" role="group" aria-label="Basic example"><button type="button" class="btn btn-secondary">Left</button><button type="button" class="btn btn-secondary">Middle</button> <button type="button" class="btn btn-secondary">Right</button></div>',
properties: [{
name: "Size",
key: "size",
htmlAttr: "class",
inputtype: SelectInput,
validValues: ["btn-group-lg", "btn-group-sm"],
data: {
options: [{
value: "",
text: "Default"
},{
value: "btn-group-lg",
text: "Large"
},{
value: "btn-group-sm",
text: "Small"
}]
}
},{
name: "Alignment",
key: "alignment",
htmlAttr: "class",
inputtype: SelectInput,
validValues: ["btn-group", "btn-group-vertical"],
data: {
options: [{
value: "",
text: "Default"
},{
value: "btn-group",
text: "Horizontal"
},{
value: "btn-group-vertical",
text: "Vertical"
}]
}
}]
});
Vvveb.Components.extend("_base", "html/buttontoolbar", {
classes: ["btn-toolbar"],
name: "Button Toolbar",
image: "icons/button_toolbar.svg",
html: '<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">\
<div class="btn-group me-2" role="group" aria-label="First group">\
<button type="button" class="btn btn-secondary">1</button>\
<button type="button" class="btn btn-secondary">2</button>\
<button type="button" class="btn btn-secondary">3</button>\
<button type="button" class="btn btn-secondary">4</button>\
</div>\
<div class="btn-group me-2" role="group" aria-label="Second group">\
<button type="button" class="btn btn-secondary">5</button>\
<button type="button" class="btn btn-secondary">6</button>\
<button type="button" class="btn btn-secondary">7</button>\
</div>\
<div class="btn-group" role="group" aria-label="Third group">\
<button type="button" class="btn btn-secondary">8</button>\
</div>\
</div>'
});
Vvveb.Components.extend("_base","html/alert", {
classes: ["alert"],
name: "Alert",
image: "icons/alert.svg",
html: '<div class="alert alert-warning alert-dismissible fade show" role="alert">\
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">\
<!--span aria-hidden="true">&times;</span-->\
</button>\
<strong>Holy guacamole!</strong> You should check in on some of those fields below.\
</div>',
properties: [{
name: "Type",
key: "type",
htmlAttr: "class",
validValues: ["alert-primary", "alert-secondary", "alert-success", "alert-danger", "alert-warning", "alert-info", "alert-light", "alert-dark"],
inputtype: SelectInput,
data: {
options: [{
value: "alert-primary",
text: "Default"
},{
value: "alert-secondary",
text: "Secondary"
},{
value: "alert-success",
text: "Success"
},{
value: "alert-danger",
text: "Danger"
},{
value: "alert-warning",
text: "Warning"
},{
value: "alert-info",
text: "Info"
},{
value: "alert-light",
text: "Light"
},{
value: "alert-dark",
text: "Dark"
}]
}
}]
});
Vvveb.Components.extend("_base", "html/badge", {
classes: ["badge"],
image: "icons/badge.svg",
name: "Badge",
html: '<span class="badge bg-primary">Primary badge</span>',
properties: [{
name: "Color",
key: "color",
htmlAttr: "class",
validValues:["bg-primary", "bg-secondary", "bg-success", "bg-danger", "bg-warning", "bg-info", "bg-body-secondary", "bg-dark"],
inputtype: SelectInput,
data: {
options: [{
value: "",
text: "Default"
},{
value: "bg-primary",
text: "Primary"
},{
value: "bg-secondary",
text: "Secondary"
},{
value: "bg-success",
text: "Success"
},{
value: "bg-warning",
text: "Warning"
},{
value: "bg-danger",
text: "Danger"
},{
value: "bg-info",
text: "Info"
},{
value: "bg-body-secondary",
text: "Light"
},{
value: "bg-dark",
text: "Dark"
}]
}
}]
});
Vvveb.Components.extend("_base", "html/card", {
classes: ["card"],
image: "icons/panel.svg",
name: "Card",
html: '<div class="card">\
<img class="card-img-top bg-body-secondary" src="' + Vvveb.baseUrl + 'icons/image.svg" alt="Card image cap">\
<div class="card-body">\
<h4 class="card-title">Card title</h4>\
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card\'s content.</p>\
<a href="#" class="btn btn-primary">Go somewhere</a>\
</div>\
</div>'
});
Vvveb.Components.extend("_base", "html/listgroup", {
name: "List Group",
image: "icons/list_group.svg",
classes: ["list-group"],
html: '<ul class="list-group">\n <li class="list-group-item">\n <span class="badge bg-success">14</span>\n Cras justo odio\n </li>\n <li class="list-group-item">\n <span class="badge bg-primary">2</span>\n Dapibus ac facilisis in\n </li>\n <li class="list-group-item">\n <span class="badge bg-danger">1</span>\n Morbi leo risus\n </li>\n</ul>',
properties: [{
name: "Flush",
key: "flush",
htmlAttr: "class",
validValues: ["", "list-group-flush"],
inputtype: ToggleInput,
data: {
on: "list-group-flush",
off: ""
}
},{
name: "Numbered",
key: "numbered",
htmlAttr: "class",
validValues: ["", "list-group-numbered"],
inputtype: ToggleInput,
data: {
on: "list-group-numbered",
off: ""
}
},{
name: "Horizontal",
key: "horizontal",
htmlAttr: "class",
validValues: ["", "list-group-horizontal"],
inputtype: ToggleInput,
data: {
on: "list-group-horizontal",
off: ""
}
}]
});
Vvveb.Components.extend("_base", "html/listitem", {
name: "List Item",
classes: ["list-group-item"],
html: '<li class="list-group-item"><span class="badge bg-primary">14</span> Cras justo odio</li>',
properties: [{
name: "Background",
key: "background",
htmlAttr: "class",
validValues:["list-group-item-primary", "list-group-item-secondary", "list-group-item-success", "list-group-item-danger", "list-group-item-warning", "list-group-item-info", "list-group-item-light", "list-group-item-dark"],
inputtype: SelectInput,
data: {
options: [{
value: "",
text: "Default"
},{
value: "list-group-item-primary",
text: "Primary"
},{
value: "list-group-item-secondary",
text: "Secondary"
},{
value: "list-group-item-success",
text: "Success"
},{
value: "list-group-item-warning",
text: "Warning"
},{
value: "list-group-item-danger",
text: "Danger"
},{
value: "list-group-item-info",
text: "Info"
},{
value: "list-group-item-light",
text: "Light"
},{
value: "list-group-item-dark",
text: "Dark"
}]
}
}, {
name: "Active",
key: "active",
htmlAttr: "class",
validValues: ["", "active"],
inputtype: ToggleInput,
inline:true,
col:6,
data: {
on: "active",
off: ""
}
},{
name: "Disabled",
key: "disabled",
htmlAttr: "class",
validValues: ["", "disabled"],
inputtype: ToggleInput,
inline:true,
col:6,
data: {
on: "disabled",
off: ""
}
}]
});
Vvveb.Components.extend("_base", "html/breadcrumbs", {
classes: ["breadcrumb"],
name: "Breadcrumbs",
image: "icons/breadcrumbs.svg",
html: `<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item"><a href="#">Library</a></li>
s<li class="breadcrumb-item active" aria-current="page"><a href="#">Book</a></li>
</ol>`,
properties: [{
name: "Divider",
key: "--bs-breadcrumb-divider",
htmlAttr: "style",
inputtype: TextInput
}]
});
Vvveb.Components.extend("_base", "html/breadcrumbitem", {
classes: ["breadcrumb-item"],
name: "Breadcrumb Item",
html: '<li class="breadcrumb-item"><a href="#">Library</a></li>',
properties: [{
name: "Active",
key: "active",
htmlAttr: "class",
validValues: ["", "active"],
inputtype: ToggleInput,
data: {
on: "active",
off: ""
}
}]
});
Vvveb.Components.extend("_base", "html/pagination", {
classes: ["pagination"],
name: "Pagination",
image: "icons/pagination.svg",
html: '<nav aria-label="Page navigation example">\
<ul class="pagination">\
<li class="page-item"><a class="page-link" href="#">Previous</a></li>\
<li class="page-item"><a class="page-link" href="#">1</a></li>\
<li class="page-item"><a class="page-link" href="#">2</a></li>\
<li class="page-item"><a class="page-link" href="#">3</a></li>\
<li class="page-item"><a class="page-link" href="#">Next</a></li>\
</ul>\
</nav>',
properties: [{
name: "Size",
key: "size",
htmlAttr: "class",
inputtype: SelectInput,
validValues: ["pagination-lg", "pagination-sm"],
data: {
options: [{
value: "",
text: "Default"
},{
value: "pagination-lg",
text: "Large"
},{
value: "pagination-sm",
text: "Small"
}]
}
},{
name: "Alignment",
key: "alignment",
htmlAttr: "class",
inputtype: SelectInput,
validValues: ["justify-content-center", "justify-content-end"],
data: {
options: [{
value: "",
text: "Default"
},{
value: "justify-content-center",
text: "Center"
},{
value: "justify-content-end",
text: "Right"
}]
}
}]
});
Vvveb.Components.extend("_base", "html/pageitem", {
classes: ["page-item"],
html: '<li class="page-item"><a class="page-link" href="#">1</a></li>',
name: "Pagination Item",
properties: [{
name: "Link To",
key: "href",
htmlAttr: "href",
child:".page-link",
inputtype: LinkInput
},{
name: "Active",
key: "active",
htmlAttr: "class",
validValues: ["active"],
inputtype: ToggleInput,
data: {
on: "active",
off: ""
}
},{
name: "Disabled",
key: "disabled",
htmlAttr: "class",
validValues: ["disabled"],
inputtype: ToggleInput,
data: {
on: "disabled",
off: ""
}
}]
});
Vvveb.Components.extend("_base", "html/progress", {
classes: ["progress"],
name: "Progress Bar",
image: "icons/progressbar.svg",
html: '<div class="progress"><div class="progress-bar w-25"></div></div>',
properties: [{
name: "Background",
key: "background",
htmlAttr: "class",
validValues: bgcolorClasses,
inputtype: SelectInput,
data: {
options: bgcolorSelectOptions
}
},
{
name: "Progress",
key: "background",
child:".progress-bar",
htmlAttr: "class",
validValues: ["", "w-25", "w-50", "w-75", "w-100"],
inputtype: SelectInput,
data: {
options: [{
value: "",
text: "None"
},{
value: "w-25",
text: "25%"
},{
value: "w-50",
text: "50%"
},{
value: "w-75",
text: "75%"
},{
value: "w-100",
text: "100%"
}]
}
},
{
name: "Progress background",
key: "background",
child:".progress-bar",
htmlAttr: "class",
validValues: bgcolorClasses,
inputtype: SelectInput,
data: {
options: bgcolorSelectOptions
}
},{
name: "Striped",
key: "striped",
child:".progress-bar",
htmlAttr: "class",
validValues: ["", "progress-bar-striped"],
inputtype: ToggleInput,
data: {
on: "progress-bar-striped",
off: "",
}
},{
name: "Animated",
key: "animated",
child:".progress-bar",
htmlAttr: "class",
validValues: ["", "progress-bar-animated"],
inputtype: ToggleInput,
data: {
on: "progress-bar-animated",
off: "",
}
}]
});
Vvveb.Components.extend("_base", "html/navbar", {
classes: ["navbar"],
image: "icons/navbar.svg",
name: "Nav Bar",
html: `<nav class="navbar navbar-expand-lg bg-body-secondary bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo02">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled">Disabled</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>`,
properties: [{
name: "Color theme",
key: "color",
htmlAttr: "class",
validValues: ["navbar-light", "navbar-dark"],
inputtype: SelectInput,
data: {
options: [{
value: "",
text: "Default"
},{
value: "navbar-light",
text: "Light"
},{
value: "navbar-dark",
text: "Dark"
}]
}
},{
name: "Background color",
key: "background",
htmlAttr: "class",
validValues: bgcolorClasses,
inputtype: SelectInput,
data: {
options: bgcolorSelectOptions
}
},{
name: "Placement",
key: "placement",
htmlAttr: "class",
validValues: ["fixed-top", "fixed-bottom", "sticky-top"],
inputtype: SelectInput,
data: {
options: [{
value: "",
text: "Default"
},{
value: "fixed-top",
text: "Fixed Top"
},{
value: "fixed-bottom",
text: "Fixed Bottom"
},{
value: "sticky-top",
text: "Sticky top"
}]
}
}]
});
Vvveb.Components.extend("_base", "html/tablebody", {
nodes: ["tbody"],
name: "Table Body",
html: "<tbody><tr><td>Cell 1</td><td>Cell 2</td><td>Cell 3</td></tr></tbody>"
});
Vvveb.Components.extend("_base", "html/gridcolumn", {
name: "Grid Column",
image: "icons/grid_column.svg",
classesRegex: ["col-"],
classes: ["col"],
html: '<div class="col-sm-4"><h3>col-sm-4</h3></div>',
properties: [{
name: "Column",
key: "column",
inline:false,
inputtype: GridInput,
data: {hide_remove:true},
beforeInit: function(node) {
_class = node.getAttribute("class");
let reg = /col(-[^-\$ ]*)?-?(\d+)?/g;
let match;
while ((match = reg.exec(_class)) != null) {
let key = "col" + ((match[1] != undefined) ? "_" + match[1].replace('-','') : "");
this.data[key] = match[2] ?? '';
}
},
onChange: function(node, value, input) {
let _class = node.getAttribute("class");
//remove previous breakpoint column size
_class = _class.replace(new RegExp(input.name + '-\\d+?'), '');
//add new column size
if (value) _class += ' ' + input.name + '-' + value;
node.setAttribute("class", _class);
return node;
},
}]
});
Vvveb.Components.extend("_base", "html/gridrow", {
name: "Grid Row",
image: "icons/grid_row.svg",
classes: ["row"],
html: '<div class="row"><div class="col-sm-4"><h3>col-sm-4</h3></div><div class="col-sm-4 col-5"><h3>col-sm-4</h3></div><div class="col-sm-4"><h3>col-sm-4</h3></div></div>',
children :[{
name: "html/gridcolumn",
classesRegex: ["col-"],
}],
beforeInit: function (node) {
properties = [];
let i = 0;
let j = 0;
node.querySelectorAll('[class*="col-"],.col').forEach(el => {
_class = el.getAttribute("class");
let reg = /col(-[^-\$ ]*)?-?(\d+)?/g;
let match;
let data = {};
while ((match = reg.exec(_class)) != null) {
let key = "col" + ((match[1] != undefined) ? "_" + match[1].replace('-','') : "");
data[key] = match[2] ?? '';
}
i++;
properties.push({
name: "Column " + i,
key: "column" + i,
//index: i - 1,
columnNode: el,
col:12,
inline:false,
inputtype: GridInput,
data: data,
onChange: function(node, value, input) {
let column = this.columnNode;
//if remove button is clicked remove column and render row properties
if (input.nodeName == 'BUTTON') {
column.remove();
Vvveb.Components.render("html/gridrow");
return node;
}
//if select input then change column class
_class = column.getAttribute("class");
//remove previous breakpoint column size
_class = _class.replace(new RegExp(input.name + '-\\d+?'), '');
//add new column size
if (value) _class += ' ' + input.name + '-' + value;
column.setAttribute("class", _class);
return node;
},
});
});
//remove all column properties
this.properties = this.properties.filter(function(item) {
return item.key.indexOf("column") === -1;
});
//add remaining properties to generated column properties, put first 2 align properties first
this.properties = this.properties.slice(0,4).concat(properties, this.properties.slice(4));
return node;
},
properties: [{
name: "Direction",
key: "direction",
htmlAttr: "class",
inline:false,
validValues: ["", "flex-row", "flex-row-reverse", "flex-column", "flex-column-reverse"],
inputtype: RadioButtonInput,
data: {
extraclass:"btn-group-sm btn-group-fullwidth",
options: [{
value: "",
icon:"la la-times",
//text: "None",
title: "Default",
checked:true,
},{
value: "flex-row",
//text: "Left",
title: "Row - horizontal",
icon:"la la-arrow-right",
checked:false,
},{
value: "flex-column",
//text: "Center",
title: "Column - vertical",
icon:"la la-arrow-down",
checked:false,
},{
value: "flex-row-reverse",
//text: "Right",
title: "Row - reversed",
icon:"la la-arrow-left",
checked:false,
},{
value: "flex-column-reverse",
//text: "Center",
title: "Column - reversed",
icon:"la la-arrow-up",
checked:false,
}],
},
},{
name: "Vertical align",
key: "vertical-align",
htmlAttr: "class",
inline:false,
validValues: ["", "align-items-start", "align-items-center", "align-items-end", "align-items-baseline", "align-items-stretch"],
inputtype: RadioButtonInput,
data: {
extraclass:"btn-group-sm btn-group-fullwidth",
options: [{
value: "",
icon:"la la-times",
//text: "None",
title: "None",
checked:true,
},{
value: "align-items-start",
//text: "Left",
title: "Start",
icon:"la la-align-left",
checked:false,
},{
value: "align-items-center",
//text: "Center",
title: "Center",
icon:"la la-align-center",
checked:false,
},{
value: "align-items-end",
//text: "Right",
title: "End",
icon:"la la-align-right",
checked:false,
},{
value: "align-items-baseline",
title: "Baseline",
icon:"la la-indent",
checked:false,
},{
value: "align-items-stretch",
title: "Stretch",
icon:"la la-align-justify",
checked:false,
}],
},
},{
name: "Horizontal align",
key: "horizontal-align",
htmlAttr: "class",
inline:false,
validValues: ["", "justify-content-start", "justify-content-center", "justify-content-end", "justify-content-around", "justify-content-between", "justify-content-evenly"],
inputtype: RadioButtonInput,
data: {
extraclass:"btn-group-sm btn-group-fullwidth",
options: [{
value: "",
icon:"la la-times",
//text: "None",
title: "None",
checked:true,
},{
value: "justify-content-start",
//text: "Left",
title: "Start",
icon:"la la-align-left",
checked:false,
},{
value: "justify-content-center",
//text: "Center",
title: "Center",
icon:"la la-align-center",
checked:false,
},{
value: "justify-content-end",
//text: "Right",
title: "End",
icon:"la la-align-right",
checked:false
},{
value: "justify-content-around",
//text: "Left",
title: "Around",
icon:"la la-indent",
checked:false,
},{
value: "justify-content-between",
//text: "Center",
title: "Between",
icon:"la la-outdent",
checked:false,
},{
value: "justify-content-evenly",
//text: "Right",
title: "Evenly",
icon:"la la-align-justify",
checked:false,
}],
},
},{
name: "Wrap",
key: "wrap",
htmlAttr: "class",
inline:false,
validValues: ["", "flex-wrap", "flex-nowrap"],
inputtype: RadioButtonInput,
data: {
extraclass:"btn-group-sm btn-group-fullwidth",
options: [{
value: "",
icon:"la la-times",
//text: "None",
title: "None",
checked:true,
},{
value: "flex-wrap",
//text: "Left",
title: "Wrap",
icon:"la la-undo",
checked:false,
},{
value: "flex-nowrap",
//text: "Center",
title: "No wrap",
icon:"la la-arrow-right",
checked:false,
}],
},
},{
name: "Column",
key: "column1",
inputtype: GridInput
},{
name: "Column",
key: "column1",
inline:true,
col:12,
inputtype: GridInput
},{
name: "",
key: "addChild",
inline:true,
inputtype: ButtonInput,
data: {text:"Add column", icon:"la la-plus", className:"btn-secondary"},
onChange: function(node)
{
node.append(generateElements('<div class="col-3"><h3>Col-3</h3></div>')[0]);
//render component properties again to include the new column inputs
Vvveb.Components.render("html/gridrow");
return node;
}
}]
});