1

I have an issue, I am trying to hide an "i" element if a "span" contains a "div" element. the "span" contains text loaded via AJAX rendered as HTML that may or may not contain the "div class=difference"

the code looks something like this:

JAVASCRIPT:

$scope.hasChild = function() {
    if ($('span.difference').has('div'))
        return true;
    else
        return false;
};

HTML:

<ul ng-repeat="instance in value">
    <li>
        <i class="fa fa-warning" style="color: #ff6a00;" ng-if="hasChild()"></i>
        <span class="difference" ng-bind-html="trustAsHtml(instance.Dati)"></span>
    </li>
</ul>

it keeps always showing the warning icon

What am I doing wrong?

Tushar
  • 85,780
  • 21
  • 159
  • 179
xechelonx
  • 562
  • 1
  • 4
  • 14

4 Answers4

0

You're using a global selector here (span.difference):

$scope.hasChild = function() {
    if ($('span.difference').has('div'))
        return true;
    else
        return false;
};

So the condition for all the element would be based on the first (or maybe last?) span element.

Anyway, you need to modify your hasChild function only for the span sibling of the current element. Something like:

if ($(this).siblings('span.difference').find('div').length > 0)

Here's a jQuery-only version, should be easy to rewrite into Angular (let me know if you need help with that):

$('i').each(function() {
  if ($(this).siblings('span.difference').find('div').length > 0)
    $(this).show();
  else
    $(this).hide();
})
i {background: #ff6a00;}
div {padding-bottom: 20px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
  <i class="fa fa-warning">Warning</i>
  <span class="difference">Span 1</span>
</div>
<div>
  <i class="fa fa-warning">Warning</i>
  <span class="difference">Span 2<div>with a div (not a proper structure btw)</div></span>
</div>
Shomz
  • 37,421
  • 4
  • 57
  • 85
0

Since jQuery's .has() always returns an object, even if your span is empty, the condition is always true. Try something like

$scope.hasChild = function() {
    return $('span.difference').find('div').length > 0;
};

But this will search in all spans with class difference. Try checking the instances Dati property instead.

<i class="fa fa-warning" style="color: #ff6a00;" ng-if="hasChild(instance.Dati)"></i>

$scope.hasChild = function(dati) {
    var dummy = document.createElement("div"); //create a dummy element
    dummy.innerHTML = dati;
    return $(dummy).find("> div").length > 0; //check if it has divs inside
};

BTW.: You should not put a block element inside an inline element.

Community
  • 1
  • 1
Florian Gl
  • 5,984
  • 2
  • 17
  • 30
0

something like this??

if ($('span.difference').html().match("(<div\b)(.*)(>)")!=null)
    return true;
else
    return false;
Vanojx1
  • 5,574
  • 2
  • 23
  • 37
0

"ng-if" accepts expressions. Please refer here: https://docs.angularjs.org/api/ng/directive/ngIf

For your case, you just need to update the function to below.

$scope.isDanger = false;
$scope.hasChild = function() {
    if ($('span.difference').has('div').find('div').length > 0)
        $scope.isDanger = true;
    else
        $scope.isDanger = false;
};

And Forgot to mention, you need to call the $scope.hasChild() function after ajax response. And replace tag with below

<i class="fa fa-warning" style="color: #ff6a00;" ng-if="isDanger"></i>