Angular UI typeahead startswith - javascript

I have a problem with typeahead. I have a field with name and surname of a person, If I type A I would like to see the focus on the surname and not on the leading character that is the name.
this is an example:
function TypeaheadCtrl($scope) {
$scope.selected = undefined;
$scope.Person = ['Jane Smith', 'John Smith', 'Sam Smith', 'John Doe','Daniel Doe'];
}
When I type S i Would like to see only jane smith and john smith. There's a way to do this??
plunker: http://plnkr.co/edit/inwmqYCCRsjs1G91Sa3Q?p=preview

I assume you would want each of the listed items found in the sourceArray to have the search term highlighted only for the surname. That is not possible without modifying the directive itself, but I have an alternate solution that, although it also highlights the search term in the first name (if matched), ONLY presents results for persons with a surname matched by the search term. I hope this helps:
angular.module("firstChar", ["ui.bootstrap"]);
angular.module("firstChar").controller("TypeaheadCtrl", function($scope, $filter) {
$scope.selected = undefined;
// ==========================================================
// You would have to replace the JSON assignment code below
// with a call to $http.get, to get that file you talked
// about in your comment below:
//
// $http.get('OutAnagrafica.json').success(function (data) {
// $scope.OutAnagrafica = data;
// });
//
// ==========================================================
$scope.OutAnagrafica = [
{
"Name": "Jane Smith"
},
{
"Name": "John Smith"
},
{
"Name": "Sam Smith"
},
{
"Name": "Sam Northrop"
},
{
"Name": "John Doe"
},
{
"Name": "Daniel Doe"
}
];
$scope.persons = $scope.OutAnagrafica.map(function (person) {
var nameParts = person.Name.split(" "),
name = nameParts[0],
surname = nameParts.slice(1).join(" ");
return {
"name": name,
"surname": surname
};
});
$scope.getPersonsFromSurnames = function(searchTerm) {
return $filter("filter")($scope.persons.map(function (person) {
return {
"fullname": person.name + " " + person.surname,
"surname": person.surname
};
}), {
"surname": searchTerm
});
}
});
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.0/ui-bootstrap-tpls.min.js"></script>
<div ng-app="firstChar">
<div class="container-fluid" ng-controller="TypeaheadCtrl">
<div>Selected: <span>{{selected}}</span>
</div>
<div>
<input type="text" ng-model="selected" typeahead="person.fullname for person in getPersonsFromSurnames($viewValue)">
</div>
</div>
</div>

From http://angular-ui.github.io/bootstrap/#/typeahead,
looking at this particular line
<input type="text" ng-model="asyncSelected" placeholder="Locations loaded via $http" typeahead="address for address in getLocation($viewValue)" typeahead-loading="loadingLocations" class="form-control">
You can probably do something like
<input type="text" ng-model="selected" typeahead="name for name in getPersonLastName($viewValue)">
Meaning that you have a getPersonLastName function that looks into $scope.Person and returns names that matches the surname with the $viewValue.

Related

Javascript autocomplete with different input field value

