2012-09-01 9 views
5

Ecco la situazione: ho una grande casella di testo grande per un URL qui: https://asafaweb.comCome si può usare type = "url" in MVC4 senza jQuery che convalida il campo come URL?

Questo non ha bisogno di aderire alla rigorosa definizione di un URL però; Autorizzo gli indirizzi senza uno schema, quindi predefinito su HTTP per scopi di usabilità. Ad esempio, "stackoverflow.com" sarebbe considerato un URL valido. Ma ci sono anche URL che non voglio permettere per vari motivi (cioè sono stati inseriti nella lista nera o sono intervalli di indirizzi IP interni).

Desidero impostare il tipo di input su "url" anziché sul "testo" predefinito in modo che gli utenti sui dispositivi mobili ottengano una tastiera progettata per il contesto dell'URL (ad esempio, iOS offre un pulsante ".com"), Il problema è che non appena faccio questo, la convalida jQuery non invadente di default in bundle con ASP.NET MVC si aspetta un URL con uno schema che rompa così il mio supporto per gli URL senza schema.

Questo è un sito MVC4 e ho un aiutante HTML in questo modo:

@Html.TextBoxFor(m => m.ScanUrl, new { type = "url" }) 

L'attributo ScanUrl ha quindi una consuetudine ValidationAttribute che fa tutti i controlli su misura per assicurarsi che l'URL può essere acquisita.

Come posso mantenere il modello di convalida esistente senza interiezione di validazione jQuery e volendo assicurarmi che un URL sia, beh, un URL rigoroso ?

+0

ne dite di aggiungere un attrib di dati come data-ValidationType = "schemeless" e modding la routine di convalida URL per verificare la presenza di essa e, se presente chiamando un metodo per fare una regex schemeless URL dai un'occhiata? – bUKaneer

+0

Oltre a quanto sopra, è possibile sovrascrivere il metodo di convalida per il controllo di url www.bennadel.com/blog/1624-Ask-Ben-Overriding-Core-jQuery-Methods.htm in un apposito include quindi non hai nemmeno bisogno di modificare il codice core – bUKaneer

+0

Troy, sei sicuro che sia la convalida MVC che sta fallendo e non la convalida del browser integrata sul controllo di input effettivo? Da dove viene il pop-up che ti dice che puoi inserire l'URL che hai digitato e ha un aspetto diverso nei vari browser? – shawty

risposta

7

Se non è necessaria la rigorosa convalida dell'URL in qualsiasi parte del sito, la modifica della convalida degli URL di jQuery Validation potrebbe essere il modo più semplice per gestirlo. Troverete la riga 1034 di jquery.validate.js se utilizzi la versione fornita con MVC 4.

È possibile modificare la regex proprio lì nello script del plug-in oppure è possibile applicare la patch alla convalida dell'url metodo dopo jQuery convalida viene caricato:

<script src="/Scripts/jquery.validate.js"></script> 
<script> 
    // To no-op url validation completely. 
    jQuery.validator.methods.url = function(value, element) { 
    return this.optional(element) || true; 
    }; 

    // Or, continue validating everything else as previously, 
    // but not require the protocol (double check my change to the regex...). 
    jQuery.validator.methods.url = function(value, element) { 
    return this.optional(element) || /^(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); 
    };  
</script> 

il vantaggio principale per l'applicazione di patch che in seguito è che non sono legati alla versione ottimizzato dello script e potrebbe aggiornare jQuery Validation stesso più tardi senza perdere il validatore url personalizzato. Questo è probabilmente ovvio per te, ma potrebbe essere utile per gli altri a trovare questa risposta più tardi.

+0

Risposte Top Dave, solo ignorando del tutto la convalida è esattamente quello di cui avevo bisogno. Grazie! –

0

È possibile utilizzare javascript per anteporre automaticamente lo schema all'URL nell'input se non è presente su focus out/change.

+0

Siamo spiacenti, dovrebbe aver letto la domanda fino alla fine. –

+0

Non proprio desiderabile in quanto non voglio andare a cambiare la stringa che è stata inserita. Se la convalida del lato server fallisce e rimangono nella pagina, preferirei che vedessero la stessa stringa che avevano originariamente inserito. –

+0

È possibile disattivare completamente la convalida del client e solo convalidare sul server: '@ Html.TextBoxFor (m => m.ScanUrl, nuovo dizionario {{" tipo "," url "}, {" dati -val "," false "}})' –

0

Si può anche dire il plugin jQuery convalida di ignorare selettivamente campi di input basati su un selettore si specifica, che potrebbe essere una classe si aggiunge a tutti gli elementi di ignorare, come class="ignorejQueryValidate", o nel tuo caso, tutti gli ingressi con type="url".

Vedere la sezione sull'opzione ignore nello jQuery docs nel metodo validate() del plug-in Validation.

@using (Html.BeginForm("SomeAction", "SomeController", FormMethod.Post, new { id = "myForm"})) 
{ 
    @Html.TextBoxFor(m => m.ScanUrl, new { type = "url", @class = "ignorejQueryValidate" }) 
} 

$("#myForm").validate({ 
    ignore: ".ignorejQueryValidate" 
}); 

o

@using (Html.BeginForm("SomeAction", "SomeController", FormMethod.Post, new { id = "myForm" })) 
{ 
    @Html.TextBoxFor(m => m.ScanUrl, new { type = "url" }) 
} 

$("#myForm").validate({ 
    ignore: "input[type=url]" 
}); 
+0

Non so se funzionerebbe correttamente nel contesto di ASP.NET MVC, poiché lo script di "validazione non invadente" di MVC chiama automaticamente il proprio '.validate()' sul modulo, in base agli attributi dei dati sugli input. Se fosse necessaria una seconda chiamata '.validate()' per impostare il selettore ignore, penso che uno sostituisca l'altro. Inoltre, ignorando l'input si disabilitava anche la convalida "richiesta" che Troy voleva ancora mantenere. –