Search by name and family but display account number in jquery autocomplete - javascript

I'm working on a piece of code which has used jquery ui autocomplete component in order filter searched items. I have to configure it in order to be available to search based on multi ple factors, here is my sample search array:
var availableTags = [{
name: "Smith",
family: "Johnson",
account_number: "10032",
nick_name: "Friend account",
}, {
name: "Susan",
family: "Rice",
account_number: "343243",
nick_name: "Mom Account",
}, {
name: "Joe",
family: "Austin",
account_number: "3434",
nick_name: "Partner Account",
}, {
}];
the auto complete should display name, family, account number and nick_name when displaying the suggestion box. but when each item is selected only the account_number must be inserted into the text box. user must also be able to search through name, family, account number and nick name all of them. How can i achieve this target?

You need to:
Revise the data array to contain the value parameter (this allows autocomplete to fill the input upon focus/select)
Write a custom source function that filters the data based on what user has typed
Write a custom _renderItem function that displays the data formatted to your liking
So you have:
var userData = [{
name: "Smith",
family: "Johnson",
value: "10032",
nick_name: "Friend account"
}, {
name: "Susan",
family: "Rice",
value: "343243",
nick_name: "Mom Account"
}, {
name: "Joe",
family: "Austin",
value: "3434",
nick_name: "Partner Account"
}];
$("#autocomplete").autocomplete({
source: function (request, response) {
var search = $.trim(request.term.toLowerCase());
var array = $.grep(userData, function (val) {
return
val.name.toLowerCase().indexOf(search) >= 0 ||
val.family.toLowerCase().indexOf(search) >= 0 ||
val.value.toLowerCase().indexOf(search) >= 0 ||
val.nick_name.toLowerCase().indexOf(search) >= 0;
});
response(array);
}
})
.data("ui-autocomplete")._renderItem = function (ul, item) {
var $a = $("<a></a>").text(item.name + " " + item.family);
$("<br />").appendTo($a);
$("<small></small>").text(item.nick_name).appendTo($a);
$("<br />").appendTo($a);
$("<small></small>").text(item.value).appendTo($a);
return $("<li></li>").append($a).appendTo(ul);
};
Demo here

Related

How to create a List Render JSON from a Dynamic List for an API response in Vue?

