Opened 9 years ago

Closed 9 years ago

#12413 closed defect (wontfix)

Possible id duplication, id-asignment via id="foo${id}" BUG in _Widget + _Templated

Reported by: zc Owned by:
Priority: high Milestone: tbd
Component: Dijit Version: 1.6.0rc1
Keywords: Cc:
Blocked By: Blocking:

Description

The problem (in dojo 1.3 to 1.6, source references for 1.5): If we want to assign id on templated widget's this.domNode via templateString: <div id="MyWidget_${id}" dojoAttachPoint="x">hello world</div>the widget's id and its domNode's id are not affected. Neither is the key in dijit.registry._hash. I have tested this solely on programmatically created widgets var x=new MyWidget({},dojo.byId('foo'));. Note: If we change constructor call to var x=new MyWidget({id:'foo'},dojo.byId('foo')); the effects are obviously the same.

Lifecycle of templated widget and id: The id is being assigned to this in _Widget line 412 (if id present in this.sourceNodeRef) or on line 422 (generated if no sourceNodeRef or no sourceNodeRef.id). The widget gets immediately registered on line 426 dijit.registry.add(this);. So no matter what id modifications are made in templated, widget is already registered at initial id value in dijit.registry._hash Now this.buildRendering(); is called (_Widget, line 427) - which means call to _Templated.buildRendering(). Despite templateString being processed properly in _Templated and proper id being assigned to this.domNode by dijit_Templated._stringRepl (e.g. MyWidget_foo), the id is immediately replaced in _Widget on line 431 via this._applyAttributes(); - and is set back to "foo". The widgetid is obviously also set to "foo".

I see no problem in such an behavior, but this feature (inability to change widget's id via templateString) is nowhere documented. On the countrary - http://docs.dojocampus.org/quickstart/writingWidgets/example implies (see template there!) that such an operation is possible - OR that widget's domNode is not being assigned any id. The outcome: if we are building degradable form with ids initially assigned to inputs (as it is the case in zend_Form) - we end up with DUPLICATE ids!

Possible solutions: moving dijit.registry.add(this); behind this.buildRendering call in_Widget (to register widget under proper key==widgetid in dijit.registry._hash)and updating this.id with this.domNode (if this.domNode!=undefined) in _Templated AFTER dijit_Templated._stringRepl was called in dijit_Templated.buildRendering. Additional ID-uniqueness might be necessary. The solution is working, though I am unaware of any side-effects it might bring about.

Example: http://jsfiddle.net/XJ9bq/ OR http://pastebin.com/FnLFemKc

Change History (2)

comment:1 Changed 9 years ago by bill

That's correct, since id is in attributeMap, you need to override attributeMap to send the id to the node you want, rather than the domNode:

attributeMap: { id: "focusNode", ... }

You are right about the documentation example, I'll update that.

comment:2 Changed 9 years ago by bill

Resolution: wontfix
Status: newclosed
Note: See TracTickets for help on using tickets.