Search bar with jquery dropdown showing results - php
When the user types something into the search bar I would like the results bellow to link to a page when you click it instead of filling the search bar with whatever you clicked. I'm very new to Jquery and I found this tutorial online but it isn't doing exactly what I wanted it to.
Index.php (Just showing some of the head and the body)
<script>
$(document).ready(function(){
$("#tag").autocomplete("autocomplete.php", {
selectFirst: true
});
});
</script>
</head>
<body>
<label>Tag:</label>
<input name="tag" type="text" id="tag" size="20" style="width:541px; height:23px; font-size:16px; text-indent:5px;" placeholder="Search foods, shopping lists, meal plans and recipes" />
</body>
autocomplete.php (Even with the and tags I was unable to achieve the linking to another page.)
<?php
$q=$_GET['q'];
$my_data=mysql_real_escape_string($q);
include ("connect.php");
$sql="SELECT id, name, description, foodgroup FROM foods WHERE name LIKE '%$my_data%' ORDER BY name";
$result = mysql_query($sql);
if($result) {
while($row=mysql_fetch_array($result)) {
print "<a href='food.php?foodGroup=" . $row['foodgroup'] . "&name=" . $row['name'] . "&desc=" . $row['description'] . "&foodID=" . $row['id'] . "'><div id='resultContainerDiv'><span id='resultText'>" . $row['name'] . " - " . $row['description'] . "</span></div></a>\n";
}
}
?>
lastly, jquery.autocomplete.js
/* * jQuery Autocomplete plugin 1.1 * * Copyright (c) 2009 Jörn Zaefferer * * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $ */
;(function($) { $.fn.extend({ autocomplete: function(urlOrData, options) { var isUrl = typeof urlOrData == "string"; options = $.extend({}, $.Autocompleter.defaults, { url: isUrl ? urlOrData : null, data: isUrl ? null : urlOrData, delay: isUrl ? $.Autocompleter.defaults.delay : 10, max: options && !options.scroll ? 10 : 150 }, options);
// if highlight is set to false, replace it with a do-nothing function options.highlight = options.highlight || function(value) { return value; };
// if the formatMatch option is not specified, then use formatItem for backwards compatibility options.formatMatch = options.formatMatch || options.formatItem;
return this.each(function() { new $.Autocompleter(this, options); }); }, result: function(handler) { return this.bind("result", handler); }, search: function(handler) { return this.trigger("search", [handler]); }, flushCache: function() { return this.trigger("flushCache"); }, setOptions: function(options){ return this.trigger("setOptions", [options]); }, unautocomplete: function() { return this.trigger("unautocomplete"); } });
$.Autocompleter = function(input, options) {
var KEY = { UP: 38, DOWN: 40, DEL: 46, TAB: 9, RETURN: 13, ESC: 27, COMMA: 188, PAGEUP: 33, PAGEDOWN: 34, BACKSPACE: 8 };
// Create $ object for input element var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
var timeout; var previousValue = ""; var cache = $.Autocompleter.Cache(options); var hasFocus = 0; var lastKeyPressCode; var config = { mouseDownOnSelect: false }; var select = $.Autocompleter.Select(options, input, selectCurrent, config); var blockSubmit; // prevent form submit in opera when selecting with return key $.browser.opera && $(input.form).bind("submit.autocomplete", function() { if (blockSubmit) { blockSubmit = false; return false; } }); // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) { // a keypress means the input has focus // avoids issue where input had focus before the autocomplete was applied hasFocus = 1; // track last key pressed lastKeyPressCode = event.keyCode; switch(event.keyCode) {
case KEY.UP:
event.preventDefault();
if ( select.visible() ) {
select.prev();
} else {
onChange(0, true);
}
break;
case KEY.DOWN:
event.preventDefault();
if ( select.visible() ) {
select.next();
} else {
onChange(0, true);
}
break;
case KEY.PAGEUP:
event.preventDefault();
if ( select.visible() ) {
select.pageUp();
} else {
onChange(0, true);
}
break;
case KEY.PAGEDOWN:
event.preventDefault();
if ( select.visible() ) {
select.pageDown();
} else {
onChange(0, true);
}
break;
// matches also semicolon case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA: case KEY.TAB: case KEY.RETURN:
if( selectCurrent() ) {
// stop default to prevent a form submit, Opera needs special handling
event.preventDefault();
blockSubmit = true;
return false;
}
break;
case KEY.ESC:
select.hide();
break;
default:
clearTimeout(timeout);
timeout = setTimeout(onChange, options.delay);
break; } }).focus(function(){ // track whether the field has focus, we shouldn't process any // results if the field no longer has focus hasFocus++; }).blur(function() { hasFocus = 0; if (!config.mouseDownOnSelect) { hideResults(); } }).click(function() { // show select when clicking in a focused field if ( hasFocus++ > 1 && !select.visible() ) { onChange(0, true); } }).bind("search", function() { // TODO why not just specifying both arguments? var fn = (arguments.length > 1) ? arguments[1] : null; function findValueCallback(q, data) { var result; if( data && data.length ) {
for (var i=0; i < data.length; i++) {
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
result = data[i];
break;
}
} } if( typeof fn == "function" ) fn(result); else $input.trigger("result", result && [result.data, result.value]); } $.each(trimWords($input.val()), function(i, value) { request(value, findValueCallback, findValueCallback); }); }).bind("flushCache", function() { cache.flush(); }).bind("setOptions", function() { $.extend(options, arguments[1]); // if we've updated the data, repopulate if ( "data" in arguments[1] ) cache.populate(); }).bind("unautocomplete", function() { select.unbind(); $input.unbind(); $(input.form).unbind(".autocomplete"); });
function selectCurrent() { var selected = select.selected(); if( !selected ) return false;
var v = selected.result; previousValue = v;
if ( options.multiple ) { var words = trimWords($input.val()); if ( words.length > 1 ) {
var seperator = options.multipleSeparator.length;
var cursorAt = $(input).selection().start;
var wordAt, progress = 0;
$.each(words, function(i, word) {
progress += word.length;
if (cursorAt <= progress) {
wordAt = i;
return false;
}
progress += seperator;
});
words[wordAt] = v;
// TODO this should set the cursor to the right position, but it gets overriden somewhere
//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
v = words.join( options.multipleSeparator ); } v += options.multipleSeparator; }
$input.val(v); hideResultsNow(); $input.trigger("result", [selected.data, selected.value]); return true; } function onChange(crap, skipPrevCheck) { if( lastKeyPressCode == KEY.DEL ) { select.hide(); return; }
var currentValue = $input.val();
if ( !skipPrevCheck && currentValue == previousValue ) return;
previousValue = currentValue;
currentValue = lastWord(currentValue); if ( currentValue.length >= options.minChars) { $input.addClass(options.loadingClass); if (!options.matchCase)
currentValue = currentValue.toLowerCase(); request(currentValue, receiveData, hideResultsNow); } else { stopLoading(); select.hide(); } }; function trimWords(value) { if (!value) return [""]; if (!options.multiple) return [$.trim(value)]; return $.map(value.split(options.multipleSeparator), function(word) { return $.trim(value).length ? $.trim(word) : null; }); } function lastWord(value) { if ( !options.multiple ) return value; var words = trimWords(value); if (words.length == 1) return words[0]; var cursorAt = $(input).selection().start; if (cursorAt == value.length) { words = trimWords(value) } else { words = trimWords(value.replace(value.substring(cursorAt), "")); } return words[words.length - 1]; } // fills in the input box w/the first match (assumed to be the best match) // q: the term entered // sValue: the first matching result function autoFill(q, sValue){ // autofill in the complete box w/the first match as long as the user hasn't entered in more data // if the last user key pressed was backspace, don't autofill if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) { // fill in the value (keep the case the user has typed) $input.val($input.val() + sValue.substring(lastWord(previousValue).length)); // select the portion of the value not typed by the user (so the next character will erase) $(input).selection(previousValue.length, previousValue.length + sValue.length); } };
function hideResults() { clearTimeout(timeout); timeout = setTimeout(hideResultsNow, 200); };
function hideResultsNow() { var wasVisible = select.visible(); select.hide(); clearTimeout(timeout); stopLoading(); if (options.mustMatch) { // call search and run callback $input.search(
function (result){
// if no value found, clear the input box
if( !result ) {
if (options.multiple) {
var words = trimWords($input.val()).slice(0, -1);
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
}
else {
$input.val( "" );
$input.trigger("result", null);
}
}
} ); } };
function receiveData(q, data) { if ( data && data.length && hasFocus ) { stopLoading(); select.display(data, q); autoFill(q, data[0].value); select.show(); } else { hideResultsNow(); } };
function request(term, success, failure) { if (!options.matchCase) term = term.toLowerCase(); var data = cache.load(term); // recieve the cached data if (data && data.length) { success(term, data); // if an AJAX url has been supplied, try loading the data now } else if( (typeof options.url == "string") && (options.url.length > 0) ){
var extraParams = {
timestamp: +new Date() }; $.each(options.extraParams, function(key, param) {
extraParams[key] = typeof param == "function" ? param() : param; });
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,
url: options.url,
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams),
success: function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed);
success(term, parsed);
} }); } else { // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match select.emptyList(); failure(term); } }; function parse(data) { var parsed = []; var rows = data.split("\n"); for (var i=0; i < rows.length; i++) { var row = $.trim(rows[i]); if (row) {
row = row.split("|");
parsed[parsed.length] = {
data: row,
value: row[0],
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
}; } } return parsed; };
function stopLoading() { $input.removeClass(options.loadingClass); };
};
$.Autocompleter.defaults = { inputClass: "ac_input", resultsClass: "ac_results", loadingClass: "ac_loading", minChars: 1, delay: 400, matchCase: false, matchSubset: true, matchContains: false, cacheLength: 10, max: 100, mustMatch: false, extraParams: {}, selectFirst: true, formatItem: function(row) { return row[0]; }, formatMatch: null, autoFill: false, width: 0, multiple: false, multipleSeparator: ", ", highlight: function(value, term) { return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"); },
scroll: true,
scrollHeight: 180 };
$.Autocompleter.Cache = function(options) {
var data = {}; var length = 0; function matchSubset(s, sub) { if (!options.matchCase) s = s.toLowerCase(); var i = s.indexOf(sub); if (options.matchContains == "word"){ i = s.toLowerCase().search("\\b" + sub.toLowerCase()); } if (i == -1) return false; return i == 0 || options.matchContains; }; function add(q, value) { if (length > options.cacheLength){ flush(); } if (!data[q]){ length++; } data[q] = value; } function populate(){ if( !options.data ) return false; // track the matches var stMatchSets = {}, nullData = 0;
// no url was specified, we need to adjust the cache length to make sure it fits the local data store if( !options.url ) options.cacheLength = 1;
// track all options for minChars = 0 stMatchSets[""] = [];
// loop through the array and create a lookup structure for ( var i = 0, ol = options.data.length; i < ol; i++ ) { var rawValue = options.data[i]; // if rawValue is a string, make an array otherwise just reference the array rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
var value = options.formatMatch(rawValue, i+1, options.data.length); if ( value === false )
continue;
var firstChar = value.charAt(0).toLowerCase(); // if no lookup array for this character exists, look it up now if( !stMatchSets[firstChar] )
stMatchSets[firstChar] = [];
// if the match is a string var row = {
value: value,
data: rawValue,
result: options.formatResult && options.formatResult(rawValue) || value };
// push the current match into the set list stMatchSets[firstChar].push(row);
// keep track of minChars zero items if ( nullData++ < options.max ) {
stMatchSets[""].push(row); } };
// add the data items to the cache $.each(stMatchSets, function(i, value) { // increase the cache size options.cacheLength++; // add to the cache add(i, value); }); } // populate any existing data setTimeout(populate, 25); function flush(){ data = {}; length = 0; } return { flush: flush, add: add, populate: populate, load: function(q) { if (!options.cacheLength || !length)
return null; /*
* if dealing w/local data and matchContains than we must make sure
* to loop through all the data collections looking for matches
*/ if( !options.url && options.matchContains ){
// track all matches
var csub = [];
// loop through all the data grids for matches
for( var k in data ){
// don't search through the stMatchSets[""] (minChars: 0) cache
// this prevents duplicates
if( k.length > 0 ){
var c = data[k];
$.each(c, function(i, x) {
// if we've got a match, add it to the array
if (matchSubset(x.value, q)) {
csub.push(x);
}
});
}
}
return csub; } else // if the exact item exists, use it if (data[q]){
return data[q]; } else if (options.matchSubset) {
for (var i = q.length - 1; i >= options.minChars; i--) {
var c = data[q.substr(0, i)];
if (c) {
var csub = [];
$.each(c, function(i, x) {
if (matchSubset(x.value, q)) {
csub[csub.length] = x;
}
});
return csub;
}
} } return null; } }; };
$.Autocompleter.Select = function (options, input, select, config) { var CLASSES = { ACTIVE: "ac_over" }; var listItems, active =
-1, data, term = "", needsInit = true, element, list; // Create results function init() { if (!needsInit) return; element = $("<div/>") .hide() .addClass(options.resultsClass) .css("position", "absolute") .appendTo(document.body);
list = $("<ul/>").appendTo(element).mouseover( function(event) { if(target(event).nodeName && target(event).nodeName.toUpperCase()
== 'LI') {
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
$(target(event)).addClass(CLASSES.ACTIVE);
} }).click(function(event) { $(target(event)).addClass(CLASSES.ACTIVE); select(); // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus input.focus(); return false; }).mousedown(function() { config.mouseDownOnSelect = true; }).mouseup(function() { config.mouseDownOnSelect = false; });
if( options.width > 0 ) element.css("width", options.width);
needsInit = false; } function target(event) { var element = event.target; while(element && element.tagName != "LI") element = element.parentNode; // more fun with IE, sometimes event.target is empty, just ignore it then if(!element) return []; return element; }
function moveSelect(step) { listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE); movePosition(step);
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
if(options.scroll) {
var offset = 0;
listItems.slice(0, active).each(function() {
offset += this.offsetHeight; });
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
} else if(offset < list.scrollTop()) {
list.scrollTop(offset);
}
} }; function movePosition(step) { active += step; if (active < 0) { active = listItems.size() - 1; } else if (active
>= listItems.size()) { active = 0; } } function limitNumberOfItems(available) { return options.max && options.max < available ? options.max : available; } function fillList() { list.empty(); var max = limitNumberOfItems(data.length); for (var i=0; i < max; i++) { if (!data[i])
continue; var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term); if ( formatted === false )
continue; var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0]; $.data(li, "ac_data", data[i]); } listItems = list.find("li"); if ( options.selectFirst ) { listItems.slice(0, 1).addClass(CLASSES.ACTIVE); active = 0; } // apply bgiframe if available if ( $.fn.bgiframe ) list.bgiframe(); } return { display: function(d, q) { init(); data = d; term = q; fillList(); }, next: function() { moveSelect(1); }, prev: function() { moveSelect(-1); }, pageUp: function() { if (active != 0 && active - 8 < 0) {
moveSelect( -active ); } else {
moveSelect(-8); } }, pageDown: function() { if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
moveSelect( listItems.size() - 1 - active ); } else {
moveSelect(8); } }, hide: function() { element && element.hide(); listItems && listItems.removeClass(CLASSES.ACTIVE); active = -1; }, visible : function() { return element && element.is(":visible"); }, current: function() { return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]); }, show: function() { var offset = $(input).offset(); element.css({
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
top: offset.top + input.offsetHeight,
left: offset.left }).show();
if(options.scroll) {
list.scrollTop(0);
list.css({
maxHeight: options.scrollHeight,
overflow: 'auto'
});
if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
var listHeight = 0;
listItems.each(function() {
listHeight += this.offsetHeight;
});
var scrollbarsVisible = listHeight > options.scrollHeight;
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
if (!scrollbarsVisible) {
// IE doesn't recalculate width when scrollbar disappears
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
}
}
} }, selected: function() { var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE); return selected && selected.length && $.data(selected[0], "ac_data"); }, emptyList: function (){ list && list.empty(); }, unbind: function() { element && element.remove(); } }; };
$.fn.selection = function(start, end) { if (start !== undefined) { return this.each(function() { if( this.createTextRange ){
var selRange = this.createTextRange();
if (end === undefined || start == end) {
selRange.move("character", start);
selRange.select();
} else {
selRange.collapse(true);
selRange.moveStart("character", start);
selRange.moveEnd("character", end);
selRange.select();
} } else if( this.setSelectionRange ){
this.setSelectionRange(start, end); } else if( this.selectionStart ){
this.selectionStart = start;
this.selectionEnd = end; } }); } var field = this[0]; if ( field.createTextRange ) { var range = document.selection.createRange(), orig = field.value, teststring
= "<->", textLength = range.text.length; range.text = teststring; var caretAt = field.value.indexOf(teststring); field.value = orig; this.selection(caretAt, caretAt + textLength); return { start: caretAt, end: caretAt + textLength } } else if( field.selectionStart !== undefined ){ return { start: field.selectionStart, end: field.selectionEnd } } };
})(jQuery);
Thank you,
Ryan
In the search script you have an error:
<?php
$q=$_GET['q'];
$my_data=mysql_real_escape_string($q);
include ("connect.php");
mysql_real_escape_string will return false (the equivalent of an empty string) if there is no database connection yet so you are effectively emptying your search string.
You need to switch that around:
<?php
$q=$_GET['q'];
include ("connect.php");
$my_data=mysql_real_escape_string($q);
You should also add error handling to your database calls and move to PDO or mysqli if possible as the mysql_* functions are deprecated.
Related
Joomla Interesting search module error!(SJ Filter for VirtueMart )
I would like to ask for help with the following topic! We use SJ Filter for VirtueMart on our website! However the price filter uses price without tax. It's not good this way.I think the system uses the "base price" (without tax).I would like the filter use "end user price" with tax.(27.tax).I didn't find anything in the setting. I attached files from filter.I checked the code but I couldn't find anything that I could change. Please someone help ! enter image description here enter image description here <?php /** * #package SJ Filter for VirtueMart * #version 2.0.0 * #license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL * #copyright (c) 2014 YouTech Company. All Rights Reserved. * #author YouTech Company http://www.smartaddons.com */ defined ('_JEXEC') or die; ?> <script type="text/javascript"> //<![CDATA[ jQuery(document).ready(function ($) { ; (function (element) { var $element = $(element), $_ft_form = $('.ft-form', $element), $_group_ft = $('.ft-group', $element), $_filtering = $('.ft-filtering', $element) $_ajax_url = '<?php echo (string)JURI::getInstance(); ?>'; var $_gr_prices = $('.ft-group-prices', $element), $_slide_prices = $(".ft-slider-price", $_gr_prices), _min_price = <?php echo (int)$params->get('price_min',0); ?>, _max_price = <?php echo (int)$params->get('price_max',1300000); ?>; var $timer = 0; $_slide_prices.each(function (index, element) { $(this)[index].slide = null; }); $_slide_prices.slider({ range: true, min: _min_price, max: _max_price, values: [_min_price, _max_price], slide: function (event, ui) { $(".ft-price-min", $_gr_prices).val(ui.values[0]); $(".ft-price-max", $_gr_prices).val(ui.values[1]); if ($timer) { clearTimeout($timer); } $timer = setTimeout( function () { processAjax() }, 1000); } }); $('.ft-price-input', $_gr_prices).on('keyup', function () { var $that = $(this); if ($timer) { clearTimeout($timer); } var _price_tmp = parseInt($that.val()); $timer = setTimeout(function () { if (!isNaN(_price_tmp) && _price_tmp >= 1) { _price_tmp = _price_tmp >= _max_price ? _max_price : _price_tmp; if ($that.hasClass('ft-price-min')) { var _maxp = $(".ft-price-max", $_gr_prices).val(); _maxp = (_maxp != '' ) ? _maxp : _max_price; _price_tmp = _price_tmp >= _maxp ? _maxp : _price_tmp; $that.val(_price_tmp); $_slide_prices.slider("values", 0, _price_tmp); } else { var _minp = $(".ft-price-min", $_gr_prices).val(); _minp = (_minp != '' ) ? _minp : _min_price; _price_tmp = (_price_tmp >= _minp && _price_tmp <= _max_price ) ? _price_tmp : _minp; $that.val(_price_tmp); $_slide_prices.slider("values", 1, _price_tmp); } } else { if ($that.hasClass('ft-price-min')) { $that.val(''); $_slide_prices.slider("values", 0, _min_price); } else { $that.val(''); $_slide_prices.slider("values", 1, _max_price); } } processAjax(); }, 1000); }); // var $_open_close = $('.ft-open-close ', $_group_ft); // $_open_close.on('click ', function () { // var $_parent = $(this).parents('.ft-heading'); // $_parent.siblings('.ft-content').stop(true, false).slideToggle(400, function () { // if ($_parent.parent().hasClass('ft-open')) { // $_parent.parent().removeClass('ft-open').addClass('ft-close'); // } // else { // $_parent.parent().removeClass('ft-close').addClass('ft-open'); // } // }); // // }); var $_ft_heading = $('.ft-heading', $_group_ft); $_ft_heading.on('click', function () { $(this).siblings('.ft-content').stop(true, false).slideToggle(400, function () { if ($(this).parent().hasClass('ft-open')) { $(this).parent().removeClass('ft-open').addClass('ft-close'); } else { $(this).parent().removeClass('ft-close').addClass('ft-open'); } }); }); if ($('.ft-group', $element).width() <= 200) { $('.sj-vm-filter .ft-content-prices .ft-price-value input[type="text"]').css('width', '38px'); } //.ft-opt-count var $_label_opt = $('.ft-opt-name, .ft-color-value', $_group_ft); $_label_opt.on('click ', function () { var _input_check = $(this).siblings('input[type="checkbox"]'), _checked = _input_check.prop('checked'), _color_value = $(this).is('.ft-color-value'); if (_checked) { if (_color_value) { $(this).removeClass('ft-checked'); } _input_check.removeAttr('checked'); } else { if (_color_value) { $(this).addClass('ft-checked'); } _input_check.attr('checked', 'checked'); } processAjax(); }); function showClearAll() { var $ft_content = $('.ft-content', $_group_ft); $ft_content.each(function () { var $that = $(this); var $i = 0; $(':input', $that).each(function () { if ($(this).prop('checked')) { $i++; } }); if ($i > 0) { $('.ft-opt-clearall', $that).fadeIn(500); } else { $('.ft-opt-clearall', $that).fadeOut(500); } }); } $('input[type="hidden"]', $element).val(''); $('input[type="hidden"]', $_group_ft).val(''); $(':checkbox ', $_group_ft).removeAttr('checked'); $(':checkbox ', $_group_ft).on('click', function () { processAjax(); }); $('.ft-opt-clearall', $_group_ft).unbind('click.clearall').on('click.clearall', function () { var _ft_select = $(this).siblings('.ft-select'); $('input[type="checkbox"]', _ft_select).removeAttr('checked'); $('.ft-color-value', _ft_select).removeClass('ft-checked'); processAjax(); }); var _config_global = ''; function processAjax() { var fields = $(":input", $element).serialize(); _config_global = fields; showClearAll(); var _loading = $('<div class="sj-loading" ><div class="ft-image-loading"></div></div>'); $("body").append(_loading); $.ajax({ type: 'POST', url: $_ajax_url, data: { is_ajax_ft: 1, ft_module_id: <?php echo $module->id ?>, _config_data: _config_global }, success: function (data) { _loading.remove(); if (data.items_markup != '') { $('.ft-filtering', $_ft_form).replaceWith(data.items_markup); updateAfterLoadAjax(); } if (data.filter_product != '') { if ($('<?php echo $params->get('area_results'); ?>').length) { $('<?php echo $params->get('area_results'); ?>').html(data.filter_product); updateAfterLoadAjax(); } } if (data == 'noresults') { window.location.href = $_ajax_url; } }, error: function () { _loading.remove(); }, dataType: 'json' }); } var parseQueryString = function (queryString) { var params = {}, queries, temp, i, l; queries = queryString.split("&"); for (i = 0, l = queries.length; i < l; i++) { temp = queries[i].split('='); params[temp[0]] = temp[1]; } return params; }; function updateAfterLoadAjax() { if(typeof Virtuemart !== 'undefined'){ var $_form = $("form.product"); Virtuemart.product($_form); } var $_ft_result = $('#ft_results_<?php echo $module->id; ?>'); $('.orderlistcontainer', $_ft_result).hover( function () { $(this).find('.orderlist').stop().show() }, function () { $(this).find('.orderlist').stop().hide() } ) var $_orderList = $('.orderlist', $_ft_result); if ($_orderList.length > 0) { $_orderList.children().on('click', function () { var _href = $('a ', $(this)).attr('href'); _href = _href.replace(/\?/g, '&').replace('by,', 'orderby='); _href = _href.replace(/\//g, '&'); var _orderby = parseQueryString(_href); $('.config-orderby', $element).attr('value', _orderby.orderby); processAjax(); return false; }); } var $_selectbox = $('select.inputbox', $_ft_result); var _limit = $('option:selected', $_selectbox).text(); $('option:selected', $_selectbox).each(function(){ var _limit = $(this).text(); $('.config-limit', $element).attr('value', _limit); $_selectbox.removeAttr('onchange'); $_selectbox.on('change', function () { var _value = $('option:selected', $(this)).text(); $('.config-limit', $element).attr('value', _value); processAjax(); return false; }); }); //add product_load_limit last run processAjax() in select box var pro_load = "<?php echo $params->get('limit_results',5)?>"; var url_option = "<?php echo JURI::base(true).'/?limit=';?>"; var _option = '<option value="' + url_option + pro_load + '">' + pro_load + '</option>'; var $_selectbox_2 = $('select.inputbox option:first', $_ft_result); if ($_selectbox_2.text() != pro_load) { $_selectbox_2.before(_option); } var $vm_pagination = $('.vm-pagination ul', $_ft_result); if ($vm_pagination.length > 0) { $vm_pagination.children().on('click', function () { var $this = $(this); if ($this.is('.disabled') || $this.is('.active')) { return false; } else { var _href = $('a ', $(this)).attr('href'); _href = _href.replace(/\?/g, '&').replace('results,', 'limit_start='); _href = _href.replace(/\//g, '&'); var _lmstart = parseQueryString(_href); var _start = 0; if (typeof _lmstart.limit_start != 'undefined') { _start = _lmstart.limit_start _start = _start.split("-"); _start = _start[1]; } else if (typeof _lmstart.start != 'undefined') { _start = _lmstart.start; } $('.config-limitstart', $element).attr('value', _start); processAjax(); } return false; }); } // Click Button function display(view) { jQuery('.browse-view .row').removeClass('vm-list vm-grid').addClass(view); jQuery('.icon-list-grid .vm-view').removeClass('active'); if(view == 'vm-list') { jQuery('.browse-view .product').addClass('col-lg-12 product-full'); jQuery('.browse-view .product .product-left').addClass('col-md-4'); jQuery('.browse-view .product .product-right').addClass('col-md-8'); jQuery('.icon-list-grid .' + view).addClass('active'); }else{ jQuery('.browse-view .product').removeClass('col-lg-12 product-full'); jQuery('.browse-view .product .product-left').removeClass('col-md-4'); jQuery('.browse-view .product .product-right').removeClass('col-md-8'); jQuery('.icon-list-grid .' + view).addClass('active'); } } jQuery('.vm-view-list .vm-view').each(function() { var ua = navigator.userAgent, event = (ua.match(/iPad/i)) ? 'touchstart' : 'click'; jQuery('.vm-view-list .vm-view').bind(event, function() { jQuery(this).addClass(function() { if(jQuery(this).hasClass('active')) return ''; return 'active'; }); jQuery(this).siblings('.vm-view').removeClass('active'); catalog_mode = jQuery(this).data('view'); display(catalog_mode); }); }); var $_filtering = $('.ft-filtering', $element), _ft_opt_close = $('.ft-opt-close', $_filtering), _filtering_clearall = $('.ft-filtering-clearall', $_filtering); _ft_opt_close.on('click', function () { var _data_value = $(this).parent().attr('data-filter'), _cls_ft = $('.' + _data_value); if (_cls_ft.length > 0) { $(':checkbox', _cls_ft).removeAttr('checked'); $(_cls_ft).attr('value', ''); $('.ft-color-value', _cls_ft).removeClass('ft-checked'); processAjax(); } }); _filtering_clearall.on('click', function () { var _opt_inner = $('.ft-opt-inner', $_filtering); if (_opt_inner.length > 0) { _opt_inner.each(function () { var _data_value = $(this).attr('data-filter'), _cls_ft = $('.' + _data_value); $(':checkbox', _cls_ft).removeAttr('checked'); $(_cls_ft).attr('value', ''); $('.ft-color-value', _cls_ft).removeClass('ft-checked'); }); processAjax(); } }); } })('#<?php echo $tag_id; ?>'); }); //]]> </script>
what can be used in place of window.location.replace to avoid page reloading?
I am using product filtering in a site like Flipkart. And I do not want to reload the page after filtering data. This is my jquery code for filtering data. Filter class is used in all the filters. Give some suggestions plz. $('.filter').click(function() { var typef = ''; var currentURL = location.protocol + '//' + location.host + location.pathname; if (window.location.href.indexOf("search") > -1) { var searchParams = new URLSearchParams(window.location.search); var aquery = searchParams.get('query'); typef = 'search'; } var brands = []; var colors = []; var price = []; if ($(this).is(":checked")) { $("input:checkbox[name=brand_check]:checked").each(function() { brands.push($(this).val()); }); $("input:checkbox[name=color_check]:checked").each(function() { colors.push($(this).val()); }); $("input:radio[name=price_check]:checked").each(function() { price.push($(this).val()); }); var filterdata = { brands: jQuery.unique(brands), color: jQuery.unique(colors), price: jQuery.unique(price) }; var filteruri = jQuery.param(filterdata); if (typef == 'search' && typeof aquery !== "undefined" && aquery !== '') { window.location.replace(currentURL + '?query=' + encodeURIComponent(aquery) + '&f=' + encodeURIComponent(filteruri)); } else { window.location.replace(currentURL + '?f=' + encodeURIComponent(filteruri)); } } else { $('input:checkbox[value="' + $(this).val() + '"]').attr('checked', false); $("input:checkbox[name=brand_check]:checked").each(function() { brands.push($(this).val()); }); $("input:checkbox[name=color_check]:checked").each(function() { colors.push($(this).val()); }); $("input:radio[name=price_check]:checked").each(function() { price.push($(this).val()); }); var filterdata = { brands: jQuery.unique(brands), color: jQuery.unique(colors), price: jQuery.unique(price) }; var filteruri = jQuery.param(filterdata); if (typef == 'search' && typeof aquery !== "undefined" && aquery !== '') { if (filteruri.length > 0) { window.location.replace(currentURL + '?query=' + encodeURIComponent(aquery) + '&f=' + encodeURIComponent(filteruri)); } else { window.location.replace(currentURL + '?query=' + encodeURIComponent(aquery)); } } else { if (filteruri.length > 0) { window.location.replace(currentURL + '?f=' + encodeURIComponent(filteruri)); } else { window.location.replace(currentURL); } } } });
If I understood correctly, you want to change url without page reloading. Read some about manipulating browser history (https://developer.mozilla.org/en-US/docs/Web/API/History_API), in particular: pushState. In your case you can use window.history.pushState (https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_pushState()_method). Instead window.location.replace you can write something like this one: window.history.pushState({ page: filteruri }, 'Page title', currentURL + '?somethingnew');
How to store post id in local storage from Single.php file
The following code in Single.php file is not working as expected. $post->ID and is_user_logged_in() are getting null values. If all works fine i can have the post id as array in local storage. <script> window.onload = function() { var logged_in='<?php echo is_user_logged_in() ?>'; if (logged_in==false || logged_in==0) { var myArray = JSON.parse(localStorage.getItem('articles') )|| []; var article_postid='<?php echo $post->ID ?>'; //check already read? if not push into array index = is_exist.call(myArray, article_postid); if(!index){ myArray.push(article_postid); localStorage.setItem('articles', JSON.stringify(myArray)); } } } var is_exist = function(article_postid) { // Per spec, the way to identify NaN is that it is not equal to itself var findNaN = article_postid !== article_postid; var indexOf; if(!findNaN && typeof Array.prototype.indexOf === 'function') { indexOf = Array.prototype.indexOf; } else { indexOf = function(article_postid) { var i = -1, index = -1; for(i = 0; i < this.length; i++) { var item = this[i]; if((findNaN && item !== item) || item === article_postid) { index = i; break; } } return index; }; } return indexOf.call(this, article_postid) > -1; }; </script>
Please try this code. Add this code to your activated theme's functions.php file and check. function add_js_code_to_footer(){ if( is_singular( 'post' ) ){ global $post; ?> <script> window.onload = function() { var logged_in='<?php echo is_user_logged_in() ?>'; if (logged_in==false || logged_in==0) { var myArray = JSON.parse(localStorage.getItem('articles') )|| []; var article_postid='<?php echo $post->ID ?>'; //check already read? if not push into array index = is_exist.call(myArray, article_postid); if(!index){ myArray.push(article_postid); localStorage.setItem('articles', JSON.stringify(myArray)); } } } var is_exist = function(article_postid) { // Per spec, the way to identify NaN is that it is not equal to itself var findNaN = article_postid !== article_postid; var indexOf; if(!findNaN && typeof Array.prototype.indexOf === 'function') { indexOf = Array.prototype.indexOf; } else { indexOf = function(article_postid) { var i = -1, index = -1; for(i = 0; i < this.length; i++) { var item = this[i]; if((findNaN && item !== item) || item === article_postid) { index = i; break; } } return index; }; } return indexOf.call(this, article_postid) > -1; }; </script> <?php } } add_action("wp_footer","add_js_code_to_footer");
JQUERY and AJAX Pagination and Calling Data
I am facing the following problem, I have a page of products with ajax pagination where users is able to select products in a form, the selected products save their id values in an array, but my problem is when the user goes to page 2 then he go back to page 1 he is able to choose the same product where I need to be the array ids unique, where user is able to select only the product 1 time even if he goes to page 2 or 3 and come back to previous pages my ajax code: $(".pageNumber").on("click",function(){ pageID = this.id; var data_string = 'pageID='+pageID; $.ajax({ type: "POST", url: "loadData.php", data: { "pageId" : pageID, "catid" : catid, "subid" : subid, "filter" : filter, "view" : view_type , "items" : itemArrayList}, cache: false, success: function (result) { $(".pageNumber").removeClass("number-page-active"); $("#"+pageID).addClass("number-page-active"); $("#results1").hide(); $("#results").html(result); console.log(result); if ($(".number-page-active").attr('id') == 1) { $('#sub1').attr("style","display:none") ; } if ($(".number-page-active").attr('id') != 1) { $('#sub1').attr("style","display:block") ; } if ($(".number-page-active").attr('id') == <?php echo $pageLast ?>) { $('#add1').attr("style","display:none") ; } if ($(".number-page-active").attr('id') != <?php echo $pageLast ?>) { $('#add1').attr("style","display:block") ; } } }); The list of selected products are saved in array as follow: $("#quotationSubmit").on("click",function(){ console.log(itemArrayList); $("#itemListArray").val(itemArrayList); }); var itemSelected = 0; itemArrayList = []; function image(divId) { if (itemSelected < 0) { itemSelected = 0; } var idDiv = 1; for (idDiv; idDiv <= 100; idDiv++) { var divDivId = "" + idDiv; var divDivId0 = "" + idDiv; if (divDivId === divId || divDivId0 === divId) { break; } } if ($("#quotation-form").css("display") === "block") { if ($("#" + idDiv).hasClass("selected-div") === true || $("#" + idDiv).hasClass("selected-div")) { $("#" + idDiv).removeClass("selected-div"); $("#" + idDiv).removeClass("selected-div"); itemSelected--; index = $.inArray(divId,itemArrayList); itemArrayList.splice(index,1); console.log(itemArrayList); } else { $("#" + idDiv).addClass("selected-div"); $("#" + idDiv).addClass("selected-div"); itemSelected++; itemArrayList.push(divId); console.log(itemArrayList); } if (itemSelected === 0) { document.getElementById("quotationText").innerHTML = "Please Select an item"; } else { if (itemSelected === 1) { document.getElementById("quotationText").innerHTML = "You have 1 item Selected"; } else { document.getElementById("quotationText").innerHTML = "You have " + itemSelected + " items Selected"; } } } else { var imageMe = $("#" + divId).find('img').attr('src'); document.getElementById('image00').src = imageMe; setTimeout(function () { $(".modal-for-image").removeClass("left-modal-image"); }, 100); } }
How to submit an iframe sub-form within main form using jQuery/AJAX?
I am using a jQuery plugin called Stepy, which is based of the FormToWizard plugin, to allow users to complete a 10-step form. Using the next/back attributes, I've added a function to post data between steps so the user can save their work and come back at a later day if they'd like. One of my steps allows the user to add items to a form within an iframe (to post data to a separate table). I'd like it to function so that when the user moves between steps, the items in the iframe post to their separate table as well. Is there a way to submit the form within the iframe between steps (i.e. submit iframe sub-form when main form submits)? I am using PHP and MySQL. Any help you could provide would be amazing! Javascript: $(function() { $('#custom').stepy({ backLabel: 'Back', block: true, errorImage: true, nextLabel: 'Next', titleClick: true, validate: false, legend: false, back: function(index) { $.post('../../process.php') } next: function(index) { $.post('../../process.php') } }); }); HTML: <html> <body> <form id="custom" name="custom"> <fieldset title="Thread 1"> <legend>description one</legend> <label>Question A:</label> <input type="text" id="question_a" name="question_a" class="required"> <label>Question B:</label> <input type="text" id="question_b" name="question_b"> </fieldset> <fieldset title="Thread 2"> <legend>description two</legend> <iframe src="../../list_form.php" width="100%" height="300"></iframe> </fieldset> <fieldset title="Thread 3"> <legend>description three</legend> <label>Question C:</label> <input type="text" id="question_c" name="question_c" class="required"> </fieldset> <input type="submit" class="finish" value="Finish!"> </form> </body> </html> iframe <html> <body> <form id="sub_form" name="sub_form"> <label>Question 1:</label> <input type="text" id="question_1" name="question_1"> <label>Question 2:</label> <input type="text" id="question_2" name="question_2"> </form> </body> </html> stepy.js ;(function($) { var methods = { init: function(options) { return this.each(function() { var opt = $.extend({}, $.fn.stepy.defaults, options), $this = $(this).data('options', opt), id = $this.attr('id'); if (id === undefined) { id = 'stepy-' + $this.index(); $this.attr('id', id); } var $titlesWrapper = $('<ul/>', { id: id + '-titles', 'class': 'stepy-titles' }); if (opt.titleTarget) { $(opt.titleTarget).html($titlesWrapper); } else { $titlesWrapper.insertBefore($this); } if (opt.validate) { $this.append('<div class="stepy-error"/>'); } var $steps = $this.children('fieldset'), $step = undefined, $legend = undefined, description = '', title = ''; $steps.each(function(index) { $step = $(this); $step .addClass('step') .attr('id', id + '-step-' + index) .append('<p id="' + id + '-buttons-' + index + '" class="' + id + '-buttons"/>'); $legend = $step.children('legend'); if (!opt.legend) { $legend.hide(); } description = ''; if (opt.description) { if ($legend.length) { description = '<span>' + $legend.html() + '</span>'; } else { $.error(id + ': the legend element of the step ' + (index + 1) + ' is required to set the description!'); } } title = $step.attr('title'); title = (title != '') ? '<div>' + title + '</div>': '--'; $titlesWrapper.append('<li id="' + id + '-title-' + index + '">' + title + description + '</li>'); if (index == 0) { if ($steps.length > 1) { methods.createNextButton.call($this, index); } } else { methods.createBackButton.call($this, index); $step.hide(); if (index < $steps.length - 1) { methods.createNextButton.call($this, index); } } }); var $titles = $titlesWrapper.children(); $titles.first().addClass('current-step'); var $finish = $this.children('.finish'); if (opt.finishButton) { if ($finish.length) { var isForm = $this.is('form'), onSubmit = undefined; if (opt.finish && isForm) { onSubmit = $this.attr('onsubmit'); $this.attr('onsubmit', 'return false;'); } $finish.click(function(evt) { if (opt.finish && !methods.execute.call($this, opt.finish, $steps.length - 1)) { evt.preventDefault(); } else { if (isForm) { if (onSubmit) { $this.attr('onsubmit', onSubmit); } else { $this.removeAttr('onsubmit'); } var isSubmit = $finish.attr('type') == 'submit'; if (!isSubmit && (!opt.validate || methods.validate.call($this, $steps.length - 1))) { $this.submit(); } } } }); $finish.appendTo($this.find('p:last')); } else { $.error(id + ': element with class name "finish" missing!'); } } if (opt.titleClick) { $titles.click(function() { var array = $titles.filter('.current-step').attr('id').split('-'), // TODO: try keep the number in an attribute. current = parseInt(array[array.length - 1], 10), clicked = $(this).index(); if (clicked > current) { if (opt.next && !methods.execute.call($this, opt.next, clicked)) { return false; } } else if (clicked < current) { if (opt.back && !methods.execute.call($this, opt.back, clicked)) { return false; } } if (clicked != current) { methods.step.call($this, (clicked) + 1); } }); } else { $titles.css('cursor', 'default'); } $steps.delegate('input[type="text"], input[type="password"]', 'keypress', function(evt) { var key = (evt.keyCode ? evt.keyCode : evt.which); if (key == 13) { evt.preventDefault(); var $buttons = $(this).parent().children('.' + id + '-buttons'); if ($buttons.length) { var $next = $buttons.children('.button right-aligned'); if ($next.length) { $next.click(); } else { var $finish = $buttons.children('.finish'); if ($finish.length) { $finish.click(); } } } } }); $steps.first().find(':input:visible:enabled').first().select().focus(); }); }, createBackButton: function(index) { var $this = this, id = this.attr('id'), opt = this.data('options'); $('<a/>', { id: id + '-back-' + index, href: 'javascript:void(0);', 'class': 'button left-aligned', html: opt.backLabel }).click(function() { if (!opt.back || methods.execute.call($this, opt.back, index - 1)) { methods.step.call($this, (index - 1) + 1); } }).appendTo($('#' + id + '-buttons-' + index)); }, createNextButton: function(index) { var $this = this, id = this.attr('id'), opt = this.data('options'); $('<a/>', { id: id + '-next-' + index, href: 'javascript:void(0);', 'class': 'button right-aligned', html: opt.nextLabel }).click(function() { if (!opt.next || methods.execute.call($this, opt.next, index + 1)) { methods.step.call($this, (index + 1) + 1); } }).appendTo($('#' + id + '-buttons-' + index)); }, execute: function(callback, index) { var isValid = callback.call(this, index + 1); return isValid || isValid === undefined; }, step: function(index) { index--; var $steps = this.children('fieldset'); if (index > $steps.length - 1) { index = $steps.length - 1; } var opt = this.data('options'); max = index; if (opt.validate) { var isValid = true; for (var i = 0; i < index; i++) { isValid &= methods.validate.call(this, i); if (opt.block && !isValid) { max = i; break; } } } $steps.hide().eq(max).show(); var $titles = $('#' + this.attr('id') + '-titles').children(); $titles.removeClass('current-step').eq(max).addClass('current-step'); if (this.is('form')) { var $fields = undefined; if (max == index) { $fields = $steps.eq(max).find(':input:enabled:visible'); } else { $fields = $steps.eq(max).find('.error').select().focus(); } $fields.first().select().focus(); } if (opt.select) { opt.select.call(this, max + 1); } return this; }, validate: function(index) { if (!this.is('form')) { return true; } var $step = this.children('fieldset').eq(index), isValid = true, $title = $('#' + this.attr('id') + '-titles').children().eq(index), opt = this.data('options'), $this = this; $($step.find(':input:enabled').get().reverse()).each(function() { var fieldIsValid = $this.validate().element($(this)); if (fieldIsValid === undefined) { fieldIsValid = true; } isValid &= fieldIsValid; if (isValid) { if (opt.errorImage) { $title.removeClass('error-image'); } } else { if (opt.errorImage) { $title.addClass('error-image'); } $this.validate().focusInvalid(); } }); return isValid; } }; $.fn.stepy = function(method) { if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('Method ' + method + ' does not exist!'); } }; $.fn.stepy.defaults = { back: undefined, backLabel: '< Back', block: false, description: true, errorImage: false, finish: undefined, finishButton: true, legend: true, next: undefined, nextLabel: 'Next >', titleClick: false, titleTarget: undefined, validate: false, select: undefined }; })(jQuery);
If you want to append Text\HTML or any other data to your iframe (which calling to a page on the same domain!) you may use: jQuery("#iframe_id").contents().find('body').append('<div>Hello World</div>'); Full Example: Full Example If your iframe is on another domain you will have to use window.postMessage, which you may read about on Mozilla's docs: Mozilla's docs OR to take a look about my blog post about this subject. Hope I helped,