Почему некорректно сохраняется мульти checkbox в повторяющихся полях виджета wordpress?

Ссылка скопирована
1 ответ

Всем привет!
В wordpress виджете с полями репитерами добавил checkbox, но не могу разобраться с багом сохранения и вывода состояния установлена ли галочка.

К примеру, добавил 4 блока с полями (1 из которых чекбокс):
1 - если во всех блоках включаю все галочки, то они все сохраняются
2 - если снимаю 2 галочки, то при сохранении она исчезает только у последнего элемента, 3 и двоих последних
3 - а, если все галочки снимаю, то при сохранении галочка всегда остаётся у первого

Код виджета

<?php class My_WidgetBase extends WP_Widget { //бэкенд public function form( $instance ) {     if ( isset( $instance[ 'blank' ]) ) {     $blank = $instance[ 'blank' ];     } ?>  <div id="repeatable-fieldset-one"> <?php if (!empty($text)) :   foreach ( $text as $k => $x ) {     if(!empty($x)) { ?>   <div class="block">     <p><input type="text" name="<?php echo $this->get_field_name( 'link' ); ?>[]" value="<?php echo esc_attr( $link[$k] ); ?>"></p>     <p><label for="<?php echo $this->get_field_id( 'blank' ).$k; ?>">Открывать в новой вкладке?</label><input class="widefat" id="<?php echo $this->get_field_id( 'blank' ).$k; ?>" name="<?php echo $this->get_field_name( 'blank' ); ?>[]" type="checkbox" value="<?php echo esc_attr($blank[$k]); ?>" <?php checked("1", array_key_exists($k, $blank)); ?> /></p>     <a class="button remove-row" href="#">Удалить блок</a>   </div>   <?php }   }   else :   // начальный пустой блок   ?>   <div class="block">     <p><input type="text" name="<?php echo $this->get_field_name( 'link' ); ?>[]" value=""></p>     <p><label for="<?php echo $this->get_field_id( 'blank' ); ?>">Открывать в новой вкладке?</label><input class="widefat" id="<?php echo $this->get_field_id( 'blank' ); ?>" name="<?php echo $this->get_field_name( 'blank' ); ?>[]" type="checkbox" value="" checked="checked" /></p>   </div>  <?php endif; ?> </div>  <?php } //сохранение public function update( $new_instance, $old_instance ) {   $instance['link'] = ( ! empty( $new_instance['link'] ) ) ? $new_instance['link'] : '';   $instance['blank'] = ( ! empty( $new_instance['blank'] ) ) ? 1 : false;   return $instance; }  }

<?php class My_WidgetBase extends WP_Widget { //бэкенд public function form( $instance ) { if ( isset( $instance[ 'blank' ]) ) { $blank = $instance[ 'blank' ]; } ?> <div id="repeatable-fieldset-one"> <?php if (!empty($text)) : foreach ( $text as $k => $x ) { if(!empty($x)) { ?> <div class="block"> <p><input type="text" name="<?php echo $this->get_field_name( 'link' ); ?>[]" value="<?php echo esc_attr( $link[$k] ); ?>"></p> <p><label for="<?php echo $this->get_field_id( 'blank' ).$k; ?>">Открывать в новой вкладке?</label><input class="widefat" id="<?php echo $this->get_field_id( 'blank' ).$k; ?>" name="<?php echo $this->get_field_name( 'blank' ); ?>[]" type="checkbox" value="<?php echo esc_attr($blank[$k]); ?>" <?php checked("1", array_key_exists($k, $blank)); ?> /></p> <a class="button remove-row" href="#">Удалить блок</a> </div> <?php } } else : // начальный пустой блок ?> <div class="block"> <p><input type="text" name="<?php echo $this->get_field_name( 'link' ); ?>[]" value=""></p> <p><label for="<?php echo $this->get_field_id( 'blank' ); ?>">Открывать в новой вкладке?</label><input class="widefat" id="<?php echo $this->get_field_id( 'blank' ); ?>" name="<?php echo $this->get_field_name( 'blank' ); ?>[]" type="checkbox" value="" checked="checked" /></p> </div> <?php endif; ?> </div> <?php } //сохранение public function update( $new_instance, $old_instance ) { $instance['link'] = ( ! empty( $new_instance['link'] ) ) ? $new_instance['link'] : ''; $instance['blank'] = ( ! empty( $new_instance['blank'] ) ) ? 1 : false; return $instance; } }

Дополнительно

на выходе пары label for и input id - соответствуют? У каждой пары свое, уникальное?

  • Александр Васильев, да, соответствуют. Но, сохранение ведь идет не по id. Здесь где-то в value, name или checked проблема зарыта, не могу отследить, чтобы понять где именно..
  • ligisayan, надо смотреть - что на выходе, я так не могу нафантазировать
  • Александр Васильев, хорошо, давайте вместе смотреть - что и в каком месте навардампить?
  • Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Mobile-редакция Ответ

    Проблема с checkbox в повторяющихся полях виджета обычно возникает из-за того, что unchecked checkbox вообще не отправляется в POST. Если вы сохраняете массив по индексам, то после снятия галочки индексы сдвигаются или старое значение остаётся.

    Нужно для каждого checkbox сохранять значение явно: 1 или 0. В форме перед checkbox часто добавляют hidden input с тем же именем и значением 0:

    <input type="hidden" name="<?php echo esc_attr($this->get_field_name('items')); ?>[<?php echo $i; ?>][enabled]" value="0">
    <input type="checkbox" name="<?php echo esc_attr($this->get_field_name('items')); ?>[<?php echo $i; ?>][enabled]" value="1" <?php checked(! empty($item['enabled'])); ?>>

    <input type="hidden" name="<?php echo esc_attr($this->get_field_name('items')); ?>[<?php echo $i; ?>][enabled]" value="0"> <input type="checkbox" name="<?php echo esc_attr($this->get_field_name('items')); ?>[<?php echo $i; ?>][enabled]" value="1" <?php checked(! empty($item['enabled'])); ?>>

    В методе update() нормализуйте данные:

    foreach ($new_instance['items'] as $i => $item) {
        $instance['items'][$i]['enabled'] = ! empty($item['enabled']) ? 1 : 0;
        $instance['items'][$i]['title'] = sanitize_text_field($item['title'] ?? '');
    }

    foreach ($new_instance['items'] as $i => $item) { $instance['items'][$i]['enabled'] = ! empty($item['enabled']) ? 1 : 0; $instance['items'][$i]['title'] = sanitize_text_field($item['title'] ?? ''); }

    Главная идея: не полагайтесь на сам факт наличия checkbox в POST. Для снятой галочки браузер ничего не отправляет, поэтому вы должны сами записать 0.

    Также следите, чтобы у каждого блока репитера был стабильный индекс. Если при удалении/добавлении блоков индексы ломаются, состояние полей будет путаться.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно