PDA

View Full Version : iPhone WebApp Developing question about Javascript




kikobarbada
Mar 11, 2008, 03:22 PM
Hello.

When I launch DashCode to develop an webapp and choose the browser sample, I can only change the text but their details are all the same except for representedObject (like The snow conditions in "representedObject" are great.). How can I change that and allow each text to go to a completely different detail?

Thanks.



kikobarbada
Mar 11, 2008, 04:13 PM
Anyone?

sadilak
Mar 11, 2008, 04:20 PM
Anyone?

I just started programming a web version of my application and I am having lots of questions myself. There is not much of help available in adc too(other than that presentation by Mark Malone)

sadilak
Mar 11, 2008, 04:21 PM
Hello.

When I launch DashCode to develop an webapp and choose the browser sample, I can only change the text but their details are all the same except for representedObject (like The snow conditions in "representedObject" are great.). How can I change that and allow each text to go to a completely different detail?

Thanks.

Ok, since it is javascript based, location.href="b.html" should work just fine..

kikobarbada
Mar 11, 2008, 04:37 PM
Here is the code. What can I change to each object load to a different page?

var listController = {
_rowData: [
"Alta",
"Aspen",
"Big Bear",
"Boreal",
"Brundage Mountain",
"Heavenly",
"Kirkwood",
"Mammoth",
"Northstar",
"Park City",
"Snowbird",
"Squaw Valley",
"Sugar Bowl",
"Sun Valley",
"Vail",
],

numberOfRows: function() {
return this._rowData.length;
},

prepareRow: function(rowElement, rowIndex, templateElements) {
if (templateElements.rowTitle) {
templateElements.rowTitle.innerText = this._rowData[rowIndex];
}

// We also assign an onclick handler that will cause the browser to go to the detail page.
var self = this;
var handler = function() {
var resort = self._rowData[rowIndex];
detailController.setRepresentedObject(resort);
var browser = document.getElementById('browser').object;
// The Browser's goForward method is used to make the browser push down to a new level. Going back to previous levels is handled automatically.
browser.goForward(document.getElementById('detailLevel'), resort);
};
rowElement.onclick = handler;
}
};

var detailController = {
// This object acts as a controller for the detail UI.

setRepresentedObject: function(representedObject) {

this._representedObject = representedObject;

var detailText = document.getElementById('detailText');
detailText.innerHTML = "The snow conditions in " + representedObject + " are awesome!";
}

};

function load()
{
setupParts();
}

lunged
Mar 12, 2008, 09:56 PM
I'd like to know the same thing. If it were Dreamweaver, I could simply make a home screen that each led to a different page of mere text in a few minutes. Thats all I want to do, but I spent well over an hour with nothing to show for it.
So does anyone know how to use this yet? Obviously, I'm no coder, but this seems like it should be able to function as a decent WYSIWYG, but I'm not getting it.

rdmartell
Mar 15, 2008, 02:35 PM
I've got it working using a dynamic xmlhttp source from my website; unfortunately, I can't post the example, as it's video site (and the login stuff isn't working yet).

Here's what I have figured out though:

Highlight the stackLayout, and in attributes, you can add another layer by clicking on the + button
Highlight the new layer, and give it a name; then drag in an edge to edge list (and give it a name- for my example categoryList).
Click on the categoryList object, and then in the Attributes, you can select if it is a dynamic list, or a static list. If you want it to be static, you can simply enter in all your list elements. If you want it to be dynamic, it's going to take more work (ie getting the data from your server).
I supposed if you just had a static number of list items, you could simply create a page for each of them, and just call the browser.goForward() to load the proper page.
Below is all of my code; Obviously, this won't work exactly for you, because I've scrubbed out all of my URLs, but it should give you an idea of how to start. It's not clean yet (it needs to be refactored, as there is lots of duplication), but it is working really well right now. (Although it crashes the simulator about 60% of the time, when it is doing the animated slide in and out)
Hope that helps; Here's what I want to know:

How can you either add a button to the header? (I want to add search and login stuff to this). OR add a footer?
How can I change the font size of the text? When I reduce it in the second (categoryList) text item, it ignores it in the simulator, and shows it the same size as the first category list.



Here's my code:
// This file was generated by Dashcode from Apple Inc.
// You may edit this file to customize your web application.

var listController = {
// This object acts as a controller for the list UI.
// It implements the dataSource methods for the list.

// This dataSource uses fixed data for the content of the list. Some applications may have such static data for their lists, others will want to replace this with information fetched remotely via XMLHttpRequest.
_rowData: null,

loadCategoryData : function() {
// Values you provide


var feedURL = "some url here....";

// XMLHttpRequest setup code
var xmlRequest = new XMLHttpRequest();
xmlRequest.onreadystatechange= function()
{
var result= null;

switch(xmlRequest.readyState)
{
case 4:
if(xmlRequest.status==200)
{
// parse it...
// dumpResponseXML(responseXML);
listController._rowData= new Array();

var nodelist= xmlRequest.responseXML.getElementsByTagName('ResultItem');
for(var ii= 0; ii<nodelist.length; ii++)
{
listController._rowData.push(new ResultItem(
nodelist[ii].getAttribute('Title'),
nodelist[ii].getAttribute('Description'),
nodelist[ii].getAttribute('OnClick'),
nodelist[ii].getAttribute('HREF'),
nodelist[ii].getAttribute('ImageHREF'),
nodelist[ii].getAttribute('MediaType')));
}

// now tell us to reload!
var list= document.getElementById('list');
list.object.reloadData();
}
break;

case 3:
break;

default:
break;
}
}

xmlRequest.open("POST", feedURL);
xmlRequest.setRequestHeader("Content-type", "text/xml; charset=utf-8");
xmlRequest.setRequestHeader("SOAPAction", "SOAP Request header info here...");
xmlRequest.send(buildXMLRequest('cat', 'XXXX', '', '', ''));
},

numberOfRows: function() {
// The List calls this dataSource method to find out how many rows should be in the list.
if(this._rowData==null)
{
return 1; // Loading text...
} else {
return this._rowData.length;
}
},

prepareRow: function(rowElement, rowIndex, templateElements) {

if(this._rowData != null)
{
// The List calls this dataSource method for every row. templateElements contains references to all elements inside the template that have an id. We use it to fill in the text of the rowTitle element.
if (templateElements.rowTitle) {
templateElements.rowTitle.innerText = this._rowData[rowIndex].Title;
}

// We also assign an onclick handler that will cause the browser to go to the detail page.
var self = this;
var handler = function() {
var resort = self._rowData[rowIndex];
categoryController.setRepresentedObject(resort);

var browser = document.getElementById('browser').object;
// The Browser's goForward method is used to make the browser push down to a new level. Going back to previous levels is handled automatically.
browser.goForward(document.getElementById('categoryLevel'), resort.Title);
/*
detailController.setRepresentedObject(resort);
var browser = document.getElementById('browser').object;
// The Browser's goForward method is used to make the browser push down to a new level. Going back to previous levels is handled automatically.
browser.goForward(document.getElementById('detailLevel'), resort);
*/
};
rowElement.onclick = handler;
} else {
if (templateElements.rowTitle) {
templateElements.rowTitle.innerText = "Loading...";
}
}
}
};

var detailController = {
// This object acts as a controller for the detail UI.

setRepresentedObject: function(representedObject) {
this._representedObject = representedObject; // a ResultItem.

// load the list for this here...
// categoryObject is a node...
// Values you provide
var feedURL = "asmx service feed is here....";

// XMLHttpRequest setup code
var xmlRequest = new XMLHttpRequest();
xmlRequest.onreadystatechange= function()
{
var result= null;

switch(xmlRequest.readyState)
{
case 4:
if(xmlRequest.status==200)
{
// parse it...
// dumpResponseXML(responseXML);
detailController._rowData= new Array();

var nodelist= xmlRequest.responseXML.getElementsByTagName('ResultItem');
for(var ii= 0; ii<nodelist.length; ii++)
{
detailController._rowData.push(new ResultItem(
nodelist[ii].getAttribute('Title'),
nodelist[ii].getAttribute('Description'),
nodelist[ii].getAttribute('OnClick'),
nodelist[ii].getAttribute('HREF'),
nodelist[ii].getAttribute('ImageHREF'),
nodelist[ii].getAttribute('MediaType')));
}

// now tell us to reload!
// we don't have to reload, we just have to change out our fields...
// var list= document.getElementById('categoryList');
// list.object.reloadData();
// When the represented object is set, this controller also updates the DOM for the detail page appropriately. As you customize the design for the detail page, you will want to extend this code to make sure that the correct information is populated into the detail UI.
r= detailController._rowData[0];
var parts= r.Title.split("|");

var detailText = document.getElementById('detailText');
detailText.innerHTML = parts[0];

var authorText = document.getElementById('authorText');
authorText.innerHTML = parts[1];

var durationText = document.getElementById('durationText');
durationText.innerHTML = parts[2];

var descriptionText = document.getElementById('descriptionText');
descriptionText.innerHTML= r.Description;

var videoBox= document.getElementById('videoBox');
videoBox.innerHTML= '<embed src="'+r.ImageHREF+'" href="'+r.HREF+
'" type="video/x-m4v" target="myself" scale="1" width="128px" height="128px" />';
}
break;

case 3:
break;

default:
break;
}
}

xmlRequest.open("POST", feedURL);
xmlRequest.setRequestHeader("Content-type", "text/xml; charset=utf-8");
xmlRequest.setRequestHeader("SOAPAction", "blam blam blam");
var parameters= representedObject.OnClick.split("|");
xmlRequest.send(buildXMLRequest(parameters[0], parameters[1],
parameters[2], parameters[3], parameters[4]));
}

};

//
// Function: load()
// Called by HTML body element's onload event when the web application is ready to start
//
function load()
{
setupParts();
listController.loadCategoryData();
}


// This object implements the dataSource methods for the list.
var categoryController = {

// Sample data for the content of the list.
// Your application may also fetch this data remotely via XMLHttpRequest.
_rowData: null,

// The List calls this method to find out how many rows should be in the list.
numberOfRows: function() {
if(this._rowData==null)
{
return 1;
} else {
return this._rowData.length;
}
},

setRepresentedObject: function(categoryObject)
{
// load the list for this here...
// categoryObject is a node...
// Values you provide
var feedURL = "SOAP service feed url here.";

// XMLHttpRequest setup code
var xmlRequest = new XMLHttpRequest();
xmlRequest.onreadystatechange= function()
{
var result= null;

switch(xmlRequest.readyState)
{
case 4:
if(xmlRequest.status==200)
{
// parse it...
// dumpResponseXML(responseXML);
categoryController._rowData= new Array();

var nodelist= xmlRequest.responseXML.getElementsByTagName('ResultItem');
for(var ii= 0; ii<nodelist.length; ii++)
{
categoryController._rowData.push(new ResultItem(
nodelist[ii].getAttribute('Title'),
nodelist[ii].getAttribute('Description'),
nodelist[ii].getAttribute('OnClick'),
nodelist[ii].getAttribute('HREF'),
nodelist[ii].getAttribute('ImageHREF'),
nodelist[ii].getAttribute('MediaType')));
}

// now tell us to reload!
var list= document.getElementById('categoryList');
list.object.reloadData();
}
break;

case 3:
break;

default:
break;
}
}

// voodoo.

xmlRequest.open("POST", feedURL);
xmlRequest.setRequestHeader("Content-type", "text/xml; charset=utf-8");
xmlRequest.setRequestHeader("SOAPAction", "Soap action header here.");

var parameters= categoryObject.OnClick.split("|");
xmlRequest.send(buildXMLRequest(parameters[0], parameters[1],
parameters[2], parameters[3], parameters[4]));
},

// The List calls this method once for every row.
prepareRow: function(rowElement, rowIndex, templateElements) {
var title= "";

if(this._rowData!=null)
{
title= this._rowData[rowIndex].Title;

// Assign a click event handler for the row.
var self = this;
rowElement.onclick = function(event) {
// Do something interesting
var resort = self._rowData[rowIndex];

detailController.setRepresentedObject(resort);
var browser = document.getElementById('browser').object;
// The Browser's goForward method is used to make the browser push down to a new level. Going back to previous levels is handled automatically.
browser.goForward(document.getElementById('detailLevel'), resort.Title);
}
} else {
title= "Loading..."
}

// templateElements contains references to all elements that have an id in the template row.
// Ex: set the value of an element with id="label".
if (templateElements.label) {
templateElements.label.innerText = title;
}
}
};

function buildXMLRequest(verb, companyCode, category, searchString, showCode)
{
return "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "+
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\""+" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
"<soap:Body>"+
"<GetResults xmlns=\"blahblahblah/\">"+
"<password>XXX</password>"+
"<verb>"+verb+"</verb>"+ // cat
"<companyCode>"+companyCode+"</companyCode>"+
"<category>"+category+"</category>"+
"<searchString>"+searchString+"</searchString>"+
"<showCode>"+showCode+"</showCode>"+
"</GetResults>"+
"</soap:Body>"+
"</soap:Envelope>";
}

function ResultItem(title, description, onclick, href, imagehref, result_type)
{
this.Title= title;
this.Description= description;
this.OnClick= onclick;
this.HREF= href;
this.ImageHREF= imagehref;
this.Type= result_type;

return this;
}

Scenario
Mar 20, 2008, 06:18 AM
1. Add some list values to _rowData (like "Settings" and "Players") and make sure they appear.
2. Add some corresponding new views to the stackLayout and give them names, like "PaneSettings" and "PanePlayers".
3. Rename the "resort" var to "pane" to make it more generic.
4. Then in the listController object's "handler" function, add a switch statement like this:

switch (pane) {
case "Settings":
browser.goForward(document.getElementById('PaneSettings'), pane);
break;
case "Players":
browser.goForward(document.getElementById('PanePlayers'), pane);
break;
default:
browser.goForward(document.getElementById('detailLevel'), pane);
}

Note that the line after "default:" was already there. I left it here so you can find it. Wrap that call up in this switch statement, or get rid of that call once you've replaced its functionality.

Hope this helps...

stankyfish
Jun 18, 2008, 04:12 PM
Here's my code:

...
// now tell us to reload!
var list= document.getElementById('list');
list.object.reloadData();
...



This finally got me working on data retrieved from an network data source. I was trying to do:


list.reloadData();


but I was getting Value undefined (result of expression list.reloadData) is not object.

Why do I need the list.object.reloadData? It appears that the list object itself is within the element named "list" as opposed to being what is returned from document.getElementById("list"). Even realizing that I needed to go to the DOM to get the list object in the first place wasn't readily obvious.

Perhaps its my lack of understanding of the delineations between Dashcode, it's generated JS and the DOM that adding to my confusion.