Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery select data attributes with common keyword

I have two elements with the following setup:

<span data-placeholder-class="test-class"></span>
<span data-placeholder-template="/some/template.hbs"></span>

I'm using underscore to loop over any elements containing either of these attributes and then performing relevant actions if they do.

Currently this is done like so

_.each($('[data-placeholder-class], [data-placeholder-template]'), function cb(element) {
  // code goes here
})

Rather than have to define each data attribute to loop over I wondered if there was a way I could select all attributes that contain a common keyword, in this case placeholder. e.g.

_.each($('[data-placeholder-*]'), function cb(element) {
  // code goes here
})

Anyone know if this is possible at all?

like image 431
woolm110 Avatar asked Oct 24 '16 10:10

woolm110


2 Answers

You could consider using a separate function which creates your selector, so you won't have to type the selector in full (but you'll have to write the function of course).

e.q.:

function getSelector() {
    return Array.prototype.map.call(arguments, function(key) {
        return '[data-placeholder-' + key + ']';
    }).join(',');
}

This will return your desired selector, and works with 1...N arguments.

getSelector('class', 'template')
// returns "[data-placeholder-template],[data-placeholder-class]"

_.each($(getSelector('class', 'template')), function cb(element) {
    // code goes here
});
like image 93
daanvanham Avatar answered Nov 12 '22 02:11

daanvanham


You can iterate the attributes of a collection of elements, push the element to an array if the element .attributes.name matches a provided string variable

var spans = document.querySelectorAll("span");

function filterAttrs(elems, attr, matches = []) {
  for (var elem of elems) {
    for (var attrs of elem.attributes) {
      // alternatively use `.indexOf()` or `RegExp()`
      // to match parts of string of `.name` or `.value`
      // of `.attributes` `NamedNodeMap`
      if (attrs.name.slice(0, attr.length) === attr) {
        matches.push({
          "element": elem,
          "attr": {
            "name": attrs.name,
            "value": attrs.value
          }
        })
      }
    }
  }
  return matches
}

var matches = filterAttrs(spans, "data-placeholder");

console.log(matches);

matches.forEach(function(match) {
  match.element.textContent = "matches:" + JSON.stringify(match.attr);
  match.element.style.color = "green";
});
<span data-placeholder-class="test-class"></span>
<span data-placeholder-template="/some/template.hbs"></span>
<span data-not-placeholder-template="/some/template.hbs">
data-not-placeholder-template
</span>
<span data-not-placeholder-template="/some/template.hbs">
data-not-placeholder-template
</span>
like image 1
guest271314 Avatar answered Nov 12 '22 02:11

guest271314