Sirwan Afifi
Sirwan Afifi

Reputation: 10824

jQuery: Removing previous elements with content

Given this markup:

<td>
   <a href="#">Item1</a> |
   <a href="#">Item2</a> |
   <a href="#">Item3</a> |
   <a href="#" class="refuseButton">Refuse</a>
   <div class="slideBox" style="display: none;">
        <div class="form-group">
             <div class="col-sm-12">
                   <input class="form-control" type="text" name="Description">
             </div>
        </div>
    </div>
</td>

When I click on the Refuse link I want the previous elements along with its content (|) to be hide. I'm using .prevAll() but it removes the elements not the content:

$('.refuseButton').on('click', function(event) {
    var button = $(event.relatedTarget);
    $(this).prevAll().slideToggle();
    $(this).next().slideToggle();
});

Upvotes: 1

Views: 599

Answers (5)

AlexBerd
AlexBerd

Reputation: 1504

How about Jquery.grep() solution:

$('.refuseButton').on('click', function(e) {
     $siblings=$($.grep($(e.target).parent().children('a'),function(item,index){
          return $(item).text() === '|'
}));
     $(siblings).remove() /*or $(siblings).text('') if you want to clear content*/
});

Also you can use children('a:not(.refuseButton)') in order to remove current click button

Upvotes: 0

Ben Hillier
Ben Hillier

Reputation: 2104

You really can't change the HTML? Then it becomes difficult because you can't use the DOM to get to the '|' pipe symbols.

The following works by removing the

$('.refuseButton').on('click', function(event) {
    var button = $(event.relatedTarget);
    $(this).prevAll().slideToggle().remove();
    $(this).next().slideToggle();
    content = $(this).parent().html();
    while(content.indexOf('|') != -1){
        content = content.replace('|', '');
    }
    $(this).parent().html(content);
});

Upvotes: 0

fdomn-m
fdomn-m

Reputation: 28611

Assuming you can't change the markup (for whatever reason).

You can wrap the textnodes with a div on the fly and then hide the wrapping container.

You can't manipulate the textnode directly, so you have to wrap it, using previousSibling as recommended by Hacketo in the comments.

$('.refuseButton').on('click', function(event) {
    var sibs = [];
    var sib = this.previousSibling;
    while (sib) {
        sibs.push(sib);
        sib = sib.previousSibling;
    }
    $(sibs).each(function() {
        $(this).wrap("div").hide();
    });
});

This:

  • collates all the nodes before the current node
  • wraps each one in a div
  • hides the div

The collate first is because wrapping then applying .previousSibling will always return null as there would no longer be any siblings. (There are other ways to do this ofc - eg wrap them all then use jquery .prevAll() - or only wrap the textnodes using this technique - or just change the html (if possible)).

Obviously this won't be idempotent as it dynamically changes the html, but there are ways around that (eg only wrap text nodes, then there won't be any text nodes on subsequent calls).

Edit: fiddle

Upvotes: 3

Aroniaina
Aroniaina

Reputation: 1252

wrap all item lines with span. Run the snippet to see the result

        $(document).ready(function(){
            $('.refuseButton').on('click', function(event) {
                var button = $(event.relatedTarget);
                $(this).prevAll().slideToggle();
                $(this).next().slideToggle();
            });           
        });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>
  <span><a href="#">Item1</a> |</span>
  <span><a href="#">Item2</a> |</span>
  <span><a href="#">Item3</a> |</span>
  <a href="#" class="refuseButton">Refuse</a>
  <div class="slideBox" style="display: none;">
    <div class="form-group">
      <div class="col-sm-12">
        <input class="form-control" type="text" name="Description">
      </div>
    </div>
  </div>            
</div>

Upvotes: 1

JackHasaKeyboard
JackHasaKeyboard

Reputation: 1665

The | characters (known as pipes) are outside of the a tags. As far as HTML is concerned that's just plain text.

You'll have to move them into the a tags or wrap it all in a container like a div.

Upvotes: 0

Related Questions