Jquery Autocomplete error menuselect and menufocus cannot read property value undefined - jquery-ui

$('.searchName').autocomplete({
source: function(req, res){
$.ajax({
url: "{{ route('airportSearch') }}",
dataType: "json",
type: "GET",
data: req,
beforeSend: function() {
$('#iconMaps').hide();
$('#loadingMaps').show();
},
success: function (data){
$('#iconMaps').show();
$('#loadingMaps').hide();
res(data);
console.log(data)
},
error: function(err){
$('#iconMaps').show();
$('#loadingMaps').hide();
}
});
}
}).data('ui-autocomplete')._renderItem = function(ul, item) {
return $('<li>')
.data('ui-autocomplete', item)
.append('<span><b>' + item.label + '</b></span><br><span>' + item.value + '</span>')
.appendTo(ul);
}
this my code, i have problem if selected list have error:
Cannot read property 'value' of undefined.
How to resolve this error?

I had a similar issue after updating JQuery version and fixed it applying few changes in data(), like bellow:
.data('uiAutocomplete')._renderItem = function(ul, item) {
return $('<li>')
.data('ui-autocomplete-item', item)
.append('<span><b>' + item.label + '</b></span><br><span>' + item.value + '</span>')
.appendTo(ul);

Related

Autocomplete not showing suggestion list when triggered second time

I have autocomplete with two sources. When an item is selected after search from first source, if certain conditions are met, the second search is forced. This brings back results - I can see them writing into console but the list of suggestions will not show up unless "keypress" is made. I tried to automate this with forcing the .ui-list to show and with forcing "keypress" events but to no avail... has anybody got any experience and advice on this? Thanks.
$(document).ready(function () {
var stopSearch = false;
var sel = "";
var finished = false;
$('#txtLiveDept').autocomplete({
source: function (request, response) {
console.log("stopSearch" + stopSearch);
if (stopSearch == false) {
console.log("first ajax");
$.ajax({
url: '/en-gb/LiveDepartures/CombinedAjax',
data: "{ inputTerm: '" + request.term + "'}",
//dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
autoFocus: true,
success: function (data) {
console.log(data.Locations);
console.log(data.ServiceResponses);
if (data)
var resp1 = data.Locations;
var resp2 = data.ServiceResponses;
var dataF = resp2.concat(resp1);
console.log(dataF);
response($.map(dataF, function (item) {
console.log("item" + item.FullText);
var label = "";
if (item.FullText == undefined) {
label = item.ServiceNumber + ", " + item.Description;
}
else {
label = item.FullText;
}
return {
Label: label,
FullText: item.FullText,
Category: item.Category,
Latitude: item.Latitude,
Longitude: item.Longitude,
value: label,
StopLabel: item.StopLabel,
ServiceId: item.ServiceId
}
}));
failure: function err(response) {
console.log("error: " + response.d);
}
},
});
}
else if (stopSearch == true) {
console.log("second ajax");
$.ajax({
url: '/en-gb/LiveDepartures/GetStops',
data: "{ serviceId: '" + sel + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
autoFocus: true,
success: function (data) {
if (data) {
response($.map(data, function (item) {
console.log("item" + item.Name + item.StopLabel);
$("#txtLiveDept").val("");
$(".ui-menu").show();
console.log("just before");
return {
label: item.Name + ", " + item.StopLabel,
FullText: item.FullText,
Category: item.Category,
Latitude: item.Latitude,
Longitude: item.Longitude,
value: item.Name + ", " + item.StopLabel,
StopLabel: item.StopLabel,
ServiceId: item.ServiceId
};
}));
}
},
});
}
},
select: function (e, selected) {
console.log("selected:" + selected.item.ServiceId);
if (selected.item.ServiceId != undefined) {
console.log("in third");
sel = selected.item.ServiceId;
var item = selected.item.ServiceId;
console.log("third item" + item);
stopSearch = true;
console.log("finished" + finished);
if (finished == false) {
$("#txtLiveDept").autocomplete("search", item);
}
else {
alert("hey");
}
}
},
minLength: 0
});
});
Please consider the following code.
$(function() {
var stopSearch = false;
var sel = "";
var finished = false;
function getCombined(q) {
var results;
$.ajax({
url: '/en-gb/LiveDepartures/CombinedAjax',
data: {
inputTerm: q
},
type: "POST",
contentType: "application/json; charset=utf-8",
success: function(data) {
console.log(data.Locations);
console.log(data.ServiceResponses);
if (data.length) {
var dataF = data.Locations.concat(data.ServiceResponses);
console.log(dataF);
results = $.map(dataF, function(item) {
console.log("item" + item.FullText);
var label = "";
if (item.FullText == undefined) {
label = item.ServiceNumber + ", " + item.Description;
} else {
label = item.FullText;
}
return {
Label: label,
FullText: item.FullText,
Category: item.Category,
Latitude: item.Latitude,
Longitude: item.Longitude,
value: label,
StopLabel: item.StopLabel,
ServiceId: item.ServiceId
}
});
}
},
failure: function err(response) {
console.log("error: " + response.d);
}
});
return results;
}
function getStops(q) {
var results;
$.ajax({
url: '/en-gb/LiveDepartures/GetStops',
data: {
serviceId: q
},
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function(data) {
if (data.length) {
results = $.map(data, function(item) {
console.log("item" + item.Name + item.StopLabel);
$("#txtLiveDept").val("");
$(".ui-menu").show();
console.log("just before");
return {
label: item.Name + ", " + item.StopLabel,
FullText: item.FullText,
Category: item.Category,
Latitude: item.Latitude,
Longitude: item.Longitude,
value: item.Name + ", " + item.StopLabel,
StopLabel: item.StopLabel,
ServiceId: item.ServiceId
};
});
}
}
});
return results;
}
$('#txtLiveDept').autocomplete({
autoFocus: true,
source: function(request, response) {
console.log("stopSearch", stopSearch);
if (stopSearch) {
console.log("second ajax");
response(getStops(sel));
} else {
console.log("first ajax");
response(getCombined(request.term));
}
},
select: function(e, selected) {
console.log("selected:" + selected.item.ServiceId);
if (selected.item.ServiceId != undefined) {
console.log("in third");
sel = selected.item.ServiceId;
var item = selected.item.ServiceId;
console.log("third item" + item);
stopSearch = true;
console.log("finished" + finished);
if (finished == false) {
$("#txtLiveDept").autocomplete("search", item);
} else {
alert("hey");
}
}
return false;
},
minLength: 0
});
$('#txtLiveDept').focus(function(){
$(this).autocomplete("search");
});
});

TFS 2017 Release Management: How to display parent PBI for Tasks under Release

Is there any way to show the parent PBI for a Task Work item under Release in the list under TFS2017?
The screenshot below shows two tasks associated with Release-3. Here I wish to be able to display the parent PBI for each of them. Either by expanding them or just by displaying an additional column with link to the parent PBI
I appreciate your help
Edit:
I know that that there is a possibility to create a query on TFS. The problem is that I need to display the information on the parent Work item that are related to a specific Release so the user can use them for reporting. I tried to to create a query for this purpose but I couldn't find a filtering option based on Release so I thought it might be possible to enable some additional columns or there might be an extension for that but I couldn't figure out how to do it..
The steps to achieve that with extension:
Get specify release to get build id
Get work items of that build per build id
Get related work items
There is simple code of extension to get work items of specific release that you can refer to:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Custom widget</title>
<meta charset="utf-8" />
<script src="node_modules/vss-web-extension-sdk/lib/VSS.SDK.js"></script>
<script type="text/javascript">
VSS.init({
explicitNotifyLoaded: true,
usePlatformStyles:true
});
VSS.require(["TFS/Dashboards/WidgetHelpers", "TFS/TestManagement/RestClient", "TFS/WorkItemTracking/RestClient", "TFS/Build/RestClient", "VSS/Service", "VSS/Identities/Contracts", "VSS/Identities/RestClient", "VSS/Authentication/Services"], function (WidgetHelpers, TFS_Test_WebApi, TFS_Work_WebApi, TFS_Build_Client, VSS_Service, idContracts, idRest, VSS_Auth_Service) {
WidgetHelpers.IncludeWidgetStyles();
VSS.register("WidgetStarain", function () {
var authHeader = "none";
var vstsAccount = "none";
var projectName = "none";
var releaseRestAPIPrex = "none"
var getReleaseWorkItems= function (widgetSettings) {
var c = VSS.getWebContext();
vstsAccount = c.account.name;
projectName = c.project.name;
releaseRestAPIPrex="https://" + vstsAccount + ".vsrm.visualstudio.com/DefaultCollection/" + projectName + "/_apis/release"
VSS.getAccessToken().then(function (token) {
authHeader = VSS_Auth_Service.authTokenManager.getAuthorizationHeader(token);
$.ajax({
type: 'GET',
url: releaseRestAPIPrex+'/definitions?api-version=3.0-preview.1',
cache: false,
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", authHeader);
},
}).done(function (data) {
var v = data.value;
$("#releaseDefList").empty();
$("#releaseDefList").append('<option value="select">select</option>');
$.each(v, function (index, value) {
$("#releaseDefList").append('<option value="' + value.id + '">' + value.name + '</option>');
});
}).error(function (e) {
var s = "ss";
});
});
};
$("#releaseDefList").change(function () {
var str = "";
$("#releaseList").empty();
$("#releaseList").append('<option value="select">select</option>');
$("#releaseDefList option:selected").each(function () {
var releaseDefId = $(this).val();
if (releaseDefId != "select") {
$.ajax({
type: 'GET',
url: releaseRestAPIPrex+'/releases?definitionId=' + releaseDefId + '&api-version=3.0-preview.2',
cache: false,
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", authHeader);
},
}).done(function (data) {
var v = data.value;
$.each(v, function (index, value) {
$("#releaseList").append('<option value="' + value.id + '">' + value.name + '</option>');
});
}).error(function (e) {
var s = "ss";
});
}
});
});
$("#releaseList").change(function () {
var str = "";
$("#releaseList option:selected").each(function () {
var releaseId = $(this).val();
if (releaseId != "select") {
$.ajax({
type: 'GET',
url: releaseRestAPIPrex+'/release/releases/' + releaseId + '?api-version=3.0-preview.2',
cache: false,
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", authHeader);
},
}).done(function (data) {
var artifacts = data.artifacts;
$.each(artifacts, function (index, value) {
var buildId = value.definitionReference.version.id;
TFS_Build_Client.getClient().getBuildWorkItemsRefs(projectName, buildId).then(function (workitemRefs) {
var workItemIds = new Array();
$.each(workitemRefs, function (index, value) {
workItemIds.push(value.id);
});
var workitemString = "";
TFS_Work_WebApi.getClient().getWorkItems(workItemIds,null,null,"All").then(function (workitems) {
$.each(workitems, function (index, value) {
workitemString += "ID: " + value.id + "; Title: " + value.fields["System.Title"];
});
$("#workitems").text(workitemString);
});
});
});
}).error(function (e) {
var s = "ss";
});
}
});
});
return {
load: function (widgetSettings) {
getReleaseWorkItems(widgetSettings);
return WidgetHelpers.WidgetStatusHelper.Success();
}
}
});
VSS.notifyLoadSucceeded();
});
</script>
</head>
<body>
<div class="widget">
<h2 class="title">widgets starain</h2>
<div class="token">none</div>
<select id="releaseDefList">
<option id="select">select</option>
</select>
<select id="releaseList">
<option id="select">select</option>
</select>
<div id="workitems">
none workitem
</div>
</div>
</body>
</html>
vss-extension.json:
{
"manifestVersion": 1,
"id": "sample-extension",
"version": "0.5.34",
"name": "My test extension",
"description": "my test extension description",
"publisher": "Starain",
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"icons": {
"default": "Images/logo.png"
},
"scopes": [
"vso.work",
"vso.build",
"vso.build_execute",
"vso.test",
"vso.test_write",
"vso.release"
],
"contributions": [
{
"id": "WidgetStarain",
"type": "ms.vss-dashboards-web.widget",
"targets": [ "ms.vss-dashboards-web.widget-catalog", "Starain.sample-extension.WidgetStarainConfiguration" ],
"properties": {
"name": "widget starain",
"description": "custom widget",
"catelogIconUrl": "Images/iconProperty.png",
"previewImageUrl": "Images/iconProperty.png",
"uri": "WidgetStarain.html",
"supportedSizes": [
{
"rowSpan": 1,
"columnSpan": 2
}
],
"supportedScopes": [ "project_team" ]
}
}
],
"files": [
{
"path": "node_modules/vss-web-extension-sdk/lib",
"addressable": true
},
{
"path": "Images",
"addressable": true
},
{
"path": "Scripts",
"addressable": true
},
{
"path": "WidgetStarain.html",
"addressable": true
}
]
}

