Home > database >  Set background color of parent div based on values of child span
Set background color of parent div based on values of child span

Time:04-20

var kb_cards = document.querySelectorAll('div.kbCardContainer');
console.log("kb_cards length: "   kb_cards.length);
<div >
    <span aria-live="assertive" role="alert" />
    <!-- ngIf: !(isMobileView == 'true') -->
    <div  ng-if="!(isMobileView == 'true')" style="">
        <!-- ngRepeat: knowledgeBase in knowledgeBases |filter:excludeAll -->
        <div  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  aria-hidden="true">Company AAA</span>
                <span >
                    <!-- ngIf: knowledgeBase.enable_socialqa -->
                    <span  aria-hidden="true"> 19 Articles</span>
                </span>
            </span>
            <span  ng-init="subscribedLabel[knowledgeBase.sys_id] = 'Subscribed'">
                <!-- ngIf: !knowledgeBase.isSubscribed -->
                <span ng-attr-id="subscribe{{knowledgeBase.sys_id}}"  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 />Subscribe</span>
                <!-- end ngIf: !knowledgeBase.isSubscribed -->
                <!-- ngIf: knowledgeBase.isSubscribed -->
            </span>
        </div>
        <!-- end ngRepeat: knowledgeBase in knowledgeBases |filter:excludeAll -->
        <div  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  aria-hidden="true">Company ADB</span>
                <span >
                    <!-- ngIf: knowledgeBase.enable_socialqa -->
                    <span  aria-hidden="true"> 0 Articles</span>
                </span>
            </span>
            <span  ng-init="subscribedLabel[knowledgeBase.sys_id] = 'Subscribed'">
                <!-- ngIf: !knowledgeBase.isSubscribed -->
                <span ng-attr-id="subscribe{{knowledgeBase.sys_id}}"  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 />Subscribe</span>
                <!-- end ngIf: !knowledgeBase.isSubscribed -->
                <!-- ngIf: knowledgeBase.isSubscribed -->
            </span>
        </div>
        <!-- end ngRepeat: knowledgeBase in knowledgeBases |filter:excludeAll -->
        <div  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  aria-hidden="true">Company BBD</span>
            <span >
                <!-- ngIf: knowledgeBase.enable_socialqa -->
                <span  aria-hidden="true"> 0 Articles</span>
            </span>
        </span>
        <span  ng-init="subscribedLabel[knowledgeBase.sys_id] = 'Subscribed'">
            <!-- ngIf: !knowledgeBase.isSubscribed -->
            <span ng-attr-id="subscribe{{knowledgeBase.sys_id}}"  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 />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:

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

CodePudding user response:

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 >
    <span role="button" tabindex="0" aria-label="Company BBD 0 Articles">
        <span  aria-hidden="true">Company BBD</span>
        <span >
            <span  aria-hidden="true"> 1 Articles</span>
        </span>
    </span>
</div>

So we have a .kbCard div, inside there is a span element with no class or anything that can help us to select it. So you want to get the first child of your .kbCard div:

let childLevel1 = element.children[0]; // "element" is the .kbCard div

This childLevel1 is this node : <span role="button" tabindex="0" aria-label="Company BBD 0 Articles">. From that node, I take a look to the HTML. I see that the element you want (where "0 Articles" is written) has the class kb-card-details. So it will be easy to select it. So it exactly what I do with childLevel1.querySelector(".kb-card-details");. And with this element I can check the content (if it is "0 Articles"), and do a treatment if it is.

Please note that I did fast so I miss a point, the real node I should select at the end is .kb-count. It is the real span containing the value. But because it is the only node, I guess it still works.

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

  • Related