Search code examples
dartdart-html

Selecting element decendants by attribute


in the following html i want to select the descendants of the view tag by attribute name

<view data-context="testviewmodel">
       <div>
         id:<input data-bind-two-way="model.id">
         name:<input data-bind-two-way="model.name">
         description:<input data-bind-two-way="model.description">
       </div>

       <div>
         id:<input data-bind-two-way="model.id">
         name:<input data-bind-two-way="model.name"> 
         description<input data-bind-two-way="model.description"> 
       </div>

       <div>
         <p>{{model.id}}</p>
         <p>{{model.name}}</p>
         <p>{{model.description}}</p>
       </div>           
    </view>

so i should get 6 elements (the 6 input elements that have the attribute data-bind-two-way) however i wrote the following recursive function and it gives me a list of 3 elements which are the first three descendant input elements

 static List<Element> decendantSelector(Element rootElement,{List<Element> collectedElements:null,
                                                       List<String> targetAttributes:null,
                                                       bool mustHaveAllAttributes:false}){

    if(collectedElements==null)
      collectedElements = new List<Element>();


    for(Element child in rootElement.children){
      bool haveAllAttributesFlag = true;
      for(String attrName in targetAttributes){
        if(child.attributes.containsKey(attrName)){
          collectedElements.add(child);
        } else {
          haveAllAttributesFlag = false;
        }
        if(!haveAllAttributesFlag && mustHaveAllAttributes)
          break;
      }
      if(child.hasChildNodes())
          return  decendantSelector(child,
              collectedElements:collectedElements,
              targetAttributes:targetAttributes,
              mustHaveAllAttributes:false);
    }
    return collectedElements;
  }

used it as

List<Element> descendantsWithAttributeDataBindTwoWay = decendantSelector(querySelector('view'),targetAttributes:['data-bind-two-way']);

any idea why the descendants in the second div get ignored?


Solution

  • This is because of this return statement

    if(child.hasChildNodes())
              return  decendantSelector(child,
    

    remove just the return and it will work.

    Have you considered something like

    Set<Element> result = new Set<Element>();
    result.addAll(querySelectorAll('view [data-bind-two-way]'));
    // repeat the same with other combinations until you have covered all cases