ADD поиск с саджестом

This commit is contained in:
Krivchikov Dmitry 2014-10-27 21:54:27 +03:00
parent afe5bcbe1e
commit 2793f74286
7 changed files with 141 additions and 26 deletions

View File

@ -26,6 +26,7 @@ class IndexController extends Controller
self::addScript('/js/route.js?ver=' . App::getConfig('version')); self::addScript('/js/route.js?ver=' . App::getConfig('version'));
self::addScript('/js/leaflet.markercluster.js'); self::addScript('/js/leaflet.markercluster.js');
self::addScript('/js/fotorama.js'); self::addScript('/js/fotorama.js');
self::addScript('/js/suggest.js');
self::addStyle('/css/style.css?ver=' . App::getConfig('version')); self::addStyle('/css/style.css?ver=' . App::getConfig('version'));
self::addStyle('http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css'); self::addStyle('http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css');

View File

@ -3,13 +3,13 @@
class JsonController extends Controller class JsonController extends Controller
{ {
/** /**
* Точки * Точки
*/ */
static function actionPoints() static function actionPoints()
{ {
$points = Point::model()->getAll(); $points = Point::model()->getAll();
$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true)); $categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));
$result = array(); $result = array();
@ -62,12 +62,12 @@ class JsonController extends Controller
$point->images = $tmp; $point->images = $tmp;
} }
$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true)); $categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));
$point->categoryIcon = $categories[$point->categoryId]['icon']; $point->categoryIcon = $categories[$point->categoryId]['icon'];
$point->categoryName = $categories[$point->categoryId]['name']; $point->categoryName = $categories[$point->categoryId]['name'];
$point->photosCount = $photosCount; $point->photosCount = $photosCount;
$point->inFavorites = Favorite::model()->checkIsMy($id); $point->inFavorites = Favorite::model()->checkIsMy($id);
self::renderPartial('json.php', $point->getValues()); self::renderPartial('json.php', $point->getValues());
} else } else
@ -76,11 +76,11 @@ class JsonController extends Controller
} }
} }
/** /**
* Категории * Категории
*/ */
static function actionCategories() static function actionCategories()
{ {
$categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true)); $categories = Category::model()->getAll(array('order' => 'ord ASC', 'asArray' => true));
self::renderPartial('json.php', array( self::renderPartial('json.php', array(
@ -106,7 +106,7 @@ class JsonController extends Controller
$id = (int) $_POST['id']; $id = (int) $_POST['id'];
$point = $point->getByPK($id); $point = $point->getByPK($id);
if ($point->author != App::$user->id || ($point->date+1800 < time() )) if ($point->author != App::$user->id || ($point->date + 1800 < time() ))
{ {
$errors[9] = 'Редактирование точек достурно только администратору!'; $errors[9] = 'Редактирование точек достурно только администратору!';
} }
@ -318,15 +318,68 @@ class JsonController extends Controller
self::renderPartial('json.php', $coords); self::renderPartial('json.php', $coords);
} }
static function actionAddRemoveFavorites() static function actionAddRemoveFavorites()
{ {
$id = (int) App::getParam('id'); $id = (int) App::getParam('id');
if (!$id || !App::$user) if (!$id || !App::$user)
{ {
App::error404(); App::error404();
} }
self::renderPartial('json.php', Helper::boolval(Favorite::addRemove($id)));
}
self::renderPartial('json.php', Helper::boolval(Favorite::addRemove($id))); static function actionSearch()
} {
$search = isset($_GET['query']) ? $_GET['query'] : '';
$results = array();
if ($search)
{
// ====== POINTS ============
$points = Point::model()->searchByString($search);
if (!empty($points))
{
foreach ($points as $point)
{
$results[] = array('value' => $point->name, 'data' => '/?point='.$point->id);
}
}
if (count($results) < 10)
{
// ====== YANDEX ============
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://geocode-maps.yandex.ru/1.x/?geocode=' . urlencode($search));
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$out = null;
$out = curl_exec($ch); // выполняем запрос curl - обращаемся к сервера php.su
if (!empty($out))
{
$obj = simplexml_load_string($out);
if (isset($obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found))
{
$count = (int) $obj->GeoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found;
if ($count > 0)
{
for ($index = 0; $index < $count && $index < 5 && count($results) < 25; $index++)
{
$name = (string) $obj->GeoObjectCollection->featureMember[$index]->GeoObject->name;
$coords = explode(' ', (string) $obj->GeoObjectCollection->featureMember[$index]->GeoObject->Point->pos);
$lat = $coords[1];
$lng = $coords[0];
$results[] = array('value' => $name, 'data' => "/?lat=$lat&lng=$lng&zoom=13");
}
}
}
}
curl_close($ch);
}
}
self::renderPartial('json.php', array('query' => $search, 'suggestions' => $results));
}
} }

