Opened 10 years ago

Closed 10 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 10 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 10 years ago by bill

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