0

It seems like the replace() method doesn't work when I ask it to remove an input-element inside a <p></p>.

Other HTML-elements like <br> will be removed when by itself.

var message = document.getElementById('message');
var firstname = document.getElementById('firstname');
var lastname = document.getElementById('lastname');

firstname.onclick = lastname.onclick = removeInput;

function removeInput() {
  var id = this.id;
  var paragraph = message.innerHTML;
  var toRemove = "<input type='text' id='inp" + id + "'><br><br>";
  var newParagraph = paragraph.replace(toRemove, '');
  message.innerHTML = newParagraph;
}
<p id="message">
   First name: <input type='text' id='inpfirstname'><br><br>
   Last name: <input type='text' id='inplastname'><br><br>
</p>

First name: <input type="radio" name="name" id="firstname">
Last name: <input type="radio" name="name" id="lastname">

Expected result: The desired input is removed.

Actual result: Nothing is removed.

artkoshelev
  • 872
  • 7
  • 22
  • The function `removeInput` has no variable as input so what `this.value` refers to? – Ali Sheikhpour May 12 '19 at 20:07
  • this.value gives the value of the exact radio button pressed. E.g if the "First name" radio button is pressed, this.value="firstname". – Frederik Vrålstad May 12 '19 at 20:09
  • So you want to delete the input element and pass the information to a function? Let's have a good use case first before having the code to fix this issue – avdg May 12 '19 at 20:18
  • @avdg I do not want the code to do anything other than deleting the desired input element from the paragraph. Do you want me to explain why I want to do this? – Frederik Vrålstad May 12 '19 at 20:22
  • Just contain the use case to this question (like "I remove when a name has been entered"). No need to add more than that. To already give a short answer, you probably want to edit the dom instead of using innerHtml or add some css style to the input element. – avdg May 12 '19 at 20:25

3 Answers3

2

I don't really know what you're trying to do, but the short answer to why it's "failing" is because your replace function is looking for single quotes (apostrophe character ') whereas the actual HTML code uses double quotes (quotation character ").

You could change your toRemove instantiation to escape the double quote (using backslashes), like so:

var toRemove = "<input type=\"text\" id=\"inp" + id + "\" onchange=\"update()\">";

but I'd recommend passing in a HTML id into your update function and using this unique id to find that element and remove it from the HTML DOM/document.

Refer to: Remove an element from the DOM from reference to element only

mirage
  • 708
  • 3
  • 8
  • If you do `console.log(paragraph.indexOf(toRemove))`, you'll notice the value is -1, which means that "text" was not found -- because you're searching for single quotes as opposed to double quotes. – mirage May 12 '19 at 20:27
  • How this solved the problem where the definition of `var id=this.value` is returning the value of input rather than its ID?! – Ali Sheikhpour May 12 '19 at 20:36
  • 1
    When you changed his question to add formatting, I noticed you changed his HTML. His original HTML had `First name: ` `Last name: ` The value was never changing - it's a radio button. `this.value` and `this.id` will be the same at runtime anyway (I think). This HTML is just bad and I have no idea what the actual intent is so I just pointed out the actual error is the quoting in the string. – mirage May 12 '19 at 20:49
  • Thanks for reply. I didn't edit the original post and someone else did. I have also copied the snippet to my answer so actually I have answered another question :D – Ali Sheikhpour May 12 '19 at 20:55
  • I'm sorry I have probalby confused you guys with my code. It's just an example code, and it was just used to show what my issue was. My actual code is partly written in another language and it was easier to just make some random code to show my issue. You gave me the reason for why it wasn't working and an example on how to fix it, so that was perfect! :D – Frederik Vrålstad May 12 '19 at 20:55
1

Just to (try to) answer your question directly without the use of replace. I set the css style of the input element to display:none.

var message = document.getElementById('message');
var firstname = document.getElementById('firstname');
var lastname = document.getElementById('lastname');

firstname.onclick = lastname.onclick = removeInput;

function removeInput() {
    var id = 'inp' + this.id;
    var element = document.getElementById(id);
    element.style="display: none;";
}
    <p id="message">
First name: <input type='text' id='inpfirstname' onchange='update()'><br><br>
Last name: <input type='text' id='inplastname' onchange='update()'><br><br>
    </p>

    First name: <input type="radio" name="name" value="firstname" id="firstname">
    Last name: <input type="radio" name="name" value="lastname" id="lastname">

Edit:

To make your code easily extendable:

function hideInputOnTrigger(id) {
    return function() {
        var element = document.getElementById(id);
        element.style="display: none;";
    }
}

firstName.onclick = hideInputOnTrigger("inpfirstname");
lastName.onclick = hideInputOnTrigger("inplastName");
avdg
  • 328
  • 1
  • 12
  • This solution is **much** better because it removes the fragility that mirage's solution highlights - you (Frederik) typed single quotes, the browser converted them to double quotes. What if you (Frederik), or someone else, changes the markup but forgets to update removeInput? That's right, the code is broken again. This solution takes away that possibility and has the added benefit of being much easier to understand at first glance and, therefore, to maintain. (I still don't like the dependency between value and id, but that's not so critical). – lukkea May 12 '19 at 21:01
  • 1
    @lukkea I understand that it is a complicated way of doing it. However, in my actual code the input is also created at demand. I wanted to figure out how to then delete the input on demand. In my school they emphasise the need for the code to be easily expanded. You can see the full code here: https://www.dropbox.com/s/gihsd2yazc2gi7l/index.html?dl=0 (It's a school assignment and is written partly in Norwegian) – Frederik Vrålstad May 12 '19 at 21:36
  • @FrederikVrålstad since you know the markup (and therefore the id) you are searching for wouldn't it be better to strip out the whole markup and use the method given in this answer for the reasons I highlighted? **But** my comment wasn't a criticism of your solution; I used your name in it so that it was clear I wasn't referring to avdg's answer when referring to your original question and made the comment to, hopefully, help others when encountering the scenario in your question. – lukkea May 13 '19 at 07:22
0

The answer to your current question is to to change this.value to this.id , however there is another problem that var paragraph = message.innerHTML; won't regard the updated valus of input fields. check the solution here.

var message = document.getElementById('message');
      var firstname = document.getElementById('firstname');
      var lastname = document.getElementById('lastname');

      firstname.onclick = lastname.onclick = removeInput;

      function removeInput() {
        var id = this.id;
        console.log(id);
        var paragraph = message.innerHTML;
        var toRemove = "<input type='text' id='inp" + id + "' onchange='update()'><br><br>";
        var newParagraph = paragraph.replace(toRemove, '');
        message.innerHTML = newParagraph;
      }
      function update(){}
<p id="message">
First name: <input type='text' id='inpfirstname' onchange='update()'><br><br>
Last name: <input type='text' id='inplastname' onchange='update()'><br><br>
    </p>

    First name: <input type="radio" name="name" value="firstname" id="firstname">
    Last name: <input type="radio" name="name" value="lastname" id="lastname">
Ali Sheikhpour
  • 10,475
  • 5
  • 41
  • 82