Search JSON Array based on variable? - javascript

I've got a JSON Array that I need to search:
[
{
"Device_ID":"1",
"Image":"HTC-One-X.png",
"Manufacturer":"HTC",
"Model":"One X",
"Region":"GSM",
"Type":"Phone"
},
{
"Device_ID":"2",
"Image":"Motorola-Xoom.png",
"Manufacturer":"Motorola",
"Model":"Xoom",
"Region":"CDMA",
"Type":"Tablet"
},
{
"Device_ID":"8",
"Image":"null",
"Manufacturer":"Motorola",
"Model":"Xoom 2",
"Region":"CDMA",
"Type":"Tablet"
}
]
Using the keyword: $_GET['keyword']; I need to be able to do the following.
Search the combined value of Manufacturer and Model, ie. Motorola Xoom. Then, for whichever set of values matches this, output them to variables.
For example: If the Keyword was HTC, then it would search the array and output:
$DeviceID = 1 $Image = HTC-One-X.png $Manufacturer = HTC $Model = One
X $Region = GSM $Type = Type
However if the keyword was Motorola, then it would need to output all entries that include Motorola.
What im trying to do, is output a live view of all JSON Array entries, as the user types the keyword. However I want this to run on the users computer to reduce the load on the server.
Does anyone know the best way to go about this?

well if you have a selection box with the values for the manufacturer in the options section it's as easy as:
HTML:
<select id="selectionBox">
<option>...</option>
</select>
<div id="outPut">
output goes in here
</div>
Javascript:
var selectedValue = document.getElementById("selectionBox").value;
for(var i = 0; i < jsonObject.length; i++){
if(jsonObject[i].Manufacturer === selectedValue){
//considering your object is an array let's
for(var key in jsonObject[i]){
document.getElementById("outPut").innerHTML += jsonObject[i][key] + "</br>";
}
}
}
that'll pretty much print everything in the object onto the output div, the rest is up to your styling.

Here's a function for filtering the JSON. Displaying the data is up to you.
var devices = <your JSON array>;
function filter(keyword, data) {
var filteredArray = [], i, j;
for (i = 0, j = data.length; i < j; i++) {
if ((data[i].Manufacturer && data[i].Manufacturer.indexOf(keyword) !== -1) || (data[i].Model && data[i].Model.indexOf(keyword) !== -1)) {
filteredArray.push(data[i]);
}
}
return filteredArray;
}
// Example usage
var MotorolaDevices = filter('Motorola', devices);

Related

How to get one by one values(value in array) from Key Json?

