Each


About

The Each component is used to create repetition of HTML markup.

Class function

const newEach = each("new-each",
    ()=>["val"],
    "<div key={ {index} }>{ {data} }</div>"
);

Render in HTML file:

HTML file

before render
<template data-cample="new-each">
    <div>text</div>
    <div>text</div>
</template>
after render
<div>text</div>
<div>text</div>

Arguments

The Each component has four arguments, the first is the value of the "data-cample" attribute (selector), the second is data, the third is an HTML template containing string interpolation, and the fourth is a settings object.

selector

The selector is the value of the "data-cample" attribute of the template in which the component will be rendered. For example, if the selector is set to "new-selector", then the HTML "template" into which the component will be rendered will look like this:

<template data-cample="new-each"></template>

It is worth noting that there can be as many "template" tags on a site as you like (within the memory of the machine where the site is located). That is, if there are 100 "templates" with the "new-each" attribute, then 100 components will be rendered.

data

The data is a function that returns an array on which to perform repetition of the HTML markup. An examples of a data:

({importedData, currentData})=>[
    ...importedData,
    ...currentData,
    "value"
]

Also, the function arguments receive an object with two properties, the first of which is the current data, and the second is the imported data. In order to modify the old data thanks to the new ones without overwriting the old ones, the current data is provided.

template

A template is essentially a string that will be rendered in a "template" with a "data-cample" attribute. The template is different from the Component template. This template does not yet support the "data-cample-import" attribute, but other syntaxes such as ":event" are supported. In future versions, all templates will be brought to the same syntax.

<div key={ {index} } class="{ {importedData.data} }">
    <div id="{ {currentData.data} }">
        <div :click={ {setData(currentData.data)} } >{ { data.data } }</div>
    </div>
</div>

Also, a necessary property for template is the "key" property. This property must be unique. It is needed to ensure that blocks are not overwritten when processing new data.

The keys by which the data will be processed in the template will be the same keys that are specified in the valueName, importedDataName, indexName and functionName properties.

Each also provides for adding an event listener for the element via string interpolation. The template itself looks like ":event="function(argumentsData)"". The data that is processed by the function in the arguments is only the data keywords from the data passed to the "template" in the string interpolation. These are data such as importedData, currentData, functions, data.

options

The options object describes the scripts, attributes, data, styles of the component, etc. Each of the listed properties describes a property of an object.

script

An array with two values is passed to the script object property, the first of which is a function that accepts the values of the component element, current data, as well as dynamic data functions and imported data and is triggered depending on the settings, and the second value is a script settings object that accepts one argument : "start". This argument takes three values: “beforeLoad”, “afterLoad” and undefined. This setting describes when the script function should be executed before or after the component is loaded. If the values are not defined, the function will be loaded after. Example script:

{
    script: [
        ({ element, functions, currentData, importedData }) => {
        element.addEventListener("click", () => {
            console.log(elements.component);
        });
        const updateFunction = (e) => {
            functions?.updateText((data) => {
                return "newText";
            });
        };
        document.addEventListener("onload", updateFunction);
            console.log(data);
        },
        {
            start: "beforeLoad",
        },
    ],
    functionName:"updateText"
}

Also, the framework supports a script without an array. That is, a function can also be passed to a value.

{
    script:({ element, functions, currentData, importedData })=>{
        console.log("123");
    }
}

The function is running after loading by default.

iteration

The iteration property specifies a function that iterates exactly as many times as the number of times Each is iterated.

{
    iteration:({ data, importedData }, index)=>{
        console.log("123");
    }
}

As arguments, the function receives as the first argument an object with iteration data, the default name of which comes from "valueName" and imported data, the default name of which comes from "importedDataName", and also receives the number in the iteration as the second argument.

valueName

The valueName property sets the name of the property by which data will be available for the corresponding iteration of Each. An example of the valueName:

{
    valueName:"dataValue"
}

In this example, valueName is set to the value "dataValue", by which the data of a particular iteration will be available in the template. By default, valueName is "value".

indexName

The valueName property specifies the name of the property by which the iteration number will be available.

{
    indexName:"i"
}

In this example, indexName is set to "i", by which the iteration number will be available in template. By default, indexName is "index". Just like in vanilla js, iteration numbers start from 0.

functionName

The functionName property specifies the name of the function that changes the data in the "script" and template. An example of the functionName:

{
    functionName:"dataFunction"
}

In this example, functionName is set to "dataFunction" which will access the function in the "script" or template that will update the data. The default functionName is "setData".

functions

The functions property takes in an object of properties whose value is an array with the function and the name of the updating function from functionName.

{
    functionName:"setComponentText",
    valueName:"component_text",
    functions: {
        updateComponentText: [
          (setData, event) => (arguments) => {
            event.preventDefault();
            setData(() => "123");
          },
          "setComponentText",
        ],
    }
}

In the array, the first function will receive the data updating function from dataFunctions as the first argument and the Event object as the second argument, and all the arguments that were specified either in the template or in the script object will be passed to the second function. Using a closure, the second function will have access to both the arguments that were passed and the updating function.

In template, a call to such a function will look like this:

