Diseñe un componente de formulario que tome la entrada de su usuario y muestre un formulario

Diseño: Estas son las cosas que debería soportar:

  • Agrupación de los campos del formulario
  • Validaciones de campos
  • Botón de enviar

Por ejemplo, el usuario podría querer validar si la entrada es una dirección válida y podría querer que este componente tenga validaciones predeterminadas para el correo electrónico, etc.
Intentemos crear un modelo de datos muy básico para nuestro componente.

Para nuestra implementación minimalista, podríamos querer usar estos campos.

  • Id: El id para el campo
  • Tipo: texto/desplegable, etc.
  • Subtipo: para el tipo de texto de entrada, es posible que deseemos una contraseña, etc.
  • Valores: para menú desplegable/Radio
  • Validador: el validador personalizado proporcionado por el usuario. Podemos usar el valor de «correo electrónico», etc. para proporcionar una validación predeterminada.
  • Grupo: el grupo al que debe pertenecer este campo
  • Marcador de posición: marcador de posición si es necesario para el campo.
  • Manejador: para proporcionar una devolución de llamada/opción para hacer clic en el botón Enviar

Para esto, intentaríamos usar el patrón MVC en JS. Primero, desarrollemos nuestra clase modelo.

Para nuestra implementación minimalista, mantendremos la entrada de este componente en nuestra clase de modelo.
Nuestro modelo tendrá una entrada para el componente que se codificará ahora y un evento que notificará que nuestra entrada ha cambiado.
Aquí está la implementación minimalista.

function ListModel() {
    this._formInput=[ {
        "id": "id1",
        "type":"text",
        "name":"name",
        "placeholder":"name",
        "values":"",
        "validator":function () {
            console.log("test1");
        }
        ,
        "group":"gr1"
    }
    ,
    {
        "id": "id2",
        "type":"dropdown",
        "name":"name",
        "placeholder":"name",
        "values":[1,
        2,
        3],
        "validator":function () {
            console.log("test2");
        }
        ,
        "group":"gr2"
    }
    ,
    {
        "id": "id3",
        "type":"radio",
        "name":"name",
        "placeholder":"name",
        "values":["male",
        "female"],
        "validator":function () {
            console.log("test");
        }
        ,
        "group":"gr3"
    }
    ,
    {
        "id":"id4",
        "type":"button",
        "name":"name",
        "placeholder":"name",
        "values":"",
        "handler": function () {
            console.log("test3");
        }
        ,
        "group":"gr3"
    }
    ];
    this.itemAdded=new Event(this);
}
  
ListModel.prototype= {
    addItem: function () {
        this.itemAdded.notify();
    }
    ,
    getFormInput: function () {
        return [].concat(this._formInput);
    }
    ,
}
  
;

Aquí, la clase de evento es una implementación básica de pub/sub donde cada módulo puede reaccionar a un evento. Aquí está la clase de evento.

function Event(sender) {
    this._sender = sender;
    this._listeners = [];
}
Event.prototype = {
    attach: function(listener) {
        this._listeners.push(listener);
    },
    notify: function(args) {
        var index;
        for (index = 0; index < this._listeners.length; index += 1) {
            this._listeners[index](this._sender, args);
        }
    }
};

Ahora llegando a nuestro controlador. Para nuestro caso de uso de muestra, hemos activado elementos agregados al modelo solo en la inicialización del controlador.
A continuación se muestra la clase:

function ListController(model, view) {
    this._model = model;
    this._view = view;
    var _this = this;
    _this.returnResult();
}
ListController.prototype = {
    returnResult : function () {
        this._model.addItem();
    }
};

Ahora llegamos a nuestra clase principal, que eventualmente generará el formulario que es nuestra clase de vista.

Aquí está la clase de vista:

function ListView(model) {
    this._model = model;
    var _this = this;
    this._model.itemAdded.attach(function () {
        _this.addResult();
    });
    this._validators = [];
}

Aquí almacenamos el modelo (que en nuestro caso es la entrada a este componente) y los validadores para cada campo.
Además, adjuntamos el controlador de eventos a nuestro cambio de modelo que creará la vista. Aquí está el código completo

