0

I have boiled down the code from a much larger application to replicate the problem.

Adding a class that contains only display: none; to list elements after that have been hidden (hide()) and then shown (show()) leaves the element with a style="display: list-element;" and leaves those elements visible because the inline style overrides the classes. A working example can be found here - http://jsfiddle.net/jayblanchard/x5bpjogj/2/ You'll want to view the browser's console to see the changes to the DOM as shown here -

DOM output

Here is the CSS -

.anchor-control-hidden {
    display: none;
}

Here is the JavaScript / jQuery -

var anchor = 'F1';
$('[data-anchor="'+anchor+'"]').find('.anchor-control').hide().show(); // this is done to replicate the problem
setAnchorControlButtons(anchor);

function setAnchorControlButtons(anchor){
  state = $('[data-anchor="'+anchor+'"]').attr('data-status');
  $('[data-anchor="'+anchor+'"]').find('.anchor-control').addClass('anchor-control-hidden');
  if( $('[data-anchor="'+anchor+'"]').attr('data-ahv') == 'null' ) {
      var ahvExists = false;
  } else {
      var ahvExists = true;
  }
    switch(state) {
       case 'laid':
           if( ahvExists ) {
                $('[data-anchor="'+anchor+'"]').find('.anchor-fetch, .anchor-raise').removeClass('anchor-control-hidden');
          } else {
                $('[data-anchor="'+anchor+'"]').find('.anchor-rack, .anchor-fetch').removeClass('anchor-control-hidden');
          }
            break;
    }
}

And finally the markup -

<div data-anchor="F1" data-status="laid" data-ahv="null">
<ul class="anchor-controls">
    <li class="anchor-control anchor-lay" data-action="anchor-lay">
        <div class="anchor-tile"><span class="button-label" style="top: 31%;">Lay</span>
        </div>
    </li>
    <li class="anchor-control anchor-drop" data-action="anchor-drop">
        <div class="anchor-tile"><span class="button-label" style="top: 31%;">Drop</span>
        </div>
    </li>
    <li class="anchor-control anchor-fetch" data-action="anchor-fetch">
        <div class="anchor-tile"><span class="button-label" style="top: 31%;">Fetch</span>
        </div>
    </li>
    <li class="anchor-control anchor-raise" data-action="anchor-raise">
        <div class="anchor-tile"><span class="button-label" style="top: 31%;">Raise</span>
        </div>
    </li>
    <li class="anchor-control anchor-retrieve" data-action="anchor-retrieve">
        <div class="anchor-tile"><span class="button-label" style="top: 31%;">Retrieve</span>
        </div>
    </li>
    <li class="anchor-control anchor-rack" data-action="anchor-rack">
        <div class="anchor-tile"><span class="button-label" style="top: 31%;">Rack</span>
        </div>
    </li>
</ul>
</div>

I have stripped away all of the irrelevant CSS and markup. In the example only two of the list items (rack and fetch) should be visible. Changing the data-ahv attribute on the div should result in only two list items (raise and fetch) to be displayed.

I have tried removing the style attribute from the list item and that results in other odd behavior. Do I need to quit using hide() and show() in favor of explicit classes or can this issue be solved in some other way?

Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119
  • based on this answer [http://stackoverflow.com/a/6553745/2359055](http://stackoverflow.com/a/6553745/2359055) it seems you can just add .css('display', '') like this [http://jsfiddle.net/x5bpjogj/4/](http://jsfiddle.net/x5bpjogj/4/) – Abraham Uribe Sep 17 '14 at 18:50
  • That is one of the methods I tried previously and it has odd side-effects too. – Jay Blanchard Sep 17 '14 at 18:57

2 Answers2

1
$('[data-anchor="'+anchor+'"]').find('.anchor-control').hide().show().removeAttr('style');

I have updated your fiddle. I didn't see any odd behavior by adding removeAttr.

Bilal
  • 2,645
  • 3
  • 28
  • 40
  • That works for the fiddle as that line was added to replicate the overall issue. Using `removeAttr()` does produce other odd behavior in the scheme of the overall application. It doesn't resolve the question of why the style attribute is still there. – Jay Blanchard Sep 17 '14 at 17:54
  • It's irrelevant to the question at hand - but removing the style attribute causes other JavaScript/jQuery actions needing to modify the style attribute to fail. – Jay Blanchard Sep 17 '14 at 17:57
  • Then you can define another class to `display` as `block` or what you want or add it in style attribute. Have you tried it? What exactly you want to keep in style attribute after show hiding? – Bilal Sep 17 '14 at 17:59
  • I have tried dozen's of things over the past couple of days including being very explicit about setting `style=""` or creating other classes to replace `hide()` and `show()`. Sometimes the style tag is used to facilitate other events that jQuery might do - like fades or other animations. If you remove the style attribute it is no longer available to those events. – Jay Blanchard Sep 17 '14 at 18:01
  • If we remove show hide methods it doesn't add style attribute and that is required. Why do you need to show hide? – Bilal Sep 17 '14 at 18:11
  • The way that I have done it here replicates the problem. In the actual application these list items can be shown or hidden for many reasons. – Jay Blanchard Sep 17 '14 at 18:15
  • I think you should use custom classes instead of show hide. – Bilal Sep 17 '14 at 18:28
  • I tend to agree which means that hundreds of lines of existing code (the application existed before I inherited it) will have to be re-factored. – Jay Blanchard Sep 17 '14 at 18:32
1

In this case the code base had to be refactored and the use of .hide() and .show() had to be removed in favor of classes that apply the display property more explicitly. This allows the behavior to be more predictable and for further functions to be added to the project with as little pain as possible.

Jay Blanchard
  • 34,243
  • 16
  • 77
  • 119