typrod

1.5.0 • Public • Published

Typrod

Typrod (acronym of "type", "property" and "data"; and abbreviated as TPD) is an AngularJS library to synthetize info handlings based on:

  • input/output displays and
  • value conversions.

⚠️ Warnings:

  • Here are some words that may create confusion since also are elemental terms of JavaScript, AngularJS, CSS or even SQL. Because of this, for avoid ambiguity, our own concepts will be explicitly designated (e.g. "TPD data").
  • We understand that it is a complex system, so we recommend that you read all the documentation before getting started.
  • We will show the functioning in the next demos with Bootstrap as testing framework, but understand that you can really use any.

Overview

Imagine AngularJS runs, you layout with Bootstrap 4 and you need to filter, list and edit a data collection. See here a improvised live demo (with one filtering <form> and one <table> to manage records) to be oriented about it. As we can view, usually the following occurs:

  1. JSON (normally from an HTTP request) is captured.
  2. Its values (if necessary) must to be transformed one by one. In the example, for these types:
    • Datetimes: from string format to Date object.
    • Maybe (hypothetical presumption) booleans are rarely passed from an old system with numbers (0/1). Then, it becomes originals (true/false).
    • And perhaps a list of options is served (another assumption) as string with IDs joined by commas. It turns into array.
  3. The result are displayed inserting manually:
    • Inputs (among others):
      • Dates: with <input type="date">.
      • Booleans: checkboxes.
      • Options: <select>s.
    • Outputs (the corresponding ones):
      • Dates: typically through date filter.
      • Booleans: answering ("Yes"/"No").
      • Options: selected items.
  4. To represent these data, facing the user, captions appear situated in <label>s and <th>s.
  5. Once ready, when user interacts, every edition requires the reverse conversion of values to save the change.

Having said that, notice that these steps are repeated continuously for each info. Do you want to build another table? The same again.

Well, so, using Typrod, all of these involving processes can be only-one-time done or excessively reduced. Look the altered demo and pay attention to the differences between two systems (extra utilities remains). In this occasion, the procedure is like this:

  1. Firstly, some simple settings are defined by a provider, transmitting:
    1. For each TPD type (datetimes, booleans, options... whatever!):
      • A conversion function.
      • An HTML template of input.
      • Output's.
      • To come back to JSON, another converting.
    2. About TPD components (in our case, table and form), indicating mainly templates.
  2. At last, in the HTML coding, empty tags are printed with some attribute directives that contains:
    1. The captured values.
    2. A proper array of TPD data (group of TPD properties that indicate TPD type, label, param name, etc.).

And voilà! It is already prepared and automated. For a future TPD component (with similar TPD types), you only need to do the 2nd step, no more!

Concepts

We will take the previous examples to show samples.

TPD type

$tpdProvider
	// ...
	.type('options', /*...*/)
	.type(['year', 'y'], /*...*/)
	.type('email', /*...*/)
	.type('boolean', /*...*/);

Whatever you can think. No limits. Like simply:

$tpdProvider.type('email', {
	/*fromJson: undefined,
	toJson: undefined,*/
	input: '<input type="email" class="form-control">',
	output: '<a ng-href="mailto:{{$property.value}}">{{$property.value}}</a>'
});

To speed up settings, every TPD type name can be referenced by one or more aliases. So, instead of write entirely 'string', 'number', 'boolean', 'email' or e.g. custom 'anotherNewType', you can put abbreviated 's', 'n', 'b', 'e' and 'ant'. Regarding the above, through:

$tpdProvider.type(['email', 'e', 'em'], /*...*/);

And linked to TPD data (explained later) like e.g.:

[
	// ...
	{
		type: 'e',
		// ...
	},
	// ...
]

Also we can achieve it thanks to other ways to register:

Overwriting
$tpdProvider.type('boolean', function (opts) {
	// ...
	return opts;
});

Starting from an already added TPD type ('boolean' is system built-in), we can define it again. Permitted to pass an object or a function (like here). And you must to indicate either its name (not alias) or the reserved '*' value to apply globally on all:

$tpdProvider.type('*', function (opts) {
	// ...
	return opts;
});
Copying

Similarly to overwrite, a new TPD type can inherit definitions of another one by the copy mechanism.

$tpdProvider.type(['year', 'y'], ['number', function (opts) {
	// ...
	return opts;
}]);

But it has a quirk: TPD components' ETCs (more info after) will be exactly duplicated.

TPD property

[
	// ...
	{
		type: 'n',
		name: 'maxWeight',
		label: 'maxWeight',
		required: true
	},
	// ...
]

