jquery and json

Soldato
Joined
12 May 2007
Posts
3,896
Location
Bristol
I have a map with 4 layers, each layer having markers for various shops. What I need to do is this.

- User chooses shop from select
- Script grabs shop name and then finds the correct data for that shop from json.

I have a rough idea of how the script should look but don't know how to write it correctly.

Code:
    $('#shopselect').change(function() {
        $.ajax({
    	type: "GET",
    	url: "data.txt",
    	dataType: "json",
    	success: function(data) {
    
    	var selected = $('#shopselect option:selected').text()
    	
    	if ($(".layer1:visible").length) {
    		$("#viewport").mapbox("center", { 
    			x: shops." + selected + ".l1x, 
    			y: shops." + selected + ".l1y 
    		});
    	} else if ($(".layer2:visible").length) {
    		$("#viewport").mapbox("center", { 
    			x: shops." + selected + ".l2x, 
    			y: shops." + selected + ".l1y 
    		});
    	} else if ($(".layer3:visible").length) {
    		$("#viewport").mapbox("center", { 
    			x: shops." + selected + ".l3x, 
    			y: shops." + selected + ".l1y 
    		});
    	} else if ($(".layer4:visible").length) {
    		$("#viewport").mapbox("center", { 
    			x: shops." + selected + ".l4x, 
    			y: shops." + selected + ".l1y 
    		});
    	}
    }
    });

The json looks like so.

Code:
    {
    shops:{
        primark:{
            l1x:310,
            l1y:132,
            l2x:388,
            l2y:264,			
            l3x:530,
            l3y:355,
            l4x:670,
            l4y:450
        },
        boots:{
            l1x:310,
            l1y:132,
            l2x:388,
            l2y:264,			
            l3x:530,
            l3y:355,
            l4x:670,
            l4y:450
        }		
    }
}


Is there anyone who could point me in the right direction.
 
Last edited:
Your JSON is invalid which isn't helping, you need to quote all strings. Also this layout might be better, it allows you to process locations easier:

PHP:
{
	"shops": {
		"primark": {
			"l1": {
				"x": 310,
				"y": 132
			},
			"l2": {
				"x": 388,
				"y": 264
			},
			"l3": {
				"x": 530,
				"y": 355
			},
			"l4": {
				"x": 670,
				"y": 450
			}
		},
		"boots": {
			"l1": {
				"x": 310,
				"y": 132
			},
			"l2": {
				"x": 388,
				"y": 264
			},
			"l3": {
				"x": 530,
				"y": 355
			},
			"l4": {
				"x": 670,
				"y": 450
			}
		}		
	}
}

http://www.jsonlint.com/
 
Thanks for that.

I'm rather new to json so would it just be shops.primark.l1.x to retrieve the value?

and if so, am I right in thinking the correct way to add in a variable would be like so..

shops.[selected].l1.x

instead of

shops." + selected + ".l1.x
 
Actually.. I changed my mind :D

PHP:
{
	"shops": {
		"primark": {
			"locations": {
				"l1": {
					"x": 310,
					"y": 132
				},
				"l2": {
					"x": 388,
					"y": 264
				},
				"l3": {
					"x": 530,
					"y": 355
				},
				"l4": {
					"x": 670,
					"y": 450
				}
			}
		},
		"boots": {
			"locations": {
				"l1": {
					"x": 421,
					"y": 151
				},
				"l2": {
					"x": 516,
					"y": 141
				},
				"l3": {
					"x": 581,
					"y": 681
				},
				"l4": {
					"x": 161,
					"y": 691
				}
			}
		}		
	}
}

This is a better way of storing it :).

Yep pretty much, shops.primark.locations.l1.x would be the x-coordinate of primark location 1.
 
Last edited:
I had a play and came up with this. Using the JSON from above you could do something like this:

PHP:
<script type="text/javascript">
	$(document).ready(function() {
		
	   $('#shopselect').change(function() {
	   
			// Clear result div
			$("#result").text('');
			
			// Read the value element of the selected option
			// they should be the same as the shop names in your JSON
			var selected = $('#shopselect').val();

			// Get JSON from file
			$.getJSON("data.txt", function(data) {
				// For each shop in the JSON data
				$.each(data.shops, function(i,item) {
					// If the current shop is the selected one
					if ( i == selected ) {
						// Loop over all locations
						$.each(item.locations, function(i,item) {
							// Dump the locations into the result div, but you would interface with your map here
							$("#result").append("Location: " + i + " - x: " + item.x + " y: " + item.y + "<br/>");
						});
						return;
					}
				});
			});
	});
});
</script>

The HTML looks like this:
PHP:
<body>
	<form action="">
		<select id="shopselect" name="shopselect">
			<option value="primark">Primark</option>
			<option value="boots">Boots</option>
		</select>
		<br/>
		
		<div id="result"></div>
	</form>
</body>
 
Is it better to loop through them all or just retrieve the one needed? There are 70 of them.

Oh, in that case using an array is probably much faster. Mind you, the 'better' option would be to get your JSON from a PHP page which you pass the search string to (i.e. Boots or Primark) which then just returns the relevant items. So if a user selected Boots then you would only get Boots' items in the JSON not the rest of them.

PHP:
<script type="text/javascript">
	$(document).ready(function() {
		
	   $('#shopselect').change(function() {
	   
			// Clear result div
			$("#result").text('');
			
			// Read the value element of the selected option
			// they should be the same as the shop names in your JSON
			var selected = $('#shopselect').val();

			// Get JSON from file
			$.getJSON("data.txt", function(data) {

				var shop = data.shops[selected];
				if ( shop ) {
						// Loop over all locations
						$.each(shop.locations, function(i,item) {
							// Dump the locations into the result div, but you would interface with your map here
							$("#result").append("Location: " + i + " - x: " + item.x + " y: " + item.y + "<br/>");
						});
				}
			});
		});
	});	
</script>
 
I'd look into using php except we use asp.net and I'm just a front end guy/creative dir. Had looked into doing this with flash but were told it'd be 2 weeks and £12k so I've been lumped into doing it with jquery. The front end I've done is quite nice and works really well, it's just this bit I'm struggling with so thanks for the help.

There is a distinct lack of json/jquery tutorials out there which explain it for someone who's never used it before.
 
I'd look into using php except we use asp.net and I'm just a front end guy/creative dir. Had looked into doing this with flash but were told it'd be 2 weeks and £12k so I've been lumped into doing it with jquery. The front end I've done is quite nice and works really well, it's just this bit I'm struggling with so thanks for the help.

There is a distinct lack of json/jquery tutorials out there which explain it for someone who's never used it before.

£12k? :eek:. jQuery is miles better than flash too. You'll be able to do the filtering with ASP.NET as well - it will help speed up the JSON processing should you need it as clients' browsers won't have to do all the processing work to find the store.

If you use Google Maps it would be very easy to get the map working too.

I pretty much just looked through here but I guess I already knew what I was looking for.
 
I've given that a go and it works great, thanks.

However, how would I go about grabbing just specific values rather than all of them for the selected shop? I need to populate this by replacing the coords for whatever layer is active.

Code:
$("#viewport").mapbox("center", { 
    			x: 313, 
    			y: 414 
    		});


So I'd need it populated something like..
Code:
$("#viewport").mapbox("center", { 
    			x: shops.[selected].locations.[activelayer].x, 
    			y: shops.[selected].locations.[activelayer].y 
    		});

I can retrieve the active layer with the following which will return l1, l2, l3 or l4.
Code:
var activelayer = $('.current-map-layer').attr('id');


I just can't figure out how to write it in to the script you posted above.
 
Last edited:
Sounds like you've pretty much already got it and would place it between if ( shop ) { ... }

Does shops.[selected].locations.[activelayer].x and shops.[selected].locations.[activelayer].y return the correct value for you?
 
Okay, almost there now.

PHP:
$('#shopselect').change(function() {
       
            $("#result").text('');
            
            var selected = $('#shopselect').val();
			var activelayer = $('.current-map-layer').attr('id');

            $.getJSON("data.txt", function(data) {

                var shop = data.shops[selected];

				
                if ( shop ) {

                      $("#result").append("" + data.shops[selected].locations[activelayer].x + " " + data.shops[selected].locations[activelayer].y + "<br/>");

                }
            });
        });

This will return the two results I need but I can't seem to shorten it.
Instead of
data.shops[selected].locations[activelayer].x
if I try to use
[shop].locations[activelayer].x
firebug comes up saying [shop].locations is undefined.
 
Last edited:
Your second version looks to be in the right direction. Try removing the [ and ] when you declare loc and when you use it in result.append:

PHP:
$('#shopselect').change(function() {
       
            $("#result").text('');
            
            var selected = $('#shopselect').val();
            var activelayer = $('.current-map-layer').attr('id');

            $.getJSON("data.txt", function(data) {

                var shop = data.shops[selected];
				
				if ( shop ) {
					var loc = shop.locations[activelayer];
					
					if ( loc ) {
						  $("#result").append("" + loc.x + " " + loc.y + "<br/>");
					}
				}
            });
        });
 
That's a winner! Thank you so so much. You've saved me so much time (which I don't have available) of fiddling about.

Now once I have this all finished, I can spend some time figuring it all out so I can do it myself next time. Thanks again.
 
:) nice.

It's actually fairly simple, I guess the biggest problem is realising how you go about actually starting to get it to work :D.
 
Yeah, that's my problem. I have a rough understanding of how it should work, I just need to learn how to actually do it.

Things like removing the dot before the variable. To me, common sense would say it should be there because if I want the final output to be shop.locations.l1, if you didn't know better, you'd put it as shop.locations.[activelayer] instead of shop.locations[activelayer].
 
The reason for that is that shop.locations is an array (or collection) of locations; there's several locations for each shop. You reference an item in an array by using array[index], i.e. array[0] (first element) or array["primark"] for the Primark element.

So you're saying shop.locations[find the one with the same signature as the activelayer variable].

You use the dot to delve further into the structure of the JSON (I can't think of the proper name right now). So on the below JSON you could have:
a.a1
a.a1.a11
a.a2.a21
a.a2.a22

or using arrays:
a[a1]
a[a1][a11]
a[a2][a21]
a[a2][a22]

PHP:
    "a": {
        "a1": {
            "a11": {
			},
        "a2": {
            "a21": {
			},
            "a22": {
			}			
		}
	}

Mind you, I got stuck trying to explain this half way in :p.
 
Back
Top Bottom