PDA

View Full Version : Help --Updating div's innerHTML with item in JSON response



sb32
18 Oct 2007, 1:32 PM
Please help me do this one simple thing. I can't seem to update the innerHTML of a div with content from a json response. Here is my horrific attempt at inserting "3.02" in a div id'd as 'milk'.

The json response is as follows:

{"prices"=>{:milk=>"3.02", :bread=>"2.67"}}

html/js:


<script type="text/javascript">

function getFieldValue(store, rowIndex, fieldName) {
var myDataRecord = store.getAt(rowIndex);
return myDataRecord.get(fieldName);
}
function display() {
var ds = new Ext.data.Store({
proxy: new Ext.data.ScriptTagProxy({url: 'http://somewebsite.com/prices'}),
reader: new Ext.data.JsonReader({
root: 'prices'
},
[
{name: 'milk', mapping: 'milk'}
])
});
ds.load();
document.getElementById('milk').innerHTML = getFieldValue(ds, 0, 'milk');
}
</script>
<body onLoad="display()">
<div id="milk"></div>
</body>
</html>

Firebug says:


myDataRecord has no properties
[Break on this error] return myDataRecord.get(fieldName);
test (line 11)
invalid assignment left-hand side
[Break on this error] {"prices"=>{:milk=>"3.02", :bread=>"2.93"...

fay
18 Oct 2007, 2:27 PM
load (http://extjs.com/deploy/ext/docs/output/Ext.data.Store.html#load) is asynchronous so you need to wait until the data is loaded before using it. See the load (http://extjs.com/deploy/ext/docs/output/Ext.data.Store.html#event-load) event, and try:


ds.on('load', function(store, records, options){
document.getElementById('milk').innerHTML = getFieldValue(ds, 0, 'milk');
});
ds.load();

Also take a look at Ext.get() (http://extjs.com/deploy/ext/docs/output/Ext.html#get) and Element (http://extjs.com/deploy/ext/docs/output/Ext.Element.html) instead of using getElementById().

EDIT: I know next-to-nothing about JSON but is this valid: {"prices"=>{:milk=>"3.02", :bread=>"2.67"}}

sb32
19 Oct 2007, 8:19 AM
Thanks for all your help. it now works. Here's all the content for future reference:

Json:


{prices: [{milk: "3.50", bread: "2.73"}]}



html/js:

<script type="text/javascript">
function getFieldValue(store, rowIndex, fieldName) {
return store.getAt(rowIndex).get(fieldName);
}

function display() {
var ds = new Ext.data.Store({
//proxy: new Ext.data.ScriptTagProxy({url: 'http://somesite.com/prices'}), // WILL USE WHEN CONNECTING TO REMOTE HOST
proxy: new Ext.data.HttpProxy({url: 'http://localhost/prices'}),
reader: new Ext.data.JsonReader({root: 'prices'},
[
{name: 'milk'},
{name: 'bread'}
])
});
ds.on('load', function(store, records, options){
document.getElementById('milk').innerHTML = getFieldValue(ds, 0, 'milk');
});
ds.load();
}
</script>
</head>

<body onLoad="display()">
<div id="milk"></div>
</body>

sb32
19 Oct 2007, 11:07 AM
Almost there!!

So, when I deploy and use ScriptTagProxy, the milk & bread <spans> never get updated with the prices. There are no errors in Firebug and under the Net tab, I can see the json being queried and returned in the response tab.


json:

{prices: [{milk: "$2.60", bread: "$2.05"}]}

html/js:

<script type="text/javascript">
function display() {

var items = [
{name: 'milk'},
{name: 'bread'}
];

var ds = new Ext.data.Store({
proxy: new Ext.data.ScriptTagProxy({url: 'http://somesite.com/prices'}), //is not working
//proxy: new Ext.data.HttpProxy({url: 'http://localhost/prices'}), //works
reader: new Ext.data.JsonReader({root: 'prices'},items)
});
ds.on('load', function(store, records, options){
for(var i=0; i < items.length; i++ ){
Ext.get('item-' + items[i]['name']).update(ds.getAt(0).get(items[i]['name']));
}
});
ds.load();
}
</script>
</head>

<body onLoad="display()">
Milk: <span id="item-milk"></span><br/>
Bread: <span id="item-bread"></span><br/>
</body>
</html>

tryanDLS
19 Oct 2007, 11:32 AM
Did you set a BP in the load handler? Is it even getting there? Try adding a handler for loadexception to see if there's a problem processing your response.

Animal
20 Oct 2007, 1:32 AM
Read the docs for ScriptTagProxy properly. You don't just send back data, it must be executable code - it's the result of the src of a <script> tag.

sb32
20 Oct 2007, 8:55 PM
Got it animal thx!

To the next person, all I had to do was prefix my json response with this:

stcCallback1001 ((

and suffix my json response with this:

));

In rails, I did it as such ;-)

render :text => 'stcCallback1001 ((' + {"prices" => [content]}.to_json.to_s + '));'


Again, thanks to all who helped

Animal
20 Oct 2007, 11:22 PM
That's not reliable.

99.9% of the time it will work, but the callback name is not guaranteed to be "stcCallback1001"

The name of the callback function to use is passed in the HTTP parameter "callback". Read that parameter. If it is non-null, then the request was sent by a ScriptTagProxy, and you need to wrap your data with a call to that function. If it is null, then just return your data.

if you do that, your script will be usable by both kins of proxies, and you will have flexibility.

sb32
29 Oct 2007, 6:39 AM
Ah, that makes sense.

I'll update the code tonight and repost the changes.

One other question that came up:

For redundancy, I'd like to have ScriptTagProxy try an alternate host if it can't get data from the first host. I need to see but, off hand do you know if js throws an exception if the remote host isnt available or do I need to just see if the results are empty/null?

Kind regards and thanks for all your help