Связанные списки на jQuery

http://www.appelsiini.net/projects/chained

See standalone demo page for quick working example.

Class Based Usage
Child selects are chained to parent select. Child select options must have class names which match option values of parent select. When user selects something in parent select the options in child select are updated. Options which have matching classname with parents currently selected option will stay visible. Others are hidden.

NOTE! Class names are case sensitive. This means Audi and audi will not match.
First you must include jQuery and Chained in your code:



Then lets assume you have the following HTML code:



You can now chain the #series to #mark. There are two different ways to do it. Choose yourself if you prefer more english like or shorter version. I prefer the shorter version.

$(«#series»).chained(«#mark»); /* or $(«#series»).chainedTo(«#mark»); */

Рюкзак

Сегодня начинаю новую рубрику — lifehack. И первое, что напишу будет о быте. Чтобы все получалось красиво, нужно использовать красивые вещи. Но чтобы, было понятно, я четко разделяю понятия красота и гламур. К-Ра-Сота — встроенная в систему жизни частичка к Ра.

http://lifehacker.ru/2015/05/25/rabochie-mesta-sergej-oseledko/

У меня удобный деловой рюкзак Samsonite с кучей отделений, как я люблю. И такой же кейс на колёсах для командировок, туда к обычному содержимому добавляется комплект одежды и туалетных принадлежностей.

Геолокация в браузере

http://webmap-blog.ru/obzors/ispolzuem-html5-geolocation-api

Используем HTML5 Geolocation API

HTML5 Geolocation API дает возможность пользователям обмениваться информацией о их местоположении (координаты долготы и широты в браузере) в веб-приложениях.

Для этого пользователь должен разрешить возможность определения своего расположения.

Geolocation API поддерживается большеством современных браузеров: Firefox 3.5+, Opera 10.6+, Chrome 5+, Safari 5+ и Internet Explorer 9+.

В этой заметке я расскажу как использовать эту возможность с различными API карт.

Первое, Вы должны проверить поддерживает или нет HTML5 Geolocation API браузер пользователя.

Это можно сделать с помощью кода:

<script type="text/javascript">
if(navigator.geolocation) {
    alert("Geolocation API поддерживается");
} else {
    alert("Geolocation API не поддерживается в вашем браузере");
}
</script>

Определить местоположение пользователя можно, используя следующий код:

navigator.geolocation.getCurrentPosition(function(position) {
            var latitude = position.coords.latitude;
            var longitude = position.coords.longitude;
        }

Соединим два примера кода в один, получим простейший пример определения положения пользователя:

<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 Geolocation API</title>
 
<script type="text/javascript">
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
            var latitude = position.coords.latitude;
            var longitude = position.coords.longitude;
			alert(latitude+' '+longitude);
});
 
} else {
    alert("Geolocation API не поддерживается в вашем браузере");
}
</script>
 
</head>
 
<body>
<p>Пример определения местоположения пользователя - HTML5 Geolocation API</p>
</body>
</html>

Посмотреть пример в действии

При просмотре примера в верху окна браузера может появиться информационная панель вида:

Информационная панель с сообщением

Нужно разрешить сообщить местоположение.

Тогда мы увидим окно с координатами

Окно с координатами

Информативней, если местоположение будет сразу показано на карте.

Рассмотрим как это можно сделать, используя различные API карт (Google, Bing , Nokia Maps, Яндекс.Карты и OpenStreetMap).

1. Пример с использованием API Яндекс.Карт

HTML5 Geolocation API - Яндекс.Карты

Посмотреть пример в действии

2. Пример с использованием API Google Maps

HTML5 Geolocation API - Google Maps

Посмотреть пример в действии

3. Пример с использованием API Bing Maps

HTML5 Geolocation API и Bing Maps

Посмотреть пример в действии

4. Пример с использованием API Nokia Maps

HTML5 Geolocation и Nokia Maps

Посмотреть пример в действии

5. Пример с использованием OpenStreetMap и библиотеки Leaflet

HTML5 Geolocation и OpenStreetMap

Посмотреть пример в действии

6. Пример с использованием OpenStreetMap и API Яндекс.Карт

HTML5 Geolocation - OpenStreetMap - Яндекс.Карты

Посмотреть пример в действии

Загрузить архив с файлами примеров

Для написания заметки использовалась статья: «Using HTML5 Geolocation API with Google, Bing and Nokia Maps».

Шпоргалка по OpenCart

Полезный код для разработчиков OpenCart.

Серия старей для разработчиков модулей под OpenCart. В этой серии статей будут опубликованы маленькие и полезные модули, полезные участки кода, описания основных классов и нестандартные решения стандартными способами. Без костылей и велосипедов.

