Reputation: 15047
Situation:
There are many checkboxes, this is only a small part of a tree:
<li class="main">
<input type="checkbox" id="cat_6" class="parent_cat_0" name="local[]">
<label class="strong" for="cat_6">Stellenbeschreibungen</label>
<ul>
<li class="main">
<input type="checkbox" id="doc_31" class="parent_cat_6" name="local[]">
<label for="doc_31">Stellenbeschreibung Marketing/Vertrieb</label>
</li>
</ul>
</li>
I want to make a selector for parent of this checkbox that has class "parent_cat_6"
So the final selector should be:
let parent = $('#cat_6');
But I don't know how to cut off the 'parent_' out of checked checkbox class.
child has class="parent_cat_6"
parent has id="cat_6"
Do I need to use regex to make selector for the parent or there is another way?
UPDATE: This works:
selected.attr('class').split(' ').slice(-1)[0].substr(7);
But it's ugly, any improvements are welcome!
Upvotes: 1
Views: 41
Reputation: 206121
Suffixed or prefixed ClassNames are not the best when you have to deal with references in JavaScript.
Just to target such suffixed class - the selector gets complicated:
[class^="parent_cat_"], [class*=" parent_cat_"]
you would better go using two classes in such case, one that is common to all your elements, and the specific one: class="cat_checkbox parent_cat_42"
. That way the selector becomes as simple as
.cat_checkbox // BETTER - Common class for all checkboxes
The problem is that a className can house many names, and to find the desired one might be tricky.
How to get 42
out of class="foo bar fooBar parent_cat_42 bla_bli_40"
?
classList
parent_cat_\d+
#cat_[ID]
const findIndex_parent_cat = klass => /^parent_cat_\d+$/.test(klass);
const findNum_parent_cat = klass => klass.replace(/\D+/, '');
$('[class^="parent_cat_"], [class*=" parent_cat_"]').on('change', function() {
const klasses = $(this).attr('class');
const ID = klasses.match(/(?:^|\s)parent_cat_(\d+)(?:$|\s)/)[1];
const cat_ID = `#cat_${ID}`;
console.log(`ID: ${cat_ID}`);
$(cat_ID).prop({checked: this.checked});
});
<ul>
<li class="main">
<input type="checkbox" id="cat_6" class="something parent_cat_0 bla" name="local[]">
<label class="strong" for="cat_6">Stellenbeschreibungen</label>
<ul>
<li class="main">
<input type="checkbox" id="doc_31" class="blue red inp parent_cat_6 foo bar" name="local[]">
<label for="doc_31">Stellenbeschreibung Marketing/Vertrieb</label>
</li>
</ul>
</li>
</ul>
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
or it can be done by using Regex (?:^|\s)parent_cat_(\d+)(?:$|\s)
:
const findIndex_parent_cat = klass => /^parent_cat_\d+$/.test(klass);
const findNum_parent_cat = klass => klass.replace(/\D+/, '');
$('[class^="parent_cat_"], [class*=" parent_cat_"]').on('change', function() {
const klasses = [...this.classList];
const klassIndex = klasses.findIndex(findIndex_parent_cat); // Get index
const klass = klasses[klassIndex]; // Find it in classList
const ID = findNum_parent_cat(klass); // Now let's extract the N number ID
const cat_ID = `#cat_${ID}`; // Finally we have the ID...
console.log(`${klass} found in classList at index ${klassIndex}. ID: ${cat_ID}`);
$(cat_ID).prop({checked: this.checked});
});
<ul>
<li class="main">
<input type="checkbox" id="cat_6" class="something parent_cat_0 bla" name="local[]">
<label class="strong" for="cat_6">Stellenbeschreibungen</label>
<ul>
<li class="main">
<input type="checkbox" id="doc_31" class="blue red inp parent_cat_6 foo bar" name="local[]">
<label for="doc_31">Stellenbeschreibung Marketing/Vertrieb</label>
</li>
</ul>
</li>
</ul>
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
data-*
attribute instead!Exactly, here's a remake of the above madness.
And yeah, see HTML how to use the <label>
without the for
attribute:
$('[data-cat]').on('change', function() {
const cat_ID = $(this).attr('data-cat'); // Finally we have the ID...
console.log(`ID: ${cat_ID}`);
$(cat_ID).prop({checked: this.checked});
});
<ul>
<li class="main">
<label>
<input type="checkbox" id="cat_6" data-cat="#cat_0" name="local[]">
Stellenbeschreibungen
</label>
<ul>
<li class="main">
<label>
<input type="checkbox" id="doc_31" data-cat="#cat_6" name="local[]">
Stellenbeschreibung Marketing/Vertrieb
</label>
</li>
</ul>
</li>
</ul>
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
Upvotes: 1