I am getting values together from one key. Because in my case multiple values in array form come into the one key.
JSON
engine_data: {
internal: {
poling: {
account: [
"2009-38554",
"2009-38554"
],
secure: [
"2008-11833"
]
}
}
}
Javascript:
call.all('xyz').get(id).then(function(resp)
{
var res=resp.data;
var jsonData =
res.engine_data.internal.poling;
for(var i in jsonData){
if(i == "account")
{
alert(jsonData[i]);
alert(jsonData[i].length);
var account = jsonData[i].join(",")
$scope.acount = www.xyz/+account;
}if (i == "secure") {
var secure = jsonData[i].join(",")
$scope.secure = www.abc/+secure;
}
}
In my Json value in array form, So account (keys) has two value in array form. When I put in alert for printing then both value print together.
Screen Shot:
So I want to append these two value in www.xyz/ url.
Like out put result should be
www.xyz/2009-38554
www.xyz/2009-38554
But Right now I am getting
www.xyz/2009-38554,2009-38554
Share your ideas thanks in advance.
you can iterate over the array you get from account key and make all possible urls you can form values in array and you can make $scope.account an array and push all possible combinations, something like this:
for(var i in jsonData){
if(i == "account")
{
alert(jsonData[i]);
alert(jsonData[i].length);
$scope.account = [];
var account = jsonData[i];
for(var i=0; i<account.length; i++)
$scope.acount.push("www.xyz/"+account[i]);
}if (i == "secure") {
var secure = jsonData[i].join(",")
$scope.secure = www.abc/+secure;
}
}

Search JSON using user date input from dropdown menus

I'm looking to be able to take a user date input from three different drop down menus (day, month, year) and use a JSON file that I created by exporting my database to a JSON file to pull back the data that matches the date inputted by the user.
Here's an example of a record in my JSON file:
"items": [
{"id":"1","artistName":"REDNEX","songTitle":"COTTON EYE JOE"," startDate":"1995-01-14"},
If the users input matches a date in the JSON array then I wish to display the artist name and song title. How would I go about doing this? I have never worked with JSON before now.
Thank you in advance for any help!
Let us assume obj as your JSON data.
var output = [];
var searchField = "startDate";
var searchVal = year+"-"+month+"-"+day;
for (var i=0 ; i < obj.list.length ; i++)
{
if (obj.list[i][searchField] == searchVal) {
output.push(obj.list[i]["artistName"] + "," + obj.list[i]["songTitle"]);
}
}
You can use the filter function
data = {"items": [
{"id":"1","artistName":"REDNEX","songTitle":"COTTON EYE JOE","startDate":"1995-01-14"},
]};
function getArtistByDate(date) {
items = data["items"];
return items.filter(
function(items){ return items["startDate"] == date }
);
}
console.log(getArtistByDate("1995-01-14"));
console.log(getArtistByDate("1995-01-15"));
You say "JSON", but your post includes what appears to be a raw javascript object. JSON data is simply a string, which can then converted to an object.
Addtionally, you want to use filter to select the artists of interest.
var userDate = "1995-01-14";
var itemString = '[{"id":"1","artistName":"REDNEX","songTitle":"COTTON EYE JOE", "startDate":"1995-01-14"}]'
var items = JSON.parse(itemString);
var filtered = items.filter(x => x.startDate === userDate);
for (var i = 0; i < filtered.length; ++i)
console.log(filtered[i].artistName + ": " + filtered[i].songTitle);
I would use takeWhile() from Lodash: https://lodash.com/docs/4.16.4#takeWhile. (Moreover, once you get started with Lodash you are going to find a wealth of utility functions that you cannot live without.)
var userInputDate;
var matchingItems = _.takeWhile(items, {'startDate': userInputDate});
// matchingItems is an array of all items with the same startDate

Assign new value to variable using itself

This doesn't work but I can't see why it wouldn't? any help people? :)
params = qs.split("=", 2),
id = params[1];
if(id.indexOf("?") != -1){
id = id.split("?", 1);
}
basically I want to change the value of 'ID' if the IF statement is true, if not.. it skips it and the value Id remains the default.
Thanks
The result of id = id.split("?", 1) is an array (of at most 1 item), but I think you want id to be a string. That would explain why id is not a string like you want.
I agree with the other comments. Please show us the URL string you want to parse and tell us which piece you're trying to get. Usually, you look for ? first, separate after that and then divide up various key=value sections.
If you had a URL like this:
http://www.example.com?foo=bar
Here's a simple function that gets you all the query parameters into an object:
function getParms(url) {
var sections, key, pieces = url.split("?");
var results = {};
if (pieces.length > 1) {
sections = pieces[1].split("&");
for (var i = 0; i < sections.length; i++) {
key = sections[i].split("=");
results[key[0]] = key[1];
}
}
return(results);
}
Working demo: http://jsfiddle.net/jfriend00/kNG3u/

Get value of JSON object with inner objects by HTML form field name without eval

I have a problem like this Convert an HTML form field to a JSON object with inner objects but in to the other direction.
This is the JSON Object response from the server:
{
company : "ACME, INC.",
contact : {
firstname : "Daffy",
lastname : "Duck"
}
}
And this is the HTML form:
<form id="myform">
Company: <input type="text" name="company" />
First Name: <input type="text" name="contact.firstname" />
Last Name: <input type="text" name="contact.lastname" />
</form>
And this is the (pseudo)code:
var aFormFields;
for (var i = 0, iMax = aFormFields.length; i < iMax; i++) {
var sFieldName = aFormFields[i].getAttribute('name');
eval("sFieldValue = oResponse."+sFieldName);
}
Ok my solution works, but i looking for a good way to remove the evil eval from the code.
And the solution should also work for form fields with any count of dots in the field name.
Instead of:
eval("sFieldValue = oResponse."+sFieldName);
Use for single dotted fields:
sFieldValue = oResponse[sFieldName];
This will retrieve the value via its key.
Now if you need more than that you need to do the following:
Split sFieldName on .
Loop over that array and go down in oResponse till you reach the value that you desire
Code could look like this:
var node = oResponse, parts = sFieldName.split('.');
while(parts.length > 0) {
node = node[parts.shift()];
}
// node will now have the desired value
Further information on "Member Operators":
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Member_Operators
This works for a single property:
sFieldValue = oResponse[sFieldName]
But it won't work for nested data like contact.firstname.
For that, split the name by dots, and use loop through each name:
var aFormFields;
for (var i = 0, iMax = aFormFields.length; i < iMax; i++) {
var aFieldNameParts = aFormFields[i].getAttribute('name').split(".");
var oFieldValue = oResponse;
for(var j=0; j<aFieldNameParts.length; j++) {
oFieldValue = oFieldValue[aFieldNameParts[j]];
}
var sFieldValue = oFieldValue;
}
Note: if a property does not exist, an error will occur. You might want to check whether oFieldValue[ aFieldNameParts[j] ] exists or not.
While it is possible, I wouldn't loop over the input fields, but over the JSON object:
function fillForm (form, data, prefix) {
prefix = prefix ? prefix + "." : "";
for (var x in data) {
if (typeof data[x] === "string") {
var input = form.elements[prefix + x];
if (input)
input.value = data[x];
} else
fillForm(form, data[x], prefix + x);
}
}
fillForm(document.getElementById("myform"), oResponse);
(untested)
Assuming your naming scheme is consistent, you can convert the dot-notation into subscripts. You'd have to split the field name on the period and iterate or recurse over the tokens, converting each into a subscript. Of course this assumes that oResponse always contains a value for every field.
for (var i = 0; i < aFormFields.length; i++) {
var sFieldName = aFormFields[i].getAttribute('name');
var tokens = sFieldName.split('.');
var cur = oResponse;
for (var j = 0; j < tokens.length; j++) {
cur = cur[tokens[j]];
}
sFieldValue = cur;
}
please treat this as a combination of answer and question :)
i am currently trying to get my server to jsonify the data that i get sent from a form just like you...
in my case the form will in the end create a json object with multiple subobjects that can have subobjects which can have... as well.
the depth is up to the user so i should be able to support infinite recursion.
my "solution" so far just feels wrong, but it correctly does the job,
the function getRequestBody gets fed a req.body object from expressjs,
this is basically an object with the following mapping:
{
"ridic-ulously-deep-subobject": "value",
"ridic-ulously-deep-subobject2": "value",
"ridic-ulously-deep2-subobject3": "value",
}
the following html is in use:
<form>
<input name="ridic-ulously-long-class-string" value="my value" />
</form>
and the javascript function (that should work genericly, feed it a req.body object like above and it will return a json object):
function getRequestBody(reqB){
var reqBody = {};
for(var keys in reqB) {
var keyArr = keys.split('-');
switch(keyArr.length){
case 1:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
reqBody[keyArr[0]] = reqB[keys];
break;
case 2:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
if(!reqBody[keyArr[0]][keyArr[1]]) reqBody[keyArr[0]][keyArr[1]] = {};
reqBody[keyArr[0]][keyArr[1]] = reqB[keys];
break;
case 3:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
if(!reqBody[keyArr[0]][keyArr[1]]) reqBody[keyArr[0]][keyArr[1]] = {};
if(!reqBody[keyArr[0]][keyArr[1]][keyArr[2]]) reqBody[keyArr[0]][keyArr[1]][keyArr[2]] = {};
reqBody[keyArr[0]][keyArr[1]][keyArr[2]] = reqB[keys];
break;
case 4:
// ...
//and so on, always one line longer
}
return reqBody;
}
this just feels wrong and its only covering 5 levels of subobjects right now,
it might happen that an application has enough functionality to reach seven or even ten levels though.
this should be a common problem, but my search effort turned up nothing within 10 minutes,
which usually means that i am missing some keywords
or
that there is no viable solution [yet] (which i cant really imagine in this case).
is there someone out there who has imagination and logic sufficient enough to unspaghettify this or will i just have to expand this function with even more clutter to get me down to 10 possible sublevels?
i think that in the end it wont make a big difference performance wise,
but i would really like NOT to create this awful behemoth :D
have fun
jascha

remove json attribute where attribute is a variable

I have a news feed where items in the feed are created from JSON returned from a server. When the user takes an action on an item, I want to remove it from the object via javascript.
The feed looks like this:
{"newsFeed":[{"feedId":"1",
"title":"item1 title",
"desc":"description of the item"},
{"feedId":"2",
"title":"item2 title",
"desc":"description of the item"}]}
I'm trying to remove a JSON attribute or entry where the feedId is passed in via a variable using jQuery. I'm not sure exactly where I'm going wrong here, but when I alert the feed before and after the removal of the object, I'm getting the same response:
function removeFromFeed(feedId){
var newsFeed=jQuery('div#newsFeed').data('newsFeed');
alert(newsFeed.toSource());
delete newsFeed.feedId[feedId]
jQuery('div#newsFeed').data('newsFeed',newsFeed);
alert(newsFeed.toSource());
}
If I undertand you correctly you want to remove e.g. this whole entry {"feedId":"1", "title":"item1 title", "desc":"description of the item"} if removeFromFeed(1) is called.
So what we need to do is remove an entry from an array.
New version which should work now. (btw. what is this toSource() my browser doesn't know this method)
//http://ejohn.org/blog/javascript-array-remove/
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
function removeFromFeed(feedId){
var data = jQuery('div#newsFeed').data('newsFeed');
var len = data.newsFeed.length;
for (var i = 0; i < len; i++) {
if (data.newsFeed[i].feedId == feedId) {
data.newsFeed.remove(i);
break;
}
}
jQuery('div#newsFeed').data('newsFeed', data);
}
Demo: http://jsbin.com/ekali3 (Code view: http://jsbin.com/ekali3/edit)
I'm not sure why the 'Array.prototype.remove' stuff was breaking my page, but I created a new array and just left out the object I wanted to remove.
var newsFeed=jQuery('div#newsFeed').data('newsFeed');
var newFeed={"feed":[]};
alert(newsFeed.toSource());
for (var i = 0; i < newsFeed.length; i++) {
if(newsFeed.feed[f].shiftId!=shiftId){
newFeed.feed.push(newsFeed.feed[f]);
}
}
seems to work.

Categories

Resources