jquery ui- Autocomplete selects value instead of label - javascript

This is my coding
$("#txtBox").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
url: '#Url.Action("Get", "Ctrl")',
dataType: 'json',
data: "{ 'mode': 'associate','prefix': '" + request.term + "' }",
contentType: "application/json;charset=utf-8",
success: function (data) {
var transformed = $.map(data, function (item) {
return {
label: item.Name,
value: item.Id
};
});
response(transformed);
},
error: function() {
alert('error');
},
});
},
minLength: 3,
select: function (event, ui) {
console.log('ui.item.label', ui.item.label);
$('#txtBox').val(ui.item.label);
},
focus: function (event, ui) {
console.log('ui.item.label - focus', ui.item.label);
$('#txtBox').val(ui.item.label);
}
});
});
I am getting Name and Id from c# controller as Json. I want to the auto complete textbox to display Name and while sending it back to backend while saving, I wanted to send the Id of the Name. But now when I type the name and select the name from the list of suggestions. The Id gets displayed in the text box instead of name.Where am i making the mistake. Can some one guide me on this.

I would suggest you to keep two <input /> one type=text and other type=hidden. You can initialize autocomplete on the type=text, and set the value in type=hidden and in server you can access the value of type hidden.
e.g.
<input type="text" id="txtBox" name="label" />
<input type="hidden" id="valBox" name="value" />
$("#txtBox").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
url: '#Url.Action("Get", "Ctrl")',
dataType: 'json',
data: "{ 'mode': 'associate','prefix': '" + request.term + "' }",
contentType: "application/json;charset=utf-8",
success: function (data) {
var transformed = $.map(data, function (item) {
return {
label: item.Name,
value: item.Id
};
});
response(transformed);
},
error: function() {
alert('error');
},
});
},
minLength: 3,
select: function (event, ui) {
console.log('ui.item.label', ui.item.label);
$('#txtBox').val(ui.item.label);
$('#valBox').val(ui.item.value);
},
focus: function (event, ui) {
console.log('ui.item.label - focus', ui.item.label);
$('#txtBox').val(ui.item.label);
}
});
});
In your controller, you can access both values Request["label"], Request["value"]

Related

Add autocomplete input control as part of knockout view model

I have the following markup where any skills that exists as part of my view model are displayed. I have a button in my html that runs the self.create function in my view model to create a new item in the EmployeeSkillsArray IF the user decides to add a new skill. The input control below works as expected when the autocomplete portion is removed, however, my goal is to allow a user to begin typing a skill and if that skill exists allow them to select it from autocomplete. It is THIS autocomplete functionality that seems to be causing the issue within the EmployeeSkillsArray. I am able to see autocomplete working when an input control is placed OUTSIDE the array in my markup.
Is there a way to accomplish this goal of having an input control inside the foreach loop to display an item if it is in the array, otherwise allow the user to use autocomplete?
<tbody data-bind="foreach: EmployeeSkillsArray">
<tr>
<td class="col-xs-2">
<input type="hidden" data-bind="value: EmployeeSkillId, visible: false" />
<div class="input-group">
<input type="text" id="skillName" class="form-control" placeholder="Type a skill..." data-bind="value: SkillName, id: SkillsId, autoComplete: { selected: $root.selectedOption, options: $root.options }" /> <!-- corrected based on answer provided by f_martinez -->
</div>
</td>
</tr>
</tbody>
I am getting an Uncaught ReferenceError: Unable to process binding "autoComplete: function (){return { selected:selectedOption,options:options} }"
Message: selectedOption is not defined
I DO have selectionOption defined as part of my view model....
$(function () {
ko.bindingHandlers.autoComplete = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var settings = valueAccessor();
var selectedOption = settings.selected;
var options = settings.options;
var updateElementValueWithLabel = function (event, ui) {
event.preventDefault();
$(element).val(ui.item.label);
if(typeof ui.item !== "undefined") {
selectedOption(ui.item);
}
};
$(element).autocomplete({
source: options,
select: function (event, ui) {
updateElementValueWithLabel(event, ui);
},
focus: function (event, ui) {
updateElementValueWithLabel(event, ui);
},
change: function (event, ui) {
updateElementValueWithLabel(event, ui);
}
});
}
};
function ActivityViewModel() {
var self = this;
var remoteData;
$.ajax({
url: '#Url.Action("GetAllSkills", "EmployeeSkills")',
data: { },
async: false,
dataType: 'json',
type: 'GET',
contentType: "application/json; charset=utf-8",
success: function (data) {
remoteData = ($.map(data, function (item) {
return {
id: item.SkillId,
name: item.SkillName
};
}));
}
});
self.skills = remoteData;
self.selectedOption = ko.observable('');
self.options = ($.map(self.skills, function (element) {
return {
label: element.name,
value: element.id,
object: element
};
}));
var EmployeeSkill = {
EmployeeSkillId: self.EmployeeSkillId,
EmployeeId: self.EmployeeId,
SkillsId: self.SkillsId,
SkillName: self.SkillName,
SkillLevelId: self.SkillLevelId,
ApplicationUsed: self.ApplicationUsed,
selectedOption: self.selectedOption,
options: self.options
};
self.EmployeeSkill = ko.observable();
self.EmployeeSkillsArray = ko.observableArray();
$.ajax({
url: '#Url.Action("GetAllEmployeeSkills", "EmployeeSkills")',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON({ 'UserId' : employeeId, 'ActivityHistoryId' : activityHistoryId }),
success: function (data) {
self.EmployeeSkillsArray(data); // Put the response in ObservableArray
}
});
self.cloneRow = function () {
$.ajax({
url: '#Url.Action("AddSkill", "EmployeeSkills")',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.EmployeeSkillsArray.push(data);
}
}).fail(function (xhr, textStatus, err) {
alert(err);
});
}
}
var viewModel = new ActivityViewModel();
ko.applyBindings(viewModel);
});