I am a beginner in at Vue.js version 2.6.11.
I have a form where a person can add a list of toys. So the list is dynamic. How do we add this dynamic list into a JSON data structure in a POST request?
I cannot change the API.
For example the first list to send to a POST request might be
"toyCollection":
[
{
"toyName": "yo-yo",
"toyDescription": "ball on a string",
"toyAge": 15,
"company": {
"companyName": "yo yo company"
"companyYear": "1999"
}
}
]
The second time someone creates a list of toys in this dynamic list might be
"toyCollection":
[
{
"toyName": "yo-yo",
"toyDescription": "ball on a string",
"toyAge": 15,
"company": {
"companyName": "yo yo company"
"companyYear": "1999"
}
},
{
"toyName": "barbie",
"toyDescription": "dolls in a house",
"toyAge": 21,
"company": {
"companyName": "mattel"
"companyYear": "1959"
}
},
{
"toyName": "transformers",
"toyDescription": "robots in disguise",
"toyAge": 20,
"company": {
"companyName": "Hasbro"
"companyYear": "1984"
}
}
]
How do we write this in Vue so that this is dynamic?
methods: {
const postRequest = {
toyCollection: [ //if 1 toy in list
{
toyName: "yo-yo", // this.form.toyName <---- would read the data
toyDescription: "ball on a string", //hardcoded here for simplicity for example
toyAge: 15,
company: {
companyName: "yo yo company"
similarToysFromCompany: "1999"
}
}
]
}
}
If there are three toys in the collection
methods: {
const postRequest = {
toyCollection: [ //if 3 toys in list
{
toyName: "yo-yo",
toyDescription: "ball on a string",
toyAge: 15,
company: {
companyName: "yo yo company"
similarToysFromCompany: "1999"
}
},
{
toyName: "barbie",
toyDescription: "dolls in a house",
toyAge: 21,
company: {
companyName: "mattel"
companyYear: "1959"
}
},
{
toyName: "transformers",
toyDescription: "robots in disguise",
toyAge: 20,
company: {
companyName: "Hasbro"
companyYear: "1984"
}
}
]
}
}
The list can be any size, depending on how many toys a person adds to this list.
How do we make this dynamic based on the list?
Then I would call my API with this object
this.methodCallToAPI(postRequest);
Thanks for any help!
==============
EDIT
I have a template to input fields
<form>
<!-- Name -->
<input
v-model="form.toyName"
id="toy-name"
class="input"
type="text"
/>
</div>
</form>
Then in the Script, it watches or updates the data fields based on what the user types into the input text fields.
export default {
name: "CreateToyCollection",
data () {
return {
form: {
toyName: "",
toyDescription: "",
toyAge: "",
company: {
companyName: "",
similarToysFromCompany: ""
}
}
}
},
watch: {
this.form.toyName = "";
this.form.toyDescription = "";
this.form.toyAge = "";
// etc for Company
}
}
I'm working on the list part, but this is how I want to pass in the dynamic data
In the data add a new array toyCollection :
data () {
return {
toyCollection: [],
form: {
toyName: "",
...
},
...
Every time form is submitted, push the submitted data to it like this.toyCollection.push(data)
Later in your post request you can send this.toyCollection as the payload.

JavaScript array filtering based on any combination of properties

I have array like this.
[{
id: 1,
name: 'Stephen',
Team: {
name: 'Lion',
color: 'blue'
},
skills: ['allrounder', 'middleorder']
}, {
id: 2,
name: 'Daniel',
Team: {
name: 'Panther',
color: 'green'
},
skills: ['batsman', 'opener']
}, {
id: 3,
name: 'Mark',
Team: {
name: 'Lion',
color: 'blue'
},
skills: ['bowler', 'fielder']
}]
I am providing search facility on every field.
Name: inputbox
Team name: dopdownlist (to select team name)
Team color: dropdownlist (to select team color)
Skills: checkboxes
User can provide only Name field and click on Search , or can use multiple options like only skills or combination of any of input.
What is best way to filter an array based on these conditions.
e.g.
myArr.filter(item => item.Name.toLowerCase().startsWith(searchData.name.toLowerCase())
&& / || item.skills.include(searchData.skillsArr)
Expected output is based on any single or combination of input provided.
You could write a function using filter like this:
Check if there is value in name parameter. If yes, check if the name property of the array object includes the name
If not, check for teamName and color parameter in a similar way
Then check for an array of selected skills. Check if some of the skills are included in the object's skills array property
const input=[{id:1,name:'Stephen',Team:{name:'Lion',color:'blue'},skills:['allrounder','middleorder']},{id:2,name:'Daniel',Team:{name:'Panther',color:'green'},skills:['batsman','opener']},{id:3,name:'Mark',Team:{name:'Lion',color:'blue'},skills:['bowler','fielder']}]
function filter(array, name, teamName, color, skills) {
return array.filter(a =>
(!name || a.name.toLowerCase().includes(name.toLowerCase())) &&
(!teamName || a.Team.name.toLowerCase().includes(teamName.toLowerCase())) &&
(!color || a.Team.color.toLowerCase().includes(color.toLowerCase())) &&
(!skills || skills.length === 0 || skills.some(s => a.skills.includes(s)))
)
}
console.log(filter(input, "Mark"))
console.log(filter(input, null, "Panther"))
console.log(filter(input, null, null, "blue", ["bowler"]))

html5 mustache get the index of article and compare the value

I have a mustache file, and I am iterating over the array:
var data = {
sales: [
{
name: "Jim Frost",
region: "USA East",
phone: "212-555-1212",
email: "jfrost#acme-travel.com"
},
{
name: "Jan Smith",
region: "USA West",
phone: "310-555-1212",
},
{
name: "Fred Wesley",
phone: "608-555-1212",
email: "fwesley#acme-travel.com"
},
{
name: "Lisa Moore",
region: "USA South",
phone: "315-555-1212",
email: "lmoore#acme-travel.com"
},
{
name: "Jim Dio",
phone: "+ 44 022-555-1212",
email: "jdio#acme-travel.com"
},
{
name: "Charles Watts",
region: "Spain",
email: "cwatts#acme-travel.com"
},
{
name: "Bert Cooper",
region: "Italy",
email: "bcooper#acme-travel.com"
}
]
};
here is the markup:
<div>
<section>
{{#data.sales}}
<article class="items">
<div class="region">{{{region}}}</div>
</article>
{{/data.sales}}
</section>
</div>
I want to add some special style (like, bold font, color etc) ONLY if the region is USA East.
how can i detect inside this inherent loop in the article element if {{{region}} has a specific value? Given that the comparison will be made against a value that i get from backend, say {{myValue}}, which is manually set to USA East in the backend.
You can add a function in the data which will return the correct class depending on the region value. Something like
data['regionClass'] = function(){
if ( this['region'] == 'USA East' ) {
return "strong green";
}else{
return "";
}
}
And then in the Mustache you can do: <div class="region {{regionClass}}">{{{region}}}</div>

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()

How to add array items in javascript?

In a wordpress plugin, there is a field box called 'data' where I can add code for it to pull, below in the code where it says 'data =' that is me referencing the box. In the box:
What I put in the field box entitled 'data':
{
contacts: [
{ name: "Name 1", email: "email1#test.com" },
{ name: "Name 2", email: "email2#test.com" }
]
};
This is what I put in the global field box, for it to apply to everything.
function (jQueryPopoverObj, mapObject, mapsvgInstance) {
// "this" = clicked mapObject
if(this.mapsvg_type == "region"){
return '<b>'+this.id+'</b>' +
this.data.contacts.map(function(contact) {
return contact.name + '<br>' +
'' + contact.email + ''
}).join('<br>');
} else if (this.mapsvg_type == "marker"){
return 'Marker - <b>'+this.id+'</b>, contact: '+this.data.email;
}
}
I want to also add { seat: "County Seat"} to the data portion and add it in the function.
I tried adding a line in the contacts, and then adding + '<br>' + contact.seat, after return contact.name, with no luck. Basically when it does the popover (which it pulls from global function for the template and the information from the data field box), I want it to have the CountySeat under the County Name (e.g. the County Seat for Harris County is Houston, so it would have Houston under Harris County).
Example of Lubbock County without the City name under it
var data = {
contacts: [
{ name: "Name 1", email: "email1#test.com" },
{ name: "Name 2", email: "email2#test.com" }
]
}
To add a new property seat you can simply do this-
data["seat"] = "County Seat"
or
data.seat = "County Seat"
JSFiddle
It looks like you want to set the seat assignment on the contact? You'd have to get the contact from the array, looping through each one and figuring out the one you want to use, then do contact.seat = "XYZ", which will add a seat property to the contact object. You can then use contact.seat in the string output but you have to null check it because it may be null. To help with that, I'd recommend defaulting it to an empty string like:
data = {
contacts: [
{ name: "Name 1", email: "email1#test.com", seat: "" },
{ name: "Name 2", email: "email2#test.com", seat: "" }
]
}
And then change it when it is assigned.

Categories