Как создать такую форму на yii2?

258
13 января 2018, 00:11

Здравствуйте. Есть вот такая форма с кучей радио кнопок. В каждом блоке своя группа радио кнопок. Они должны создаваться динамически на основе данных из БД и группироваться по просмотрам. Для каждого года свой блок.

Вопрос: каким образом можно данный html перевести в валидный код для yii2? И как грамотно организовать модель для обработки данных с этих форм?

.ThisDay-default-index { 
  position: relative; 
} 
 
.horizontal-scroll-wrapper { 
  width: 100%; 
} 
 
.control-group { 
  display: inline-block; 
  vertical-align: middle; 
  background: #fff; 
  text-align: left; 
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); 
  width: auto; 
  height: auto; 
  margin: 10px; 
  max-width: 250px; 
  max-height: 275px; 
  overflow-y: scroll; 
  word-wrap: break-word; 
  white-space: normal; 
} 
 
.thisday-container { 
  width: 55%; 
  height: 100%; 
  display: flex; 
  flex-wrap: wrap; 
  justify-content: center; 
  align-items: center; 
  white-space: nowrap; 
  overflow-x: auto; 
  -webkit-overflow-scrolling: touch; 
  -ms-overflow-style: -ms-autohiding-scrollbar; 
  margin: 0 auto; 
} 
 
.control { 
  display: block; 
  position: relative; 
  padding-left: 30px; 
  margin-bottom: 15px; 
  cursor: pointer; 
  font-size: 14px; 
  font-weight: 600; 
} 
 
.control input { 
  position: absolute; 
  z-index: -1; 
  opacity: 0; 
} 
 
.control__indicator { 
  position: absolute; 
  top: 2px; 
  left: 0; 
  height: 20px; 
  width: 20px; 
  background: #e6e6e6; 
} 
 
.control--radio .control__indicator { 
  border-radius: 50%; 
} 
 
.control:hover input~.control__indicator, 
.control input:focus~.control__indicator { 
  background: #ccc; 
} 
 
.control input:checked~.control__indicator { 
  background: #2aa1c0; 
} 
 
.control:hover input:not([disabled]):checked~.control__indicator, 
.control input:checked:focus~.control__indicator { 
  background: #0e647d; 
} 
 
.control input:disabled~.control__indicator { 
  background: #e6e6e6; 
  opacity: 0.6; 
  pointer-events: none; 
} 
 
.control__indicator:after { 
  content: ''; 
  position: absolute; 
  display: none; 
} 
 
.control input:checked~.control__indicator:after { 
  display: block; 
} 
 
.control--radio .control__indicator:after { 
  left: 7px; 
  top: 7px; 
  height: 6px; 
  width: 6px; 
  border-radius: 50%; 
  background: #fff; 
} 
 
.control--radio input:disabled~.control__indicator:after { 
  background: #7b7b7b; 
} 
 
#thisday-resume { 
  position: absolute; 
  right: 45%; 
  top: 0%; 
} 
 
.control-views-count { 
  position: relative; 
  display: block; 
  float: right; 
  font-weight: 500; 
} 
 
.thisday-butt { 
  float: right; 
} 
 
.thisday-time { 
  float: left; 
} 
 
.thisday-content { 
  clear: both; 
}
<div class="ThisDay-default-index"> 
  <div class="form-group thisday-butt"> 
    <div class="col-md-2"> 
      <button type="submit" class="btn btn-default">Далее</button> 
    </div> 
  </div> 
  <p class="thisday-time">Выберите ключевые новости 
    12 Января из прошлого:</p> 
  <form class="thisday-content" action="thisday-edit.php" method="post"> 
    <!-- <button type="submit" name="button" class="btn btn-default">Далее</button> --> 
    <div class="thisday-container"> 
      <div class="horizontal-scroll-wrapper"> 
        <div class="control-group"> 
          <h3>2016</h3> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio1"/> 
      <div class="control__indicator"></div> 
      <span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio1"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio1"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio1"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
        </div> 
        <div class="control-group"> 
          <h3>2015</h3> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio2"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio2"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio2"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio2"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
        </div> 
        <div class="control-group"> 
          <h3>2014</h3> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio3"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio3"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio3"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio3"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
        </div> 
        <div class="control-group"> 
          <h3>2013</h3> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio4"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio4"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio4"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio4"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
        </div> 
        <div class="control-group"> 
          <h3>2012</h3> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio5"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio5"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio5"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio5"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
        </div> 
        <div class="control-group"> 
          <h3>2011</h3> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio6"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio6"/> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio6"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
          <label class="control control--radio">Заголовок новости длииииииииииииный 
      <input type="radio" name="radio6"> 
      <div class="control__indicator"></div> 
