I'm struggling trying to find a way to get the text of child elements and use them as separate classes for the parent element. I kinda got the logic but can't find a way to separate each class.
To add more complication, I want to remove special characters, replace blank spaces and put everything lowercase. I think I already got this part (hopefully).
Anyway... I have this html code:
<div class="parent">
<div class="child">Child #1</div>
<div class="child">Child #2</div>
<div class="child">Child #3</div>
<div class="child">Child #4</div>
</div>
<div class="parent">
<div class="child">Child #A</div>
<div class="child">Child #b</div>
<div class="child">Child #9</div>
<div class="child">Child #K</div>
</div>
What I want to see is the following:
<div class="parent new_child_1 new_child_2 new_child_3 new_child_4">
<div>Child #1</div>
<div>Child #2</div>
<div>Child #3</div>
<div>Child #4</div>
</div>
<div class="parent new_child_a new_child_b new_child_3 new_child_1">
<div>Child #A</div>
<div>Child #b</div>
<div>Child #3</div>
<div>Child #1</div>
</div>
So I got this so far:
$(".parent").each(function(){
var child_text = $(this).find(".child").text();
var new_class = child_text.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '_').toLowerCase()
$(this).addClass("new_" new_class);
});
But I get a single string of all the texts (i.e. "new_child_1child_2child_3child_4").
Thanks to everyone who will help.
CodePudding user response:
you're iterating on the parent only, you need to iterate on the children directly. I haven't tried this yet, but I believe it should be close.
$(".parent").children().each(function(){
var child_text = $(this).text();
var new_class = child_text.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '_').toLowerCase()
$(this).addClass("new_" new_class);
});
Edit: If you just need to add a space, you can do that within the function:
$(".parent").each(function(){
var child_text = $(this).find(".child").text();
var new_class = child_text.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '_').toLowerCase()
// check if newclass has data, if it does, add a leading space
if (new_class.length > 0) { $(this).addClass(" new_" new_class); );
});
CodePudding user response:
You could make an array from the children and use Array.reduce
, like this:
$(".parent").each(function() {
var children = $(this).find('.child');
var new_class = Array.from(children).reduce((carry, child) => {
var text = child.innerText.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '_').toLowerCase();
carry = `new_${text} `;
return carry;
}, '');
console.log(new_class);
$(this).addClass(new_class);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div class="child">Child #1</div>
<div class="child">Child #2</div>
<div class="child">Child #3</div>
<div class="child">Child #4</div>
</div>
<div class="parent">
<div class="child">Child #A</div>
<div class="child">Child #b</div>
<div class="child">Child #9</div>
<div class="child">Child #K</div>
</div>
CodePudding user response:
If the character you want is always after a #, you can use a split function, like this
EDITED
$(".parent").each(function() {
var childs = [];
$(this).find(".child").each(function(key) {
childs[key]='new_child_' $(this).text().replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '_').toLowerCase();
$(this).removeClass('child');
});
console.log(childs.join(' '));
$(this).addClass(childs.join(' '));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div class="child">Child #1</div>
<div class="child">Child #2</div>
<div class="child">aBc*d#</div>
<div class="child">Child #4</div>
</div>
<div class="parent">
<div class="child">Child #A</div>
<div class="child">Child #b</div>
<div class="child">Child #9</div>
<div class="child">Child #K</div>
</div>