Selecting element decendants by attribute

Issue

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

Answered By – Günter Zöchbauer

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *