I am creating the search functionality in my laravel 5 ecommerce web application.
I want the user to move the cursor with the arrow keys on the search results, but I am failing to achieve this.
Here's the controller:
public function searchProduct(Request $request)
{
$productName = $request->input('name');
if($productName !== '')
{
$products = Product::where('name', 'LIKE', '%' . $productName . '%')->where('display', 'Enabled')->get();
return view('partials.search', compact('products'));
}
return false;
}
The search results:
#foreach($products as $product)
<li>
<a href="{{ url('/store/'.$product->code .'/'.Safeurl::make($product->name)) }}" class="link_scheme_color_main">
{{ $product->name }}
</a>
</li>
#endforeach
And the AJAX:
$('.searchProduct').keydown(function(e) {
var name = $(this).val();
var inputData = $('.formSearchProduct').serialize();
var prodList = $('.showProds');
var countList = prodList.find('ul li').length;
var prd = prodList.find('ul li');
if(name.length === 0) {
prodList.hide();
} else {
$.ajax({
url: '{{ url('/store/product/search') }}',
type: "POST",
data: inputData
})
.done(function(m) {
if (m) {
prodList.show();
prodList.find('ul.searchedProducts').html(m);
prodList.find('ul li').first().addClass('activeProduct');
} else {
prodList.hide();
}
});
}
});
The css:
.activeProduct {background: #ccc !important;}
I have made this application live. You can check it here. The application is still in the development stage and not in production.
What I want to achieve is:
When the user searches for the product, he/she can use the up and down arrow keys to navigate the search results, and on click of any of the results, he/she should go to the product page.
When the user searches and removes the search keyword(s), all the products are shown, I don't want that.
UPDATE 1:
I have added this code and it seems there is a bug, where I don't know. The bug is that I can only move to the second list item when pressing the down arrow key and at the very next second, it moves back to the first list item.
$('.searchProduct').keydown(function(e) {
var prodList = $('.showProds');
var countList = prodList.find('ul li').length;
var prd = prodList.find('ul li');
var active = prodList.find('ul li.activeProduct');
console.log(e.keyCode);
if (e.which === 40) {
var next = active.removeClass('activeProduct').next('li');
next = next.length > 0 ? next : $('li:eq(0)');
next.addClass('activeProduct');
}
});
UPDATE 2:
I have got it working to a certain extent. I have removed the code of update 1 and added the below code to done() method.
if (m) {
prodList.show();
prodList.find('ul.searchedProducts').html(m);
prodList.find('ul li').first().addClass('activeProduct');
if(e.keyCode == 40) {
prodList.find('ul li').prev().removeClass('activeProduct');
prodList.find('ul li').next().first().addClass('activeProduct').focus();
}
} else {
prodList.hide();
}
But this moves only to the second list item on every time the down arrow key is pressed. You can have a look at the link that I provided above.
Kindly help me out with this. Thanks.
Related
How to count how many clicks have made on the link tag:
this is my code:
#foreach($news as $key => $value)
<li>
<a href="" id="news_link" class="news_link">
<h3 class="title">{{$value->title}}</h3>
</a>
</li>
#endforeach
can anyone suggest what is the correct way to do this.?
$(document).ready(function() {
var count = 0;
$('.news_link').click(function() {
count++;
});
alert(count);
});
counter is not getting incremented on alert
The best way to track this for analytics is to use Google Tag Manager to keep track of internal and external links.
If it is just for a function you could make use of Javascript and store it in a cookie, or if you want to store it like forever; in a database.
if(document.cookie.indexOf("clicks=") >= 0) {
var clicks = getCookie('clicks');
} else {
var clicks = 0;
}
$('#news_link').click(function() {
clicks++;
document.cookie = "clicks="+clicks;
});
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
Or use Ajax to store it in lets say your database:
$(function () {
$('#news_link').on('click', function () {
clicks++;
$.ajax({
url: 'Ajax/StatusUpdate.php',
data: {
count: clicks,
},
dataType : 'json'
});
});
});
I have a function that on click add/removes stuff from a SQL database.
I do a condition to check if it is refering to an add or remove and execute the code.
the add function works perfectly, but the remove not and its the same code, am i missing something obvious? And is this the best way to do this?
jquery:
//add card from list
$("#listcards a").click(function() {
if($(this).attr('add').length > 1) {
var value = $(this).attr('add');
$.post('searchc.php',{add:value}, function(data){
$("#add_result").html(data);
});
return false;
}
});
//remove card from list
$("#listcards a").click(function() {
if($(this).attr('rem').length > 1) {
var value = $(this).attr('rem');
$.post('searchc.php',{rem:value}, function(data){
$("#add_result").html(data);
});
return false;
}
});
html code:
<form id="listcards" method="post">
<input type='hidden' id='lcard' name='lcard' value=''>
<div>
bla bla -> imagem no + ? ou por algum efeito css+ | -<br>
coiso coiso + | -<br>
</div>
</form>
Do i also need to be in a form for the POST or a div would work too?
You've got two click handlers for the same elements, which could be causing a problem. You don't need to run both sets of code for each <a> element. Instead give the elements a class to show exactly what they do, and then limit your selectors to those elements
HTML:
+ | <a href="" class="remove" rem="bla bla">
Script:
$("#listcards a.add").click(function() {
var value = $(this).attr('add');
$.post('searchc.php',{add:value}, function(data){
$("#add_result").html(data);
});
return false;
});
//remove card from list
$("#listcards a.remove").click(function() {
var value = $(this).attr('rem');
$.post('searchc.php',{rem:value}, function(data){
$("#add_result").html(data);
});
return false;
});
You can use it like thisi will give only remove functionality. And oif possible add ajax.
$("#listcards .rem").click(function() {
var value = $(this).text();
if($(this).length()>1) {
$.post('searchc.php',{rem:value}, function(data){
$("#add_result").html(data);
});
return false;
}});
Suppose you don't have any card when you're loading this page 1st time. Then you click add new & a new card get's added to your html.
Now for this newly added card, the "remove" method doesn't get bind as that was loaded on page load (when this new card element was not present). Hence your remove method is not working for newly added cards.
So to make it work, you need to bing the remove method on new cards too. You can do that by keeping you remove part in a js function which you would call in "add" part after putting new card into html.
function removeCard(){
// first unbind the click event for all cards if any & then bind it
$("#listcards a").off('click');
//remove card from list
$("#listcards a").click(function() {
if($(this).attr('rem').length > 1) {
var value = $(this).attr('rem');
$.post('searchc.php',{rem:value}, function(data){
$("#add_result").html(data);
});
return false;
}
});
}
And you add part should be like this:
//add card from list
$("#listcards a").click(function() {
if($(this).attr('add').length > 1) {
var value = $(this).attr('add');
$.post('searchc.php',{add:value}, function(data){
$("#add_result").html(data);
removeCard(); // adding remove method here
});
return false;
}
});
Follow up your code,
$("#listcards a").click(function() {
var action = $(this).attr("add") ? "add" : "rem";
var value;
if(action == "add")
value = $(this).attr('add');
if(action == "rem")
value = $(this).attr('rem');
var param = {};
param[action] = value;
$.post('searchc.php',param, function(data){
$("#add_result").html(data);
});
});
Use onclick function to do this
It can help you out
+
-<br>
function addthis(addthis) {
if(addthis.length > 1) {
alert(addthis);
// $.post('searchc.php',{add:addthis}, function(data){
// $("#add_result").html(data);
// });
return false;
}
}
function removethis(remthis) {
if(remthis.length > 1) {
alert(remthis);
// $.post('searchc.php',{reb:remthis}, function(data){
// $("#add_result").html(data);
// });
return false;
}
}
I am learning AngularJS on Laravel, and I am making a simple app. So far the app displays rows from the DB in either a completed area, or a not completed area. If a user clicks the item, it moves to the opposite area.
$scope.move = function(item) {
item.has_item = !item.has_item;
};
The above moves the item on click, however for persistence I add:
$scope.move = function(item) {
var newState = !item.completed;
$http.post('/items', item).success(function() {
item.completed = newState;
});
};
Now, I just need a route to accept this post and insert the updated value of completed to the DB.
I've tried:
Route::post('items', function()
{
$completed = Input::get('completed');
return $completed->push();
});
However, I have had no luck. What do I need to do to insert the value into the DB?
$scope.move = function(item) {
item.has_skill = !item.has_skill;
$http.post('/items', item).success(function(data) {
item = data;
});
};
//in controller
$http.get('/items').success(function(data) {
$scope.items = data;
});
<ul>
<li ng-repeat="item in items" ng-click="move(item)">{{item.skill_name}}</li>
</ul>
Route::post('items', function() {
$id = Input::get('id');
$item = Skill::find($id);
$item->has_skill = Input::get('has_skill');
$item->save();
return Response::json($item);
});
Route::get('items', function() {
return Response::json(Skill::all());
});
http://jsbin.com/bavawiko/1/edit
i am trying to build a small single page wordpress theme, but struggling to find a way to make the navigation menu work.
The pages are loaded with this function: http://pastebin.com/Di5MhS8y . Each page is displayed as a section of my homepage, based on its menu_order.
If i make a custom menu voice linking outsite my website (tried with www.google.com) the menu works just fine.
Problems arise when i try to link to a single section of my website. The whole page gets reloaded and i'm brought back at the top of it.
I reckon i should maybe give a specific id to each section, and link to it, but i'm not sure. Any suggestion would be super appreciated!
The best way would be to give each section an ID.
if you want clean URLS you can create a function with Jquery
here's one i used in a one page website
var locationPath = filterPath(location.pathname);
var scrollElem = scrollableElement('html', 'body', 'document', 'window');
//console.log(scrollElem);
$('a[href*=#]').each(function() {
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath
&& (location.hostname == this.hostname || !this.hostname)
&& this.hash.replace(/#/,'') ) {
var $target = $(this.hash), target = this.hash;
if (target) {
//console.log('Target: ' + target + ' offset: ' + targetOffset);
$(this).click(function(event) {
var targetOffset = $target.offset().top;
event.preventDefault();
$(scrollElem).animate({scrollTop: targetOffset}, 1000, function() {
//console.log($(scrollElem).scrollTop());
location.hash = target;
$(scrollElem).animate({scrollTop: targetOffset}, 0);
});
});
}
}
});
// use the first element that is "scrollable"
function scrollableElement(els) {
for (var i = 0, argLength = arguments.length; i <argLength; i++) {
var el = arguments[i],
$scrollElement = $(el);
if ($scrollElement.scrollTop()> 0) {
return el;
} else {
$scrollElement.scrollTop(1);
var isScrollable = $scrollElement.scrollTop()> 0;
//console.log(el + ': ' + $scrollElement.scrollTop());
$scrollElement.scrollTop(0);
if (isScrollable) {
return el;
}
}
}
return 'body';
}
I'm receiving the following error on this line of code
select.up().appendChild(sw);
With error "SCRIPT438: Object doesn't support property or method 'up' "
This only happens in Internet Explorer... Chrome, Safari, and Firefox all run the code fine. I'm unable to find anything via Google searching for "select.up()". This code isn't my own and I'm not very adept with using DOM in Javascript.
Here is rest of the code:
<?php
$swatches = $this->get_option_swatches();
?>
<script type="text/javascript">
document.observe('dom:loaded', function() {
try {
var swatches = <?php echo Mage::helper('core')->jsonEncode($swatches); ?>;
function find_swatch(key, value) {
for (var i in swatches) {
if (swatches[i].key == key && swatches[i].value == value)
return swatches[i];
}
return null;
}
function has_swatch_key(key) {
for (var i in swatches) {
if (swatches[i].key == key)
return true;
}
return false;
}
function create_swatches(label, select) {
// create swatches div, and append below the <select>
var sw = new Element('div', {'class': 'swatches-container'});
select.up().appendChild(sw);
// store these element to use later for recreate swatches
select.swatchLabel = label;
select.swatchElement = sw;
// hide select
select.setStyle({position: 'absolute', top: '-9999px'})
$A(select.options).each(function(opt, i) {
if (opt.getAttribute('value')) {
var elm;
var key = trim(opt.innerHTML);
// remove price
if (opt.getAttribute('price')) key = trim(key.replace(/\+([^+]+)$/, ''));
var item = find_swatch(label, key);
if (item)
elm = new Element('img', {
src: '<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA); ?>swatches/'+item.img,
alt: opt.innerHTML,
title: opt.innerHTML,
'class': 'swatch-img'});
else {
console.debug(label, key, swatches);
elm = new Element('a', {'class': 'swatch-span'});
elm.update(opt.innerHTML);
}
elm.observe('click', function(event) {
select.selectedIndex = i;
fireEvent(select, 'change');
var cur = sw.down('.current');
if (cur) cur.removeClassName('current');
elm.addClassName('current');
});
sw.appendChild(elm);
}
});
}
function recreate_swatches_recursive(select) {
// remove the old swatches
if (select.swatchElement) {
select.up().removeChild(select.swatchElement);
select.swatchElement = null;
}
// create again
if (!select.disabled)
create_swatches(select.swatchLabel, select);
// recursively recreate swatches for the next select
if (select.nextSetting)
recreate_swatches_recursive(select.nextSetting);
}
function fireEvent(element,event){
if (document.createEventObject){
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
else{
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
}
}
function trim(str) {
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
$$('#product-options-wrapper dt').each(function(dt) {
// get custom option's label
var label = '';
$A(dt.down('label').childNodes).each(function(node) {
if (node.nodeType == 3) label += node.nodeValue;
});
label = trim(label);
var dd = dt.next();
var select = dd.down('select');
if (select && has_swatch_key(label)) {
create_swatches(label, select);
// if configurable products, recreate swatches of the next select when the current select change
if (select.hasClassName('super-attribute-select')) {
select.observe('change', function() {
recreate_swatches_recursive(select.nextSetting);
});
}
}
});
}
catch(e) {
alert("Color Swatches javascript error. Please report this error to support#ikova.com. Error:" + e.message);
}
});
</script>
Appreciate any insight anyone could give me!
I'm pretty sure up() is a PrototypeJS method, so i'm pretty sure you would need it to work.
http://prototypejs.org/api/element/up
I m also facing this problem. so, i comment
var sw = new Element('div', {'class': 'swatches-container'});
$(select).up().appendChild(sw);
select.setStyle({position: 'absolute', top: '-9999px'})
lines from function create_swatches
and paste it in function trim(str).
After this i did not error again.