how enable a button if entered text is valid for autocomplete function?

i have a textbox with autocomplete feature,and a button.I want to enable the button only when a value is selected from the autocomplete list.
how to do this?
Here is my autocomplete function:
<script type="text/javascript">
$(document).ready(function () {
$("#<%=xyz.ClientID %>").autocomplete({
source: function (request, response) {
$.ajax({
url: '<%=ResolveUrl("~/WebService.asmx/Get") %>',
data: "{ 'prefix': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function (item) {
return {
label: item.split('-')[0],
val: item.split('-')[1]
}
}))
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
select: function (e, i) {
$("#<%=abc.ClientID %>").val(i.item.val);
},
minLength: 0
}).bind('focus', function () { $(this).autocomplete("search"); });
});
</script>
In your select function add this:
select: function (e, i) {
$("#<%=abc.ClientID %>").val(i.item.val);
$("#buttonid").prop("disabled", true); // true disabled, false enabled
},
EDIT:
$("#buttonid").prop("disabled", false); // this put button enabled
JsFiddle - Example
For a plain button you'll want to set the the button as disabled when the document loads, e.g.
$(document).ready(function () {
$('#btn')[0].disabled = true;
...
and then enable it with the select function, e.g.
select: function (e, i) {
$("#<%=abc.ClientID %>").val(i.item.val);
$('#btn').disabled = false; // <-- enables button
},
Try This: The following will be called when you perform select (use keyboard to select, dont know about mouse select)
$( "#<%=xyz.ClientID %>"" ).on( "autocompleteselect", function( event, ui ) {
$("#buttonid").prop("disabled", false);
});

How to populate extra fields with jQuery autocomplete

I am passing complex JSON data to jQuery autocomplete plugin. And it is working fine so it shows the list of Products.
Now I want to get somehow Price that is already included into JSON data and when I select product from autocomlete list I would like to populate input tag with Price.
I really cannot get if it is possible to do. What I know that data is already in JSON but how to get it?
Any clue?
Here is JS for jQuery autocomplete plugin
function CreateAutocomplete() {
var inputsToProcess = $('[data-autocomplete]').each(function (index, element) {
var requestUrl = $(element).attr('data-action');
$(element).autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: requestUrl,
dataType: "json",
data: { query: request.term },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Name,
value: item.Name,
realValue: item.UID
};
}));
},
});
},
select: function (event, ui) {
var hiddenFieldName = $(this).attr('data-value-name');
$('#' + hiddenFieldName).val(ui.item.UID);
}
});
});
}
To make clear item.LastPrice has Price data.
And HTML
#Html.AutocompleteFor(x => x.ProductUID, Url.Action("AutocompleteProducts", "Requisition"), true, "Start typing Product name...", Model.Product.Name)
In your ui.item object you should be able to find the the Price property in there and then set the value in the select function.
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Name,
value: item.Name,
realValue: item.UID,
price: item.LastPrice // you might need to return the LastPrice here if it's not available in the ui object in the select function
};
}));
},
..
select: function (event, ui) {
var hiddenFieldName = $(this).attr('data-value-name'),
unitPriceEl = $('#price');
$('#' + hiddenFieldName).val(ui.item.UID);
unitPriceEl.val(ui.item.LastPrice); //set the price here
}
Thanks to dcodesmith!!! I am gonna mark his solution like an answer but just in case I will share my final code that is working fine now.
function CreateAutocomplete() {
var inputsToProcess = $('[data-autocomplete]').each(function (index, element) {
var requestUrl = $(element).attr('data-action');
$(element).autocomplete({
minLength: 1,
source: function (request, response) {
$.ajax({
url: requestUrl,
dataType: "json",
data: { query: request.term },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Name,
value: item.Name,
realValue: item.UID,
lastPrice: item.LastPrice
};
}));
},
});
},
select: function (event, ui) {
var hiddenFieldName = $(this).attr('data-value-name');
$('#' + hiddenFieldName).val(ui.item.UID);
var unitPriceEl = $('#UnitPrice');
unitPriceEl.val(ui.item.lastPrice);
console.log(ui.item.lastPrice);
}
});
});
}

