: 4581 | 108544 | 12346

Make it easier to get XPage components by rendered id - XSP.byId 
New idea submissions, commenting and voting are no longer available on this site. Logins have also been disabled.
Use this IdeaSpace to post ideas about Domino Designer.

: 21
: 21
: 0
: Domino Designer
: xpages
: Tommy Valand2746 11 Sep 2009
:
: / Email
The current implementation of id's in XPages is -very- cumbersome, and makes it harder to write unobtrusive JS. A workaround for this would be to make a hashmap (converted to a JS object in the browser) of all the element names/their rendered id.
 
I would think this shouldn't be too hard to implement in the compiler-engine..?
 
--
// Pseudocode for the browser (I don't know the XSP API)
XSP.byId = function( id ){
id = XSP.pageIds[id] || id;
return document.getElementById( id )
}



1) Patrick Kwinten22013 (11 Sep 2009)
it's a pain in the ass, indeed.
2) Matt White9275 (11 Sep 2009)
I'm assuming that Tommy knows the various ways of getting an id, but for those XPages newbies, there are two main ways of getting hold of the id of an element as it is rendered to the browser (so that you can use the id in client side Javascript):

In the JS for an object you can use "#{id:myfield}" which will get translated into something like "view:_id1:_id2:_id51:repeat1:1:_id53:myfield"

In server side JS code where you need to get a field you can use "getClientId("myfield")"

More details here: { Link }
3) Barry McGovern629 (11 Sep 2009)
I think what you described can be done with dojo.query.

It works great if there is only one object with that ID. It will not work if that object is in a repeat though. If there is more then one object - you will have to pass the complete ID with SS JS. Not much getting around that one.

Here's where I originally saw the dojo.query method:
{ Link }
4) Tommy Valand2746 (11 Sep 2009)
@Barry: I think you're missing the point. The page you're linking to is describing the same as Matt did in his blog.

What I'm after is to be able to write a static JS library (a text file), and get the element using the stored id. Not by the id attribute in the rendered HTML, but by a helper method, that has access to both the "designer id" and the rendered id. Not sure if this made it clearer..?
5) Peter Presnell26654 (11 Sep 2009)
I think the assumption here would have to be that the "designer id" is only represented once in the HTML. The reason why Xpages (and most other Web development environments) create these complicated names for the rendered ID is that design elements can be reused multiple times in a single piece of HTML. e.g. repeater controls, multiple custom controls can assign the same ID and one Xpage can insert another Xpage.
6) Tim Tripcony860 (11 Sep 2009)
@Tommy - Matt's example of a namespaced ID is a perfect illustration of WHY the ID must be namespaced: if you have an edit box with a "designer" ID of "myField", but it's inside a repeat control, you could end up with 10, 20, maybe 100 fields in the rendered HTML, all with an ID of "myField"... unless the ID is translated into something guaranteed to be unique.

So I like your idea of having a client-side function that we can just pass the source ID and have it resolve the client ID... except for two caveats:

1. As Matt mentioned, we already have that in the form of the #{id:myField} syntax.
2. A "true" client-side function (i.e. one that is not translated by Domino at render time) would be forced to return a NodeList (just like dojo.query), because any ID passed to it would potentially match numerous elements (not just in the example of a repeat control, but also in cases where the same ID is used in multiple custom controls included in the same XPage (or once in a control and once on the XPage itself). In other words, you'd still end up having to do something like this:

XSP.byId("myField").forEach(function(thisNode){
if(someEvaluation(thisNode)) { // is this actually the one we want?
executeSomeProcess(thisNode);
}
});

In the case of a repeat, you might have to loop through dozens or even hundreds of nodes that all have the same source ID but have different client IDs, and try somehow to determine which of them is actually the one you're targeting.

I'm guessing that what you're really looking for is a way to target an element that WILL be unique (i.e. it's not inside a repeat, and you've named your elements uniquely across the entire render hierarchy). My recommendation would be to assign your elements a unique class as well - in addition to any other CSS classes applied to the element, list the ID as another class to apply. Then you could do something like this:

XSP.byId = function(id) {
var returnNode;
dojo.query("." + id).forEach(function(thisNode){returnNode = thisNode;});
return returnNode;
}

The result is that it will return the last element it finds using the passed ID as a class... as long as the class was used uniquely, this will return the precise element you're looking for.
7) Tommy Valand2746 (11 Sep 2009)
@Tim
1. With that method of fetching items, you have to write JS code all over the XPage. This easily becomes a maintenance nightmare if you're maintaining other people's code. It also makes it hard to write unobtrusive JS, unless I've missed something(?)/you use classes.

2. Automatically fetching the nodelist would be unnecessary/a potential memory hog. If there were multiple entities with the same "designer id", then the map would contain an array of namespaced ids ({ customerRepeat: [..] }).. Using classes, as you mention, all over the place is the only option today, but that adds "unnecessary bytes" to the webpage if some kind of JS mapping of ids were available.

I haven't made any real applications with XPages, but I can't see where I'd actually want to get to a specific repeated item on the client side. That is unless it had to do with event handling. In that case, I'd add a listener to a container with a unique id, and use event delegaton. OnClick -> does the clicked node have an id matching the item in the componentId-map/object. That is similar to what I do in Domino applications today. It's fast, and requires little memory, as opposed to adding an event listener to every item in the repeat control.










:
:




Welcome to IdeaJam™


You can run IdeaJam™ in your company. It's easy to install, setup and customize. Your employees, partners and customers will immediately see results.

Use IdeaJam to:

  • Collect ideas from employees
  • Solicit feedback and suggestions from employees and customers
  • Run innovation contests and competitions
  • Validate concepts
  • Use the power of "crowd-sourcing" to rank ideas and allow the best ideas to rise to the top

IdeaJam™ works with:

  • IBM Connections
  • IBM Lotus Quickr
  • Blogs and Wikis
  • Websphere Portal
  • Microsoft Sharepoint
  • and other applications.

IdeaJam has an extensive set of widgets and API's that allow you to extend and integrate IdeaJam™ with other applications.

Learn more about IdeaJam >>






IdeaJam developed by

Elguji Software Logo