I have used Jquery autocomplete example from http://jqueryui.com/autocomplete/#remote-jsonp. I have included all the specific code from the reference site but that doesn't work in my local.
I want only company name to be search in it.
Here i am attaching image to get the exact idea what i am getting
<script>
$( function() {
function log( message ) {
$( "<div>" ).text( message ).prependTo( "#log" );
$( "#log" ).scrollTop( 0 );
}
$( "#company_name" ).autocomplete({
source: "http://localhost:5050/api/v1/web-customer-list",
type: "GET",
minLength: 1,
autoSelect: true,
autoFocus: true,
dataType : "json",
response: function( event, ui ) {
var responseObj = ui.content[0];
var companyNameList = [] ;
for(var i = 0 ; i<= 6 ; i ++){
companyNameList.push(responseObj[i].company.company_name) ;
}
},
select: function( event, ui ) {
console.log(event);
console.log(ui);
log( "Selected: " + ui.item.company.company_name + " aka " + ui.item.id );
}
});
} );
</script>
I have forked over the example and made some adjustments to fit what you appear to be doing.
Working Example: https://jsfiddle.net/Twisty/0Lajrcfv/
HTML
<div class="ui-widget">
<label for="companyName">Company Name: </label>
<input id="companyName">
</div>
<div class="ui-widget" style="margin-top:2em; font-family:Arial">
Result:
<div id="log" style="height: 200px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
</div>
jQuery
$(function() {
function log(message) {
$("<div>").text(message).prependTo("#log");
$("#log").scrollTop(0);
}
$("#companyName").autocomplete({
source: function(req, resp) {
var companyNameList = [];
$.ajax({
//url: "http://localhost:5050/api/v1/web-customer-list",
//type: "GET",
url: "/echo/json/",
type: "POST",
data: {
json: JSON.stringify({
company: {
company_name: [
"Apple",
"Google",
"IBM",
"HP",
"Yahoo!",
"AltaVista",
"Yelp",
"2600"
]
}
})
},
dataType: "json",
success: function(respObj) {
for (var i = 0; i <= 6; i++) {
companyNameList.push({
id: i,
value: respObj.company.company_name[i]
});
}
resp(companyNameList);
}
});
},
minLength: 1,
autoSelect: true,
autoFocus: true,
select: function(event, ui) {
log("Selected: " + ui.item.value + " aka " + ui.item.id);
}
});
});
So, as you can see from the example, the source option can accept the response from a string or callback function. The callback function is passed two parameters, request and response.
The callback gets two arguments:
A request object, with a single term property, which refers to the value currently in the text input. For example, if the user enters "new yo" in a city field, the Autocomplete term will equal "new yo".
A response callback, which expects a single argument: the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data. It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.
Based on your code, it looks like you are not going to filter clientside, you're just going to accept the top 6 from whatever your GET request returns. So we just ignore req.term in my example. We're then only really concerned about collecting the results, formatting them properly, and returning them to resp().
For my working example, we POST the data so it can be echo'd back as a response. Based on your example, you're expecting an object of some type, roughly similar to:
[{
company: {
company_name
}
}]
If you want your version to work, where you call the URL via GET, the data returned should be:
An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ]
For example:
[{
label: "Apple",
value: 1
},
{
label: "Google",
value: 2
}];
I hope this helps a bit.
Related
I have a Kendo jquery AutoComplete UI component with a remote REST web API dataSource. I want to map the responce of the API to the autoComplete. I have it displaying the choices but when I examine the select function I just see what I've selected. What I want is the complete json object on the select event. Or at least what I really need is the unitKey property.
my code:
//create AutoComplete UI component
$("#autoAddress").kendoAutoComplete({
minLength: 3,
dataTextField: "address",
filter: "startswith",
placeholder: "Address lookup ...",
select : function(e) {
var item = e.item;
console.log(item.text());
},
dataSource: new kendo.data.DataSource ({
serverFiltering: true,
transport: {
read: {
url: "https://testapi.mydomain.com/homeinfo/api/address/",
// dataType: "jsonp",
data: {
q : function() {
return $("#autoAddress").data("kendoAutoComplete").value();
},
maxRows: 30
}
}
},
schema : {
data: function(response){
return response;
}
}
})
});
sample date from api call:
[
{
"unitKey": "S37.75 ",
"address": "1234 ADDISON AVE"
},
{
"unitKey": "S22.215 ",
"address": "1234 AUGUSTINE DR"
},
{
"unitKey": "L100.9 ",
"address": "1234 AVENIDA DE LAS CASAS"
}
]
I'm trying to get the "unitKey" when the user makes a selection from the autocomplete component.
You want to look at e.dataItem rather than e.item:
console.log(e.dataItem.unitKey);
In cases like this I usually log 'e' itself to the console or breakpoint with the debugger to inspect it to see what it contains since the documentation is not always as comprehensive as it could be.
I've been struggling with this one all day. I'm making an ajax call to a hard coded JSON file and attempting to store some of the contents into option tags using custom attributes. When I try to retrieve the data that I'm storing in the custom attribute, I keep getting [object Object]. If I try to JSON.stringify() that, I just get "[object Object]" (same as before, except wrapped in double quotes).
Some advice would be very helpful.
This is my currently empty select tag in HTML:
<select id="attackList"></select>
Actual JSON file:
{"attacks":[
{
"attackName":"Jab (1)",
"attackData":{"hitFrame":"9", "faf":"26", "damage":"1.5"}
},
{
"attackName":"Jab (3)",
"attackData":{"hitFrame":"11", "faf":"34", "damage":"2.7"}
},
{
"attackName":"Dash Attack (Early)",
"attackData":{"hitFrame":"15", "faf":"47", "damage":"10"}
},
{
"attackName":"Dash Attack (Late)",
"attackData":{"hitFrame":"21", "faf":"47", "damage":"8"}
},
{
"attackName":"Forward Tilt (1)",
"attackData":{"hitFrame":"12", "faf":"32", "damage":"3.5"}
},
{
"attackName":"Forward Tilt (3)",
"attackData":{"hitFrame":"14", "faf":"43", "damage":"8.5"}
},
{
"attackName":"Up Tilt(1, Early)",
"attackData":{"hitFrame":"7", "faf":"27", "damage":"5"}
},
{
"attackName":"Up Tilt (1, Late)",
"attackData":{"hitFrame":"9", "faf":"27", "damage":"2"}
},
{
"attackName":"Up Tilt (2)",
"attackData":{"hitFrame":"11", "faf":"27", "damage":"6"}
},
{
"attackName":"Down Tilt (Weak)",
"attackData":{"hitFrame":"7", "faf":"26", "damage":"6"}
},
{
"attackName":"Down Tilt (Strong)",
"attackData":{"hitFrame":"7", "faf":"26", "damage":"7"}
},
{
"attackName":"Forward Smash (Weak)",
"attackData":{"hitFrame":"19", "faf":"68", "damage":"14"}
},
{
"attackName":"Forward Smash (Strong)",
"attackData":{"hitFrame":"19", "faf":"68", "damage":"16"}
},
{
"attackName":"Up Smash (Early)",
"attackData":{"hitFrame":"18", "faf":"65", "damage":"17"}
},
{
"attackName":"Up Smash (Mid)",
"attackData":{"hitFrame":"20", "faf":"65", "damage":"16"}
},
{
"attackName":"Up Smash (Late)",
"attackData":{"hitFrame":"22", "faf":"65", "damage":"15"}
},
{
"attackName":"Up Smash (Late)",
"attackData":{"hitFrame":"22", "faf":"65", "damage":"15"}
},
{
"attackName":"Down Smash (1)",
"attackData":{"hitFrame":"20", "faf":"69", "damage":"5"}
},
{
"attackName":"Down Smash (2, Early)",
"attackData":{"hitFrame":"25", "faf":"69", "damage":"16"}
},
{
"attackName":"Down Smash (2, Late)",
"attackData":{"hitFrame":"26", "faf":"69", "damage":"15"}
}
]}
AJAX call that populates the select tag:
$.ajax({
url: attackerFileName,
dataType: 'json',
type: 'get',
cache:true,
success: function(data){
$(data.attacks).each(function(index,value){
console.log(value.attackData);
dropdownOptions.append($("<option></option>").attr("data-value", value.attackData).text(value.attackName));
});
}
});
And the JS code that attempts to retrieve the custom attribute from the currently selected option:
var selectedAttack = $("#attackList option:selected").data("value");
console.log(selectedAttack);
Anyone have any clue why I can't get the actual "attackData" contents from the JSON to come back? If I add code to log the attackData element from the JSON BEFORE its stored into the custom attribute, it comes back just fine. But after I retrieve it, [object Object] is all I get.
Thanks so much in advance to anyone who takes the time to look into this!
The html options can only take primitive values as a string representation.
When you set an option using the attr function, the string representation of the value is taken. In case it is an object, you will get back [object Object] as you are actually storing this value.
However, you can use the $.data function to set the data as an object.
Setting the data value in the following way should do the trick
$('<option></option>').data('value', value.attackData);
or as shown in the code snippet below
'use strict';
var mock = [{
name: 'Option 1',
value: {
identifier: 'option1',
value: {
hello: 'world'
}
}
}, {
name: 'Option 2',
value: {
identifier: 'option2',
value: {
world: 'hello'
}
}
}, {
name: 'Option 3',
value: {
identifier: 'option3',
value: {
sentence: 'hello world'
}
}
}];
$(function() {
setTimeout(function(data) {
// fake postback
var targetElement = $('#dropdown');
data.forEach(function(item) {
var option = $('<option></option>').data('value', item.value).text( item.name );
$(targetElement).append( option );
});
}.bind(null, mock));
$('#dropdown').on('change', function() {
var si = this.selectedIndex,
option = this.options[si],
name = option.text,
value = $.data( option, 'value' );
$('#output').html(name + '<br/>' + JSON.stringify(value));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="dropdown">
</select>
<div id="output">
</div>
$('#placeSelect').select2({
width: '100%',
allowClear: true,
multiple: true,
maximumSelectionSize: 1,
placeholder: "Click here and start typing to search.",
data: function(query) {
queryData{!randomJsIden}(query);
},
matcher: function (term, text) {if (text.toUpperCase().indexOf(term.toUpperCase()) == 0){return true;}return false;}
});
function queryData{!randomJsIden}(query){
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.AutoCompleteV2_Con.getData}','{!sObjVal}','{!labelFieldVar}','{!valueFieldVar}',query.term,
function(result, event){
//if success
if(event.status){
var data = {results:[{ id: 1, text: "Ford" },
{ id: 2, text: "Dodge" },
{ id: 3, text: "Mercedes" },
{ id: 4, text: "Jaguar" }]}
query.callback( data);
}
},
{escape: true}
);
}
</script>
How to initialize query call back data to data attribute in select2 .
I cannot use data directly .In above example i am using sample data .
query : function(query){
queryData{!randomJsIden}(query);
}
I want to replace this by data attribute like this : the below one is not working
data : function(query){
queryData{!randomJsIden}(query);
}
here is the fiddle :
http://jsfiddle.net/Lnf8j/303/
Let me know any ideas from you
There are couple of issues in your code
you cannot name a function using flower braces as it is reserved notation symbol in javascript function queryData{!randomJsIden}(query), instead name it as function queryData(query){ ... }
if your adding a callback for data of your select2 then you need to return that data constructed from queryData() function.
data: function(query) {
return queryData(query);
},
function queryData(query){
...
return data;
}
If i'am not wrong,data is sourced to select2 via asynchronous call inside queryData(), which means the data is returned at unpredictable time,so you need to restrict the user from accessing the select2 component until data is feeded to it.
which means you either need to prefetch the data or disable the select2 field until data is returned from remote call.
Working Demo # JSFiddle
I have an input (textarea) that has Select2's tags applied to it. So when a user types in the name of an item that exists in my data base, it shows a list of matching items and the user can select one and a tag is created.
Here is my code so far for basic tag functionality:
$('#usualSuppliers').select2({
placeholder: "Usual suppliers...",
minimumInputLength: 1,
multiple: true,
id: function(e) {
return e.id + ":" + e.name;
},
ajax: {
url: ROOT + 'Ajax',
dataType: 'json',
type: 'POST',
data: function(term, page) {
return {
call: 'Record->supplierHelper',
q: term,
page_limit: 10
};
},
results: function(data, page) {
return {
results: data.suppliers
};
}
},
formatResult: formatResult,
formatSelection: formatSelection,
initSelection: function(element, callback) {
var data = [];
$(element.val().split(",")).each(function(i) {
var item = this.split(':');
data.push({
id: item[0],
title: item[1]
});
});
//$(element).val('');
callback(data);
}
});
Is there a way for a new tag to be created if the text typed does not exist? Initially I thought this could some how be done by delimiting with spaces, but some items (supplier names) will have spaces in them, so that won't work.
I think when no matches are found the user needs to somehow "create" the tag by pressing a button that could appear in the drop down box, but I have no idea how to do this.
How can I allow users to create new tags that may have spaces in them and still be able to carry on adding more tags, existing or otherwise?
Yes you can do it. There is a example in the documentation. Look at http://ivaynberg.github.io/select2/#events
$("#e11_2").select2({
createSearchChoice: function(term, data) {
if ($(data).filter( function() { return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
multiple: true,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
You have to create a function like createSearchChoice, that returns a object with 'id' and 'text'. In other case, if you return undefined the option not will be created.
Right now, the server response I'm working with sends back a JSON response like this:
{"status":1}
After saving, jeditable places the actual response: {"status":1} on the page. Anyway to get around this issue?
A better solution is to post-process the returned json data before it hits the page.
Suppose your server returns the following json string:
{ "status": 1, "result": "value to be displayed", "other": "some other data" }
and you would like to process the "status" and "other" fields, and display the "result" field in the jeditable input field.
Add the following 2 lines to jquery.jeditable.js:
(around line 95):
var intercept = settings.intercept || function(s) {return s; };
(around line 350, right after " success : function(result, status) {"
result = intercept.apply(self,[result]);
Then, in your own code, do something like the following:
$(some_field).editable(
'/some_url_on_your_server',
{
indicator : "<img src='/images/spinner.gif'>",
tooltip: "Click to edit.",
indicator: "Saving...",
onblur: "submit",
intercept: function (jsondata) {
obj = jQuery.parseJSON(jsondata);
// do something with obj.status and obj.other
return(obj.result);
},
etc.
This allows you do cool stuff like having your server convert abbreviations to full strings etc.
Enjoy!
There's a simple way of doing this by using the callback. .editable() converts any response to a string, so the response has to be converted to a JSON variable. The values can then be retrieved and then written using a '.text()' method. Check the code:
$("#myField").editable("http://www.example.com/save.php", {
submit : 'Save',
cancel : 'Cancel',
onblur : "ignore",
name : "sentText",
callback : function(value, settings) {
var json = $.parseJSON(value);
$("#myField").text(json.sentText);
}
});
This is how I handled the json response.
First, set the datatype using ajaxoptions. Then, handle your data in the callback function. Therein, this.revert is your original value.
oTable.$('td:eq(3)').editable('/admin/products/add_quantity_used', {
"callback" : function(sValue, y) {
var aPos = oTable.fnGetPosition(this);
if($("#dialog-message").length != 0){
$("#dialog-message").remove();
}
if(!sValue.status){
$("body").append('<div id="dialog-message" style="display:none;">'+sValue.value+'</div>');
$( "#dialog-message" ).dialog({
modal: true,
buttons: {
Ok: function() {
$( this ).dialog( "close" );
}
}
});
if(this.revert != '')
oTable.fnUpdate(this.revert, aPos[0], aPos[1]);
else
oTable.fnUpdate("click to edit", aPos[0], aPos[1]);
}else
if(sValue.status)
oTable.fnUpdate(sValue.value, aPos[0], aPos[1]);
},
"submitdata" : function(value, settings) {
return {
"data[users_to_products][users_to_products_id]" : this.parentNode.getAttribute('id'),
"column" : oTable.fnGetPosition(this)[2]
};
},
"height" : "30px",
"width" : "30px",
"maxlength" : "3",
"name" : "data[users_to_products][quantity_used]",
"ajaxoptions": {"dataType":"json"}
}).attr('align', 'center');
So the solution I came up with is similar to what madcapnmckay answered here.
var editableTextArea = $('.editable-textarea');
editableTextArea.editable(submitEditableTextArea, {
type : 'textarea',
cancel : 'Cancel',
submit : 'Save',
name : editableTextArea.attr('id'),
method : 'post',
data : function(value, settings) {
return $.fn.stripHTMLforAJAX(value);
},
event : "dblclick",
onsubmit : function(value, settings) {
//jquery bug: on callback reset display from block to inline
$('.btn-edit').show(0, function(){$(this).css('display','inline');});
},
onreset : function(value, settings) {
//jquery bug: on callback reset display from block to inline
$('.btn-edit').show(0, function(){$(this).css('display','inline');});
}
});
Then the url function is
function submitEditableTextArea(value, settings) {
var edits = new Object();
var result = $.fn.addHTMLfromAJAX(value);
edits[settings.name] = [value];
var returned = $.ajax({
type : "POST",
data : edits,
dataType : "json",
success : function(_data) {
var json = eval( _data );
if ( json.status == 1 ) {
console.log('success');
}
}
});
return(result);
}