Определение текущего layout_id в модуле и на странице

Вывод модуля на странице определенной категории или товара

Этот код добавляется в код модуля. В настройках модуля должны быть два массива – $show_on_categories, $show_on_products, в которых содержатся category_id и product_id, соответственно.

А теперь применение функции. Вставляется в начало функции index() модуля.

Полная очистка кэша

Описание функций основных классов

 

Обновление грида через ajax

Прочитал, но не понимаю, почему у меня работает по другому, а не так как Вы описали в Способ 2. Все через Ajax

Вот action, который выводит список пользователей:

getRequest()->getQuery(‘User’)) $model->attributes=$_GET[‘User’];

if(Yii::app()->getRequest()->getQuery(‘ajax’))//проверка «а есть ли в запросе призрак ajax’a»
{
$this->controller->renderPartial(‘usersListGrid’,array(‘model’=>$model));
}
else
{
$this->controller->render(‘usersList’,array(‘model’=>$model));
}
}
}

* This source code was highlighted with Source Code Highlighter.

Вышеописанный action рендерит представление usersList.php, которое в свою очередь вызывает usersListGrid.php.

Если же потом мы будем переходит по страницам, фильтровать, сортировать, то CGridView подставит в запрос ajax и вышеописанный action будет отдавать только представление usersListGrid.php (чистый html-код, без всяких вызовов jquery.js и остальных скриптов), так как они уже были загружены при первом вызове.

И все будет работать.

Представление: usersList.php

renderPartial(‘usersListGrid’,array(‘model’=>$model),true,false); ?>

* This source code was highlighted with Source Code Highlighter.

Представление: usersListGrid.php

createUrl(«admin/itemsSelected»),’post’,array(‘enctype’=>’multipart/form-data’)); ?>
widget(‘zii.widgets.grid.CGridView’, array(
‘id’=>’usersListGrid’,
‘dataProvider’=>$model->search(),
‘selectableRows’=>3,
‘template’=>»{summary}
{pager}
{items}
{pager}
«,
‘pager’=>array(
‘class’=>’CLinkPager’,
‘header’=>»,
‘firstPageLabel’=>’<<', 'prevPageLabel'=>‘<', 'nextPageLabel'=>‘>’,
‘lastPageLabel’=>’>>’,
),
‘filter’=>$model,
‘columns’=>array(
array(
‘class’=>’CCheckBoxColumn’,
‘id’=>’itemsSelected’,
),
array(
‘name’=>’id’,
‘value’=>’$data->id’,
//’filter’=>»,
‘htmlOptions’ => array(‘style’ => ‘text-align:center;width:40px;’),
),
array(
‘name’=>’datreg’,
‘type’=>’raw’,
‘value’=>’date(«d/m/Y H:i:s»,$data->datreg)’,
‘filter’=>»,
‘htmlOptions’ => array(‘style’ => ‘text-align:center;width:130px;’),
),
array(
‘class’=>’CButtonColumn’,
‘template’=>'{myupdate} {mydelete}’,
‘htmlOptions’ => array(‘style’ => ‘width:30px;’),
‘buttons’=>array(
‘myupdate’=>array(
‘label’=>’Редактировать’,
‘url’=>’array(«admin/usersEdit»,»id»=>$data->id)’,
‘imageUrl’=>Yii::app()->theme->baseUrl.’/img/pencil.png’,
),
‘mydelete’=>array(
‘label’=>’Удалить’,
‘url’=>’array(«admin/usersDelete»,»id»=>$data->id)’,
‘imageUrl’=>Yii::app()->theme->baseUrl.’/img/minus.png’,
‘click’=>’function(){return confirm(«‘.Yii::t(‘lan’,’Удалить ?’).'»);}’,
‘visible’=>’$data->role!=User::ROLE_ADMIN’,
),
),
),

),
));
?>
С отмеченными: WorkItemsSelected,array(’empty’ =>’—‘)); ?>
«return confirm(‘?’);»)); ?>

* This source code was highlighted with Source Code Highlighter.

Создание формы-фильтра записей WordPress по произвольным полям и другим параметрам

Создание формы-фильтра записей WordPress по произвольным полям и другим параметрам

