Too many identical CSS IDs

Hi! Does anyone know how to change the default behavior during "render()" which sets the CSS ID of a component?

Right now I see that elements inside a Repeater all have the same CSS ID. I thought that was not allowed in true HTML... only one CSS ID for the entire document otherwise when you call "document.getElementById()" it's not deterministic what you will get.

Is there a way to turn off this default behavior or alter it to show up as a "class" instead of an ID?

Thanks.

Comments

  • What, no takers? this should be easy peasy lemon squeezy for members of the old guard.
  • You could work around this issue by explicitly setting the id of the control during onSetupItem. For example, in ListBasicSample:
    module.exports = kind({
    	name: 'enyo.sample.ListBasicSample',
    	classes: 'list-sample enyo-fit',
    	components: [
    		{name: 'list', kind: List, count: 20000, multiSelect: false, classes: 'enyo-fit list-sample-list', onSetupItem: 'setupItem', components: [
    			{name: 'item', classes: 'list-sample-item enyo-border-box', components: [
    				{name: 'index', classes: 'list-sample-index'},
    				{name: 'name'}
    			]}
    		]}
    	],
    	names: [],
    	setupItem: function(sender, event) {
    		// this is the row we're setting up
    		var i = event.index;
    		// make some mock data if we have none for this row
    		if (!this.names[i]) {
    			this.names[i] = names.makeName(5, 10, '', '');
    		}
    		var n = this.names[i];
    		var ni = ('00000000' + i).slice(-7);
    		this.$.item.set('id', 'item_'+ni);  // <== ADDED
    		// apply selection style if sender (the list) indicates that this row is selected.
    		this.$.item.addRemoveClass('list-sample-selected', sender.isSelected(i));
    		this.$.name.setContent(n);
    		this.$.index.setContent(ni);
    		return true;
    	}
    });
    This will only add a unique ID for the containing <div> but should do the trick for many scenarios requiring finding outside of enyo.
  • Thanks theryanjduffy, that's a clever way to manually override the ID during generation. As you noted, it only works on the containing DIV and not the sub components in the item.

    For those following at home, generally the best would be to not use an Enyo "List" and instead use the "Repeater" which is stateful and probably generally what most of us want 80% of the time. The "List" is useful when you have lots and lots of data to scroll through and a very simple "item" to render. In that case forcing the ID would certainly work.

    Generally we don't need to use the ID for anything but it bugged me since I know it violates the 10 commandments of HTML.

    The right way to think about this is to reflect on how ridiculously cool the "List" paradigm is and live with this idyosyncracy, along with this nice workaround provided by theryanjduffy. BUT, realize that most of the time we should be using a "Repeater" where this isn't even an issue.
  • IIRC, the reason we can get away with duplicate IDs in List is that there is technically only one "live" item that just got set up, or that was how it was described to me long ago.

    Eschewing List for Repeater will work as long as your list isn't terribly long, but eventually you will run into performance problems as you add more and more items.

    I've found it's been useful to switch all my Lists to DataLists and not care about the IDs of rendered elements. When I want a thing, I just grab the model in DataList.collection.at(index) or event.model in the tap handler. Of course, this only works in the context of the Enyo app and won't let you find/select those elements from somewhere else.

    In the spirit of "living with it" and not messing with the ID, you could perhaps set a className with a unique row-based identifier for each item and externally select them that way.
Sign In or Register to comment.