This is each of instances of a certain TPD type (and other several fits) whose a double TPD values (see below) are part of.

TPD value
<form tpd-values="..."></form>
<table tpd-values="..."></table>

Handled in conversions whose two kinds are:

JSON
{
	id: 2,
	name: 'Noah Baker',
	gender: 'f',
	birthdate: '1963-11-28',
	weight: 85.12,
	email: 'tur@jedigfu.eg',
	isForeign: 0
}

Original values arranged in JSON.

Formatted
{
	// ...
	birthdate: new Date('1963-11-28'),
	// ...
	isForeign: false
}

Transformed (if is needed) from aforesaid, and gave back too (cyclic process).

TPD container
<div class="form-group">
	<label for="..." translate="..."></label>
	<input type="..." class="form-control" id="..." ng-model="...">
</div>
...
<th scope="col" translate="..."></th>
...
<td>
	<input type="..." class="form-control" ng-model="..." ng-if="...">
	<span ng-if="...">...</span>
</td>
...

The repeated tags, corresponding each to a TPD property, that contains an appropriate HTML content.

ETC

It may happen that, for a concrete TPD component, we find a particular TPD type which is not structured than regularly. Take a look:

<div class="form-group form-check">
	<input type="checkbox" class="form-check-input" id="..." ng-model="...">
	<label class="form-check-label" for="..." translate="..."></label>
</div>

So, you can define this too. We know it as exceptional TPD container (ETC).

TPD data

Grouping of TPD properties. Paste the following attribute to components:

<form tpd-data="..."></form>
<table tpd-data="..."></table>

And let Typrod start to deploy all its mechanism.

TPD component

In our case: <form>...</form> and <table>...</table>. Determined like:

$tpdProvider.component('form', /*...*/, { /*...*/ });

And:

$tpdProvider.component('table', /*...*/);

It is possible customize any tag with any classname, attribute, parent... Here you have some varied samples:

$tpdProvider
	.component('form', /*...*/)
	.component('form.form-horizontal', /*...*/)
	.component('table.table.table-striped', /*...*/)
	.component('form[ng-submit]', /*...*/)
	.component('form.form-inline[ng-submit]', /*...*/)
	.component('tbody > tr', /*...*/)
	.component('form + table', /*...*/);
TPD content

Full internal HTML included in TPD components. Concatenation of TPD container and extra elements.

Advantages

Why to use Typrod?:

  • Code extremely simplified. On the principle of "Write less, do more".
  • Clear distinction between representation (HTML structure, class names, styles, etc.) and logical (what kind of data is it, param name, labelling, requirement, etc.). And in consequence:
    • Centralization. Full logics are dumped into controllers, not also partially in its views.
    • Abstraction of core data, assuming that TPD properties can share homologous behaviours.
  • More maintainable and reliable source code.
    • Integrated reutilization of mechanisms.
    • Uniformity, homogeneity and consistency.
    • Possible human mistakes avoided on bad-writing, forgetting...
    • Easy and fast to migrate CSS frameworks.
  • Unlimited customization. Not adaptive to any particular CSS dependencies.
  • Well-known system, not new or weird:
    • Specifications of TPD data are similar to databases', like in SQL table creations (column name, datatype, mandatory...).
    • Use of a worldwide standard data-interchange format such as JSON.
    • TPD components are descripted by CSS syntax.
  • Flexibility, adaptability and variety on function arguments and option values.

Install

By NPM or with CDN embeds:

NPM

npm install typrod

Then import JQuery and AngularJS (important to do this way!) and add TPD as a dependency for your app:

const $ = require('jquery');
window.jQuery = $; // To set it as alias of "angular.element"
require('angular');

angular.module('myApp', [require('typrod')]);

CDN

<script src="https://unpkg.com/jquery@3.6.1"></script>
<script src="https://unpkg.com/angular@1.8.3/angular.js"></script>
<script src="https://unpkg.com/angular-translate@2.19.0"></script>
<script src="https://unpkg.com/specificity@0.4.1"></script>
<script src="https://unpkg.com/lodash@4.17.21"></script>
<script src="https://unpkg.com/typrod/dist/typrod.js"></script>
angular.module('myApp', ['tpd']);

Usage

TPD sets by a provider and gets by a service.

Provider

It is named $tpdProvider, whose methods (that all return it, allowing chaining) are:

type(name, opts)

Registers a TPD type.

Param Type Details
name String Name.
Array Name followed by its alias(es).
opts Object Options (see the next section).
Function To overwrite:
  • Argument: the original options.
  • Return: new ones (obj.).
