"Transform" one element into another with Jquery

Asked

Viewed 1,392 times

3

In my script, I have one iframe.

<iframe id="result" name="result" src="url_do_documento" sandbox="allow-same-origin"></iframe>

The file q o iframe reference, contains an element h1, as in the structure below:

<!DOCTYPE>
<html>
  <head></head>
  <body>
    <h1 class="pf-change-h1">H1 que pretendo alterar!!</h1>
  </body>
</html>

to access H1, I am using Jquery as follows:

$("#result").load(function(){
    var h1 = $("#result").contents().find(".pf-change-h1");
    h1.click(function(){
        $(this).replaceWith("<input type='text' value='" + $(this).html()  + "' class='pf-change-h1' />");
    });
    /*h1.blur(function(){
        $(this).replaceWith("<h1 class='pf-change-h1' >" + $(this).html()  + "</h1>");
    });*/
});

The purpose of this code would be to replace the element h1 by a input, so that its value could be changed, after changing it should happen exactly the opposite.

The commented code is the one that just isn’t working, the event onBlur is not fired and the input is not replaced by h1.

Does anyone have any idea how to make this substitution of elements?

UPDATE:

I tried both forms of answers and did not get the expected result :/

When viewing code execution from the browser console, H1 has an event attached to it, as you can see:

inserir a descrição da imagem aqui

But by replacing it with input, it has no event attached, causing nothing to happen.

inserir a descrição da imagem aqui

  • This iframe is in the same domain?

  • Yes, in the same domain

  • Whether or not input containing the same class as H1?

  • If you can use the contentEditable attribute maybe you can edit H1 without having to turn it into input.

  • 1

    You’re missing the object reference. Edit: just answered this :D

2 answers

3


I think the problem here is that you’re rewriting H1, and you lose the reference when you replace it... the solution I can come up with is to leave that new element before you have a reference. I suggest you also use delegation for that. In that case it would look like this:

$("#result").load(function(){
    var blur = function () {
        $(this).replaceWith("<h1 class='pf-change-h1' >" + this.value + "</h1>");
    }
    $("#result").contents().on('click', ".pf-change-h1", function () {
        var input = $("<input type='text' value='" + ($(this).html() || this.value) + "' class='pf-change-h1' />");
        $(this).replaceWith(input);
        input.focus().blur(blur);
    });
});

jsFiddle: http://jsfiddle.net/8L8xee69/

Notice that I replaced $(this).html() for this.value, the same as $(this).val(), as input elements do not have innerHTML

  • I will test both ways, depending on the result, I will comment here, thank you!

  • 1

    @Thomerson starts by the second (delegating) is the best.

  • I tried the first one, I got the same result from my script, the click event works, but Blur doesn’t. And the second did not execute any :x by the delegation, the script adds the events to the class elements ". pg-change-H1" within the iframe?

  • 1

    @Thomerson Aha... ok. This new element has to be created within the context of iframe. I don’t know how jQuery treats it, I only know it in pure JS, but I’ll edit the answer.

  • Thanks man, the second option, slightly edited, worked perfectly, Thanks!! xD

  • 1

    @Thomerson, because I really took the other one that had problems. I also added a jsFiddle. I’m glad I helped...

Show 1 more comment

1

What happens is that the replaceWith destroys the element, and so the event is lost. It is then necessary to re-associate the events with the element. As you are working with a iframe, I don’t know what the scope looks like, but the idea is more or less the following:

function h1_click() {
    $(this).replaceWith("<input type='text' value='" + $(this).html() + "' class='pf-change-h1' />");
    $(".pf-change-h1").blur(function () {
        $(this).replaceWith("<h1 class='pf-change-h1' >" + $(this).val()  + "</h1>");
    });
    $(".pf-change-h1").click(h1_click());
};

("#result").load(function(){
    var h1 = $("#result").contents().find(".pf-change-h1");
    h1.click(h1_click);
});

Browser other questions tagged

You are not signed in. Login or sign up in order to post.