View File

@ -83,5 +83,10 @@ class Point extends Model
$res = App::DB()->query('SELECT count(`id`) AS `cnt` FROM ' . $this->_tableName_ . ' WHERE `author` = ' . $userId . ' ;')->fetch(PDO::FETCH_ASSOC); $res = App::DB()->query('SELECT count(`id`) AS `cnt` FROM ' . $this->_tableName_ . ' WHERE `author` = ' . $userId . ' ;')->fetch(PDO::FETCH_ASSOC);
return $res['cnt']; return $res['cnt'];
} }
public function searchByString($search)
{
return $this->getAll(array('where' => "`name` LIKE '%$search%' OR `description` LIKE '%$search%'", 'limit' => 20));
}
} }

View File

@ -44,7 +44,7 @@
<div id="boxFilter" style="height: 100%; overflow-y: auto;"> <div id="boxFilter" style="height: 100%; overflow-y: auto;">
<h3>Фильтры и поиск</h3> <h3>Фильтры и поиск</h3>
<span class="input-group"> <span class="input-group">
<input type="text" id="addressField" class="form-control" placeholder="Поиск на карте..." onkeydown="if(event.keyCode == 13) {searchAdderess()}" /> <input type="text" id="addressField" class="form-control" placeholder="Поиск на карте..." />
<span class="input-group-btn"> <span class="input-group-btn">
<button class="btn btn-default" type="button" onclick="searchAdderess()"><span class="glyphicon glyphicon-search"></span></button> <button class="btn btn-default" type="button" onclick="searchAdderess()"><span class="glyphicon glyphicon-search"></span></button>
</span> </span>

View File

@ -73,3 +73,6 @@ div#box {background-image: url('/img/back.png'); background-repeat: no-repeat; b
/*Leaflet FIX*/ /*Leaflet FIX*/
.leaflet-popup-content-wrapper .leaflet-popup-scrolled {border-bottom: none;border-top: none;} .leaflet-popup-content-wrapper .leaflet-popup-scrolled {border-bottom: none;border-top: none;}
#suggestContainer {position: absolute;top: 40px;background-color: #fff;padding-bottom: 8px; border-bottom: 1px solid #333; width: 219px; display: none;max-height: 345px;overflow-y: scroll;}
#suggestContainer > div:hover {background-color: #eee;}

View File

@ -33,7 +33,8 @@ ymaps.ready(function () {
points.im = L.marker([lat, lng], {icon: categories.im, title: 'Вы здесь'}); points.im = L.marker([lat, lng], {icon: categories.im, title: 'Вы здесь'});
points.im.addTo(myMap); points.im.addTo(myMap);
points.im.bindPopup('<b>Ваше местоположение</b><br/><img src="/ico/man.png" /> <button type="button" class="btn btn-default btn-xs" onclick="addToRoute(\'im\')"><span class="glyphicon glyphicon-plus"></span> Добавить в маршрут</button>') points.im.bindPopup('<b>Ваше местоположение</b><br/><img src="/ico/man.png" /> <button type="button" class="btn btn-default btn-xs" onclick="addToRoute(\'im\')"><span class="glyphicon glyphicon-plus"></span> Добавить в маршрут</button>');
suggestInit('#addressField');
}); });
/** /**

52
public/js/suggest.js Normal file
View File

@ -0,0 +1,52 @@
var suggestSelector = '';
function suggestInit(selector)
{
suggestSelector = selector;
$(selector).after('<div id="suggestContainer"></div>');
$(selector).bind('input', function () {
var query = $(selector).val();
$('#suggestContainer').html('');
$.ajax({
url: "/json/search?query=" + query,
context: document.body
}).done(function (data) {
res = data.suggestions;
newHtml = '';
$('#suggestContainer').html('').show();
for (var i = 0; i < res.length; i++) {
newHtml += '<div><a href="' + res[i].data + '">' + res[i].value + '</a></div>';
}
$('#suggestContainer').html(newHtml);
}).fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
}).bind('keydown', function (event) {
suggestKeyPress(event.which);
}).bind('focus', function(){if($(selector).val())$('#suggestContainer').show();});
$(selector).parent().bind('blur', function(){$('#suggestContainer').hide();});
$('#suggestContainer').hide();
}
function suggestKeyPress(key)
{
console.log(key);
switch (key) {
case 27:
//ESCAPE
$('#suggestContainer').hide();
break
case 13:
//ENTER
break
case 38:
//UP
break
case 40:
//DOWN
break
default :
$('#suggestContainer').show();
}
}