Array Name of copied TPD type and options (obj. or fn., like above).
Options
Key(s) Type Details Default
fromJson/toJson Function TPD value conversion from/to JSON.
  • Argument: TPD value to convert.
  • Return: converted one.
angular.identity / caller of own toJSON method (if exists)
String Name of factory/service. A fn. like before is extracted.
Array Fact./serv. in inline array annotation.
input String HTML template. Tagged HTML string. If multi-level or multiple tags, you have to mark the main input element by tpd-target attribute. Current definition of 'string' TPD type
Name of fact./serv. Fn. extraction.
Array Fact./serv. in IAA.
Object JQuery element.
DOM elem.
Function
  • Argument: directive's scope.
  • Return: elem. (str. or obj.).
output String Any string (plain texts, tags, interpolations...). '{{$property.value}}'
Function
  • Argument: the scope.
  • Return: the string.

component(selector, content[, ec])

Registers a TPD component.

Param Type Details
selector String CSS selector.
content String TPD content.
Function
  • Argument: selector's JQuery element.
  • Return: the string.
ec (optional) Object Exceptional TPD containers. With keys as TPD type names while each value are composed by its TPD container with the same types than content (2nd param).

Overwriting (but basic one) is also allowed.

When Typrod activates, collects the coincidences and priors the TPD component of most CSS specificity and oldest.

Service

$tpd() proportinates a read-only object of original setters (without defaults) of registers. Regarding the TPD components, its function arguments are disposed in arrays. And the TPD type aliases appears too, grouped by names.

Directives

All of these should only be used in TPD contents and ETCs, except the first one (whose utilitation is free).

tpd-data

Put this attribute over the TPD component tag you want to locate the concerning TPD content. It contains an array where each object must to be formed as:

Key(s) Type Details
type (optional) String Name or alias of registered TPD type. Defaults to 'string'.
name String Name of param (where TPD value is stored).
label String Translation ID of Angular Translate.
required (optional) Boolean Input mandatority.
min/max (optional) Any Minimum/maximum of TPD value.

And other custom ones are permitted for a not-generic using.

Also it is possible to shorthand it putting an array, instead of the object, following this order: name, label, required, type and the rest (in an object). So ['isForeign', 'foreign?', false, 'b', { customKey1: 'one', customKey2: 'two' }] equals to { type: 'b', name: 'isForeign', label: 'foreign?', required: false, customKey1: 'one', customKey2: 'two' }.

Besides, accompanying this directive, in the same tag, tpd-values is placed, determining the TPD JSON values (manipulated by fromJson and toJson). This pure attribute is optative but its exclusion has no much sense.

tpd-property

Ubicated as attribute solely on TPD containers, Typrod turns these into a repeatedly rendered element by ng-repeat that generates $property as local scope variable derived from each tpd-data's item (adjusting name from possible alias to name and saving TPD formatted value in value property).

If a serie of adjacent elements must to be repeated (instead of just one), substitute this directive with tpd-property-start and tpd-property-end as ng-repeat-start and ng-repeat-end do.

tpd-label

Labels the attributed element.

tpd-input/tpd-output

As tagnames, these ones are substituted by the HTML of correspondent options of TPD types.

Predefinitions

Typrod proportions some built-in registrations:

TPD types

Name Alias(es) Details
'string' 's' and 'str' For single-line text.
'search' Text too but within <input type="search">.
'password' 'p' and 'pw' Outputs hiding chars too.
'number' 'n' and 'num'
'range' 'r' Percentage.
'boolean' 'b' and 'bool'
'date' 'd'
'time' 't'
'datetime' 'dt'
'option' 'o' and 'opt' Single <select>. You only must to transfer a string of scope's array (formed by objects with pairs id-label) to tpd-data in options key.
'options' 'oo' and 'opts' The same but multiple.
'color' 'c' Hexadecimal color.
'url' 'u' URL.
'email' 'e' and 'em' E-mail address.
'tel' Telephone number.

TPD components

Forms

You have namesake 'form'. It rawly prints <div>s with <label> and input, and a submit button. You have to add the ng-submit directive by yourself and data-name attribute as namespace of labelable elements.

Description lists

<dl>s exposes labels in <dt>s and outputs in <dd>s.

Tables

  • 'table': shows a labeled head and record rows. Place attribute data-expression as we make on tpd-values but with an array.
  • 'thead, tfoot': labels <th>s.
  • 'tbody > tr': outputs <td>s.

Readme

Keywords

Package Sidebar

Install

npm i typrod

Weekly Downloads

1

Version

1.5.0

License

ISC

Unpacked Size

54.3 kB

Total Files

13

Last publish

Collaborators

  • mvicens