<div class="{ {component_text} }">
    <div id="{ {component_text} }">
        <div :click={ {updateComponentText(setComponentText)} } >{ {setComponentText} }</div>
    </div>
</div>

As arguments in this form, the function takes only property names from the data argument. All event names come from vanilla in javascript, as if the addEventListener method was applied to the element.

In the framework, the "click" event is synthetic. In order to limit the process of floating within a specific element, there is a syntax "::", where the floating does not occur through the entire DOM, but only through the entire specific Each element.

<div class="{ {component_text} }">
    <div id="{ {component_text} }">
        <div ::click={ {updateComponentText(setComponentText)} } >{ {setComponentText} }</div>
    </div>
</div>

It is worth noting that if in the process of surfacing a function with "::" is found, then even if the click was made as usual, then the surfacing will still go to the element.

importedDataName

The importedData property specifies the name of the imported data. An example of the importedData:

{
    importedDataName:"newData"
}

In this example, importedDataName is set to "newData" which will access the importedData in the "script" and template. The default importedDataName is "importedData".

attributes

The attributes property contains an object of the HTML attributes and their values that will be processed in the template. An example of the attributes:

("new-each",
...,
{
    attributes:{
        id:"id"
    }
})

In this example, a template with a "data-cample" value of "new-each" will be given a id "id".

import

The import property sets the "data-cample-import" attribute. This attribute specifies data to import specific exported data. An example of the import:

import:{
    value:["text"],
    exportId:"textId"
}

For example, if a component was given import data in other components, then the import object will overwrite them in the tag attribute.

value

The value property on the import object specifies a list of exported values that will be imported into the component. An example of the value:

{
    value:["text", "text1"]
}

In this example, two values are passed to the "data-cample-import" property: "text" and "text1".

exportId

In order to understand which component to import data from, the import object provides such a property as exportId. This property is set in the component that exports the data. It is set either in the options object. An example of the exportId:

{
    exportId:"textId"
}

In this example, the data will be imported from a component that will have its exportId set to "textId".

export

Export under cunstruction!

exportId

The exportId property specifies the export identifier, by which the component will "determine" where to get the data from. An example of the exportId:

{
    exportId:"textId"
}

In this example, to export specific data, "exportId" is set with the value "textId".

style

The style property contains a string that is inserted into the HTML style tag. This string is the stylesheet syntax, i.e. cascading style sheets syntax. An example of a style:

{
    style:`
        .component{
            width:100px;
            height:100px;
        }
    `
}

Each styles are rendered in the style tag, thus it is possible to create styles in one component for another.

values

The values property takes the value of an object whose property has a value of an object that generates dynamic data depending on a condition.

values: {
    selectedValue: {
        "currentData.select === currentData.true":"selected",
        "!(currentData.currentClass && currentData.false) == currentData.anotherProperty":["class1","{ {currentData.class2} }"]
    },
}

In this example, only the values from the data property are used in the conditions; in their values, you can write both regular text and text with string interpolation. If the value is a string, then if true, the value will be this string, and if false, then "". If the value is an array of two strings, then it works like a ternary operator, when if true is the first value, if false is the second value.

**Also, it’s worth noting that difficult conditions are still being tested! The code may produce other values of true or false! It is highly recommended to use simple conditions with one or more operators!**
HTML before
<div class="class { { [selectedValue] } }">
    { { [selectedValue] } }
</div>
HTML after
<div class="class selected class1">
    selected
</div>

Also, it's worth noting that in string interpolation, values are "passed as an array". The key to the dynamic string in this example is the "selectedValue" value.

trimHTML

Depending on the value of the trimHTML property, the javascript trim() method is applied to the HTML string.

{
  trimHTML:false
}

This will avoid the errors associated with rendering a single Element in the component, but also the HTML may not be displayed correctly.

Example code

const newEach = new Each(
"new-each",
() => ["val1", "val2"],
`<tr key={ {index} } id="row" class="{ {[selected]} }">
    <td>{ {row.id} }</td>
    <td><a :click="{ {importedData.setSelected(row.id)} }">{ {row.label} }</a></td>
    <td></td>
</tr>`,
{
    values:  {
        selected: {
            "row.id === importedData.selected": "selected",
        },
    },
    script: [
        (obj) => console.log(obj),
    {
        start:"afterLoad"
    },
    ],
    functions: {
        updateRow: [
          (setData, event) => (arguments) => {
            event.preventDefault();
            setData(() => "123");
          },
          "updateTable",
        ],
    }
    valueName: "row",
    functionName: "updateTable",
    importedDataName: "importData",
    import: {
        value: ["rows", "selected", "setSelected"],
        exportId: "mainExport",
    },
    exportId: "exportId",
    trimHTML: true,
    style: "#row{ width:10px; }",
    attributes: {
        id: "id",
    },
}
);

Each table

Arguments
Name Usage Type
selector The value of the "data-cample" property of the template tag into which the component will be rendered. SelectorType
data Data for repeating HTML markup. EachDataFunctionType
template HTML rendering template including string interpolation. string
options Object options. EachOptionsType | undefined

Articles