<span class="control-views-count">1500</span> 
    </label> 
        </div> 
      </div> 
    </div> 
  </form> 
</div>

Answer 1

Работа с данными:

/**
 * Допустим, новости хранятся в таблице article с полями id, title, views и year
 */
class Article extends \yii\base\Model //\yii\db\ActiveRecord
{
    // Я добавил поля в модель и наследовал \yii\base\Model потому, что не работаю с бд
    public $id;
    public $title;
    public $views;
    public $year;
    public static function tableName()
    {
        return "article";
    }
}
/**
 * $articles = Article::find()
 * // Сортируем по году и ID
 * ->orderBy(['year' => SORT_DESC, 'id' => SORT_ASC])
 * // Массив будет такого вида: [2017 => [Article, Article, ....], 2018 => [...]]
 * ->indexBy('year')
 * ->all();
 */
// У меня такой таблиц нет, я просто эмулирую выборку
$articles = [
    2016 => [
        new Article([
            'id' => 1,
            'title' => "Test title",
            'views' => 100500,
            'year' => 2016
        ]),
        new Article([
            'id' => 2,
            'title' => "Test title 2",
            'views' => 1000,
            'year' => 2016
        ]),
        new Article([
            'id' => 3,
            'title' => "Title for 3",
            'views' => 200,
            'year' => 2016
        ]),
    ],
    2017 => [
        new Article([
            'id' => 4,
            'title' => "Test title 2017",
            'views' => 100500,
            'year' => 2017
        ]),
        new Article([
            'id' => 5,
            'title' => "Test title 2017 2",
            'views' => 0,
            'year' => 2017
        ]),
        new Article([
            'id' => 6,
            'title' => "Title for 2017 3",
            'views' => 800,
            'year' => 2017
        ]),
    ]
];

View:

<div class="ThisDay-default-index">
    <div class="form-group thisday-butt">
        <div class="col-md-2">
            <button type="submit" class="btn btn-default">Далее</button>
        </div>
    </div>
    <p class="thisday-time">Выберите ключевые новости
        12 Января из прошлого:</p>
    <?php
    $form = \yii\widgets\ActiveForm::begin([
        'options' => [
            'class' => 'thisday-content',
        ],
    ]); ?>
    <div class="thisday-container">
        <div class="horizontal-scroll-wrapper">
            <?php foreach ($articles as $year => $yearArticles): ?>
                <div class="control-group">
                    <h3><?= $year ?></h3>
                    <?php foreach ($yearArticles as $article): ?>
                        <?= $form->field($article, 'id[' . $year . '][]')->radio([
                            'value' => $article->id,
                            'label' => \app\helpers\Html::encode($article->title)
                                . \app\helpers\Html::tag('div', '', ['class' => 'control__indicator'])
                                . \app\helpers\Html::tag('span', $article->views, ['class' => 'control-views-count']),
                            'labelOptions' => [
                                'encode' => false,
                                'class' => 'control control--radio',
                            ],
                        ]); ?>
                    <?php endforeach; ?>
                </div>
            <?php endforeach; ?>
        </div>
    </div>
    <?php \yii\widgets\ActiveForm::end(); ?>
</div>

Обратите внимание на атрибут модели. Я сделал так, что бы radio работали внутри одного года. input будет содержать такие параметры: name="Article[id][2017][]" value="4". В POST будет массив ['Article' => ['id' => [5, 6]]] Если выбрать значение можно только для одного года, то можно убрать год из аттрибута

READ ALSO
Эффект растущей кривой polyline объекта?

Эффект растущей кривой polyline объекта?

Подскажите, пожалуйста, есть ли возможность добиться эффекта, так называемой растущей кривой, реализуемый изменением значения stroke-dashoffset...

221
Движение текста

Движение текста

Есть блок:

177
связать &lt;textarea&gt; с кнопкой [дубликат]

связать <textarea> с кнопкой [дубликат]

На данный вопрос уже ответили:

204
Верстка изогнутого блока

Верстка изогнутого блока

Добрый день, может кто подсказать сверстать такой блок а точнее эту изогнутую шапку на блоке?

264