How to avoid multiple ajax call from the Jquery Autocomplete ? Using Cache

I am using jquery automcomplete with the Ajax call but what i want is if part is present in the json data fetched by the ajax on first call then i want to return that data as it is without giving the ajax call i have tried it as below
function SearchText() {
var cache = {};
$("#txtItem").autocomplete({
source: function (request, response) {
var term = request.term;
$.each(cache, function (index, value) {
$.each(value, function (index, value) {
if (value.indexOf(term) >= 0) {
response(cache[term]);
return;
}
});
});
cache = {};
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "JobTagPricing.aspx/GetAutoCompleteData",
data: "{'item':'" + document.getElementById('txtItem').value + "'}",
dataType: "json",
success: function (data) {
cache[term] = data.d;
response(data.d);
},
error: function (result) {
alert("Error");
}
});
},
minLength: 3
});
}
but even if it finds the matching term in the array then also it generates the ajax call.
I m stuck here for 3 hrs now any help would be great. I have tried maxCacheLength but it is also not working.
Try this out, sometime ago i faced same problem and came up with this it might work for you
function SearchText() {
var cache = {};
var oldterm;
$("#txtItem").autocomplete({
source: function (request, response) {
if (request.term.indexOf(oldterm) >= 0) {
if (typeof (oldterm) != 'undefined') {
var data = jQuery.grep(cache[oldterm],
function (ele) {
return (ele.indexOf(request.term) >= 0);
});
response($.map(data, function (item) {
return { value: item }
}))
return;
}
} else {
cache = {};
$.ajax({
url: "JobTagPricing.aspx/GetAutoCompleteData",
data: "{ 'item': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
oldterm = request.term;
cache[request.term] = data.d;
response($.map(data.d, function (item) {
return {
value: item
}
}))
},
error: function (result) {
alert("Error");
}
});
}
},
minLength: 3,
select: function (event, ui) {
if (ui.item) {
formatAutoComplete(ui.item);
}
}
});
}
Here is a solution i found for you, It uses jQuery UI's autocomplete using cache and $.map function
function SearchText() {
var cache = {};
$("#textbox").autocomplete({
source: function(request, response) {
if (request.term in cache) {
response($.map(cache[request.term].d, function(item) {
return { value: item.value, id: item.id }
}))
return;
}
$.ajax({
url: "JobTagPricing.aspx/GetAutoCompleteData",
data: "{ 'term': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json",
dataFilter: function(data) { return data; },
success: function(data) {
cache[request.term] = data;
response($.map(data.d, function(item) {
return {
value: item.value,
id: item.id
}
}))
},
error: HandleAjaxError
});
},
minLength: 3,
select: function(event, ui) {
if (ui.item) {
formatAutoComplete(ui.item);
}
}
});
}
Hope this helps.

why jquery autocomplete doesnt work on https (secure pages)?

I am trying to make jquery autocomplete to be work on https (secured pages) pages but its not showing any dropdown.
I searched on this issue and found that its security issue.
can any one tell me how to turn on this autocomplete dropdown on https pages.
here is my code to jquery autocomplete :
function zipAutoCompletet(prefix) {
jQuery("#" + prefix + "_zip").autocomplete({
source: function (request, response) {
jQuery.ajax({
url: "http://ws.geonames.org/postalCodeSearchJSON",
dataType: "jsonp",
data: {
style: "full",
maxRows: 12,
postalcode_startsWith: request.term
},
success: function (data) {
response(jQuery.map(data.postalCodes, function (item) {
return {
label: item.placeName + (item.adminCode1 ? ", " + item.adminCode1 : "") + ", " + item.postalCode + ", " + item.countryCode,
value: item.postalCode
}
}));
jQuery('.ui-autocomplete').css('width', '188px');
}
});
},
minLength: 2,
select: function (event, ui) {
var myString = new String(ui.item.label);
var address = myString.split(',')
jQuery('#' + prefix + '_city').val(address[0]);
jQuery('#' + prefix + '_city').addClass('activated');
jQuery('#' + prefix + '_city').trigger('change');
jQuery('#' + prefix + '_city').parents('.row').removeClass('error-row')
jQuery('#' + prefix + '_city').parents('.row').addClass('ok-row')
var countryCode = address[3] ? address[3] : address[2]
countryCode = jQuery.trim(countryCode);
var countryName = jQuery('#' + prefix + '_country option[value="' + jQuery.trim(countryCode) + '"]').text()
jQuery('#countryContainer .jqTransformSelectWrapper span').html(countryName)
jQuery('#countryContainer .jqTransformSelectWrapper').addClass('selected-jqtranform');
jQuery('#' + prefix + '_country').parents('.row').addClass('ok-row')
jQuery('#' + prefix + '_country').parents('.row').removeClass('error-row')
jQuery('#' + prefix + '_country').val(jQuery.trim(countryCode))
var stateCode = address[2] ? address[1] : '';
stateCode = jQuery.trim(stateCode)
if (countryCode == 'US') {
var base = base_url;
base = base.replace("https", "http");
jQuery.ajax({
url: base + "/getStateName",
dataType: "jsonp",
data: {
stateCode: stateCode
},
success: function (data) {
stateName = data
jQuery('#jc_state').val(stateName);
jQuery('#jc_state').addClass('activated');
jQuery('#jc_state').parents('.row').removeClass('error-row')
jQuery('#jc_state').parents('.row').addClass('ok-row')
jQuery('#jc_state').trigger('change');
formValidate();
}
});
} else {
stateName = stateCode
jQuery('#jc_state').val(stateName);
jQuery('#jc_state').addClass('activated');
jQuery('#jc_state').parents('.row').removeClass('error-row')
jQuery('#jc_state').parents('.row').addClass('ok-row')
jQuery('#jc_state').trigger('change');
formValidate();
}
jQuery('#' + prefix + '_zip').parents('.row').addClass('ok-row')
jQuery('#' + prefix + '_zip').parents('.row').removeClass('error-row');
},
open: function () {
jQuery(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
jQuery(this).removeClass("ui-corner-top").addClass("ui-corner-all");
},
change: function (event, ui) {
if (ui.item === null) {
jQuery("#" + prefix + "_zip").parents('.row').removeClass('ok-row');
jQuery("#" + prefix + "_zip").parents('.row').addClass('error-row');
$("#" + prefix + "_zip").val('');
}
}
});
}
I am using above code for zipcode field.This code works fine on non-https pages it works fine but when I tried it with https pages it doesnt shows.
any solutions are welcome.
As I looked into the service provider they are supporting jsonp and the following sample worked
$("input").autocomplete({
source: function (request, response) {
$.getJSON("http://ws.geonames.org/postalCodeSearchJSON?callback=?",
{ 'postalcode_startsWith': request.term, maxRows: 12, style: "full" },
function(data) {
if(data.postalCodes){
var x = $.map(data.postalCodes, function(v, i){
console.log(v)
return {
label: v.placeName + ' - ' + v.postalCode,
v: v.postalCode
}
});
response(x);
}
}
);
}
});
Demo: Fiddle

jquery ajax to bind dropdownlist MVC

I have a 2 dropdownlist, I have to bind the 2nd one based on the Id I got from first dropdown. in the first dropdown I added OnChange event.
function onChange() {
var variantDropDown = $('#VariantName');
$.ajax({
url: '/Admin/CustomProductPinCodesManagement/GetProductVarinats',
type: 'post',
data: { productId: $("#ProductName").data("tDropDownList").value() },
success: function (data) {
$.each(variants, function (i, variant) {
$states.append('<option value="' + variant.Id + '">' + variant.Name + '</option>');
});
},
error: function () {
alert('Error');
}
});
}
and this is the c# code .
[HttpPost]
public ActionResult GetProductVarinats(string productId)
{
var variants = _productService.GetProductVariantsByProductId(Convert.ToInt32(productId));
return Json(new { Result = true, data = variants }, JsonRequestBehavior.AllowGet);
}
but it does not work.
Use val() instead of value()
Change statement
data: { productId: $("#ProductName").data("tDropDownList").value() }
to
data: { productId: $("#ProductName").data("tDropDownList").val() }
and the success should be like
success: function (data) {
//For getting list of variants, you should access it by `data.data.variants`
//because you will get your json object in data, and for getting the value `variants`
//you should capture the `data` property of returned json object like `data.data`
$.each(data.data.variants, function (i, variant) {
$states.append('<option value="' + variant.Id + '">'+ variant.Name + '</option>');
//you can try this also for creating options
//$states.append($('<option/>').text(variant.Name).attr('value',variant.Id));
});
}
so your function should look like :
function onChange() {
var variantDropDown = $('#VariantName');
$.ajax({
url: '/Admin/CustomProductPinCodesManagement/GetProductVarinats',
type : 'post',
data: { productId: $("#ProductName").data("tDropDownList").val() },
success: function (data) {
$.each(data.data.variants, function (i, variant) {
$states.append($('<option/>').text(variant.Name).attr('value',variant.Id));
});
},
error: function () {
alert('Error');
}
});
}
AcidMedia has a library called TTControls which uses Telerik and you can use the TTControls.LinkedDropDown control which solves this problem.

Resources