arrays, links, and iteration

47 views
Skip to first unread message

kumarachi

unread,
May 18, 2009, 12:36:47 PM5/18/09
to SIMILE Widgets
Hello,

Could someone help me please.
I am having some trouble creating links from an array in my JSON data.

I have this snippet from my data.js:
"scriptURI" : [
"walkthrough.doc",
"overview.doc",
"datasheet.docx"
],

And in my exhibit file, I want to be able to show these items as href
links in an Unordered List inside a Lens like this:
<ul>
<li><a href="../scripts/walkthrough.doc">walkthrough</a></li>
<li><a href="../scripts/walkthrough.doc">overview</a></li>
<li><a href="../scripts/walkthrough.doc">datasheet</a></li>
</ul>

I am sure this has been done many times elsewhere...

I am looking through the various examples for examples of iteration on
such fairly simple data - and attempted to use the foreach function,
but somehow cant get this working. I dont quite understand what the
correct syntax is...and I am not even sure if using foreach is the
right approach.

I seem to get them all concatenated together, or in other variations,
I receive an error about G[1] undefined...What should the second
parameter here be?

<ul>
<li><span ex:content="foreach(.scriptURI,???)"></span></li>
</ul>


Can anyone help me?

thanks in advance,

David Huynh

unread,
May 18, 2009, 1:32:59 PM5/18/09
to simile-...@googlegroups.com

Kumar,

Try

<ul ex:content=".scriptURI">
<li><a ex:href-subcontent="../scripts/{{value}}"
ex:content="value"></a></li>
</ul>

Elements inside an element with ex:content are used as a template for
rendering each value in the set that the ex:content expression evaluates to.

David

kumarachi

unread,
May 18, 2009, 1:58:32 PM5/18/09
to SIMILE Widgets
oh my god :-).
perfect, David, thanks so much - works exactly as I need it.
1 mins after 3 days of trying variations without fully understanding
what I was trying...

thank you!!.

kumarachi

unread,
May 27, 2009, 6:29:08 PM5/27/09
to SIMILE Widgets
Hi,

now I need a little more help on this...hope there's a solution.

the Path to the object I need to link to is actually categorized
according to the label.

so instead of

ex:href-subcontent="../scripts/{{value}}"

I need to be able to link to content that is in different folders,

scripts/<some-name>/{{value}},

where <some-name> changes according to the label on that item.


I have, with my limited understanding of expressions in Exhibit, tried
various things like:
scripts/{{label}}/{{value}}, scripts/{{.label}}/{{value}} and other
variations - all in vain.

Can you help me?

thanks
-k

John Callahan

unread,
May 27, 2009, 9:01:47 PM5/27/09
to simile-...@googlegroups.com
You could try something like this... First, create a function that
will process the data values. Then, assign that function to the
ex:href-subcontent. This also works for facets.

Exhibit.FunctionUtilities.registerSimpleMappingFunction(
"myFunction",
function(val) {
if (val == "foo") {
return "../folder1/" + val;
} else if (val == "foo2") {
return "../folder2/" + val";
}
},
"text"
);


ex:href-subcontent="myFunction(.scriptURI)" or
ex:href-subcontent="myFunction({{value}})"


You could probably also pass in multiple values to create your path information, something like
ex:href-subcontent="myFunction(.scriptURI, .data2)"



Not quite an elegant solution but it seems like it should work in your case.

- John

David Huynh

unread,
May 28, 2009, 2:40:57 AM5/28/09
to simile-...@googlegroups.com
Your mistakes can be somewhere else other than the code snippets that
you're showing us here. Could you either give a URL to your exhibit or
provide much more code so that it's easier for us to try to think what
might have gone wrong? Also, for whatever that you tried, what were the
results? Did everything break? Or did the links just not get formatted
correctly?...

David

kumarachi

unread,
May 28, 2009, 3:27:33 AM5/28/09
to SIMILE Widgets
hi, David:


The results for what i tried for what seemed like the right
expressions to use were generally that the expression keeps evaluating
to 'null':

scripts/{{.label}}/{{value}}

shows up in my rendered page as:

scripts/null/DataSheet.doc, for example.

It seems I am not using the correct expression for getting the label
into my path.

Here is the code - this is a section that is part of a Lens view:

<div ex:role="exhibit-viewPanel" style="padding: 6px; color:white;"
ex:viewClass="Exhibit.TabularView">
....
...
<div ex:role="exhibit-lens" ex:formats="date
{ mode: short; show: date }" class="item" style="display:
none;overflow:visible;width:100%">
....