I have the following javascript that autocompletes based on a users display name. Problem is that the autocomplete input field is the display name. Each user actually has a user id, but I want to look up the user in the autocomplete based on the display name but when I submit the form I want to submit the user ID itself.
<script>
$(document).ready(function() {
$("input#autocomplete").autocomplete({
source: [
"John Doe",
"Another User",
]
});
});
</script>
<input id="autocomplete" name="autocomplete"/>
Can anyone suggest how i can do this? Ideally in the source, is there a way to have the user ID as the value too and somehow have the user ID submitted but with display name?
instead of using just an array you could use object inside the array so you can still do your search for matching display name and return the user id
instead of:
source: [
"John Doe",
"Another User",
]
you can do:
var sourceValues = [
{label: "John Doe", value: 1},
{label: "Another User", value: 2},
]
$("#autocomplete").autocomplete({
source: sourceValues.map(lang=>lang.label),
});
Consider the following example.
$(function() {
$("#user_name").autocomplete({
source: [{
label: "John Doe",
value: 1001
}, {
label: "Jonny Appleseed",
value: 1002
},{
label: "Jane Doe",
value: 1003
}],
select: function(e, ui) {
$("#user_name").val(ui.item.label);
$("#user_id").val(ui.item.value);
return false;
}
});
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<div>Name: <input id="user_name" /></div>
<div>ID: <input type="text" id="user_id" /></div>
This is based on this example: https://jqueryui.com/autocomplete/#custom-data
If you define a more complex source, you can make use of it in the select callback. ui.item represents the object selected. It has a label and value that you can put in various fields.

Show the second value based on the first one in Angularjs

I have a list on ng-repeat with names. I want to take this name and pass to url as parameter to take his subjects. What i have done until now is that i can pass the name and get the subjects from another API. But the problem is that the last name replaces all the dropdowns with his values:
<ul ng-repeat="person in persons">
<li ng-init="pass(person.name)">{{person.name}}</li>
<li>
<select>
<option ng-repeat="(key, value) in choices">{{value}}</option>
</select>
</li>
</ul>
Controller.js
$scope.person = {
[
{
"id": 1,
"name": "Mark"
},
{
"id": 2,
"name": "Jakob"
}
]
}
$scope.pass = function(name) {
$scope.name = name;
$http.get('url?name=' + $scope.name, {})
.then(function(response) {
$scope.choices = response.data;
},
function(errResponse) {
console.error('Error while fetching choices');
});
}
Note: There is a get method to pass the person.name at the end of the URL.
How can it be isolated to pass from HTML to controller.
Thanks
Make your controller code like:
$scope.persons = [{
"id": 1,
"name": "Mark"
},
{
"id": 2,
"name": "Jakob"
}
];
$scope.pass = function(person) {
$scope.name = person.name;
$http.get('url?name=' + $scope.name, {}).then(function(response) {
person.choices = response.data;
},
function(errResponse) {
console.error('Error while fetching choices');
});
}
And your html like:
<ul ng-repeat="person in persons">
<li ng-init="pass(person)">{{person.name}}</li>
<li><select>
<option ng-repeat="(key, value) in person.choices">{{value}}</option>
</select></li>
</ul>
Here's a sample fiddle: https://jsfiddle.net/Lt7aP/4019/

Javascript error trying to perform a search filter using Angular JS

In my app Im trying perform a search filter on names by partial match from the beginning. Heres an example of what Im trying to do:
Lets say I have a list of names:
Ben
James
Adam
Judy
Andy
and enter the text "a" in my search field, it would return
Adam
Andy
if I further enter "an" in my search field, it would return
Andy
In my app.js, I have the code:
var myApp = angular.module("myApp", []);
myApp.controller("myController", function ($scope) {
var employees = [
{ name: "Ben", gender: "Male", salary: 55000, city: "London" },
{ name: "Jane", gender: "Female", salary: 62000, city: "Albany" },
{ name: "Rick", gender: "Male", salary: 65000, city: "Los Angeles" },
{ name: "Pam", gender: "Female", salary: 60000, city: "Paris" },
{ name: "Josh", gender: "Male", salary: 68000, city: "Brussels" },
];
$scope.employees = employees;
$scope.filtered = function (item) {
if ($scope.searchName == undefined) {
return true;
} else {
if (item.name.toLowerCase().startsWith($scope.searchName.toLowerCase()) != -1) {
return true;
}
}
return false;
}
});
And in my html page, I have the following line which displays the list of employees:
<tr ng-repeat="employee in employees | filter: filtered">
And the following line which the user inputs the search text:
<input type="text" placeholder="Search Name" ng-model="searchName.name"> <br><br>
However, when I attempt to test this, I get the error:
Error: $scope.searchName.toLowerCase is not a function. (In '$scope.searchName.toLowerCase()', '$scope.searchName.toLowerCase' is undefined)
As your ng-model is set to searchName.name, $scope.searchNameis an object, therefore it has no .toLowerCase() function.
You need to adjust your if-case like this:
if (item.name.toLowerCase().startsWith($scope.searchName.name.toLowerCase()) !== -1) {}
Furthermore, it is advisable to use identity operators instead of equality operators, unless strict identity is explicitly not needed.
The ng-model is set to searchName.name, so you may need to call on $scope.searchName.name.toLowerCase() instead of $scope.searchName.toLowerCase()

AngularJS Autocomplete not showing options

My Angular autocomplete is using an object array and returning the correct result list. I can access the variables and map them to name and id field, but once I do this my drop down selector won't display text.
Here is the fiddle I started with and works correctly: http://fiddle.jshell.net/59nq55rf/
Here is the fiddle using the array and fails to display text in the drop down:
http://fiddle.jshell.net/ua1r8kjv/
$(function () {
var categoryList = [
{ "CategoryName": "Groceries", "CategoryID": "1" },
{ "CategoryName": "Games", "CategoryID": "2" },
{ "CategoryName": "Gadgets", "CategoryID": "3" },
]
$("#Category").autocomplete({
source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
var matching = $.grep(categoryList, function (value) {
var name = value.CategoryName;
var id = value.CategoryID;
return matcher.test(name) || matcher.test(id);
});
response(matching);
}
});
});
HTML
<div class="ui-widget">
<form>
<label for="txtEmployeeName">Developer:</label>
<input id="Category" />
</form>
</div>
It definitively has to do with the jQuery UI library. It seems that it is expecting the property names to be exactly "value" and "id", anything else will not work. Run the code snippet below and test it with the letter 'g' to see for yourself. The result will correctly show 3 but fail to display the ones with the incorrect property names.
$(function () {
var categoryList = [
{ "value": "Groceries", "id": "1" },
{ "categoryname": "Games", "categoryid": "2" },
{ "doIwork": "Gadgets", "doIworkId": "3" },
]
$("#Category").autocomplete({
source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
var matching = $.grep(categoryList, function (value) {
var name = value.categoryname || value.doIwork || value.value;
var id = value.categoryid || value.doIworkId || value.id;
return matcher.test(name) || matcher.test(id);
});
response(matching);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<div class="ui-widget">
<form>
<label for="txtEmployeeName">Developer:</label>
<input id="Category" />
</form>
</div>
This is my custom solution for the answer posed above by #Urielzen
_CustomPair[] pairList = new _CustomPair[length];
private class _CustomPair
{
public string value;
public string id;
public _CustomPair(string curval, string curid)
{
value = curval;
id = curid;
}
}

angularjs - select with object of object as options

I'm currently trying to build a AngularJS app with a complex data structure.
The data source is an array of people with languages and skill level.
I need to filter those people by language skill, to do so I tried to build a select with the languages and another select with the skill levels, but i failed.
Here is a plnkr of my effords
Maybe there is also a simpler/better way to structure the data array ($scope.people)
Take a look at this
Working Demo
Html
<div ng-app='myApp' ng-controller="MainCtrl">LANGUAGES:
<select ng-model="selectLang" ng-options="lang as lang for lang in languages"></select>
<br>SKILL:
<select ng-model="selectSkill" ng-options="skill as skill for skill in skills"></select>
<br>
<button ng-click="getPeople()">Submit</button>
<br>PEOPLE:
<select ng-model="selectPeoples" ng-options="people as people for people in peoples"></select>
</div>
script
var app = angular.module('myApp', []);
app.controller('MainCtrl', function ($scope) {
$scope.people = [{
"name": "Jane Doe",
"gender": "Female",
"languages": [{
"lang": "German",
"skill": "Good"
}, {
"lang": "English",
"skill": "Very Good"
}]
}, {
"name": "John Doe",
"gender": "Male",
"languages": [{
"lang": "French",
"skill": "Good"
}, {
"lang": "English",
"skill": "Very Good"
}]
}];
$scope.languages = [];
$scope.skills = [];
angular.forEach($scope.people, function (peopleValue, peopleKey) {
angular.forEach(peopleValue.languages, function (langValue, langKey) {
$scope.languages.push(langValue.lang);
$scope.skills.push(langValue.skill);
});
});
$scope.languages = _.uniq($scope.languages);
$scope.skills = _.uniq($scope.skills);
$scope.getPeople = function () {
$scope.peoples = [];
angular.forEach($scope.people, function (peopleValue, peopleKey) {
angular.forEach(peopleValue.languages, function (langValue, langKey) {
if (langValue.lang === $scope.selectLang && langValue.skill === $scope.selectSkill) {
$scope.peoples.push(peopleValue.name);
}
});
});
}
});
Your problem is that you're not actually looping through each person's languages array in your ng-options directive. And I don't believe such a thing is actually possible given how your data is structured. I don't think you can loop through nested arrays (or at least I'm not aware of any ng-options syntax that would allow for such a thing.
So to make things easier, I would suggest doing the following in your controller:
$scope.langs = [];
angular.forEach($scope.people, function(person){
angular.forEach(person.languages, function(lang){
$scope.langs.push({
lang: lang.lang,
skill: lang.skill,
name: person.name,
gender: person.gender
});
});
});
This will give you an array that will allow you to filter using ng-options with the `orderBy' filter.

Categories