Статьи из рубрики form
Как написать валидатор
Пример валидатора для серверной и клиентской частей
Есть таблица цен на номера в пансионате. Цена зависит от различных параметров - номера, типа ценника, типа питания, варианта размещения, наличия или отсутствия лечения. Цена, для определенной комбинации значений этих параметров, может быть только одна.
Нужно записать правило проверки уникальности комбинации атрибутов как для обычной формы так и для ее модального варианта.
Интерфейс для полнотекстового поиска
Использование ElasticSearch во frontend
На создание ElasticSearch
индекса понадобилось совсем не много усилий, как видно из предыдущей статьи. Чтобы сделать индекс доступным конечному пользователю, усилий понадобиться не многим больше.
Теперь нужна форма ввода и нужно немного подправить действие контроллера для ее обработки и получения результатов и представление, чтобы отображать форму.
Как написать виджет для WordPress
Пример виджета для WordPress
Иногда производители предоставляют возможность покупателю самостоятельно выбрать на сайте комплектацию товара. В этом случае, при разработке сайта, нужно предусмотреть возможность показа текущей цены на видном месте (demo).
В WordPress
для подобных задач используется область виджетов. Как писать виджет
в WordPress подробно написано в кодексе. Но всегда есть нюансы.
Как написать short-code для WordPress
Пример написания short-code для WordPress
На сайте магазина нужно, чтобы пользователь мог, выбирать комплектацию товара отвечая на вопросы. Вопросы должны сопровождаться наглядными картинками.
Должна быть возможность легко размещать такой вопросник в статье или на странице блога WordPress
. Об этом была речь в предыдущем посте.
Как написать плагин для WordPress
Плагин для WordPress подсчета цены по компонентам
Любой товар состоит из элементов. Довольно часто производитель, поставив задачу написать электронный магазин, позволяет выбирать комплектацию заранее, до производства. Выбирая комплектующие есть возможность сэкономить или наоборот, согласиться с утверждением "Я этого достоин(а)" и заказать по полной.
Например можно представить пиццерию, где в меню указана стоимость составляющих - лепешка, сыр трех сортов, помидоры двух сортов, колбаса 5 видов. Комбинируете вы сами и постоянно видите, как ваш выбор отражается на цене.
Как отсортировать картинки мышкой
Сортировка строк мышкой
Оставили комментарий в конце января: "Напишите, пожалуйста, статью, как массово загружать изображения через ajax с возможностью сортировки перетаскиванием."
Речь о расширении yii2-uploader, которое может загружать, сжимать, обрезать картинки для любой модели. Я писал о нем уже пару раз.
На тот момент этой функциональности не было. Собирался я долго. Наконец добавил требуемое. Теперь спешу написать несколько слов о процессе. Демо (при редактировании).
Как добавить атрибут к загруженному файлу
Добавление описания к файлу
Иногда важно определить дополнительную информацию для загружаемого файла. Например это может быть описание. В расширении yii2-uploader возможность добавить описание к файлу уже предусмотрена.
Кроме описания может быть добавлено и любое другое свойство. В предыдущем примере использовалось свойство when
типа radio
с двумя значениями - "до" и "после". Как добавить новое свойство?
Как сделать галерею фотографий "До и После"
Показ фотографий до и после момента времени
Представьте, что вы продаете курс похудания. Вам нужно наглядно представить результат вашего курса. Фото "До" и "После", что может быть лучшей иллюстрацией?
Как и в предыдущем примере примем, что участников ограниченное количество. Например 4. Забудем про похудающих - слишком скучно. Будем "работать" с кинозвездами. Для каждого можно загрузить только 4 фотографии. Таким образом всего 16 фото. Если загружены все 16 и кому-то захочется добавить "свои" фото, то придется что-то удалить. Демо.
Делаем демо для загрузки фото
Загрузка жестко определенного количества файлов
Чтобы показать, как работает загрузка изображений, нужно разрешить загружать изображения на свой сайт. Но, в этом случае, дисковое пространство может быть быстро исчерпано и нужно как-то удалять оставленный посетителями "мусор".
Обычно загруженные файлы удаляются автоматически спустя время, но можно ограничить количество файлов - демо.
Редактирование и валидация модальной формы
Использование pop-up формы
Бывает, что количество полей в таблице не слишком велико и редактировать в модальном окне проще и нагляднее. Что необходимо, чтобы организовать стандартный набор операций - CReate, Update, Delete?
Поиск
Метки
- 1. Делаем демо для загрузки фото
- 2. Как сделать галерею фотографий "До и После"
- 3. Как добавить атрибут к загруженному файлу
- 4. Как отсортировать картинки мышкой
Представьте, что вы продаете курс похудания. Вам нужно наглядно представить результат вашего курса. Фото "До" и "После", что может быть лучшей иллюстрацией?
Как и в предыдущем примере примем, что участников ограниченное количество. Например 4. Забудем про похудающих - слишком скучно. Будем "работать" с кинозвездами. Для каждого можно загрузить только 4 фотографии. Таким образом всего 16 фото. Если загружены все 16 и кому-то захочется добавить "свои" фото, то придется что-то удалить. Демо.
Опять будем использовать расширение yii-uploader. Это расширение хранит все файлы в одной модели и модель имеет поле defs
в котором могут храниться json
определения любых переменных.
По умолчаниюю доступно поле description
, но можно добавить любое другое. Например when
со значениями - 0 ("До"), 1 ("После").
Model
Подключение поведения такое же, как в предыдущем примере. Фото, однако, квадратное.
А отличие app\models\Stout.php
в том, что необходимо найти, среди фото, принадлежащих модели, фотографии "До" и "После".
<?php namespace app\models; use yii\base\Model; use sergmoro1\uploader\behaviors\HaveFileBehavior; class Stout extends Model { const BEFORE = 0; const AFTER = 1; public $id; public $name; public function behaviors() { return [ [ 'class' => HaveFileBehavior::className(), 'file_path' => '/stout/', 'sizes' => [ 'original' => ['width' => 800, 'height' => 800, 'catalog' => 'original'], 'main' => ['width' => 600, 'height' => 600, 'catalog' => ''], 'thumb' => ['width' => 90, 'height' => 90, 'catalog' => 'thumb'], ], ] ]; } public function attributeLabels() { return [ 'name' => \Yii::t('app', 'Name'), ]; } /** * Search for a model by ID * This method is required for the extension to work. * * @param integer $id * @return yii\base\Model */ public function findOne($id) { return new Stout(['id' => $id]); } private function getMainImage($when) { $image = false; for($i = 0; $i < $this->fileCount; $i++) { $file = $this->files[$i]; if(isset($file->vars->when)) { if($file->vars->when == $when) { $image = $this->getImage('', $i); break; } } else { // image was added without any defs by mistake & must be deleted $this->deleteFile($file->name, $file->subdir); } } return $image; } public function getBefore() { return $this->getMainImage(self::BEFORE); } public function getAfter() { return $this->getMainImage(self::AFTER); } }
Сделано это простым перебором среди всех, принадлежащих модели, файлов.
Controller
Действия всего два и они не отличаются от действий предыдущего примера. Несколько "странноватый" вид метода getModel
обусловлен тем, что модель - это массив, а не объект, как обычно.
<?php namespace app\controllers; use yii\data\ArrayDataProvider; use app\models\Stout; class StoutController extends Controller { public $models = [ ['id' => 1, 'name' => 'Danila Kozlovsky'], ['id' => 2, 'name' => 'Anna Kovalchuk'], ['id' => 3, 'name' => 'Julia Snegir'], ['id' => 4, 'name' => 'Vladimir Vdovichenkov'], ]; public $_model; public function actionIndex() { $dataProvider = new ArrayDataProvider([ 'allModels' => $this->models, ]); return $this->render('index', [ 'dataProvider' => $dataProvider, ]); } public function actionUpdate($id) { return $this->render('update', [ 'model' => $this->getModel($id), ]); } public function getModel($id) { if($this->_model === null) { $data = $this->models[$id - 1]; $this->_model = new Stout($data); } return $this->_model; } }
View
app\views\stout\index.php
проще некуда.
<?php use yii\widgets\ListView; ?> <?= ListView::widget([ 'dataProvider' => $dataProvider, 'layout' => "{items}", 'itemView' => '_stout', ]); ?>
Вся магия в app\views\stout\_stout.php
<?php * @var model Stout */ use yii\helpers\Html; use app\models\Stout; $model = new Stout($model); ?> <div class='col-sm-6'> <div class='photo-block'> <div class='photo-column pull-left'> <div class='mark'>before</div> <?= ($image = $model->getBefore()) ? Html::img($image, ['class'=>'grow']) : '<i class="fa fa-3x fa-user"></i>' ?> </div> <div class='photo-column pull-left'> <div class='mark'>after</div> <?= ($image = $model->getAfter()) ? Html::img($image, ['class'=>'grow']) : '<i class="fa fa-3x fa-user"></i>' ?> </div> <div class='footer'> <?= $model->name ?> </div> </div> <p class='text-center'> <?= Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->id]) ?> </p> </div>
и в css app\web\css\stout.css
.
.photo-block { position:relative; margin:0px; padding:0px; height:240px; width:480px; } .photo-column { position:relative; width:240px; height:240px; overflow:hidden; background-color:#fff; } .photo-left { border-left:4px solid #fff; border-top:4px solid #fff; border-bottom:4px solid #fff; } .photo-right { border-right:4px solid #fff; border-top:4px solid #fff; border-bottom:4px solid #fff; } .photos-left, .photos-right {margin-top:10px;} .photos-left .description, .photos-right .description { margin:10px 0px; color:#fff; } .photo-full {width:100%;} .mark { position:absolute; left:20px; top:0px; width:45px; height:35px; z-index:1; text-align:center; display:none; } .mark .middle {padding-top: 5px;} .photo-left .mark { background-color:#d8d8d8; font-size:10pt; color:#333; } .photo-right .mark { background-color:#51adee; font-size:10pt; color:#fff; } .photo-block .footer { position:absolute; bottom:0px; left:0px; height:30px; width:472px; margin:0px 4px; padding:0px; background-color:#fff; color:#000; opacity:0.5; z-index:1; text-align:center; } .brighten { -webkit-filter: brightness(35%); -webkit-transition: all 1s ease; -moz-transition: all 1s ease; -o-transition: all 1s ease; -ms-transition: all 1s ease; transition: all 1s ease; } .brighten:hover { -webkit-filter: brightness(100%); } .grow { -webkit-transition: all 0.5s ease-out; -moz-transition: all 0.5s ease-out; -o-transition: all 0.5s ease-out; -ms-transition: all 0.5s ease-out; transition: all 0.5s ease-out; } .grow:hover { -webkit-transform: scale(1.2); -moz-transform: scale(1.2); -o-transform: scale(1.2); -ms-transition: scale(1.2); transition: scale(1.2); } .list-view .items .photo-block a {cursor:pointer;}
Осталось обеспечить ввод фото app\views\stout\update.php
.
<?php use sergmoro1\uploader\widgets\Uploader; ?> <?= Uploader::widget([ 'model' => $model, 'secure' => false, 'limit' => 4, 'appendixView' => '/stout/appendix', 'cropAllowed' => true, 'draggable' => true, ]) ?>
Все! Если предположить, что значение поля when
определяется средствами расширения, то можно считать, что алгоритм вывода фотографий "До" и "После" ясен и пора посмотреть, что получилось.
Демо.
Заключение
Использовать расширение yii-uploader просто. Можно добавлять дополнительные поля данных, не меняя модели. Как было добавлено поле when
можно узнать в следующей статье.
Оставьте комментарий
Только зарегистрированные пользователи могут оставлять комментарии. Пожалуйста войдите или пройдите регистрацию.
Можно авторизоваться, используя социальную сеть-
-
-