Взято из (http://wppost.ru/postroenie-filtra-zapisej-wordpress-po-proizvolnym-polyam-i-ne-tolko/)

В нашей предыдущей статье мы рассмотрели возможность построения get-запроса к базе данных Worpress и рассмотрели варианты использования этой возможности для формирования фильтра записей, страниц и тд. Как вы помните в прошлой статье нам удалось избежать процесса создания скрипта-обработчика данных с формы и мы целиком возложили этот процесс на  сам WordPress, ограничившись только построением правильного запроса через форму фильтра. Но как мы выяснили, этот способ имеет один существенный недостаток — невозможность поиска по произвольным полям этих страниц или записей.

Сегодня мы попробуем пойти другим путем и научимся формировать фильтры с использованием произвольных полей.

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

Итак, начнем подготовку к реализации нашего фильтра.

Для начала подготовим шаблон страницы, где и будет происходить вывод результатов выборки.

Для этого в админке нашего сайта создадим новую пустую страницу, назовем ее «Результаты поиска» и назначим ей URL «customsearch»

02.10

Далее связываемся с нашим сервером с помощью FTP-клиента, находим файл page.php, делаем с него копию и переименовываем в page-customsearch.php. Таким образом, мы сообщаем, что все обращения к нашей созданной в админке странице будут обрабатываться именно в этом файле, не затрагивая другие, а обращаться мы к ней будем через наш фильтр записей.

02.102

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<form action="/customsearch/" method="get">
//выборка по отдельному слову
<p><label>Поисковый запрос</label><br />
<input type="text" name="word" value=""></p>
//выборка по терминам определенной таксономии, в нашем случае prodcat
<p><label>Укажите товарную категорию:</label><br />
<select name="prodcat">
<option value="">--------</option>
<option value="148">Плагины WordPress</option>
<option value="199">Изображения</option>
</select>
</p>
//Выборка по значениям цены, которые указаны произвольными полями
<p><label>Диапазон цены</label><br />
от <input type="text" name="min-price" size="3" value="">
до <input type="text" name="max-price" size="3" value=""></p>
//Указание сортировки результатов выборки
//Тут мы можем отсортировать и по значению цены, заданного
//произвольным полем
<p><label>Сортировка по</label><br />
<select name="orderby">
<option value="date">дате добавления</option>
<option value="title">заголовку</option>
<option value="meta_value_num">цене</option>
</select>
</p>
//Указание направление результатов сортировки
<p><label>Направление сортировки:</label><br />
<input type="radio" name="order" value="DESC"> по убыванию<br />
<input type="radio" name="order" value="ASC"> по возрастанию </p>
//Указание количества записей на одну страницу
<p><label>Получить:</label><br />
<select name="num">
<option value="-1">Все товары</option>
<option value="2">2 товара</option>
<option value="4">4 товара</option>
<option value="6">6 товаров</option>
</select>
</p>
<p><input type="submit" value="Получить товары"></p>
//так как мы можем производить сортировку и по произвольным полям, то
//в запросе следует указывать ключ этого поля.
//В нашем случае это цена товара "price-products"
<input type="hidden" name="meta_key" value="price-products">
</form>

Обратите внимание на атрибут action тега form, в нем мы указываем адрес именно той страницы, которую создали в админке и для которой мы создали отдельный шаблон на сервере. Метод передачи данных мы можем использовать любой, POST или GET.

Собственно, когда мы имеем на руках код формы мы можем переходить к этапу обработки данных, передаваемых этой формой. Здесь следует отметить, что нам не придется писать какой то большой скрипт, мы лишь будем максимально использовать возможности WordPress по обоработке переданных с формы данных. Поэтому мы ограничимся лишь построением массива данных, который затем передадим в цикл WordPress для вывода результата.

Обратимся к стандартной функции query_posts(), именно в эту функцию мы и должны передать сформированный нами массив. Эта функция распологается перед началом цикла записей и влияет на него, заставляя его выводить именно те записи, которые нам нужны и в том порядке который мы указали, лишь получив сформированный массив.

Как же формировать этот массив? Для этого мы можем обратиться к обширному описанию этой функции в кодексе Worpress. Это описание я дублировать тут не буду, но постараюсь подробно описать логику построения массива данных именно для нашей формы.

Итак, перейдем к построению массива данных для функции query_posts(). Для этого мы должны открыть для редактирования созданный нами ранее файл page-customsearch.php, где и будет происходить обработка и вывод результатов обработки нашего запроса.

Находим в нем начало цикла, которое выглядит примерно так:

1
if (have_posts()) : while (have_posts()) : the_post();

и ставим перед этой строкой функцию query_posts() и заготовку для нашего массива. Должно получиться примерно следующее:

1
2
3
4
5
<?php $args = array
);
query_posts( $args ); ?>        
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>

