• Item1
    1. SubItem1
    2. SubItem2
    3. ...">

      Insert li element after selected li by text

      I have the following list:

      <ol id="mainlist">
      <li>Item1
          <ol>
              <li>SubItem1</li>
              <li>SubItem2</li>
              <li>SubItem3</li>
          </ol>
      </li>
      <li>Item2
          <ol>
              <li>SubItem1</li>
              <li>SubItem2</li>
              <li>SubItem3</li>
          </ol>
      </li>
      <li>Item3
          <ol>
              <li>SubItem1</li>
              <li>SubItem2</li>
              <li>SubItem3</li>
          </ol>
      </li>
      </ol>
      
      <span>Add text</span><input type="text" /><span>, after the element </span> <input type="text" /><input type="button" value="Add" />
      
            

      I have two text inputs. The first is where the user should write the text he / she wants to insert after the element specified in the second input text box.

      The problem is I don't know how to select the correct one li

      based on its text.

      I've tried using jQuery:

      $('input[type="button"]').on('click',function(){
          $item=$('<li>',{
              html:$('input')[0].value
          });
          $position=$('input')[1];
      
          $('li:contains("'+$position.value+'")').filter(function() {
                return $(this).text() == $position.value;
          }).after($item);
      });
      
            

      But it doesn't work. I don't know how to select the element where I am going to insert the object <li>

      .

      +3


      source to share


      3 answers


      I cleaned up your code and had to make a small tweak to make it work correctly.

      One problem was that your structure was <ol><li><ol><li>

      , which meant that any element search, li

      or even ol li

      means it adds to both parent and child, which doesn't seem to be what you want to achieve.

      Hope this is what you were trying to achieve.



      $(document).ready(function() {
        $('input[type="button"]').on('click', function() {
          var item = $('<li>', {
            html: $('input')[0].value
          });
          var position = $('input')[1].value;
      
          $('ol li').each(function() {
            var firstWord = $(this).text().substr(0, $(this).text().indexOf(" "));
            if (firstWord.trim() == position) {
              $(this).after(item);
            }
          });
        });
      });
            

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <ol id="mainlist">
        <li>Item1
          <ol>
            <li>SubItem1</li>
            <li>SubItem2</li>
            <li>SubItem3</li>
          </ol>
        </li>
        <li>Item2
          <ol>
            <li>SubItem1</li>
            <li>SubItem2</li>
            <li>SubItem3</li>
          </ol>
        </li>
        <li>Item3
          <ol>
            <li>SubItem1</li>
            <li>SubItem2</li>
            <li>SubItem3</li>
          </ol>
        </li>
      </ol>
      
      <span>Add text</span>
      <input type="text" /><span>, after the element </span>
      <input type="text" />
      <input type="button" value="Add" />
            

      Run codeHide result


      +1


      source


      The main problem is what you used .value

      to get the input value in jQuery. However, it .value

      belongs to javascript. Since you are using jquery you need to use .val()

      .

      I worked on an example: https://jsfiddle.net/6r18ag68/2/



      $('input[type="button"]').on('click',function(){
          var newitem = $('<li>' + $('#txt1').val() + '</li>');
      
          $('li').filter(function () {
              return $(this).text() == $('#txt2').val();
          }).after(newitem);
      
          $('#mainlist > li').filter(
                function(){ 
                   return $.trim($(this).html().split('<')[0]) == $('#txt2').val(); }).append(newitem);
          });
      });
      
            

      +1


      source


      Several points:

      • You must declare type variables $item

        with var

        if you don't want to be put in the enclosing scope
      • The statement return $(this).text() == $posicion.value;

        contains a "position" with an error
      • Some of the nodes are li

        identical in your example. I assume you need a way to distinguish them from their ancestor li

        . This means you need three inputs

      How about this?

      $('input[type="button"]').on('click',function(){
          var newText = $('input#newText').val();
          var ancestorLiText = $('input#ancestorLiText').val();
          var liText = $('input#liText').val();
      
          var $ancestorEl = $('ol#mainlist').find('li').filter(function (i) {
              return $(this).text() === ancestorLiText;
          });
          var $el = $ancestorEl.find('li').filter(function (i) {
              return $(this).text() === liText;
          });
          var $newLi = $('<li>').text(newText);
          $el.after($newLi);
      });
      
            

      You should be able to output HTML code from this code (you need inputs with IDs "newText", "ancestorLiText" and "liText")

      Also note that a selector :contains()

      is similar to a global text search for an element. Therefore, the search li:contains(chair)

      will match both <li>chair</li>

      and <li>not a chair</li>

      .

      0


      source







      All Articles