I found more than a couple examples of this with a plain jquery autocomplete but not in a way that will work with the autocomplete included in the combobox code from the demo because the structure of the code is structured so differently.
I want to match every item that has all of the search tokens anywhere in any word. I don't need to match the start of any word, any part of it is fine. I don't care if the search strings are highlighted in the autocomplete list if that makes things too complicated.
Desired search/result combos: (please excuse the spacing)
"fi th" "fi rst second th ird"
"rs on" "fi rs t sec on d third"
"ec rd" "first s ec ond thi rd"
but not limited to any max/min length or number of tokens.
EDIT
I figured part of it out using the code structure from the other autocorrect I had working.
source: function( requestObj, responseFunc ) {
var matchArry = $("select > option").map(function(){return this.innerHTML;}).get();
var srchTerms = $.trim(requestObj.term).split(/\s+/);
// For each search term, remove non-matches
$.each (srchTerms, function (J, term) {
var regX = new RegExp (term, "i");
matchArry = $.map (matchArry, function (item) {
if( regX.test(item) ){
return{
label: item,
value: item,
option: HTMLOptionElement
} ? item :null;
}
} );
});
// Return the match results
responseFunc (matchArry);
},
and
select: function( event, ui ) {
ui.item.option.selected = true;
self._trigger( "selected", event, {
item: ui.item.option
});
$("destination").val(ui.item.value); // I added this line
},
but I can't get both multiple words AND being able to click to select working at the same time.
If I remove the } ? item :null; on the return in the map function I can click to select an item. If I leave it I can type multiple words, but I can't click any of the items...
Is that the problem or the option: this? I've tried replacing it with HTMLOptionElement and null and I'm stuck.
I am able to set the value of another field with ui.item.value within the select label but that doesn't put the value in the search box or close the dropdown menu.
On a whim I added ui.item.option = ui.item.value; to the select label and everything works as expected. the option: value in source doesn't seem to matter now.
*I make no claims that any of this is good coding practice
updated fiddle: http://jsfiddle.net/eY3hM/
Related
I have successfully implemented the jQuery Autocomplete function in my HTML input filed, it returns an array of JSON objects, what I would like to achieve is the following:
click on an item of the dropdown list
filter such item's string to get only the objID string.
So, here's my js code:
$.ajax({
url: "<?php echo $pointerClass ?>.json",
type: "POST",
dataType: "JSON"
}).done(function(data){
var jsonData = data;
var arr = new Array();
var keys = Object.keys(jsonData);
for(var i=0; i<keys.length; i++){
var key = keys[i];
var jString = JSON.stringify(jsonData[key]);
arr.push(jString);
}// ./ for
console.log('arr: ' + arr[0]);
// autocomplete jquery function
$( "#ar-type-pointer-objID" ).autocomplete({
source: arr,
minLength: 1
});
});
Here's a screenshot of my drop-down menu:
As you can see by the red frame, I need to click on an item and pass only the "objID" value to my input field, so it'll be "qO19zg8mV4" since I'm clicking on the row in the red square.
Here's how my input should look like after clicking on a drop-down's row:
According to the autocomplete documentation, you have two interesting events: select and close.
select is
Triggered when an item is selected from the menu. The default action is to replace the text field's value with the value of the selected item
close is:
Triggered when the menu is hidden. Not every close event will be accompanied by a change event.
Select has two parameters:
event
ui
ui is an object like this:
item: {
label: string,
value: string
}
Not sure where you will get your JSON, probably value, so I assume that...do a console.log to be sure of it!
You should rewrite with something like
$( "#ar-type-pointer-objID" ).autocomplete({
source: arr,
select: function(event, ui) {
const target = event.target;
const val = JSON.parse(ui.item.value); // Check if decode is needed or is already passed as an object
jQuery(target).val(val.ObjID);
event.preventDefault();
return false;
}
});
We prevent the default, because "The default action is to replace the text field's value with the value of the selected item." and your change in the input field will be lost.
You still have to manage some info by yourself but the idea should be enough!
I have a problem with jQuery autocomplete, I try to get the value of the input but I get the label but no the value.
var listeClients = [{"value":1,"label":"Orange"},{"value":2,"label":"Blue"}];
$( "#site_client_first" ).autocomplete({
source: listeClients,
select: function (event, ui) {
$("#site_client_first").val(ui.item.label);
return false;
}
And for get the value I use :
$("#site_client_first").val();
https://jsfiddle.net/fyz8vL3a/
How to get the value ?
Thanks by advance =)
In the select event of autocomplete, you are setting the label as value property of element #site_client_first i.e. here $("#site_client_first").val(ui.item.label). Hence when you try to set the span's innerHTML by assigning $("#site_client_first").val(), you will always get the label and not your item.value.
Try the code below. I have added an attribute 'itemValue' to $("#site_client_first"). This will hold your item's value and $("#site_client_first").val() will hold the item's label.
And when setting up the span innerhtml, you assign $("#site_client_first").attr("itemValue") which is your item's value.
<input class="form-control" name="site[client]" id="site_client_first" itemValue="100" />
Make change to the above line in your HTML change.
Your final html is as belows:
<input class="form-control" name="site[client]" id="site_client_first" itemValue="100" />
<button onclick="getValue()">Get</button>
<span id="svalue"></span>
Your script goes here:
$(document).ready(function() {
var listeClients = [{ "value": 1, "label": "Orange"}, {
"value": 2,
"label": "Blue"
}];
$("#site_client_first").autocomplete({
source: listeClients,
select: function(event, ui) {
$("#site_client_first").val(ui.item.label);
$("#site_client_first").attr("itemValue", ui.item.value);
return false;
}
});
})
var getValue = function() {
document.getElementById("value").innerHTML = $("#site_client_first").attr("itemValue");
}
function getValue() {
document.getElementById("value").innerHTML = $("#site_client_first").attr("itemValue");
}
The problem is you are trying to use an input element as a select element.
Unlike for a select, the value for an input is simply what is written in it.
The default behavior of the autocomplete plugin is to display the labels of given source as suggestions, and when you select one them it sets the corresponding value in the input. You are overriding this functionality in the code below, by setting the label as value of the input:
select: function (event, ui) {
$("#site_client_first").val(ui.item.label);
return false;
}
If you were to remove the piece of code above, you would notice that the value field will be written in the input element upon selection of an option.
Solution 1
I recommend replacing your input element with a select one. Which I think better suits your needs. If you need to search through the options you may want to use a plugin like chosen or select2.
Solution 2
If you're keen on using an input with autocomplete, set the value as an extra attribute in the select callback
select: function (event, ui) {
$("#site_client_first").val(ui.item.label); // what the user sees
$("#site_client_first").attr('data-realValue', ui.item.value); // value is hidden
return false;
}
You can retrieve the value using
$("#site_client_first").attr('data-realValue');
Demo: https://jsfiddle.net/fyz8vL3a/1/
I have a grid in which I am providing search when the user highlights the text they want to filter.
The onCellSelect looks like this:
onCellSelect: function(row, col, content, event) {
var cm = grid.jqGrid("getGridParam", "colModel");
if (window.getSelection) {
selection = window.getSelection();
} else if (document.selection) {
selection = document.selection.createRange();
}
selectionColumn = cm[col].name;
selection.toString() !== '' && $("#gs_"+selectionColumn).val(selection.toString());
console.log($("a.soptclass[data-colname='"+selectionColumn+"']").attr('data-soper'));
if(selection.toString() != '')
{
grid[0].triggerToolbar();
}
}
Now I have some search operators which I have customized and using it in the grid:
searchoptions:{sopt:["cn",'mc','mn',"eq","ne","lt","le","gt","ge","bw","ew","nc"]}
The mc and mn are a part of customSortOperations.
Now what I want is when the user selects some text inside a specific cell inside a grid, I want to detect which search filter was used. For example by default the search filter is cn.
I have tried this:
$("a.soptclass[data-colname='"+selectionColumn+"']").attr('data-soper')
but it gives me the default cn everytime.
I can get the text inside the link which will give me a symbolic name like ~ for cn, == for eq with
$("a.soptclass[data-colname='"+selectionColumn+"']").text()
However is there a jqgrid way of rather getting the exact search operator selected? i.e. cn,eq,ne,le, etc
Please let me know if a working demo is required and I will update the question.
UPDATE: DEMO.
On line 659 and 660 I am using this callback $("a.soptclass[data-colname='"+selectionColumn+"']").text()
In other words I want the selected search operator inside onCellSelect
I still not full understand what exact behavior you want to implement, but it seems that you can start the onCellSelect code with the following:
onCellSelect: function(row, col, content, event) {
var p = $(this).jqGrid("getGridParam");
var hDiv = p.frozenColumns === true && p.colModel[col].frozen === true ?
this.grid.fhDiv : this.grid.hDiv;
var $elem = $(hDiv).find("#gs_" + $.jgrid.jqID(p.id + "_" + p.colModel[col].name));
var oper = $elem.parent().prev().children("a").data("soper");
...
}
The $elem uses the standard id behavior of the current free jqGrid implementation (no idMode option of filterToolbar is specified). The element $elem is the <input> or <select> element in the filter toolbar. You can use $elem(selection) to change the value. The oper variable contains the currently chosen searching operation. One should use .data("soper") instead of .attr("data-soper") to access the data.
I hope it's what you are missing currently.
Previously I asked how to do this and was directed to this:
<script>
jQuery.fn.filterByText = function(textbox) {
return this.each(function() {
var select = this;
var options = [];
$(select).find('option').each(function() {
options.push({value: $(this).val(), text: $(this).text()});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var options = $(select).empty().scrollTop(0).data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search,"gi");
$.each(options, function(i) {
var option = options[i];
if(option.text.match(regex) !== null) {
$(select).append(
$('<option>').text(option.text).val(option.value)
);
}
});
});
});
};
</script>
(http://www.lessanvaezi.com/filter-select-list-options/)
When I use this filter on the select box it filters both the unselected AND the selected. I'd like it to ONLY filter the unselected because if a user wants to ammend the selections and filters again, the previously selected items go away - unless they meet the filter criteria.
I'm not that good at JavaScript or JQuery and can't understand how I might tell the above script to ignore options that are ":selected" but filter all else.
Here's a jfiddle if it helps: http://jsfiddle.net/UmKXy/ I'd like option one and two to remain selected and in the list when user begins to type.
Thanks for help!
The solution you had would not work with selected elements because he created an array of options at the start and then matched those options against the regex(Without regards to what is actually selected). I've used spans to hide options in the past and created an example for you to see how it works. Here is the link : http://jsfiddle.net/rD6wv/
Here is the code
$(function() {
$("#filterByText").bind('keyup',function(){
var search = $.trim($(this).val());
var regex = new RegExp(search,"gi");
$("#filez").find('option').each(function(){
if(!$(this).is(':selected')){
if($(this).val().match(regex) === null) {
$(this).wrap('<span>');
}else if($(this).parent().is('span')){
$(this).parent().replaceWith($(this));
}
}
});
});
});
You simply need to loop through all the options of the select when you type in the textbox.
You then check if it is selected, if it is you do nothing, else you check if it matches the search filter, if it does you wrap it in a span, making it invisible, else it means you need to see it, so you check if it is already wrapped in a span, and in that case you replace it with the option so you can see it again.
to selected the non selected options, use this:
$('option:not[selected]') or $('#myselect > option:not[selected]')
to remove them, use this:
$('option:not[selected]').remove();
in css, :not filters for opposite of what comes in the curved brackets.
and [] is attribute selector.
so :not[selected] means: does not have an attribute whose key is "selected"
Looking at jQuery UI auto complete: http://jqueryui.com/demos/autocomplete/ and changing it to meet my requirements, I'm coming across some issues.
If you look at the default list at the link provided one of the options is "ActionScript" and if you type "Sc" it suggests "ActionScript" which in my case isn't suitable.
I only want it to suggest "ActionScript" for example if the user types:
A
Ac
Act
Acti
Actio
Action
ActionS
ActionSc
ActionScr
ActionScri
ActionScrip
ActionScript
"ActionScript" is just an example but it gets the point across.
Looking at the suggest function within jQuery UI auto complete code:
_suggest: function( items ) {
var ul = this.menu.element
.empty()
.zIndex( this.element.zIndex() + 1 );
this._renderMenu( ul, items );
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
this.menu.deactivate();
this.menu.refresh();
// size and position menu
ul.show();
this._resizeMenu();
ul.position( $.extend({
of: this.element
}, this.options.position ));
if ( this.options.autoFocus ) {
this.menu.next( new $.Event("mouseover") );
}
},
I can't seem to find the part the narrows down the selections. Can someone point me in the right direction? I'm using the most recent stable build.
function hackAutocomplete(){
$.extend($.ui.autocomplete, {
filter: function(array, term){
var matcher = new RegExp("^" + term, "i");
return $.grep(array, function(value){
return matcher.test(value.label || value.value || value);
});
}
});
}
hackAutocomplete();
Found this code which solved it.