Creación de campos y subcampos en Catalis

En este documento analizamos la forma en que se lleva a cabo la creación de campos y subcampos en la versión original de Catalis, y las posibles modificaciones para la segunda versión.

Referencias:

create-field-subfield.js

dom-functions.js

data-in.js

Funciones básicas

Las funciones básicas son:

createSubfield: builds a DOM node that represents a subfield,

createField: builds a DOM node that represents a field,

displaySubfield: appends the subfield DOM node to the document,

displayField: appends the field DOM node to the document.

createSubfield

/** * @param code Subfield code * @param sfText Subfield value * @param label Subfield name [optional] * @param fieldTag Parent field's tag [optional] */ function createSubfield(code, sfText, label, fieldTag) /** * Simplified code, omitting properties and listeners for the nodes. */ // create table row var newSubfield = document.createElement("tr"); // cell for subfield code var newCell = document.createElement("td"); var newCode = document.createElement("div"); newCell.appendChild(newCode); newSubfield.appendChild(newCell); // cell for subfield label var newCell = document.createElement("td"); var newLabel = document.createElement("div"); newCell.appendChild(newLabel); newSubfield.appendChild(newCell); // cell for subfield value var newCell = document.createElement("td"); var newSubfieldBox = document.createElement("textarea"); newCell.appendChild(newSubfieldBox); newSubfield.appendChild(newCell); // return the DOM node return newSubfield;

createField

/** * @param tag * @param ind * @param subfields */ function createField(tag, ind, subfields) /** * Simplified code, omitting properties and listeners for the nodes. */ // create table row var newField = document.createElement("tr"); // cell for field tag var newCell = document.createElement("td"); var newTag = document.createElement("div"); newCell.appendChild(newTag); newField.appendChild(newCell); // cell for indicators var newCell = document.createElement("td"); var newIndPair = document.createElement("div"); newCell.appendChild(newIndPair); newField.appendChild(newCell); // cell for subfields var newCell = document.createElement("td"); var newTable = document.createElement("table"); // <== this table will hold the subfields newCell.appendChild(newTable); var newTBody = document.createElement("tbody"); // call createSubfield for each subfield for (var i=0; i < subfieldsArray.length; i++) { var newSubfield = createSubfield(code, sfText, label, tag); newTBody.appendChild(newSubfield); // <== this replaces a call to displaySubfield (newTBody is not rendered yet) } newTable.appendChild(newTBody); newField.appendChild(newCell); // return the DOM node return newField;

displaySubfield

/** * @param newSubfield The subfield's DOM node * @param field The parent field's DOM node */ function displaySubfield(newSubfield, field) { var container = field.firstChild.nextSibling.nextSibling.firstChild.firstChild.nextSibling; container.insertBefore(newSubfield, refNode); /* OR */ container.appendChild(newSubfield); }

displayField

/** * @param newField The field's DOM node * @param refNode The DOM node for a reference field */ function displayField(newField, refNode) { var fieldBlock = getFieldBlockName(tag); var container = document.getElementById("recordContainer_" + fieldBlock); container.insertBefore(newField, refNode); /* OR */ container.appendChild(newField); }

Casos de uso

Presentación de un registro en el formulario de edición

function renderDatafields(datafields) { /** * Simplified code */ for (var i = 0, len = datafields.length; i < len; i++) { var fieldBlock = getFieldBlockName(tag); var container = document.getElementById("recordContainer_" + fieldBlock); var newField = createField(tag, ind, subfields); container.appendChild(newField); } }

Creación de un nuevo campo

/** * @param tags The list of tags to create. */ function createFieldList(tags) { for (var i=0; i < validTags.length; i++) { var newField = createField(validTags[i]); displayField(newField); } }

Creación de un nuevo subcampo

/** * @param field The parent field's DOM node * @param codes The list of subfield codes to create */ function createSubfieldList(field, codes) { for (var i=0; i < validCodes.length; i++) { var newSubfield = createSubfield(validCodes[i], "", label, tag); displaySubfield(newSubfield, field); } }

Orientación a objetos + Ext

Para la segunda versión de Catalis, necesitamos reproducir esta misma funcionalidad, sólo que ahora las funciones deben ser métodos de las clases Catalis.DataField y Catalis.Subfield.

Para crear un campo, usamos

var field = new Catalis.DataField({ tag: '245', ind: '14', subfields: [{ code: 'a', value: 'The name of the rose /' }, { code: 'c', value: 'Umberto Eco.' }] });

y para crear un subcampo:

var subfield = new Catalis.Subfield({ code: 'a', value: 'Incluye referencias bibliográficas.' });

Pero esto sólo crea representaciones “abstractas” de un campo y de un subcampo, en el sentido de que aún no están asociadas a ningún objeto DOM (necesarios para hacer el render o display en el formulario). Para incorporar los nodos DOM tenemos estas opciones:

Que en ambos casos (DataField, Subfield) el constructor del objeto cree el nodo DOM asociado y lo asocie al objeto, dejándolo ya listo para un futuro render.

Que la creación del nodo DOM sea diferida para cuando se invoque el método display/render del objeto.

Dado que todos los campos y subcampos que se crean en la aplicación deben ser mostrados en el formulario (es decir, necesitan su propio nodo DOM), no parece haber una ventaja en diferir la creación de los nodos. Sí tiene sentido, como en la versión original, mantener la separación entre creación del objeto/nodo y presentación (display, render) del nodo en la página.

Catalis.DataField = function(config) { this.node = document.createElement('tr'); this.tagCell = document.createElement('td'); this.node.appendChild(this.tagCell); this.indCell = document.createElement('td'); this.node.appendChild(this.indCell); this.subfieldsCell = document.createElement('td'); this.node.appendChild(this.subfieldsCell); };
Catalis.Subfield = function(config) { this.node = document.createElement('tr'); this.codeCell = document.createElement('td'); this.node.appendChild(this.codeCell); this.labelCell = document.createElement('td'); this.node.appendChild(this.labelCell); this.valueCell = document.createElement('td'); this.node.appendChild(this.valueCell); };
/** * @param where (optional) */ Catalis.DataField.prototype.render = function(where) { var container = // the associated fieldblock's TBODY element; container.appendChild(this.node); /* OR */ container.insertBefore(this.node, where) };
/** * @param where (optional) */ Catalis.Subfield.prototype.render = function(where) { var container = // parent field's subfields cell's TBODY element; container.appendChild(this.node); /* OR */ container.insertBefore(this.node, where) };