Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Set background color of parent div based on values of child span

var kb_cards = document.querySelectorAll('div.kbCardContainer');
console.log("kb_cards length: " + kb_cards.length);
<div class="row kbCardContainer">
    <span aria-live="assertive" role="alert" class="sr-only ng-binding"/>
    <!-- ngIf: !(isMobileView == 'true') -->
    <div class="col-md-12 ng-scope" ng-if="!(isMobileView == 'true')" style="">
        <!-- ngRepeat: knowledgeBase in knowledgeBases |filter:excludeAll -->
        <div class="kbCard ng-scope" role="none" tabindex="-1" ng-style="getStyle($index,knowledgeBase)" ng-click="clickKnowledgeBase(knowledgeBase)" ng-repeat="knowledgeBase in knowledgeBases |filter:excludeAll" style="border-left: 4px solid rgb(39, 142, 207);">
            <span role="button" tabindex="0" aria-label="Company AAA 19 Articles">
                <span class="kb-title kbCardOverflow ng-binding" aria-hidden="true">Company AAA</span>
                <span class="kb-card-details">
                    <!-- ngIf: knowledgeBase.enable_socialqa -->
                    <span class="kb-count ng-binding" aria-hidden="true"> 19 Articles</span>
                </span>
            </span>
            <span class="kb-card-details" ng-init="subscribedLabel[knowledgeBase.sys_id] = 'Subscribed'">
                <!-- ngIf: !knowledgeBase.isSubscribed -->
                <span ng-attr-id="subscribe{{knowledgeBase.sys_id}}" class="subscribe ng-scope" ng-if="!knowledgeBase.isSubscribed" ng-click="knowledgeBase.isSubscribed = !knowledgeBase.isSubscribed; clickSubscribe(knowledgeBase, $event)" role="button" aria-label="Subscribe to Company AAA" tabindex="0" id="subscribe47f9af20dbaae810b2fe3313f39619df">
                    <i class="icon-empty-circle"/>Subscribe</span>
                <!-- end ngIf: !knowledgeBase.isSubscribed -->
                <!-- ngIf: knowledgeBase.isSubscribed -->
            </span>
        </div>
        <!-- end ngRepeat: knowledgeBase in knowledgeBases |filter:excludeAll -->
        <div class="kbCard ng-scope" role="none" tabindex="-1" ng-style="getStyle($index,knowledgeBase)" ng-click="clickKnowledgeBase(knowledgeBase)" ng-repeat="knowledgeBase in knowledgeBases |filter:excludeAll" style="border-left: 4px solid rgb(75, 215, 98);">
            <span role="button" tabindex="0" aria-label="Company ADB 0 Articles">
                <span class="kb-title kbCardOverflow ng-binding" aria-hidden="true">Company ADB</span>
                <span class="kb-card-details">
                    <!-- ngIf: knowledgeBase.enable_socialqa -->
                    <span class="kb-count ng-binding" aria-hidden="true"> 0 Articles</span>
                </span>
            </span>
            <span class="kb-card-details" ng-init="subscribedLabel[knowledgeBase.sys_id] = 'Subscribed'">
                <!-- ngIf: !knowledgeBase.isSubscribed -->
                <span ng-attr-id="subscribe{{knowledgeBase.sys_id}}" class="subscribe ng-scope" ng-if="!knowledgeBase.isSubscribed" ng-click="knowledgeBase.isSubscribed = !knowledgeBase.isSubscribed; clickSubscribe(knowledgeBase, $event)" role="button" aria-label="Subscribe to Company ADB" tabindex="0" id="subscribe83f9af20dbaae810b2fe3313f39619e6">
                    <i class="icon-empty-circle"/>Subscribe</span>
                <!-- end ngIf: !knowledgeBase.isSubscribed -->
                <!-- ngIf: knowledgeBase.isSubscribed -->
            </span>
        </div>
        <!-- end ngRepeat: knowledgeBase in knowledgeBases |filter:excludeAll -->
        <div class="kbCard ng-scope" role="none" tabindex="-1" ng-style="getStyle($index,knowledgeBase)" ng-click="clickKnowledgeBase(knowledgeBase)" ng-repeat="knowledgeBase in knowledgeBases |filter:excludeAll" style="border-left: 4px solid rgb(255, 202, 31);">
            <span role="button" tabindex="0" aria-label="Company BBD 0 Articles">
            <span class="kb-title kbCardOverflow ng-binding" aria-hidden="true">Company BBD</span>
            <span class="kb-card-details">
                <!-- ngIf: knowledgeBase.enable_socialqa -->
                <span class="kb-count ng-binding" aria-hidden="true"> 0 Articles</span>
            </span>
        </span>
        <span class="kb-card-details" ng-init="subscribedLabel[knowledgeBase.sys_id] = 'Subscribed'">
            <!-- ngIf: !knowledgeBase.isSubscribed -->
            <span ng-attr-id="subscribe{{knowledgeBase.sys_id}}" class="subscribe ng-scope" ng-if="!knowledgeBase.isSubscribed" ng-click="knowledgeBase.isSubscribed = !knowledgeBase.isSubscribed; clickSubscribe(knowledgeBase, $event)" role="button" aria-label="Subscribe to Company BBD" tabindex="0" id="subscribe07f9af20dbaae810b2fe3313f39619e9">
                <i class="icon-empty-circle"/>Subscribe</span>
            <!-- end ngIf: !knowledgeBase.isSubscribed -->
            <!-- ngIf: knowledgeBase.isSubscribed -->
        </span>
    </div>
    <!-- end ngRepeat: knowledgeBase in knowledgeBases |filter:excludeAll -->