How to push the fetched autocomplete data from JSON API to a text box?

I am trying to fetch the values as Autocomplete jQuery method and store the selected input values into a text box (push to text box). Sounds easy but this JSON schema is kinda taking buzzy time.
Can I get a quick help here?
http://jsfiddle.net/ebPCq/1/
jQuery Code:
$("#material_number").autocomplete({
source: function (request, response) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
dataType: "json",
data: {
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function (data) {
response($.map(data.geonames, function (item) {
return {
// following property gets displayed in drop down
label: item.name + ", " + item.countryName,
// following property gets entered in the textbox
value: item.name,
// following property is added for our own use
my_description: item.fcodeName
}
}));
}
});
After fixing up and finalizing the initial functionality, I came upon conclusion with this fiddle as the solution to my query posted above.
http://jsfiddle.net/ebPCq/7/
JS Code:
$(function () {
$("#input").autocomplete({
source: function (request, response) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
dataType: "json",
data: {
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function (data) {
response($.map(data.geonames, function (item) {
return {
// following property gets displayed in drop down
label: item.name + ", " + item.countryName,
// following property gets entered in the textbox
value: item.name,
// following property is added for our own use
my_description: item.fcodeName
}
}));
}
});
},
minLength: 2,
select: function (event, ui) {
if (ui.item) {
$("#push-input").prepend(ui.item.value + '\r\n');
}
}
});
});

Tag it submit id not value or label

using this plugin
https://github.com/aehlke/tag-it
its very cool by the way.
problem:
<input type="hidden" name="tags" id="mySingleField" value="Apple, Orange" disabled="true">
Tags:<br>
<ul id="mytags"></ul>
<script type="text/javascript">
$(document).ready(function () {
$("#mytags").tagit({
singleField: true,
singleFieldNode: $('#mySingleField'),
allowSpaces: true,
minLength: 2,
removeConfirmation: true,
tagSource: function (request, response) {
//console.log("1");
$.ajax({
url: "../City/GetList",
data: { term: request.term },
dataType: "json",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.label + " (" + item.id + ")",
value: item.value
}
}));
}
});
}
});
});
</script>
When tag it selects the values it adds values to the hidden field in CSV format in value attr. i want it to do ID instead anyone know how to ?
A couple of things here. You can set the delimeter instead of a CSV to anything by setting the parameter as such say to an underscore:
$("#mytags").tagit({
...
singleFieldDelimiter: '_',
...
Then you can modify the tag-it.js file on line 197 to say use the ID attribute.
Change:
var tags = node.val().split(this.options.singleFieldDelimiter);
To be
var tags = node.attr("id").split(this.options.singleFieldDelimiter);
So let's say that you modified the hidden field to be:
<input type="hidden" name="tags" class="mySingleField" id="Apple_Orange_Banana" value="Apple_Orange" disabled="true">
You would modify the javascript as such to get the desired output:
$(document).ready(function () {
$("#mytags").tagit({
singleField: true,
singleFieldNode: $('.mySingleField'),
singleFieldDelimiter: '_',
allowSpaces: true,
minLength: 2,
removeConfirmation: true,
tagSource: function (request, response) {
//console.log("1");
$.ajax({
url: "../City/GetList",
data: { term: request.term },
dataType: "json",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.label + " (" + item.id + ")",
value: item.value
}
}));
}
});
}
});
});
Change the tag-it.js file
Comment from line 264
// that.createTag(that._cleanedInput());
// The autocomplete doesn't close automatically when TAB is pressed.
// So let's ensure that it closes.
// that.tagInput.autocomplete('close');
around line 285
var autocompleteOptions = {
select: function(event, ui) {
that.createTag(ui.item);
Create a new function
assignedTagsData: function(){
// Only to be used when singleField option is not seleted
var tags = [];
this.tagList.children('.tagit-choice').each(function() {
tags.push($(this).data('tag_item_data') );
});
return tags;
}
that.createTag(ui.item);
Create tag
var tag = $('<li></li>')
.data('tag_item_data',item) //add this line
.addClass('tagit-choice ui-widget-content ui-state-default ui-corner-all')
.addClass(additionalClass)
.append(label);

Categories