1. Introducción
Con htmx, es facil modificar un componente tipo <div> con la información devuelta por una petición ajax provocada por un elemento de un formulario. En este ejemplo llenamos el componente <div> con el string "Hola
<form> <input type="text" name="miCampo" hx-get="/ruta-del-endpoint" hx-trigger="blur,change" hx-target="#resultado"> </form> <div id="resultado"></div>
#Python y fastHTML
@app.get("/ruta-del-endpoint") def getFieldEvent(request:Request): return "Hola!
Pero si queremos actualizar el valor de un element tipo input, no funciona.
2. Modificar el valor de elementos "input"
Para ello tenemos que recurrir a javascript
Supongamos que tenemos 4 campos. De ellos 2 se encargan de modificar el conenido de los otros dos campos. En este ejemplo el campo1 modifica al campo2 y el campo3 modifica al campo4
<form> <input type="text" id="campo1" name="campo1" hx-get="/ruta-del-endpoint"
hx-trigger="blur,change" hx-target="#campo2">
<input type="text" id="campo2" name="campo2"><input type="text" id="campo3" name="campo3" hx-get="/ruta-del-endpoint"hx-trigger="blur,change" hx-target="#campo4"><input type="text" id="campo4" name="campo4">
</form>
Supongamos que el código Python del endpoint es el mismo
Para ello vamos a crear un program Python con FastHTML que haga los siguientes pasos:
1. Crear un objeto que guarde los ids de los campos que lanzan el evento como nombre del campo y como valor que sea el id del campo a modificar. En Python sería:
strJs="var paramsChange={'campo1':'campo2', 'campo3':'campo4'}"
2. Creamos un fichero (static/js/fieldChange.js) con el contenido de la función javascript que actualiza los campos: Para ello busca el evento "htmx:afterRequest" y filtra aquellos cuyo endpoint es "/ruta-del-endpoint" y si el campo que lanza el evento (event.target) se encuentra dentro de la variable paramsChange entonces actualiza el valor del campo con lo que retorno la llamada ajax
// Update an input element with the value of the request document.addEventListener("htmx:afterRequest", (event) => { const hxget=event.target.getAttribute('hx-get'); if (hxget) { const elemId=event.target.id; //Only for request type get to the url "/fieldEvent" if (hxget.startsWith("/ruta-del-endpoint") && elemId in paramsChange) {
const targetId=paramsChange[elemId]; const input = document.querySelector(targetId); input.value = event.detail.xhr.responseText; } } });
3. A la variable python "strJs" hay que añadirle el contenido de este fichero: que es javascript
with open('static/js/fieldChange.js', 'r') as file: content = file.read() strJs+="\n"+content
4. Para crear los campos con FastHTML podemos creatr un diccionario para cada campo con los atributos de cada "input". Podríamos haber creado un form , pero para simplificar meto el javascript y los 4 campos dentro de un <div> (fh.Div). A mi me encanta como resuelve fastHTML la creaciópn de campos. Ojo que utiliza guiones bajos "_" en vez de "-" cuando define los parámetros de htmx!
fieldDicts=[ {'type':'text', 'id':'campo1', 'name':'campo1','hx_post':'/ruta-del-endpoint', 'hx_target':'#campo2', 'hx_trigger':'blur,change'}, {'type':'text', 'id':'campo2', 'name':'campo2'}, {'type':'text', 'id':'campo3', 'name':'campo3','hx_post':'/ruta-del-endpoint', 'hx_target':'#campo4', 'hx_trigger':'blur,change'}, {'type':'text', 'id':'campo4', 'name':'campo4'}, ] return fh.Div( fh.Script(strJs), *[fh.Input(**fieldDict) for fieldDict in fieldDicts], )
No hay comentarios :
Publicar un comentario