I have an array and its data shows on a table. Live Code
Filter by date or by name are working well.
I write some more code to show "No Data Found" if users enter a name, which is not on the list, but somehow it doesn't work.
Is there any way to write a code which will show a result if users enter only last name or first name, that matches last names or first names on the list?
Please give a hand. Thanks!
HTML
<p>From: <input class="datepicker" id="dateFrom" type="text"> To: <input class="datepicker" id="dateTo" type="text"><button class="buttApply">APPLY</button></p>
Search by Name<input type="text" id="searchByName"><button type="button" id="byNamebutton">SEARCH</button><span id="errmsg"></span>
<div class="text"></div>
<table id="myTable" border="1" width="300" cellpadding="5">
</table>
JS
$( ".datepicker" ).datepicker();
var dateList =[
{
name: "Mike Jenson",
email: "mike_j#yesware.com",
phone: "9433550193",
joined: "05/23/2014",
},
{
name: "Jim Stevens",
email: "jim_s#yesware.com",
phone: "1299331944",
joined: "05/22/2014"
},
{
name: "Paul Smith",
email: "paul_s#yesware.com",
phone: "4351289654",
joined: "04/14/2014"
},
{
name: "Sarah Andrews",
email: "sarah_a#yesware.com",
phone: "1299332944",
joined: "03/15/2014"
},
{
name: "Edward O'Brien",
email: "edward_ob#yesware.com",
phone: "4782456897",
joined: "03/27/2014"
},
{
name: "Nicole Plano",
email: "nicole_p#yesware.com",
phone: "6657831564",
joined: "03/30/2013"
},
{
name: "Peter Min",
email: "peter_m#yesware.com",
phone: "8893923938",
joined: "01/07/2013"
},
{
name: "Aaron Jackson",
email: "aaron_j#yesware.com",
phone: "6174896315",
joined: "04/11/2014"
}
];
$('#byNamebutton').click(
function()
{
var Namefilter = dateList.filter(function(NameItem)
{
if(NameItem.name == $('#searchByName').val())
{
return NameItem.name == $('#searchByName').val();
}
else
{
$('#mytable').append('No data found!');
}
});
refreshTable(Namefilter);
}
);
$('.buttApply').click(
function()
{
var filtered = dateList.filter(function(item){
return item.joined >= $('#dateFrom').val() && item.joined <= $('#dateTo').val();
});
refreshTable(filtered);
}
);
function refreshTable(list){
$("#myTable").html("");
for (var i=0; i< list.length; i++)
{
var tr="<tr>";
var td1 = "<td>" + list[i]["name"] + "</td>";
var td2 = "<td>" + list[i]["email"] + "</td>";
var td3 = "<td>" + list[i]["phone"] + "</td>";
var td4 = "<td>" + list[i]["joined"] + "</td></tr>";
$('#myTable').append(tr+td1+td2+td3+td4);
}
}
refreshTable(dateList);
If you want your search by name to work by containing phrase and ignore case sensitive:
return NameItem.name.toLowerCase().indexOf($('#searchByName').val().toLowerCase()) != -1;
As for the no data found, you just need to include this in the end of your reFreshTable function:
if(list.length==0){
$('#myTable').html("No Data Found");
}
JSFiddle: https://jsfiddle.net/juvian/WWscZ/9/
I would also recommend If your data is not very large to change your $('#byNamebutton').click( for a $('#searchByName').keyup( to make it more responsive, as it filters as you type
For #1 add at line 91,
if ($('#myTable').html() == "") {
var tr="<tr>";
var td1 = "<td colspan=4>No Results Found</td></tr>";
$('#myTable').append(tr+td1);
}
This addresses your #2 question:
indexOf returns the position of the string in the other string. If not found, it will return -1:
On line 59, use this instead:
return NameItem.name.indexOf($('#searchByName').val()) > -1;
It will search for partial instead of entire matches. So if you search for "Mike" or "Jensen" it will return "Mike Jensen".
Related
I have an array as below:
var locations = [{
plot: "24-17",
address: "XYZ",
city: "Something",
pin: "24399",
phone: "041678993"
}, {
plot: "24-18",
address: "ABC",
city: "Something",
pin: "24398",
phone: "041678995"
}, {
plot: "24-19",
address: "DEF",
city: "Something",
pin: "24397",
phone: "041678994"
}];
Now, i want to loop through the array and display them int the below dom:
<div id="locations-grid">
<div id="di-locations">
<div id="plot"></div>
<div id="address"></div>
<div id="city"></div>
<div id="pin"></div>
<div id="phone"></div>
</div>
</div>
Each object in the array corresponds to one location. I want to display all the locations as different columns in a css grid.
I tried
locations.map((item)=>{
plot.innerHTML = item.plot;
address.innerHTML = item.address;
city.innerHTML = item.city;
pin.innerHTML = item.pin;
phone.innerHTML = item.phone;
});
But this displays only the last object in the array. This doesn't get me the 3 objects into 3 different columns of the grid.
Putting your structure in DIVS is not the right way use a TABLE instead of it (here with a header-row). You had to dynamical build the rows and cell of it because you don't know how many rows will be needed and it's much more structured.
First get the handler from your table with document.getElementById Than create for every row a new table-row TR and then iterate through your data. For each property of it create a new cell TD and add to it's innerHTML the value. Append the TD to your row TR with appendChild because the elemnts is till now not in the DOM. After you have done this for every property append the TR to the table. Now the tablerow will be presented in the table.
var locations = [{
plot: "24-17",
address: "XYZ",
city: "Something",
pin: "24399",
phone: "041678993"
}, {
plot: "24-18",
address: "ABC",
city: "Something",
pin: "24398",
phone: "041678995"
}, {
plot: "24-19",
address: "DEF",
city: "Something",
pin: "24397",
phone: "041678994"
}
];
let table = document.getElementById('di-locations');
locations.forEach(location => {
let tr = document.createElement('tr');
Object.entries(location).forEach(value => {
let td = document.createElement('td');
td.innerHTML= value;
tr.appendChild(td);
});
table.appendChild(tr);
});
td, th { border: 1px solid black; }
<div id="locations-grid">
<table id="di-locations">
<tr>
<th>plot</th>
<th>address</th>
<th>city</th>
<th>pin</th>
<th>phone</th>
</tr>
</table>
</div>
You can iterate over these location objects and append new grid items containing the location property data as you go. From your question it's a little unclear how exactly the result should look like, but this snippet gives you something to build upon...
var locations = [{
plot: "24-17",
address: "XYZ",
city: "Something",
pin: "24399",
phone: "041678993"
}, {
plot: "24-18",
address: "ABC",
city: "Something",
pin: "24398",
phone: "041678995"
}, {
plot: "24-19",
address: "DEF",
city: "Something",
pin: "24397",
phone: "041678994"
}];
var container = document.getElementById("di-locations");
// iterate locations
for (loc of locations) {
// iterate location properties
for (var prop in loc) {
if (Object.prototype.hasOwnProperty.call(loc, prop)) {
//create and append grid item
var item = document.createElement("DIV");
item.classList.add(loc[prop]);
item.innerHTML = loc[prop];
container.appendChild(item);
}
}
}
#di-locations {
display: grid;
grid-template-columns: auto auto auto auto auto;
font-family: sans-serif;
}
#di-locations>* {
padding: .8rem;
border-bottom: 1px solid #ddd;
}
<div id="locations-grid">
<div id="di-locations"></div>
</div>
This should help, shouldn't be too hard to turn into a grid:
HTML:
<div id="i"></div>
JavaScript:
var locations = [{
plot: "24-17",
address: "XYZ",
city: "Something",
pin: "24399",
phone: "041678993"
}, {
plot: "24-18",
address: "ABC",
city: "Something",
pin: "24398",
phone: "041678995"
}, {
plot: "24-19",
address: "DEF",
city: "Something",
pin: "24397",
phone: "041678994"
}];
txt = "<p>"; // Define txt so it can be accessed inside of functions
locations.forEach(foo); // Run foo for each item in the array
function foo(value,index,array) {
txt = txt + "Plot: " + value["plot"] + "<br>"; // Add Plot: _____ to the end of txt
txt = txt + "Address: " + value["address"] + "<br>"; // Similar to above
txt = txt + "City: " + value["city"] + "<br><br>"; // Similar to above
}
document.getElementById("i").innerHTML = txt + "</p>"; // Set the inner html of i to txt
I need to write a conditional that checked each image value and if its empty displays a stock photo 'selfie.jpg' and if it is not then display whatever is inside of it.
I know how to access it beat.officers[0].image. what I don't know is how to make the program check through the length of officers for each items image value, check if its empty and then display a photo based on the results of that check.
pls help its for a test.
A image of the Json object I am trying to work with
const policeData = [
{
beat:
{
name: 'Portishead',
latLong: ' ',
introText: 'Contact your local policing team, find opportunities to meet the team and view or contribute to community policing priorities for your area.',
officers: [
{
name: 'Trevor Dyson',
role: 'Neighbourhood Police Team Sergeant',
image: ''
},
{
name: 'Kirsten Karcher',
role: 'Police Community Support Officer',
image: 'kkarcher.jpg'
},
{
name: 'Bill Hoover',
role: 'Police Community Support Officer',
image: ''
},
{
name: 'Andrew Henry',
role: 'Partnership Support Officer',
image: ''
}
],
priorities: [
{
title: 'Road Safety Week',
updated: '18 November 2019',
path: '/road-safety-week/'
},
{
title: 'Community SpeedWatch',
updated: '14 August 2019',
path: '/community-speedwatch/'
},
{
title: 'Mopeds using footpaths and speeding vehicles',
updated: '04 September 2019',
path: '/mopeds-using-footpaths-and-speeding-vehicles/'
}
]
}
}];
So here is my template which is functional. As you can see though its not dynamic and I tried to input the conditional as a function with an if statement but its just not working. I did consider trying the turnery (condition : if yes : if no) but I struggled with that too.
Some of the image values are empty you see? Ultimately, I am trying to make it go through each object and check its image value and then run the conditional.
function kk(police) {
officers = police.beat.officers.length;
return `
<div class=person>
<img class="pol-photo" src = "${photoO(police.beat.officers[0])}"
<h2 class ="pol-name">${police.beat.officers[1].name}</h2>
<p> ${police.beat.officers[1].role}</p>
</div>
`
}
function photoO(pol) {
if (pol == '' ) {
return 'officer-profile.jpg'
} else {
return 'kkarcher.jpg'
}
}
You can use the functions from below to get the correct output. One function will return the HTML for just one officer while the other will return the HTML of all of them. You can test it below.
const policeData = [
{
beat:
{
name: 'Portishead',
latLong: ' ',
introText: 'Contact your local policing team, find opportunities to meet the team and view or contribute to community policing priorities for your area.',
officers: [
{
name: 'Trevor Dyson',
role: 'Neighbourhood Police Team Sergeant',
image: ''
},
{
name: 'Kirsten Karcher',
role: 'Police Community Support Officer',
image: 'kkarcher.jpg'
},
{
name: 'Bill Hoover',
role: 'Police Community Support Officer',
image: ''
},
{
name: 'Andrew Henry',
role: 'Partnership Support Officer',
image: ''
}
],
priorities: [
{
title: 'Road Safety Week',
updated: '18 November 2019',
path: '/road-safety-week/'
},
{
title: 'Community SpeedWatch',
updated: '14 August 2019',
path: '/community-speedwatch/'
},
{
title: 'Mopeds using footpaths and speeding vehicles',
updated: '04 September 2019',
path: '/mopeds-using-footpaths-and-speeding-vehicles/'
}
]
}
}];
// helper function to check if value is empty
function existsAndNotEmpty(value) {
if (typeof value != 'undefined' && value.length > 0) {
return true;
}
return false;
}
function getOfficerHTML(officer) {
let result = "";
if( existsAndNotEmpty(officer.image) ) {
result += '<img class="pol-photo" src = "' + officer.image + '" />';
} else {
result += '<img class="pol-photo" src = "officer-profile.jpg" />';
}
if( existsAndNotEmpty(officer.name) ) {
result += '<h2 class ="pol-name">' + officer.name + '</h2>';
} else {
result += '<h2 class ="pol-name">Unknown officer</h2>';
}
if( existsAndNotEmpty(officer.role) ) {
result += '<p>' + officer.role + '</p>';
} else {
result += '<p>Unknown role</p>';
}
return result;
}
function getAllOfficerHTML() {
let result = "";
let officerLength = policeData[0].beat.officers.length;
let officers = policeData[0].beat.officers;
for(var i=0; i < officerLength; i++){
result += getOfficerHTML(officers[i]);
}
return result;
}
// Now you can use it like this to print a single officer
var singleOfficer = getOfficerHTML(policeData[0].beat.officers[1]);
console.log(singleOfficer);
// or like this to get all ooficers at once
var allOfficers = getAllOfficerHTML();
console.log(allOfficers);
My from elements are written in Object. I need to populate HTML form elements from that. Problem is that Object contains different input types, structure, custom rules etc. For example, there will be text input, image type input, select box, radio, checkbox etc. So, I don't understand looping over the object will be good idea (I started this, but couldn't complete by myself :( ). I could write the html tag element in html file too. But, I must take the value from that object. So, what's the best solution for it?
Sample Object:
var formObj = {
username: {
value: null,
type: 'text',
placeholder: 'Enter username'
},
password: {
value: null,
type: 'password',
placeholder: 'enter password'
},
country: {
value: null,
type: 'select',
defaultText: 'Choose here',
option: [
{
value: '1',
label: 'Australia'
},
{
value: '2',
label: 'USA'
},
{
value: '3',
label: 'UK'
}
]
},
gender: {
value: null,
type: 'select',
defaultText: null,
option: [
{
value: 'male',
label: 'Male'
},
{
value: 'female',
label: 'Female'
},
{
value: 'other',
label: 'Other'
}
]
}
}
jsfiddle demo
your jsfiddle demo revised
Added some comments to your demo. I'd also look into template strings. They'll make your life easier and code cleaner :) and the single responsibility principle for breaking your code into easier to manage/read pieces.
var html = ''; // <-- Initialize as empty string for `+=`
$.each(formObj, function(key, value) {
if (value.value === null) {
value.value = '';
}
// Add label
html += '<label for="' + key + '">' + key + '</label>';
// Add input
if (value.type === 'select') {
// Type is select
html += '<select class="form-control">' + generateOptionPlaceholder(value.defaultText) + generateOptionMarkup(value.option) + '</select>';
} else {
html += '<input name="' + key + '" type="' + value.type + '" value="' + value.value + '" placeholder="' + value.placeholder + '" class="form-control" />';
}
console.log(html);
});
You could use a strategy pattern for this sort of thing. For any variance, used a dictionary where the keys are based off of the variant, and the values are a function to call for that variant.
For example, if your object with form data had a structure like this:
var form = {
"field1": {
type: "text"
value: "foo",
attrs: {...}
},
...
}
You can use a strategy to handle different field types. Your strategy dictionary might start our like this:
var FIELD_STRATEGY = {
"input": function (name, value, attrs) {
// General purpose method for <input>
// Needs type included in attrs
"text": function (name, value, attrs) {
// Constructs an <input type="text">
attrs.type = "text";
return FIELD_STRATEGY.input(name, value, attrs);
},
"option": function (value, label, attrs) {
// Constructs an <option>
},
"select": function (name, options, attrs {
// Constructs a <select>
var opts = options.map(function(opt) {
return FIELD_STRATEGY.option(
null,
opt.value,
opt.label);
}).join("");
var attr_str = Object.keys(attrs).map(function(attr) {
var value = attrs[attr];
return name + '="' + value '"';
}).join(" ");
return '<select name="' + name + '" ' + attr_str + '>' +
opts + '</select>';
}
};
To use it, loop over the field names and invoke strategies based on type:
var fields = Object.keys(form).map(function (name) {
var conf = form[name] || {};
var strategy = FIELD_STRATEGY[conf.type];
var rendered = "";
if (strategy) {
rendered = strategy(name, conf.value, conf.attrs);
}
return rendered;
});
This will give you a final fields list containing rendered strings based on the strategy for each field type.
have being watching youtube videos trying to learn how to search array for specific entry data?
here below is a js array example using console.log
Js array example:
var data = {
username: "john",
email: "28#GSDF.COM",
status: true,
id: 25
};
var data = {
username: "jIM",
email: "27#GSDF.COM",
status: false,
id: 23
};
var data = {
username: "Jane",
email: "25#GSDF.COM",
status: false,
id: 22
};
{
console.log(data);
}
here below is html which I want to make it show specific result from above js array with onclick submit button to search array? and then display/print back in the html div.
<html>
<head>
<title>get value</title>
<script type="text/javascript">
function getDisplay(){
var username = document.getElementById("username").value;
var email = document.getElementById("email").value;
document.getElementById("display").innerHTML = "username" + username + "<br/>email" + email;
}
</script>
</head>
<body>
<div id="whole">
Username : <input type="text" name="username" id="username">
Email : <input type="email" name="email" id="email"></br>
<button onclick=getDisplay()>Submit</button>
</div>
<div id="display">
</div>
</body>
</html>
if you can recommend any videos or things to read to help me learn would be greatly appreciated.
Firstly what you do is not an array, you want this array-object like this:
var data=[{
username: "john",
email: "28#GSDF.COM",
status: true ,
id: 25
},
{
username: "jIM",
email: "27#GSDF.COM",
status: false,
id: 23
}];
As you can see this is an array with obejcts, now you can work with it.
Use Object.keys(data).
Assuming your json should be like this. and your search logic will look like this.
var data = [
{
username: "john",
email: "28#GSDF.COM",
status: true,
id: 25
},
{
username: "jIM",
email: "27#GSDF.COM",
status: false,
id: 23
},
{
username: "Jane",
email: "25#GSDF.COM",
status: false,
id: 22
}
];
function getDisplay(){
var username = document.getElementById("username").value;
var email = document.getElementById("email").value;
data.forEach(function(item, index){
if((item.username == username) && (item.email == email)) {
var displayData = "<li><b>User Name</b>: "+ item.username +"</li>"+
"<li><b>EMail</b>: "+ item.email +"</li>"+
"<li><b>Status</b>: "+ item.status +"</li>"+
"<li><b>ID</b>: "+ item.id +"</li>";
$("#display").html(displayData);
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="whole">
Username : <input type="text" name="username" id="username"></br>
Email : <input type="email" name="email" id="email"></br>
<button onclick=getDisplay()>Submit</button>
</div>
<div id="display"></div>
An array of objects should look like this:
var arr = [{
username: "john",
email: "28#GSDF.COM",
status: true,
id: 25
},
{
username: "jIM",
email: "27#GSDF.COM",
status: false,
id: 23
},
{
username: "Jane",
email: "25#GSDF.COM",
status: false,
id: 22
}
]
And in your code you want to do the following :
<html>
<head>
<title>get value</title>
<script type="text/javascript">
var arr = [/*Your data here */];
function getDisplay(){
var username = document.getElementById("username").value;
var email = document.getElementById("email").value;
document.getElementById("display").innerHTML = "username" + username + "<br/>email" + email;
for(let i = 0; i < arr.length; i++) {
let element = arr[i];
//Your search logic goes here
}
}
</script>
</head>
<body>
<div id="whole">
Username : <input type="text" name="username" id="username">
Email : <input type="email" name="email" id="email"></br>
<button onclick=getDisplay()>Submit</button>
</div>
<div id="display">
</div>
</body>
</html>
Good morning, i'm new to angularjs and want to practice it more, and here i have a question regarding a simple case while trying to learn to build my own angularjs webpage.
I have these two sets of data
$scope.data1 = [{ id: 1, name: "abc" },
{ id: 2, name: "efg" }]
$scope.data2 = [{ id: 1, info: "this is abc" },
{ id: 2, info: "absolutely not abc"}]
$scope.user = {
id: "",
name: "",
info: ""
}
and i have this input
<input ng-blur="passTheValue()" ng-model="user.idx" ng-type="text" placeholder="write name here"></input>
where i can write name on the text box.
my question is, how to pass all the value from data1 and data2 to $scope.user based on what input i have entered? For example, i write "abc" on the textbox, then my $scope.user will contain
id: 1, name: "abc", info: "this is abc"
i've tried to use $filter but i'm stuck at passing the value to the scope.
i'm sorry for my English, it's not my main language.
This is not the classical usecase for a filter: Do the processing of your data in the passTheValue() function.
this.passTheValue = function(){
$scope.data1.forEach(function(value, index, array){
if(value.name == $scope.idx){
$scope.user = {id: value.id, name: value.name, info: $scope.data2[index] }
}
})
}
HTML
<input ng-blur="passTheValue(user.idx)" ng-model="user.idx" ng-type="text" placeholder="write name here"></input>
Angular
$scope.passTheValue = function(name) {
angular.forEach($scope.data1, function(value, key){
if(value.name == name){
$scope.user.id = value.id;
$scope.user.name= value.name;
$scope.user.info = $scope.data2.filter(function(v) {
return v.id === value.id; // Filter out the appropriate one
})[0].info;
console.log($scope.user.id);
console.log($scope.user.name);
console.log($scope.user.info);
}
});
}
In your HTML , I've replaced the user.idx by name because you're searching by name. Sample on Plunker : https://plnkr.co/edit/bumDWC713dVWGnKoO5G3?p=preview
<body ng-app='app'>
<div ng-controller='appCtrl'>
<input ng-blur="passTheValue()" ng-model="name" ng-type="text" placeholder="write name here">
</div>
</body>
In your javascript, I add to simply search methods.
var app = angular.module('app',[])
.controller('appCtrl',function(){
$scope.data1 = [{
id: 1,
name: "abc"
},
{
id: 2,
name: "efg"
}];
$scope.data2 = [{
id: 1,
info: "this is abc"
},
{
id: 2,
info: "absolutely not abc"
}];
$scope.name = "";
$scope.user = {
id: "",
name: "",
info: ""
};
function findIdByName(name) {
for (var i = 0 ; i< $scope.data1 ; i++) {
if($scope.data1[i].name == name)
return $scope.data1[i].id;
}
return -111 ; //Assume that it's an impossible ID
}
function findInfoById(id) {
for (var i = 0 ; i< $scope.data2 ; i++) {
if($scope.data1[i].id == id)
return $scope.data1[i].info;
}
return -111 ; //Assume that it's an impossible Info
}
$scope.passTheValue = function(){
var id = findIdByName($scope.name);
if(id != -111){
var info = findInfoById(id);
if(info != -111){
$scope.user.id= id;
$scope.user.name = $scope.name;
$scope.info = info;
}else {
console.log(id,"Id doesn't exist in $scope.data2")
}
}else {
console.log(name,"name doesn't exist in $scope.data1")
}
}
});