I was working with a friend today who had an interesting question. How do you preselect a row in a Spry Dataset? Turns out this was pretty simple (at first).
The initial solution is to simply add an "observer" to the dataset. You can think of this as a watcher. He will sit there until a certain event (the one he cares about) is fired. At that point he will then execute custom code. There are a set of default events you can observe:
onPreLoad, onPostLoad, onLoadError, onDataChanged, onPreSort, onPostSort, onCurrentRowChanged.
You can find details about these by scrolling down to "Observer Notifications" on the Spry documentation page.
So obviously onPostLoad will do it for you. Let's take a look at an example:
var myObserver = new Object;
myObserver.onPostLoad = function(dataSet, data) {
var preselected = 1;
var id = entries.getData()[preselected]["ds_RowID"];
//sets the ds row
entries.setCurrentRow(id);
};
entries.addObserver(myObserver);
In this example I created a function within a JavaScript object named myObserver. This is tied to a dataset named entries. My preselect value is 1 and hard coded, but obviously it could be dynamic:
var preselected = <cfoutput>#form.foo#</cfoutput>;
Remember that dataset rows start with 0. (Who else thinks ten million years from now we will still be starting arrays with 0 instead of 1??) Next we get the ID of the row we want:
var id = entries.getData()[preselected]["ds_RowID"];
And then lastly we use that ID to set the current selected row:
entries.setCurrentRow(id);
So this works like a charm.... almost. My friend was using a select box. I needed to preselect that as well. That's simple, right?
formfieldid.selectedIndex=preselected;
However when I ran this, the dropdown went away completely! Turns out my observer was running when the data was loaded. This was expected. But it was firing before Spry had a chance to actually update the HTML!
Luckily there is another way of handling it. Instead of watching over the dataset, we simply observe the region! I've blogged about region notifications before, using the simpler format of div's with state values. You can also write custom JavaScript code as well. Consider this new example:
var myObserver = new Object;
myObserver.onPostUpdate = function(notifier, data) {
var preselected = 1;
var id = entries.getData()[preselected]["ds_RowID"];
//sets the ds row
entries.setCurrentRow(id);
//sets the drop down
entrydd.selectedIndex=preselected;
};
Spry.Data.Region.addObserver('entry', myObserver);
This code is pretty similar, except that I use the Spry.Data.Region.addObserver function to assign the observer code to the region. Thanks go to Kin Blas of Adobe for the help with this.
Archived Comments
Thanks. I think this will definitely help me out.
This is a great hint Ray. I shall have to post all the work I have been doing with spry. Although currently one of the main limitations that I find is that it cant have complex data with in a spry dataset, wonder when they are releasing an update?
Mark, what do you mean by complex? The dataset can be as complex as the XML.
For example I cant return something like
<code>
-root
-product
-name
-relatedproducts
-product
-name
</code>
i.e. a prouct has a number of related products, when I select that product, I want another region to give me the related products, each of those products might contain more products etc.
That should be possible - but you will need to write JS code. You would need to use the select observer and then manually grab that data out of the set. It _should_ be possible. If not, maybe send me over your XML and I'll try to get it to work.