Skip to content

Commit

Permalink
add composite list type.
Browse files Browse the repository at this point in the history
  • Loading branch information
wildone committed Apr 22, 2024
1 parent 3d2bb38 commit 677e3bc
Show file tree
Hide file tree
Showing 7 changed files with 395 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
"ai.typerefinery.websight.components.forms.composite"
],
"css": [
"style.css"
],
"js": [
"/apps/typerefinery/clientlibs/vendor/sortable/sortable.js",
"functions.js",
"behaviour.js"
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,58 @@ window.Typerefinery.Components = Typerefinery.Components || {};
window.Typerefinery.Components.Forms = Typerefinery.Components.Forms || {};
window.Typerefinery.Components.Forms.Composite = Typerefinery.Components.Forms.Composite || {};

;(function (ns, document) {
;(function (ns, componentsNs, document) {
"use strict";
$(document).ready(function () {
console.log('Composite component Behaviour loaded');
$("[component='composite']").each(function () {
ns.init(this);

//init and watch for new components
componentsNs.watchDOMForComponent(`${ns.selectorComponent}${ns.selector}`, ns.init);

//listen for change event on all input fields and compile value for composite input
$(document).on("change", `${ns.selectorComponent}`, function() {
console.group("document onchange - composite change");
console.log($(this));
ns.compileValue($(this));
console.groupEnd();
});

//composite list global event listeners
//move current row to top
$(document).on("click", `${ns.selectorComponent} .top`, function() {
$(this).closest(".rows").prepend($(this).closest(".row"));
});

//move current row to bottom
$(document).on("click", `${ns.selectorComponent} .bottom`, function() {
$(this).closest(".rows").append($(this).closest(".row"));
});

//move current row above next sibling
$(document).on("click", `${ns.selectorComponent} .up`, function() {
if ($(this).closest(".row").prev().length > 0) {
$(this).closest(".row").prev().before($(this).closest(".row"));
}
});

//move current row below previous sibling
$(document).on("click", `${ns.selectorComponent} .down`, function() {
if ($(this).closest(".row").next().length > 0) {
$(this).closest(".row").next().after($(this).closest(".row"));
}
});

//move current row to trash
$(document).on("click", `${ns.selectorComponent} .delete`, function() {
//remove row if new
if ($(this).closest(".row").attr("state") == "new") {
$(this).closest(".row").remove();
} else {
//move row to trash if existing
$(this).closest(".row").attr("state", "deleted");
$(this).closest(`${ns.selectorComponent}`).find(".trash").append($(this).closest(".row"));
}
});

});
})(window.Typerefinery.Components.Forms.Composite, document);
})(window.Typerefinery.Components.Forms.Composite, window.Typerefinery.Components, document);
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ window.Typerefinery.Components.Forms.Form = Typerefinery.Components.Forms.Form |
window.Typerefinery.Components.Forms.Composite = Typerefinery.Components.Forms.Composite || {};


;(function ($, ns, componentsNs, formNs, document, window) {
;(function ($, ns, componentsNs, formNs, Sortable, document, window) {
"use strict";


ns.selectorComponentName = "composite";
ns.selectorComponent = "[component=composite]";
ns.selectorAttribute = "isCompositeParent";
ns.selector = `[${ns.selectorAttribute}]`;
ns.selectorValueAttribute = "isCompositeValue";
Expand All @@ -21,35 +23,96 @@ window.Typerefinery.Components.Forms.Composite = Typerefinery.Components.Forms.C
//template for form components in parent
ns.selectorTemplate = "> [template]";
ns.selectorNameAttribute = "name";
ns.selectorName = `[${ns.selectorNameAttribute}]`;
ns.selectorIdAttribute = "id";
ns.selectorTypeList = "list";

$.fn.findExclude = function(selector, mask) {
return this.find(selector).not(this.find(mask).find(selector));
}

$.fn.compositeVal = function(addFieldHint) {
//get all immediate isCompositeParent
var $compositeParents = this.parent(ns.selector).findExclude(ns.selector,ns.selector);
var data = {};

//add current field values to data
Object.assign(data,JSON.parse(this.val()));
console.group('compositeVal');
const type = this.attr('type');
const isList = type === ns.selectorTypeList;
console.group("type", type);
console.group("isList", isList);

//for each get their values and merge their composites in
$compositeParents.each(function(){
//find composite value input field
var $compositeValue = $(this).findExclude(ns.selectorValue,ns.selector);
if ($compositeValue) {
// create placeholder for composite value
data[$compositeValue.attr(ns.selectorNameAttribute)] = {};
// get composite value for this field, this will cascade to other composite fields
Object.assign(data[$compositeValue.attr(ns.selectorNameAttribute)],$compositeValue.compositeVal());
}
});
return data;
if (!isList) {
//get all immediate isCompositeParent components
var $compositeParents = this.parent(ns.selector).findExclude(ns.selector,ns.selector);
var data = {};

console.log("this.value", this.val());
//add current field values to data
Object.assign(data,JSON.parse(this.val()));

console.log("compositeParents", $compositeParents);
//for each get their values and merge their composites in
$compositeParents.each(function(){
//find composite value input field
var $compositeValue = $(this).findExclude(ns.selectorValue,ns.selector);
console.log("compositeValue", $compositeValue);
if ($compositeValue) {
const compositeValueName = $compositeValue.attr(ns.selectorNameAttribute);
console.log("compositeValueName", compositeValueName);
// create placeholder for composite value
data[compositeValueName] = {};
// get composite value for this field, this will cascade to other composite fields
Object.assign(data[compositeValueName],$compositeValue.compositeVal(addFieldHint));
}
});
console.groupEnd();
return data;
} else {
var data = [];
console.log("parent", this.parent(ns.selector));
console.log("rows", this.parent(ns.selector).find('.row'));
this.parent(ns.selector).find('.row').each(function() {
console.log("row", this);
const $row = $(this);
const $rowContents = $row.find('.content');
console.log("contents", $rowContents);

var rowData = {};
//get all simple input fields and add to data
$rowContents.find(ns.selectorInput).each(function() {
const $field = $(this);
console.log("$field", $field);
rowData[$field.attr(ns.selectorNameAttribute)] = $field.val();
});
console.log("rowData", JSON.stringify(rowData));
//get all immediate isCompositeParent components and add to data
var $compositeParents = $rowContents.findExclude(ns.selector,ns.selector);
console.log("compositeParents", $compositeParents);
$compositeParents.each(function(){
//find composite value input field
var $compositeValue = $(this).findExclude(ns.selectorValue,ns.selector);
console.log("compositeValue", $compositeValue);
if ($compositeValue) {
const compositeValueName = $compositeValue.attr(ns.selectorNameAttribute);
console.log("compositeValueName", compositeValueName);
// create placeholder for composite value
var data = {};
// get composite value for this field, this will cascade to other composite fields
Object.assign(data,$compositeValue.compositeVal(addFieldHint));
rowData[compositeValueName] = data;
}
console.log("rowData", JSON.stringify(rowData));
});
//add row data to data
data.push(rowData);
});
console.groupEnd();
return data;
}
}

ns.setValue = function($compositeParent, data) {

const type = $compositeParent.attr('type');
const isList = type === ns.selectorTypeList;

//get all immediate isCompositeParent
var $compositeParents = $compositeParent.parent(ns.selector).findExclude(ns.selector,ns.selector);
//set value of composite input
Expand Down Expand Up @@ -90,28 +153,97 @@ window.Typerefinery.Components.Forms.Composite = Typerefinery.Components.Forms.C
$field.val(JSON.stringify(data));
}

ns.init = async ($component) => {
const componentConfig = componentsNs.getComponentConfig($component);
ns.addRow = function($compositeParent) {
var $newRow = $($compositeParent.find("template.content").html());
const $templateActions = $($compositeParent.find("template.actions").html());
const $templateMove = $($compositeParent.find("template.move").html());

//add move and actions to new row
$newRow.prepend($templateMove.clone());
$newRow.append($templateActions.clone());
$newRow.attr('id', 'row-' + Math.random().toString(36));
$newRow.attr('state', "new");

$compositeParent.find(".rows").append($newRow.clone());
}

ns.init = async ($compositeParent) => {
console.group("composite init");
const componentConfig = componentsNs.getComponentConfig($compositeParent);

console.log($compositeParent);
console.log(componentConfig);

const type = $compositeParent.attr('type');
const isList = type === ns.selectorTypeList;

console.log(type);
console.log(isList);

$(document).ready(function () {
if (isList) {
console.log('Composite List component Behaviour loading');
//setup list variant
var $newRow = $($compositeParent.find("template.content").html());
const $templateActions = $($compositeParent.find("template.actions").html());
const $templateMove = $($compositeParent.find("template.move").html());

$(ns.selector).each(function(){
//find all input fields that are not inside another composite input
var $field = $(this).findExclude(ns.selectorTemplate,ns.selector).findExclude(ns.selectorInput, ns.selector);
//remove isInput attribute and add isCompositeInput attribute, this will ensure that form fields are not processed by form submit
$field.removeAttr(ns.selectorInputAttribute);
$field.attr(ns.selectorCompositeInputAttribute,"true");
//compile value for composite input
ns.compileValue($(this));
//add move and actions to new row
$newRow.prepend($templateMove.clone());
$newRow.append($templateActions.clone());
$newRow.attr('id', 'row-' + Math.random().toString(36));
$newRow.attr('state', "new");

//add move and actions to all rows
$compositeParent.find(".rows .row").each(function(){
$(this).prepend($templateMove.clone());
$(this).append($templateActions.clone());
});
})

//listen for change event on all input fields and compile value for composite input
$(ns.selector).on("change", function() {
ns.compileValue($(this));
console.log("sortable target",$compositeParent.get(0), $compositeParent.find(".rows").get(0));
//initialize sortable on rows
new Sortable($compositeParent.find(".rows").get(0), {
handle: '.move', // handle's class
animation: 150
});


//add new row listener
$compositeParent.find(".add").on("click", function() {
$compositeParent.find(".rows").append($newRow.clone());
});
console.log('Composite List component Behaviour loaded');
}

// compile current values for all input fields
//find all input fields that are not inside another composite input
var $field = $compositeParent.findExclude(ns.selectorTemplate,ns.selector).findExclude(ns.selectorInput, ns.selector);
console.log('remove input attribute and add composite input attribute', $field);
//remove isInput attribute and add isCompositeInput attribute, this will ensure that form fields are not processed by form submit
$field.removeAttr(ns.selectorInputAttribute);
$field.attr(ns.selectorCompositeInputAttribute,"true");
//compile value for composite input
ns.compileValue($compositeParent);

//find all input fields that are not inside another composite input
// var $field = $(this).findExclude(ns.selectorTemplate,ns.selector).findExclude(ns.selectorInput, ns.selector);
// console.log('remove input attribute and add composite input attribute', $field);
// //remove isInput attribute and add isCompositeInput attribute, this will ensure that form fields are not processed by form submit
// $field.removeAttr(ns.selectorInputAttribute);
// $field.attr(ns.selectorCompositeInputAttribute,"true");
//compile value for composite input
// ns.compileValue($(this));

// //compile all values within this parent now for all input fields
// $compositeParent.find(ns.selector).each(function(){
// //find all input fields that are not inside another composite input
// var $field = $(this).findExclude(ns.selectorTemplate,ns.selector).findExclude(ns.selectorInput, ns.selector);
// //remove isInput attribute and add isCompositeInput attribute, this will ensure that form fields are not processed by form submit
// $field.removeAttr(ns.selectorInputAttribute);
// $field.attr(ns.selectorCompositeInputAttribute,"true");
// //compile value for composite input
// ns.compileValue($(this));
// });

console.groupEnd();
}


})(jQuery, Typerefinery.Components.Forms.Composite, Typerefinery.Components, Typerefinery.Components.Forms.Form, document, window);
})(jQuery, Typerefinery.Components.Forms.Composite, Typerefinery.Components, Typerefinery.Components.Forms.Form, Sortable, document, window);
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

[component=composite][type=list] .rows {
display: flex;
flex-direction: column;
}

[component=composite][type=list] .row {
display: flex;
flex-direction: row;
margin: 0.5rem;
}


[component=composite][type=list] .row .content {
display: flex;
flex-direction: row;
align-items: center;
width: auto;
max-width: unset;
flex-grow: 1;
flex-wrap: wrap;
}

[component=composite][type=list] .row .move {
display: flex;
flex-direction: row;
align-items: start;
margin: 0.5rem;
width: 4rem;
flex-wrap: wrap;
align-content: center;
}
[component=composite][type=list] .row .move .drag {
width: 4rem;
}

[component=composite][type=list] .row .move button {
width: 2rem;
}

[component=composite][type=list] .row .actions {
display: flex;
flex-direction: column;
align-items: center;
margin: 0.5rem;
justify-content: center;
width: auto;
margin-left: auto;
}

[component=composite][type=list] .row:hover {
background-color: lightgray;
}
[component=composite][type=list] .add {
margin: 1em;
}

[component=composite][type=list] .delete {
margin: 1em;
}

[component=composite][type=list] .handle {
margin-right: 5px;
width: 1.4em;
position: relative;
background-color: #E4E6EB;
background-image: linear-gradient(45deg, #E4E6EB, #E4E6EB 2px, #fff 2px, #fff 4px, #E4E6EB 4px, #E4E6EB 9px, #fff 9px, #fff 11px, #E4E6EB 11px, #E4E6EB 16px, #fff 16px, #fff 18px, #E4E6EB 18px, #E4E6EB 22px);
background-size: 10px 20px;
cursor: move;
border-top: 2px solid #FFF;
border-bottom: 2px solid #FFF;
}

[component=composite][type=list] .handle:active {
background-image: linear-gradient(45deg, #bab86c, #bab86c 2px, #fff 2px, #fff 4px, #bab86c 4px, #bab86c 9px, #fff 9px, #fff 11px, #bab86c 11px, #bab86c 16px, #fff 16px, #fff 18px, #bab86c 18px, #bab86c 22px);
background-size: 10px 20px;
}
Loading

0 comments on commit 677e3bc

Please sign in to comment.