Tom
Tom

Reputation: 1618

Jquery How to replace HTML after specific element?

I have a very simple layout, part of it is as follows:

<td class="subset">
<form name="searchFrm" method="get" action="update.php">
<input type="text" name="search">
</form>

html 
html
html

</td>

I want to replace everything after the form up to the td with new html loaded from a PHP Page.

eg: Changing it to:

<td class="subset">
<form name="searchFrm" method="get" action="update.php">
<input type="text" name="search">
</form>

New HTML from PHP

</td>

I know I can select the form using $( '[name="searchFrm"]' ) and load an external page using .load('new.php') but how do I remove the HTML after the form and then add the new html ?

I tried

$( '[name="searchFrm"]' ).after().load('new.php')

Which didn't help, is there any way to do this ? I'm not trying to add or remove individual rows, but replace HTML after an element with in a row.

Updated post with correct form name.

Thanks

Upvotes: 2

Views: 780

Answers (2)

Gabriele Petrioli
Gabriele Petrioli

Reputation: 195992

First of all a note, the $('[name="search"]') will not select just the form but the input as well since it also has the same name value. So use $('form[name="search"]').

There are a couple of approaches to tackle your issue.

One is the answer of @pavel which re-writes the form html along with the new content.

Some problems with this approach are

  • The exact posted code also suffers from the missing form in the selector and will therefore remove the form tag from the result.
  • if you later add some contents before the form (in the same td) it will stop working (it will remove that content)
  • if there are attached handlers on the form or any of its descendants, they will be lost, as .html only keeps the html text and not anything attached through code.
  • it will also not work directly with .load. But you can work around that with $.ajax

Another more involved solution, but much safer, is to go through the pain of selecting the actual nodes after the form.

To do this you need to use .contents which is the only jQuery method that returns textNodes as well.

A verbose implementation (so you can see each step) could be

function replaceContentsAfterForm(newUrl) {
  const form = $('form[name="search"]'); // select the form only
  const formParent = form.parent(); // get the form container
  const contents = [...formParent.contents()]; // select the contents of the container in an array
  const formIndex = contents.indexOf(form[0]); // find where the form is in the array 
  const afterForm = contents.slice(formIndex + 1); // select everything after the form
  const placeholder = $('<div id="placeholder" />'); // create a temporary placeholder to contain the data after the form
  placeholder.append(afterForm); // fill the placeholder with the contents after the form
  form.after(placeholder); // put the placeholder after the form in the DOM

  $(placeholder).load(newUrl, function() { // load the new content
    placeholder.replaceWith(placeholder.contents()) // and finally remove the placeholder eleemnt
  })
}

// and you can call it with
replaceContentsAfterForm('new.php');

Upvotes: 1

pavel
pavel

Reputation: 27082

Change parent element content by form + new content.

var form = $('[name=search]');
var parent = form.parent();

parent.html(form.html() + 'new HTML content');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<td class="subset">
    <form name="search" method="get" action="update.php">
        <input type="text" name="search">
    </form>

    html 
    html
    html

</td>

Upvotes: 0

Related Questions