<div
id="scriptsList" class="scriptsList">
<p class="section-title">Scripts:</p>
<ul ex:content=".scriptURI" id="scriptsList">
<li><a ex:href-subcontent="scripts/{{.label}}/{{value}}"
ex:content="value" class="lens-link"></a></li>

<!--other variations I tried: -->

<!-- li><a ex:href-subcontent="scripts/',.label,{{value}}"
ex:content="value" class="lens-link"></a></li -->

<!-- li><a ex:href-content="concat('scripts/',#{{.label}},value)"
ex:content="value" class="lens-link"></a></li -->
<!-- li><a ex:href-content="concat('scripts/',.label,value)"
ex:content="value" class="lens-link"></a></li -->


</ul>
</div>

...
</div>
....
</div >


And this is the data:
{
"items" : [
{
"type" : "Item",
"label" : "PUMA",
"scriptURI" : [
"DataSheet.doc",
"KnownIssues.doc",
"Demo script.doc",
"Manifest.doc"
],
"release-date" : "2009-04-20T00:00:00-04:00"
},
{
"type" : "Item",
"label" : "COUGAR",
"scriptURI" : [
"FlowDiagram.doc",
"KnownIssues.doc",
"Architecture.doc",
"CaseStudy.doc"
],
"release-date" : "2009-04-20T00:00:00-04:00"
},

[etc....]

]


So that in the end, i'd like the lens to render this for each item,
dynamically:

/scripts/PUMA/DataSheet.doc
/scripts/PUMA/KnownIssues.doc
/scripts/PUMA/Manifest.doc;

and for label=COUGAR:
/scripts/COUGAR/CaseStudy.doc
/scripts/COUGAR/FlowDiagram.doc

etc.






John:

the problem is that I dont know these label name values beforehand,
even if I wanted to hardcode them in the function you provided.


The URL to this exhibit is internal to my company, so I am sorry I
cannot share that.

I hope this is sufficient info, sorry I was unclear.


best,
-k

David Huynh

unread,
May 29, 2009, 1:17:58 AM5/29/09
to simile-...@googlegroups.com
kumarachi wrote:
> hi, David:
>
>
> The results for what i tried for what seemed like the right
> expressions to use were generally that the expression keeps evaluating
> to 'null':
>
> scripts/{{.label}}/{{value}}
>
> shows up in my rendered page as:
>
> scripts/null/DataSheet.doc, for example.
>
Oh I see. That can be tricky since you have several items sharing the
same .doc.

If each .doc belongs to only one item, then you could have used this
expression

scripts/{{!scriptURI.label}}/{{value}}

The !scriptURI part retrieves the item given a .doc. But since that's
not the case--a .doc can belong to several items, then I'd try the
following approach. First, extend Exhibit by defining a new control
construct called "with" that you can used to define a variable, and a
function called "last-segment":

<script>
Exhibit.Controls["with"] = {
f: function(
args,
roots,
rootValueTypes,
defaultRootName,
database
) {
var valueCollection = args[0].evaluate(roots,
rootValueTypes, defaultRootName, database);
var nameCollection = args[1].evaluate(roots,
rootValueTypes, defaultRootName, database);

var name = null;
nameCollection.forEachValue(function(v) {
if (v) {
name = v;
return true;
}
});

var oldValue = null
var oldValueType = null
if (name in roots) {
oldValue = roots[name];
oldValueType = rootValueTypes[name];
}

rootValueTypes[name] = valueCollection.valueType;
roots[name] = valueCollection;

var r = args[2].evaluate(roots, rootValueTypes,
defaultRootName, database);

if (oldValue != null) {
rootValueTypes[name] = oldValueType;
roots[name] = oldValue;
} else {
delete rootValueTypes[name];
delete roots[name];
}

return r;
}
};


Exhibit.FunctionUtilities.registerSimpleMappingFunction("last-segment",
function(v) {
var slash = v.lastIndexOf("/");
return v.substr(slash + 1);
}, "text");
</script>

Then your ul can be

<ul ex:content="with(value, 'parent', foreach(.scriptURI,
concat('script/', parent, '/', value)))">
<li><a ex:href-content="value"
ex:content="last-segment(value)"></a></li>
</ul>

Let me know if that works. It's somewhat of a hack but the right
solution would require deeper changes to Exhibit.

David

kumarachi

unread,
May 29, 2009, 3:57:22 AM5/29/09
to SIMILE Widgets
awesome! that works - thanks David!


On May 29, 6:17 am, David Huynh <dfhu...@alum.mit.edu> wrote:
> kumarachiwrote:
Reply all
Reply to author
Forward
0 new messages