Теперь основываясь на описание функции query_posts в кодексе,  данные которые форма передает и метод передачи этих данных начинаем наполнение массива. Смотрим на нашу форму и идем по порядку:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$args = array(
//Для начала укажем тип записей по которым осуществляем поиск
//В нашем случае это products
    'post_type' => 'products',
//Передадим поисковый запрос из первого текстового поля
    's' => $_GET['word'],
//Тут передаем ключ произвольного поля по которому осуществляем
//сортировку, если сортировка идет по произвольному полю
    'meta_key' => $_GET['meta_key'],
//Здесь передаем количество записей выводимых на одной странице
    'posts_per_page' => $_GET['num'], // "-1" - получаем все
//Эти данные нужны для правильной работы постраничной навигации
//в результатах поиска
    'paged' => get_query_var( 'paged' ),
//Тут передаем направление сортировки, указанное пользователем
    'order' => $_GET['order'], //DESC,ASC
//Здесь указываем по чему именно производим сортировку
    'orderby' => $_GET['orderby'], //title, ID, author, name, date, meta_value
//В этом параметре передаем идентификатор термина таксономии prodcat, в котором ищем
//записи. Ограничиваем область поиска в пределах одного пользовательского термина
    'tax_query' => array
        array
            'taxonomy' => 'prodcat'
            'field' => 'id'
            'terms' => array($_GET['prodcat']) 
        
    ),
//Здесь передаем минимальную и максимальную цены в диапазоне которых производим поиск.
//т.е. осуществляем поиск в пределах значений определенного произвольного поля.
//В нашем случае 'price-products'
    'meta_query' => array
        array
            'key' => 'price-products'
            'value' => array( $_GET['min-price'], $_GET['max-price'] ),
            'type' => 'numeric',
            'compare' => 'BETWEEN'
        )
    
);

Остановлюсь более подробно на указании значений произвольного поля в этом массиве. В нашем случае, мы указали диапазон значений цены «от и до», поэтому значение параметра compare мы установили, согласно документации к функции, как BETWEEN, что означает, что выборку будем делать в диапазоне значений. Но поиск по произвольным полям может быть очень разнообразным и в зависимости от нужного нам результата будет менять и порядок формирования этих значений в массиве функции query_posts.

Например, для поиска записей только по определенному значению произвольных полей или ключу произвольного поля, достаточно будет указать в массиве:

1
2
3
4
5
6
7
//Ищем по ключу произвольного поля
'meta_key'=>'color'
//или только по значению
'meta_value'=>'green'
//Если ищем и по значению и по ключу, то выглядит так
'meta_key'=>'color',
'meta_value'=>'green'

А для поиска уже нескольким произвольным полям придется использовать параметр meta_query, который мы использовали в нашем примере

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'meta_query' => array(
//здесь мы указали что производим поиск по произвольным полям
//с ключом color, значения которых не равны blue
        array
            'key' => 'color'
            'value' => 'blue'
            'compare' => 'NOT LIKE'
        ),
//тут мы указали диапазон значений произвольного поля price,
//в котором производим поиск
//type - параметр уточняющий тип передаваемых данных
        array
            'key' => 'price'
            'value' => array( 20, 100 ), 
            'type' => 'numeric'
            'compare' => 'BETWEEN'
        
    )

Следует отметить, что параметр compare — определяет сравнение и может быть: =, !=, >, >=, <, <=, LIKE, NOT LIKE, IN, NOT IN, BETWEEN, NOT BETWEEN. По умолчанию =;

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

Разместив код сформированного массива в наш файл page-customsearch.php, мы получаем примерно такой конечный код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
/*Выше распологается какой то код*/
/*********************************/
    $args = array
        'post_type' => 'products',
        's' => $_GET['word'],
        'meta_key' => $_GET['meta_key'],
        'posts_per_page' => $_GET['num'],
        'paged' => get_query_var( 'paged' ),
        'order' => $_GET['order'],
        'orderby' => $_GET['orderby'],
        'tax_query' => array
            array
                'taxonomy' => 'prodcat'
                'field' => 'id'
                'terms' => array($_GET['prodcat']) 
            
        ),
        'meta_query' => array
            array
                'key' => 'price-products'
                'value' => array( (int)$_GET['min-price'], (int)$_GET['max-price'] ),
                'type' => 'numeric',
                'compare' => 'BETWEEN'
            )
        
    );
    query_posts( $args ); ?>
    <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
/*********************************/
/*Ниже распологается какой то код*/

Получилось очень коротко и понятнее, чем если бы вам кто то писал функцию обработчик данных с вашей формы не используя возможности функции query_posts.

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

Нам осталось лишь облагородить нашу форму с помощью CSS и разместить ее в любом месте нашего шаблона.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#customsearch{
    width:250px;
    margin:15px auto;
    border:1px solid #ccc;
    border-radius:10px;
    padding:10px