English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Análise de problemas de tooltip de erro em jquery.validate[.unobtrusive] e Bootstrap

Artigos semelhantes já existem, veja aqui, acho que são um pouco complexos, recentemente também estava planejando escrever um simples para o projeto, alguns pontos chave são registrados aqui. O efeito final é o seguinte:

Backend usando Asp.net mvc5Existem frameworks de frontend como jQuery.validate, jQuery.validate.unobtrusive, requirejs, Bootstrap, todos os mais/Versão mais recente. jQuery.validate, sem dizer, é um componente de validação de frontend bastante popular; jQuery.validate.unobtrusive é baseado em jQuery.validate, projetado para se integrar com Asp.net mvc, escrito pela Microsoft, pode ser encontrado no NuGet como Microsoft.jQuery.Unobtrusive.Validation. Como usá-lo, continue lendo.

Primeiro, no backend, definimos a classe de entidade:

/// summary>
/// Informações da Fabricante
/// </summary>
public class Manufacturer : OperatedModel
{
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int ID { get; set; }
  /// summary>
  /// Código de Crédito/número de registro}}
  /// </summary>
  [Required(ErrorMessage = "Código de crédito/O número de registro não pode estar vazio")]
  [MaxLength(30)]
  public string EnterpriseNo { get; set; }
  /// summary>
  /// nome da empresa
  /// </summary>
  [Required(ErrorMessage = "O nome da empresa não pode estar vazio")]
  public string EnterpriseName { get; set; }
  /// summary>
  /// endereço de registro
  /// </summary>
  [Required(ErrorMessage = "O endereço de registro não pode estar vazio")]
  public string RegisteredAddress { get; set; }
  /// summary>
  /// representante legal
  /// </summary>
  [Required(ErrorMessage = "O representante legal não pode estar vazio")]
  public string ArtificialPerson { get; set; }
  /// summary>
  /// pessoa responsável responsável
  /// </summary>
  [Required(ErrorMessage = "O responsável não pode estar vazio")]
  public string PIC { get; set; }
  [Required(ErrorMessage = "O número do telefone celular não pode estar vazio")]
  [RegularExpression(RegexLib.Mobile, ErrorMessage = "Número do telefone celular inválido")]
  public string Mobile { get; set; }
  [EmailAddress]
  public string Email { get; set; }
  /// summary>
  /// Número do comércio
  /// </summary>
  public string ShopNumber { get; set; }
  /// summary>
  /// Nome do gerente da loja
  /// </summary>
  public string StoreManagerName { get; set; }
  /// summary>
  /// Contato do gerente da loja
  /// </summary>
  [RegularExpression(RegexLib.Mobile, ErrorMessage="Número do telefone celular inválido")]
  public string StoreManagerNumber { get; set; }
  /// summary>
  /// licença principal,营业执照三证合一
  /// </summary>
  public string MainLicence { get; set; }
  /// summary>
  /// json, outras licenças, como licença de produção
  /// </summary>
  public string OtherLicence { get; set; }
  /// summary>
  /// data de entrada
  /// </summary>
  [Required(ErrorMessage = "A data de entrada não pode estar vazia")]
  public DateTime EnterDate { get; set; }
  /// summary>
  /// data de saída
  /// </summary>
  [Required(ErrorMessage = "A data de vencimento não pode estar vazia")]
  public DateTime QuitDate { get; set; }
  /// summary>
  /// saldo disponível para resgate do fabricante
  /// </summary>
  public decimal Balance { get; set; }
}

Cada propriedade do entidade tem regras de validação no formato Attribute, quando o usuário envia um Model para o Action no back-end, o framework MVC o ajudará automaticamente a completar o trabalho de validação, então o desenvolvedor no back-end ficará feliz. No entanto, antes de submeter os dados, o frontend também precisa fazer uma validação de primeira linha, se usar jquery.validate, então é necessário escrever novamente regras semelhantes no js ou tags, será possível reutilizar o código existente no back-end? Vamos usar a propriedade EnterpriseNo como exemplo, escrever em cshtml:

@Html.TextBoxFor(m => m.BasicInfo.EnterpriseNo, new { placeholder = "Campo obrigatório", @class = "form-control" })

O html gerado finalmente é o seguinte:

<input class="form-control" data-val="true" data-val-maxlength="O campo EnterpriseNo deve ser de comprimento máximo de"30” de string ou tipo de array.\" data-val-maxlength-max="30" data-val-required="Código de crédito/O número de registro não pode estar vazio" id="BasicInfo_EnterpriseNo" name="BasicInfo.EnterpriseNo" placeholder="Campo obrigatório" value="" data-original-title="" title="" type="text">

muitos data foram adicionados automaticamente dentro da etiqueta-propriedades começam com data-val representa que o controle precisa ser validado, outras data-O início é uma série de regras de validação e mensagens de erro ao falhar, as mensagens de erro podem ser personalizadas, caso contrário, o framework gerará automaticamente algo como "O campo EnterpriseNo deve ser de comprimento máximo de"30 é do tipo string ou array.

