Question

I have two li elements I want to ensure have the same parent ONLY if they have the same city inside their anchor value. They are rendered as:

<ul>
  <li>
    <a href='/home.aspx'>Calgary</a><span>[+]</span>
    <ul class='courses'>
      <li>Course Name 1</li>
    </ul> 
  </li>
</ul>

<!-- Remove this ul after grabbing the inner <li> (Course Name) -->
<ul>
  <li>
    <a href='/home.aspx'>Calgary</a><span>[+]</span>
    <ul class='courses'>
      <li>Course Name 2</li>
    </ul> 
  </li>
</ul>

<!-- Leave this ul alone -->
<ul>
  <li>
    <a href='/home.aspx'>Montreal</a><span>[+]</span>
    <ul class='courses'>
      <li>Course Name 3</li>
    </ul> 
  </li>
</ul>

Using jQuery, please show me how to grab the 'Course Name 2' li and place it under the 'Course Name 1' parent ul. Also, I would like to remove the originating ul marked with 'RemoveMe'.

Was it helpful?

Solution

I have something that works, taking the liberty of adding a class called "city" to some of the li elements to help differentiate them.

JSFiddle here

It loops through and finds other anchors share the same text but do not reference the same element. It then finds the courses in their lists and adds them to the original anchor's list. I think it could be made clearer by adding additional classes, but the general concept is there.

One thing I hadn't originally counted on was needing to make sure that the elements are still visible. I grab the array of anchors up top, and they're still referenced even after having been removed.

$(function() { 

    $('li.city a').each(function(ix) {

        if ($(this).is(':visible'))
        {

            var $anchor = $(this);
            var myText = $(this).text();

            var $matches = $('a').filter(function() {
                return (($(this).text() == myText) && (this !== $anchor.get(0)));
            });

            $.each($matches, function() {

                var $snip = $(this).parent().find('ul.courses li');

                // add the li elements to the first anchor's list
                $anchor.parent().find('ul.courses').append($snip);

                // bubble up to duplicate anchor's ul tag and remove it entirely
                $(this).closest('li.city').parent().remove();

            });

        }

    });

});

OTHER TIPS

Something like this should work, but I admit - I didn't test this piece of code.

$("ul").each(function(){
    // get city
    var city = $(this).find("li > a").text();

    // find similar cities
    var other = $(this).siblings("ul").has("li > a:contains('"+city+"')");

    // move LI elements and remove similar ULs
    // not sure, maybe this should be done one by one (using each() for example)
    // that's in case if you have found more than 1 similar entry
    other.find("ul.courses > li").appendTo($(this).find("ul.courses"));
    other.remove();
});
<ul id='AddToMe'>
  <li>
    <a href='/home.aspx'>Calgary</a><span>[+]</span>
    <ul class='courses'>
      <li>Course Name 1</li>
    </ul> 
  </li>
</ul>

<ul id='RemoveMe'>
  <li>
    <a href='/home.aspx'>Calgary</a><span>[+]</span>
    <ul class='courses'>
      <li>Course Name 2</li>
    </ul> 
  </li>
</ul>

<script>
$(document).ready(function() {
   if($('#AddToMe a').text() == $('#RemoveMe a').text()){
       $('#RemoveMe').find('.courses li').appendTo($('#AddToMe .courses'));
       $('#RemoveMe').remove();
   }
});
</script>

jsFiddle

EDIT NOTES - added the removal of the "RemoveMe" id ul EDIT 2 - added if condition to compare anchor tags

Something along these lines would work.

I have given the first <ul> an id "Ul1" for simplicity's sake.

 var x = $("#RemoveMe").getChildren().first();

    if( $("#RemoveMe").getChildren().eq(1).text() == $("#Ul1").getChildren().eq(1).text())
{
    $("#Ul1").getChildren().first().append(x);

    $("#RemoveMe").getChildren().first().remove();
}

A more generalised solution:

$("li").each(function(){
  if ($(this).getChildren().first().text() == "some city name")
 {
    $("#Ul1").getChildren().first().append($(this));
    $(this).remove();
 }  
});

Note: I suggest giving these particular <li> some particular class name to use as a selector.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top