2

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

Tom
  • 1,436
  • 24
  • 50
  • Can there also be content before the form that you want to keep ? – Gabriele Petrioli Mar 18 '21 at 09:23
  • Why not wrap the contents after the form in an element with an id so you can target it directly ? – Gabriele Petrioli Mar 18 '21 at 09:35
  • @GabrielePetrioli - In this specific `td` there is nothing before the `form`. There are other rows before and after this one. I have no control over some of the code so can't add new elements etc. – Tom Mar 18 '21 at 09:43
  • Does this answer your question? [Add/remove HTML inside div using JavaScript](https://stackoverflow.com/questions/17650776/add-remove-html-inside-div-using-javascript) – Reporter Mar 18 '21 at 12:05
  • HI, check [this](https://stackoverflow.com/a/27538239/10606400) might be helpful. – Swati Mar 18 '21 at 13:30

2 Answers2

1

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');
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • I've realised a typo in the code I posted. The form is actually called `searchFrm` I've updated the code to be `const form = $('form[name="searchFrm"]'); // select the form only` When I run the code I get `Uncaught TypeError: formParent.contents is not a function or its return value is not iterable` – Tom Mar 18 '21 at 13:18
  • @Tom what jquery version are you using ? can you log what `formParent` and `formParent.contents()` return ? – Gabriele Petrioli Mar 18 '21 at 16:26
  • I'm running v1.8.0 :( I hadn't realised it was that old. What is the required version for this to work ? – Tom Mar 18 '21 at 16:45
  • @Tom it needs 2.2 at least, since that is when iterators where added. You can alternatively replace `const contents = [...formParent.contents()];` with `const contents = Array.from(formParent.contents());` Example at https://jsfiddle.net/gaby/bqLpk4vc/5/ – Gabriele Petrioli Mar 18 '21 at 18:00
0

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>
pavel
  • 26,538
  • 10
  • 45
  • 61