Agora vamos falar sobre como esses js se usam juntos.

A nova versão do jquery.validate já suporta o modo AMD, então pode ser carregada diretamente com o requirejs, o jquery.validate.unobtrusive não pode, precisa de configuração de shim, código:


      baseUrl: '/scripts',
      paths: {
        "jquery": 'jquery-2.2.3.min',
        "knockout":'knockout-3.4.0',
        "bootstrap":'../components/bootstrap/3.3.6/js/bootstrap.min','validate':'jquery.validate',
        'validateunobtrusive':'jquery.validate.unobtrusive.min'
      },
      shim : {
        'bootstrap' : {
          deps : [ 'jquery' ],
          exports : 'bootstrap'
        },
        'validateunobtrusive':{
          deps:['validate'],
          exports: 'validateunobtrusive'
        }
      }
    });

Depois de configurado, no página, require, neste momento, clique no botão submit para submeter o formulário, os js começam a funcionar. Mas além de focar no primeiro controle que falhou na verificação, parece que não há outro efeito, nem mesmo o errorPlacement padrão do jquery.validate, que exibe mensagens de erro após o controle (função errorPlacement) existe, are you kidding me? Na verdade, isso é porque o jquery.validate.unobtrusive cobre a configuração do errorPlacement (veja a função attachValidation no código-fonte), para nós, isso economiza uma etapa. Como o marcador html do tooltip é gerado dinamicamente pelo bootstrap, o errorPlacement não é adequado para nós, consulte o link no início do artigo, escolha sobrescrever a função showErrors, o código nuclear é o seguinte (tooltipvalidator.js):

define(['validateunobtrusive'], function () {}}
  function TooltipValidator() {}
  TooltipValidator.prototype = {
    init: function (validatorOptions, tooltipOptions) {
      tooltipOptions = tooltipOptions || {};
      validatorOptions = validatorOptions || {};
      this._tooltipOptions = $.extend({}, {
        placement: 'top'
      }, tooltipOptions, { animation: false });
      this._validatorOptions = $.extend({}, {
        //errorPlacement: function (error, element) {
        //  // nada fazer
        //},
        showErrors: function (errorMap, errorList) {
          for (var i = 0; i < this.successList.length; i++) {
            var success = this.successList[i];
            $(this.successList[i]).tooltip('destroy');
            $(this.successList[i]).parents('div.form-group').removeClass('has-error');
          }
          for (var i = 0; i < errorList.length; i++) {
            var errorElement = $(errorList[i].element);
            errorElement.parents('div.form-group').addClass('has-error');
            errorElement.attr('data-original-title', errorList[i].message).tooltip('show');
          }
        },
        submitHandler: function (form) {
          return false;
        }
      }, validatorOptions)
      this._configTooltip();
      this._configValidator();
    },
    _configTooltip: function () {
      $('[data-val="true"]').tooltip(this._tooltipOptions);
    },
    _configValidator: function () {
      $.validator.setDefaults(this._validatorOptions);
      $.validator.unobtrusive.parse(document);
    }
  }
  return new TooltipValidator();
});

Dessa forma, podemos executar tooltipvalidator.init dentro da função de callback do require, sem precisar escrever lógica adicional, e os colegas de frente também ficaram felizes. Algo a ser notado aqui, vejam o49Aqui está o código, são os passos de inicialização do jquery.validate.unobtrusive. Originalmente, o jquery.validate.unobtrusive já tinha $(function () { $jQval.unobtrusive.parse(document); }); mas devido ao $.ready ser executado após a carga dos elementos DOM (dito isso: não após a renderização), ele termina antes de ter a chance de _configValidator do tooltipvalidator, resultando em configurações inválidas (se estiver em uma aplicação de página única sem recarregamento, perceberá que as configurações são válidas novamente ao recarregar a página local, porque $.ready é executado apenas na primeira carga, enquanto os callbacks do require são executados em cada carga). Existem duas soluções possíveis:1Dependendo do tooltipvalidator, o jquery.validate.unobtrusive2Remova $jQval.unobtrusive.parse(document); aqui escolha o2Espécie.

Obrigado por ler, esperamos ajudar a todos, obrigado pelo apoio ao site!

Declaração: o conteúdo deste artigo é proveniente da Internet, pertence ao autor original, foi contribuído e carregado voluntariamente pelos usuários da Internet. Este site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidade legal relevante. Se você encontrar conteúdo suspeito de violação de direitos autorais, por favor, envie e-mail para: notice#oldtoolbag.com (ao enviar e-mail, substitua # por @) para denunciar e forneça provas relevantes. Atingido, o site deletará imediatamente o conteúdo suspeito de infringência.

Você também pode gostar