wpbrasil / odin

Framework and base theme for development with WordPress.
http://wpod.in
563 stars 196 forks source link

Validação HTML5 no comment_form #303

Closed AdsonCicilioti closed 9 years ago

AdsonCicilioti commented 9 years ago

Olá prezados!

Estou a tentar habilitar a validação html5 no formulário de comentário, e até agora só consegui deixar os campos prontos para receber a validação, faltando a retirada do atributo novalidate do <form>. Segue a modificação que fiz no arquivo comments.php do tema:

<?php
    $commenter = wp_get_current_commenter();

    $args = wp_parse_args( $args );
    if ( ! isset( $args['format'] ) )
        $args['format'] = current_theme_supports( 'html5', 'comment-form' ) ? 'html5' : 'xhtml';

    $req = get_option( 'require_name_email' );
    $aria_req = ( $req ? " aria-required='true'" : '' );
    $html_req = ( $req ? " required='required'" : '' );
    $html5    = 'html5' === $args['format'];

    comment_form(
    array(
        'comment_notes_after' => '',
        'comment_field' => '<div class="comment-form-comment form-group"><label class="control-label" for="comment">' . __( 'Comment', 'odin' ) . '</label><div class="controls"><textarea id="comment" name="comment" cols="45" rows="8" class="form-control" aria-required="true" ></textarea></div></div>',
        'fields' => apply_filters( 'comment_form_default_fields', array(
            'author' => '<div class="comment-form-author form-group">' . '<label class="control-label" for="author">' . __( 'Name', 'odin' ) . ( $req ? '<span class="required"> *</span>' : '' ) . '</label><input class="form-control" id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . $html_req  . ' /></div>',
            'email' => '<div class="comment-form-email form-group"><label class="control-label" for="email">' . __( 'E-mail', 'odin' ) . ( $req ? '<span class="required"> *</span>' : '' ) . '</label><input class="form-control" id="email" name="email" ' . ( $html5 ? 'type="email"' : 'type="text"' ) . ' value="' . esc_attr(  $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . $html_req  . ' /></div>',
            'url' => '<div class="comment-form-url form-group"><label class="control-label" for="url">' . __( 'Website', 'odin' ) . '</label>' . '<input class="form-control" id="url" name="url" ' . ( $html5 ? 'type="url"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" /></div>' ) )
    )
); ?>

Atualmente estou removendo usando jQuery, mas não quero depender de js pra isso. Acho que ficaria mais limpo um código que removesse o atributo novalidate apenas se o suporte ao html5 estiver habilitado, igual é feito com a condição dos tipos de input ( $html5 ? 'type="email"' : 'type="text"' ). Mas não faço ideia de como fazer isso. :P

Acredito que isso pode virar um PR, habilitando uma pequena melhoria nos comment forms do Odin.

AdsonCicilioti commented 9 years ago

Putz.. Agora vi que já tinha uma issue nesse sentido - #8 .

Mas minha proposta seria para deixar o padrão mais atual e no padrão HTML5, uma vez que esta é uma das premissas do projeto.

Apesar de ser um interesse próprio penso que é uma boa. Deixo a bola com vocês e peço desculpas por meio que ter duplicado a issue.

Abçs!

adammacias commented 9 years ago

@AdsonCicilioti acho que devemos tirar esse atributo novalidate e adicionar nos campos, type HTML5, e required nos obrigatórios.

adammacias commented 9 years ago

@fdaciuk será que conseguimos fazer aquela validação que vi no seu blog aí? Seria bem útil! :dancers:

AdsonCicilioti commented 9 years ago

Então, @adammacias, já deixei os campos obrigatórios com os atributos required através da variável $html_req. Também coloquei a variável $html5 que determina se o campo de email será type="text" ou type="email", com base no suporte html5 que está habilitado no arquivo functions.php (linha 148). Ambas variáveis são padrões WP.

A única coisa que está impedindo a validação html5 de funcionar é esse novalidate no <form>. Atualmente estou usando uma linha de jquery pra remover: $('#commentform').removeAttr('novalidate');

ivanildodias commented 9 years ago

Olá galera... Pelo que entendo, confesso que não é muito :sweat_smile:, mesmo com esse novalidate aí no <form> o WordPress não deixa a mensagem ser enviada se os campos de Nome, Email e Comentário não estiverem preenchidos.

O novalidate só atrapalha a validação automática na hora que o usuário está preenchendo o formulário.

Seria esse o seu problema @AdsonCicilioti? Usando o regexp no atributo pattern resolveria, ou o novalidate continuaria a atrapalhar?

AdsonCicilioti commented 9 years ago

Sim, @ivanildodias , o WP impede mas carrega aquela tela cinza da morte. Minha intenção é evitar o load desta tela através da validação html5, que é simples, mas por uma questão de usabilidade é bem mais amigável.

ivanildodias commented 9 years ago

Sem usar JQuery não tem jeito mesmo. Não tem nem como fazer um str_replace() nem nada assim porque essa parte do elemento <form> nem php é. Complicado. :pensive:

ivanildodias commented 9 years ago

Se usarmos essas actions do_action( 'comment_form_before' ); e do_action( 'comment_form_top' ); para definir a variável $html5 como false e depois para true. Seria uma opção?

ivanildodias commented 9 years ago

Essas actions ficam exatamente acima e logo abaixo do elemento <form>.

fdaciuk commented 9 years ago

Isso é bem simples de fazer.. olhando na documentação, vc tem um parâmetro format, que pode passar nos argumentos como html5. Quando você faz isso, ele adiciona o novalidate no form e faz a validação com html5 ;)

AdsonCicilioti commented 9 years ago

Eu vi isso @fdaciuk , mas não, ele não faz a validação html5, passando direto para validação tela cinza da morte do WP. Deveria ser o contrário, mas parece que eles passam o novalidate justamente para não haver essa camada de validação html5, tipo pra não atrapalhar validação de (plugins) terceiros.. sei lá.. Só Acho que deveria haver uma forma de tirar esse novalidate sem js, e não sei como :cry:

ivanildodias commented 9 years ago

A minha solução das actions não é viável?

AdsonCicilioti commented 9 years ago

Sim @ivanildodias acho que é o caminho. Acredito que só a do_action( 'comment_form_top' ); já dê conta do recado. Olha o Comentário do arquivo comment-template.php.

Poderia mandar um exemplo de sua proposta?

adammacias commented 9 years ago

Se o WordPress adiciona isso por padrão, eu acho melhor não modificar. Apenas a validação HTML5 dos types esta bom, deixa o novalidate aí rs...Como você disse @AdsonCicilioti pode influenciar em plugins. :neutral_face:

ivanildodias commented 9 years ago

@AdsonCicilioti tem que ser as duas actions mesmo. Uma para mudar o valor da variável $html5 para false antes da tag <form> e a outra para retornar ao padrão logo depois da tag.

Estou tentando aqui mas não estou conseguindo uma forma de alterar essa variável através das actions. :confused:

AdsonCicilioti commented 9 years ago

Claro @adammacias . Minha proposta é ativar a validação HTML5 sem mudar o padrão do core mas dando essa opção para quem não for usar plugins. dividamente Documentada na Wiki e no código.

Bom ainda gostaria de manter a issue aberta pois ainda estarei em busca de uma forma válida de fazer essa função.

ivanildodias commented 9 years ago

Galera... Consegui fazendo assim:

<?php // Comment form
    ob_start();
    $commenter  = wp_get_current_commenter();
    $req        = get_option( 'require_name_email' );
    $aria_req   = ( $req ? " aria-required='true'" : '' );
    $html_req   = ( $req ? " required='required'" : '' );
    $span_req   = ( $req ? ' <span class="required">*</span>' : '' );

    comment_form( array(
        'title_reply'           => __( 'Leave your thoughts', 'issimple' ),
        'comment_notes_after'   => '',
        'fields'                => apply_filters( 'comment_form_default_fields', array(
            'author' => '<div class="comment-form-author form-group">' . '<label for="author">' . __( 'Name', 'issimple' ) . $span_req . '</label> ' .
                        '<input id="author" class="form-control" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="40"' . $aria_req . $html_req . ' /></div>',
            'email'  => '<div class="comment-form-email form-group"><label for="email">' . __( 'Email', 'issimple' ) . $span_req . '</label> ' .
                        '<input id="email" class="form-control" name="email" type="email" value="' . esc_attr(  $commenter['comment_author_email'] ) . '" size="40" aria-describedby="email-notes"' . $aria_req . $html_req . ' /></div>',
            'url'    => '<div class="comment-form-url form-group"><label for="url">' . __( 'Website', 'issimple' ) . '</label> ' .
                        '<input id="url" class="form-control" name="url" ' . ( $html5 ? 'type="url"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="40" /></div>',
        ) ),
        'comment_field'         => '<div class="comment-form-comment form-group"><label for="comment">' . __( 'Comment', 'issimple' ) . ' <span class="required">*</span></label> ' .
                                   '<textarea id="comment" class="form-control" name="comment" cols="45" rows="8" aria-describedby="form-allowed-tags" aria-required="true" required="required"></textarea></div>',
        'class_submit'          => 'submit btn btn-default',
    ) );
    $comment_form = ob_get_contents();
    ob_end_clean();

    echo str_replace( 'novalidate', '', $comment_form );
?>
romuloctba commented 9 years ago

@AdsonCicilioti , a solução do @ivanildodias resolveu pra vc?

AdsonCicilioti commented 9 years ago

Olá @romuloctba .. Ainda vou testar.. vou tirar um tempo ainda hoje.

AdsonCicilioti commented 9 years ago

Bom galera, avaliando melhor essa implementação descobri o porquê o novalidate foi inserido no WP justo quando o suporte ao HTML5 é habilitado. O Support HTML5 foi implementado por uma questão de usabilidade na escrita em dispositivos móveis, exemplo: no preenchimento de campos do tipo email, url o teclado do dispositivo mostra os botões @ e/ou .com, facilitando a escrita nos mesmos. E também porque a validação HTML5 não é suportada por alguns browsers.

Ficando mesmo a cargo de cada projeto utilizar outros tipos de validação com JS ou substituindo o comment form nativo com plugins como o DISCUS.

Porém vemos que mesmo a validação HTML5 falhando em alguns browsers, o WP não submete os dados, mostrando a sua tela de validação cinza da morte (auhsuhasuh). Então logo prefiro manter o padrão.

Acho que o melhor a fazer é apenas retornar os tipos de campo HTML5, que ainda não foi ajustada no odin.

ivanildodias commented 9 years ago

Olá @romuloctba, você testou essa forma que eu coloquei? Comigo aqui funcionou.

O @AdsonCicilioti achou melhor manter o novalidate e deu uma ótima explicação do porquê. Mas se quiser removê-lo sem usar JS, acho que a minha opção é válida. Fica sendo uma opção para cada um.