Как удалить оболочку span в контактной форме 7?

Я использую контактную форму 7 в теме WordPress.

В настоящее время он возвращает span и input:

<span class="wpcf7-form-control-wrap name">
  <input type="text" name="name" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control" id="name">
</span>

Но мне нужно только input:

<input type="text" name="name" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control" id="name">

Как удалить обертку span?

Ответ 1

Я столкнулся с той же проблемой и, наконец, закончил с помощью фильтра wpcf7_form_elements, чтобы удалить тег <span> с помощью регулярного выражения. Вы можете, например, скопировать этот код в свой functions.php файл. Здесь я передаю анонимную функцию в качестве обратного вызова, поэтому обязательно используйте PHP >= 5.3.

add_filter('wpcf7_form_elements', function($content) {
    $content = preg_replace('/<(span).*?class="\s*(?:.*\s)?wpcf7-form-control-wrap(?:\s[^"]+)?\s*"[^\>]*>(.*)<\/\1>/i', '\2', $content);

    return $content;
});

Ответ 2

Вы можете удалить оболочку span с помощью jQuery:

$("#name").unwrap();

Он удалит входной родительский элемент, поэтому в этом случае он удалит span. Обратите внимание, что после удаления диапазона некоторые функции Contact Form 7 могут работать некорректно. Например, проверка может не работать.

$("button").click(function(){
  $("#name").unwrap();
});
span {
  background-color: #333;
  padding: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="wpcf7-form-control-wrap name">
  <input type="text" name="name" value="" size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control" id="name" aria-required="true" aria-invalid="false">
</span>

<button>Remove span</button>

Ответ 3

Я пробовал подобные вещи на днях, и многие люди упоминали, что Regex не является правильным способом изменения HTML/удаления тегов и т.д., И это звучит логично.

Поэтому я выбрал DOMDocument и нашел следующее решение:

add_filter('wpcf7_form_elements', function( $content ) {
  $dom = new DOMDocument();
  $dom->preserveWhiteSpace = false;
  $dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

  $xpath = new DomXPath($dom);
  $spans = $xpath->query("//span[contains(@class, 'wpcf7-form-control-wrap')]" );

  foreach ( $spans as $span ) :
    $children = $span->firstChild;
    $span->parentNode->replaceChild( $children, $span );
  endforeach;

  return $dom->saveHTML();
});

РЕДАКТИРОВАТЬ: теперь я также добавил некоторые html/text в мою форму, и первый элемент заголовка был неправильно упакован после того, как я использовал класс DOMDocument. Это началось в первой строке и закончилось в самом конце формы. поэтому я завернул всю свою форму в div, что заставило разметку снова вернуться правильно.

Ответ 4

Начиная с версии 4.9 WPCF7, адаптация ответа выше, чтобы не потерять сообщения об ошибках:

Прежде всего, в редакторе на CMS оберните ваше поле ввода и любые другие элементы, которые вы хотите сгруппировать, например:

<span class="wpcf7-form-control-wrap your-name">{field codes, etc, here}</span>

Обратите внимание, что вам нужно будет использовать класс "wpcf7-form-control-wrap" и класс, соответствующий вашему имени поля.

Затем используйте этот код регулярного выражения в functions.php. Возможно, потребуется адаптация для ваших конкретных потребностей.

add_filter('wpcf7_form_elements', function($content) {
    preg_match_all('/<(span).*?class="\s*(?:.*\s)?wpcf7-form-control-wrap(?:\s[^"]+)?\s*"[^\>]*>(.*)<\/\1>/i', $content,$matches);

    foreach($matches[2] as $match):
        $content = str_replace(trim($match),trim(preg_replace('/<(span).*?class="\s*(?:.*\s)?wpcf7-form-control-wrap(?:\s[^"]+)?\s*"[^\>]*>(.*)<\/\1>/i', '\2', $match)),$content);
    endforeach;
    return $content;
});

Это разделит тег span вокруг поля ввода, оставив ваш новый тег span неповрежденным. Эффект заключается в том, чтобы по существу перемещать тег span только из поля ввода, чтобы быть вокруг любых элементов, которые вы хотите обернуть.

Причина этого заключается в том, что код для подачи формы, к сожалению, очень жестко закодирован. Чтобы иметь полную свободу над структурой вашего HTML, вам нужно либо:

  • Измените код в rest-api.php вокруг строки 295, чтобы изменить значение "в" на нечто менее конкретное. Естественно, это не рекомендуемый маршрут, хотя тот, который дает вам полную свободу структурирования вашего контента по вашему желанию. Он будет перезаписан обновлениями плагинов.

    foreach ( (array) $result['invalid_fields'] as $name => $field ) {
        $invalid_fields[] = array(
            'into' => 'span.wpcf7-form-control-wrap.'
                . sanitize_html_class( $name ),
            'message' => $field['reason'],
            'idref' => $field['idref'],
        );
    }
    
  • Нажмите на wpcf7: недопустимое событие и запустите свой собственный код проверки на результат. Излишне говорить, что это дублирует большую часть работы, которую плагин уже делает для вас, когда принятие (пока) использования тега span с классом "wpcf7-form-control-wrap" описанным выше образом сохраняет всю функциональность плагин, отменяя одну из самых раздражающих жестких кодировок плагина.

Ответ 5

В дополнение к php-коду Guicara, следующий код javascript может получить текст сообщения об ошибке:

document.addEventListener('wpcf7invalid',function(e){
    if ('validation_failed' === e.detail.apiResponse.status){
        $.each(e.detail.apiResponse.invalidFields,function(i,el){
        console.log('this is error response and form object',el.message, $('#'+el.idref));
        });
    }
});