</div>
<!-- end ngIf: !(isMobileView == 'true') -->
<!-- ngIf: (isMobileView == 'true') -->
</div>

In the snippet above, I have an extract of HTML from a Service Now Knowledge Base page.

When there are hundreds of KB categories, most of which have no articles against them, I wanted to work out how to add a style attribute to the divs with a class of kbCard so that e.g. the background is yellow.

I realise I could do something like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

var this_card = document.querySelectorAll('div.kbCard');
var_name.setAttribute("style", "background:yellow;");

However, in this scenario, I need to loop through all of the kbCard divs nested below the parent kbCardContainer div, and from there, check the value of the kb-count span, and if it is not "0 Articles", then set the style attribute of the kbCard div.

I realise that’s asking for a lot though!

I’m familiar with looping through records and updating them – e.g.

var table_cells = document.querySelectorAll('td.vt');
for (var j = 0; j < table_cells.length; j++) {
    var cell = table_cells[j];
    cell.innerHTML = cell.innerHTML.replaceAll('Work in Progress', 'WIP');
    cell.innerHTML = cell.innerHTML.replaceAll('Root Cause Analysis', 'RCA');
    cell.innerHTML = cell.innerHTML.replaceAll('Development', 'Dev');
}

But in this case, I am stuck on a number of fronts because:

  1. The length of kbCardContainer is only returning 1 because there is only 1 div nested below it, with a class of col-md-12. I can’t select on that class as there are other divs on the page with the same class. How can I select the contents of div col-md-12 nested below the kbCardContainer div?
  2. Even if I could fix 1, I’m not sure how to check the contents of a SPAN nested below another DIV, and then set an attribute of the parent DIV…

Sorry, I am asking for "the moon on a stick" here, but thought I’d ask for advice anyway.

Apologies for my mistakes etc.

Thanks

>Solution :

Fist you want to do, is to get all your cards, by doing something like it:

const cards = document.querySelectorAll(".kbCard");

Then you will need to loop throw them, to do what you need:

for(card of cards) {
    let subChild = GetWantedSubchild(card);
    if (!subChild) continue;

    if (subChild.textContent.includes("0 Articles")) {
        // Do what ever you want
        card.setAttribute("style", "background:yellow;");
    }
}

function GetWantedSubchild(element) {
    let childLevel1 = element.children[0];
    if (!childLevel1) return undefined;

    return childLevel1.querySelector(".kb-card-details");
}

So now, how I created this GetWantedSubchild. I looked at the HTML structure you show us, and I tried to simplify it, by removing no "needed elements" (for our problem).

<div class="kbCard ng-scope">
    <span role="button" tabindex="0" aria-label="Company BBD 0 Articles">
        <span class="kb-title kbCardOverflow ng-binding" aria-hidden="true">Company BBD</span>
        <span class="kb-card-details">
            <span class="kb-count ng-binding" aria-hidden="true"> 1 Articles</span>
        </span>
    </span>
</div>

I made a test on my side and it seems working 🙂 Do not hesitate if you have any question.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading