validacion - validar formulario javascript onclick
Determine si la sintaxis de JavaScript es vĂ¡lida en el controlador de cambios de ACE (4)
Ace utiliza JsHint
internamente (en un worker ) y, como puede ver en el archivo, se emite un evento:
this.sender.emit("jslint", lint.errors);
Puede subscribe a este evento o llamar al código de JSHint usted mismo (es bastante corto) cuando sea necesario.
Estoy usando el editor ACE para la edición interactiva de JavaScript. Cuando configuro el editor en el modo JavaScript, ACE determina automáticamente si el código es válido o no, con un mensaje de error y un número de línea resaltado cuando no lo es.
Durante el controlador de eventos de change
, quiero detectar si ACE piensa que el código es válido o no antes de intentar eval()
. La única forma en que pensé que podría hacerlo es:
var jsMode = require("ace/mode/javascript").Mode;
var editor = ace.edit(''mycode''), edEl = document.querySelector(''#mycode'');
editor.getSession().setMode(new jsMode);
editor.getSession().on(''change'',function(){
// bail out if ACE thinks there''s an error
if (edEl.querySelector(''div.ace_gutter-cell.ace_error'')) return;
try{
eval(editor.getSession().getValue());
}catch(e){}
});
Sin embargo:
- Apoyarse en la presencia de un elemento en la interfaz de usuario con una clase particular parece terriblemente frágil, pero lo más importante,
- La actualización visual para el análisis se produce después de que se produce el
change
devolución de llamada.
Por lo tanto, en realidad tengo que esperar más de 500 ms (el retraso antes de que el trabajador de JavaScript se active):
editor.getSession().on(''change'',function(){
setTimeout(function(){
// bail out if ACE thinks there''s an error
if (edEl.querySelector(''div.ace_gutter-cell.ace_error'')) return;
try{
eval(editor.getSession().getValue());
}catch(e){}
},550); // Must be longer than timeout delay in javascript_worker.js
});
¿Hay alguna forma mejor, algo en una API no documentada para el modo JS, para preguntar si hay algún error o no?
Encontré que puedes suscribir eventos de trabajo en Ace 1.1.7:
Para el código javascript, suscriba el evento ''jslint'':
session.setMode(''ace/mode/javascript}'');
session.on(''changeMode'', function() {
if (session.$worker) {
session.$worker.on(''jslint'', function(lint) {
var messages = lint.data, types;
if (!messages.length) return ok();
types = messages.map(function(item) {
return item.type;
});
types.indexOf(''error'') !== -1 ? ko() : ok();
});
}
});
Para el código JSON, suscriba el evento ''error'' y ''ok'':
session.setMode(''ace/mode/json'');
session.on(''changeMode'', function() {
// session.$worker is available when ''changeMode'' event triggered
// You could subscribe worker events here, whatever changes to the
// content will trigger ''error'' or ''ok'' events.
session.$worker.on(''error'', ko);
session.$worker.on(''ok'', ok);
});
Encontré una solución que es probablemente más rápida que atravesar el DOM. La sesión del editor tiene un método getAnnotations que puede utilizar. Cada anotación tiene un tipo que muestra si son un error o no.
Así es como configuro mi devolución de llamada para el cambio en
function callback() {
var annotation_lists = window.aceEditor.getSession().getAnnotations();
var has_error = false;
// Unfortunately, you get back a list of lists. However, the first list is
// always length one (but not always index 0)
go_through:
for (var l in annotation_lists) {
for (var a in annotation_lists[l]) {
var annotation = annotation_lists[l][a];
console.log(annotation.type);
if (annotation.type === "error") {
has_error = true;
break go_through;
}
}
}
if (!has_error) {
try {
eval(yourCodeFromTextBox);
prevCode = yourCodeFromTextBox;
}
catch (error) {
eval(prevCode);
}
}
}
Por lo que sé, hay otros dos tipos de anotaciones: "advertencia" e "información", en caso de que también desee verificarlas.
Realicé un seguimiento del código anterior que funcionaba en forma global (bueno, fuera del alcance de la función de devolución de llamada) porque a menudo habría errores en el código pero no en la lista de anotaciones. En ese caso, al evaluar el código con error, sería el código y el código anterior en su lugar.
Aunque parece que dos evals serían más lentos, me parece que el rendimiento no es tan malo, hasta ahora.
La sesión actual activa el evento OnChangeAnnotation cuando cambian las anotaciones.
después de eso, el nuevo conjunto de anotaciones se puede recuperar de la siguiente manera
var annotations = editor.getSession().getAnnotations();
Parece funcionar. Devuelve un objeto JSON que tiene la fila como clave y una matriz como valor . La matriz de valores puede tener más de un objeto, dependiendo de si hay más de una anotación para cada fila.
la estructura es la siguiente (copiada de firebug para un script de prueba que escribí)
// annotations would look like
({
82:[
{/*annotation*/
row:82,
column:22,
text:"Use the array literal notation [].",
type:"warning",
lint:{/*raw output from jslint*/}
}
],
rownumber : [ {anotation1}, {annotation2} ],
...
});
asi que..
editor.getSession().on("changeAnnotation", function(){
var annot = editor.getSession().getAnnotations();
for (var key in annot){
if (annot.hasOwnProperty(key))
console.log("[" + annot[key][0].row + " , " + annot[key][0].column + "] - /t" + annot[key][0].text);
}
});
// thanks http://.com/a/684692/1405348 for annot.hasOwnProperty(key) :)
debería darle una lista de todas las anotaciones en la sesión de edición de Ace actual, cuando las anotaciones cambien!
¡Espero que esto ayude!