ListView.prototype = {
    addResult: function() {
        var data = this._model.getFormInput();
        this.createContent(data);
    },
    createContent: function(data) {
        var totalFieldGroup = [];
        var fieldGroup = [];
        var groups = {};
        for (var itr = 0; itr < data.length; itr++) {
            if (!totalFieldGroup.includes(data[itr]["group"]))
                totalFieldGroup.push(data[itr]["group"]);
            if (typeof data[itr]["validator"] == "function")
                this._validators.push(data[itr]["validator"]);
        }
        var form = document.createElement("form");
        for (var j = 0; j < totalFieldGroup.length; j++) {
            fieldGroup.push(data.filter(function(individual) {
                if (individual["group"] == totalFieldGroup[j]) {
                    return true;
                } else {
                    return false;
                }
            }));
            var fieldset = document.createElement("fieldset");
            var legend = document.createElement("legend");
            legend.innerHTML = fieldGroup[0][0]["group"];
            fieldset.appendChild(legend);
            this.createComponent(fieldGroup, fieldset);
            form.appendChild(fieldset);
            fieldGroup = [];
        }
        var subbtn = data.filter(function(individual) {
            if (individual["type"] == "button") {
                return true;
            } else {
                return false;
            }
        });
        if (subbtn.length == 0) {
            alert("no submit button found");
            return;
        }
        var btn = this.addSubmitButton(subbtn, form);
        form.appendChild(btn);
        form.setAttribute("id", "parentForm");
        document.body.appendChild(form);
    },
    addSubmitButton: function(subbtn, form) {
        var x = document.createElement("button");
        x.setAttribute("type", "submit");
        x.innerHTML = "Submit";
        var self = this;
        x.addEventListener("click", function() {
            for (var i = 0; i < self._validators.length; i++) {
                self._validators[i]();
            }
            subbtn[0]["handler"]();
            form.submit();
        });
        return x;
    },
    createComponent: function(fieldGroup, fieldset) {
        var ret = fieldset;
        for (var i = 0; i < fieldGroup.length; i++) {
            switch (fieldGroup[0][i].type) {
                case "text":
                    var label = document.createElement("label");
                    label.innerHTML = fieldGroup[0][i].name;
                    var x = document.createElement("INPUT");
                    x.setAttribute("type", "text");
                    x.setAttribute("placeholder", 
                                   fieldGroup[0][i].placeholder);
                    x.setAttribute("id", fieldGroup[0][i].id);
                    fieldset.append(label);
                    fieldset.append(x);
                    break;
                case "dropdown":
                    var label = document.createElement("label");
                    label.innerHTML = fieldGroup[0][i].name;
                    var select = document.createElement("select");
                    select.setAttribute("id", fieldGroup[0][i].id);
                    for (var k = 0; k < fieldGroup[0][i].values.length; k++) {
                        var option = document.createElement("option");
                        option.innerHTML = fieldGroup[0][i].values[k];
                        select.appendChild(option);
                    }
                    select.setAttribute("placeholder", 
                                        fieldGroup[0][i].placeholder);
                    fieldset.append(label);
                    fieldset.append(select);
                    break;
                case "radio":
                    var label1 = document.createElement("label");
                    label1.innerHTML = fieldGroup[0][i].name;
                    var label = document.createElement("radiogroup");
                    for (var k = 0; k < fieldGroup[0][i].values.length; k++) {
                        var radio = document.createElement("input");
                        radio.type = "radio";
                        radio.label = fieldGroup[0][i].values[k];
                        radio.innerHTML = fieldGroup[0][i].values[k];
                        radio.value = fieldGroup[0][i].values[k];
                        label.appendChild(radio);
                    }
                    label1.appendChild(label);
                    fieldset.append(label1);
                    break;
            }
        }
    }
};

Así es como creamos una instancia del componente.

window.onload = function() {
    var model = new ListModel([]),
        view = new ListView(model),
        controller = new ListController(model, view);
};

Producción:

Publicación traducida automáticamente

Artículo escrito por shiv161 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *