remove <strong> from text box - jquery-ui

I have implemented autocomplete using Jquery. I have also implemented highlighting the matching text. I am using <strong> tag in the high light function. When I go through the autocomplete dropdown one by one using keyboard arrows, the text where I am currently on, is displayed in the text box. When it displays, it displays with the <strong> tag. Any suggestions to remove the tag? I have given my code below.
<input type="text" id="institution-list"/>
<script type="text/javascript" language="javascript">
$(function () {
$("#institution-list").autocomplete({
source: function (request, response) {
$.ajax({
url: "/home/findinstitutions", type: "POST", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
success: function (data) {
response($.map(data, function (item) {
return { label: highlight(item.InstitutionName, request.term),
id: item.InstitutionId
};
}));
}
});
},
minLength: 3
})
.data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append($("<a></a>").html(item.label))
.appendTo(ul);
};
});
function highlight(s, t) {
var matcher = new RegExp("(" + $.ui.autocomplete.escapeRegex(t) + ")", "i");
return s.replace(matcher, "<strong>$1</strong>");
}
</script>

I think that the problem is that you're taking the label of your recently found data and render it as HTML, instead of plain text. Thus, instead of Berkeley, your autocomplete is showing <strong>Ber</strong>keley.
Try to parse it and remove any HTML tag before displaying it:
function sanitize(text){
var regex = /(<([^>]+)>)/ig;
return text.replace(regex, "");
}
.data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append($("<a></a>").html(sanitize(item.label)))
.appendTo(ul);
};
The regular expression was extracted from here: Remove HTML Tags in Javascript with Regex

Find below the solution I found for my problem
Existing code:
response($.map(data, function (item) {
return { label: highlight(item.InstitutionName, request.term),
id: item.InstitutionId
};
Solution:
response($.map(data, function (item) {
return { label: highlight(item.InstitutionName, request.term),
value: item.InstitutionName,
id: item.InstitutionId
};
The original code returned the label (which had embedded html tags) and no value. Since there was no value, the textbox used the label to display. Now, I explicitly assign the value of the text box with my text (without html tags) and that fixes my problem.
Here is the snapshot of how it appears now.

Related

Auto-complete doesn't work as expected

I tried to implement this in MVC 5 with jquery ui 1.10.2
#{
ViewBag.Title = "Home Page";
Layout = null;
}
<p>
Enter country name #Html.TextBox("Country")
<input type="submit" id="GetCustomers" value="Submit" />
</p>
<span id="rData"></span>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery-ui.js"></script>
#Styles.Render("~/Content/themes/base/css")
<script type="text/javascript">
$(document).ready(function () {
$("#Country").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Home/AutoCompleteCountry",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function(data) {
response($.map(data, function(item) {
return { label: item.Country, value: item.Country };
}));
}
});
}
});
})
</script>
the server side is
...
[HttpPost]
public JsonResult AutoCompleteCountry(string term)
{
// just something to return..
var list = new List<string>() { "option1", "option2", "option3"};
var result = (from r in list
select r);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
I have two issues
1. it open up drop down autocomplete with 3 dots but without the actual strings.
2. It has this annoying message of "3 results were found" - I'd like to eliminate it..
DO you have any idea how to face those two issues or neater way to implement it in MVC5?
The 3 bullet points and "3 results were found" is because you are missing the jQuery UI css file. That file will format a drop down that will look a lot better. You can customize how the dropdown looks with additional css.
Also, you are seeing 3 empty results because your JS is referencing item.Country ...
return { label: item.Country, value: item.Country };
But your server code is just sending 3 strings.
new List<string>() { "option1", "option2", "option3"};
To fix, change your JS to just reference the item (the string) ...
return { label: item, value: item};
OR, change your server code to send more complex objects
new List<Object>() { new { Country = "option1" }, new { Country = "option2" }, new { Country = "option3" } };
use return data in place of return { label: item.Country, value: item.Country };

select2 unable to search if data source is remote

I am using select2 select box to populate and show some server data. Most of it works fine as I am able to get the results and populate the combo box. But when I type in the search box, the selection doesn't narrow down the the closest match.
I found the problem was because the backend URL doesn't support searching based on the string provided, while select2 keeps making multiple search request to backend, based on user entered text. The legacy backend code returns results in one shot, which is populated into the combobox the first time.
My question is, how do I get the the select box to focus to the closest matching result, without making multiple Ajax calls. I want the search to happen in the results which are already fetched.
Thanx to anyone helping me out on this.
My ajax call is like below, if this helps...
select2: {
placeholder: 'Select Next Plan Id',
allowClear: true,
id: function (item) {
return item.id;
},
ajax: {
type: 'GET',
dataType: "jsonp",
url: "http://172.16.7.248:8480/app/gui?action=1&type=11",
data: function (term, page) {
return { search: term };
},
results: function (data, page) {
return { results: data.aaData };
},
success : function(data, status, xhr) {
var html = "<option value=''>None</option>";
$.each(data.aaData, function(i, item) {
html += "<option data=" + JSON.stringify(item.id) + " value=" + item.id + "'>" + item.id + "</option>";
});
$('#nextplanid').html(html);
self.prop('data-loaded', 'true');
},
error : function(data, status, xhr) {
}
},
formatResult: function (item) {
return item.id;
},
formatSelection: function (item) {
return item.id;
},
initSelection: function (element, callback) {
return $.get('/getText', { query: element.val() }, function (data) {
callback(data);
});
}
},

How to retain Angular model and watch when using JQuery UI plugin Selectize

Plunker: http://plnkr.co/edit/ElXFi2mo44VpLVsaooOJ
I am modifying a working web app to utilize a jQuery UI plugin called Selectize. Previously I had an input element bound to the controller and a watch placed on that variable. I added the required code to selectize the component which has undone my watch and binding because this plugin modifies the DOM elements and obscures my bound element with new elements.
I would prefer to stay with the angular watch rather than calling a method in selectize to watch the value.
Comment out lines 7-16 to see that the watch is called correctly on every input change.
<input id="itemQuery" type="text" placeholder="Search" class="form-control" ng-model="myValue">
And the script:
angular.module('Sample.controllers', [])
.controller('mainController', ['$scope',
function($scope) {
$scope.myValue="";
$('#itemQuery').selectize({
delimiter: ',',
persist: false,
create: function(input) {
return {
value: input,
text: input
}
}
});
$scope.$watch('myValue', function(newValue, oldValue) {
alert("Old value: " + oldValue + " New value: " + newValue);
});
}]);
angular.module('Sample', ['Sample.controllers']);
First thing you can do is avoid implicit DOM manipulation inside controller and write a directive for that instead.
Updated Demo
App.directive('sampleSelectivize', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.selectize({
delimiter: ',',
persist: false,
create: function(input) {
return {
value: input,
text: input
}
}
}).on('change', function(event) {
console.log($(this).val());
});
}
};
})
And apply it to your input
<input sample-selectivize id="itemQuery" />
If you've checked the documentation, there are different events can be helpful for you
https://github.com/brianreavis/selectize.js/blob/master/docs/events.md
Thanks to codef0rmer for pointing me in the right direction. The solution was to tell angular that the scope needed updating and to provide it with the new value for this components. The key part being that I needed to include require: '?ngModel' in my directive initializers and then angular provided it as the 4th parameter to the link function.
angular.module('Sample.controllers', [])
.controller('mainController', ['$scope',
function($scope) {
$scope.myValue = "";
$scope.$watch('myValue', function(newValue, oldValue) {
console.log("OldValue: " + oldValue + " New value: " + newValue);
});
}]).directive('sampleSelectivize', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
element.selectize({
delimiter: ',',
persist: false,
create: function(input) {
return {
value: input,
text: input
}
}
}).on('change', function(event) {
scope.$apply(applyChange);
});
function applyChange() {
ngModel.$setViewValue(element.context.value);
}
}
};
});
angular.module('Sample', ['Sample.controllers']);
I found this resource to be helpful though incomplete: http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController
Solution plunk http://plnkr.co/edit/ieqQRWBub8ZJ8zOdEhEs?p=preview
Note: It uses console.log rather than alert.

jquery event.preventDefault() issues with IE 8

In my jquery autocomplete select function, I need to use the event.preventDefault() method to prevent the default ui.item.value from populating the input text box the autocomplete is wired too. This works great in Chrome, however in IE 8 (which is in use by a majority of our users) the .preventDefault() line throws the following error:
Unexpected call to method or property access
Here is the jQuery for good measure. Does anyone know of a work-around for this method in IE 8?
var tempResults = [];
$(function () {
$('#DRMCompanyName').autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("compSearchByName", "AgentTransmission")',
type: 'GET',
dataType: 'json',
data: request,
success: function (data) {
tempResults = data;
response($.map(data, function (value, key) {
return {
label: value + " " + key,
value: key
};
}));
},
});
},
minLength: 2,
select: function (event, ui) {
event.preventDefault(); // <-Causing a problem in IE 8...
$('#DRMCompanyName').val(tempResults[ui.item.value]);
$('#DRMCompanyName').text(tempResults[ui.item.value]);
if ($('#DRMCompanyId').text() == '') {
$('#DRMCompanyId').val(ui.item.value);
$('#DRMCompanyId').text(ui.item.value);
}
}
});
});
You could use return false instead but as i said in comment: return false = event.preventDefault() + event.stopPropagation() But in your case, should fit your needs.

jQuery UI Autocomplete how to implement Must Match in existing setup?

I have the following code and am curious as how to force the input to match the contents of the autocomplete:
$("#foo").autocomplete({
source: function( request, response ) {
$.ajax({
url: "index.pl",
dataType: "json",
data: {
type: 'foo',
term: request.term
},
success: function( data ) {
response( $.map( data.items, function( item ) {
return {
value: item.id
}
}));
}
});
},
minLength: 1
});
Answering this question for the benefit of anyone who stumbles upon this problem in 2013(yeah right!)
$("#my_input").autocomplete({
source: '/get_data/',
change: function(event, ui) {
var source = $(this).val();
var temp = $(".ui-autocomplete li").map(function () { return $(this).text()}).get();
var found = $.inArray(source, temp);
if(found < 0) {
$(this).val(''); //this clears out the field if non-existing value in <select><options> is typed.
}
}
});
Explanation:
The map() method creates a jQuery object populated with whatever is returned from the function (in this case, the text content of each <li> element).
The get() method (when passed no argument) converts that jQuery object into an actual Array.
Here is the original link of where I saw the solution.
I hope this helps. Thanks!

Resources