Diff two containers with JS or jQuery
Asked Answered
V

5

5

I want to update a container with a new version without replacing it. For example:

Container1:

<div id="container-one">
    <p>
        <webview src="https://i.sstatic.net/Ed1aw.jpg"></webview>
    </p>
    <p>
       Text
    </p>
</div>

Container2:

<div id="container-two">
    <p>
        Cool intro
        <webview src="https://i.sstatic.net/Ed1aw.jpg"></webview>
    </p>
    <p>
       Long text
    </p>
    <p>
       New Paragraph with text in it.
    </p>
</div>

Container1 updated:

<div id="container-one">
    <p>
        Cool intro
        <webview src="https://i.sstatic.net/Ed1aw.jpg"></webview>
    </p>
    <p>
       Long text
    </p>
    <p>
       New Paragraph with text in it.
    </p>
</div>

A Container1.innerHTML = Container2.innerHTMLwould be simple but I don't want to reload my webview so the code should detect new divs or updated content in existing divs and apply the modifications in Container1.

UPDATE :

Container2 is a new version of container1 edited by a user, so Container2 can have anything in it: images, links, new paragraphs.

How can I do this?

Vocalism answered 29/3, 2014 at 10:28 Comment(2)
why don't you just wrap the texts into id'd containers (div, span, whatever) and do it that way?Lyckman
but you said in your question that the paragraphs are text... have I misunderstood something...? Have a look at my answer...Lyckman
L
2

I might have not understood your question correctly, but by adding an id to the text that you want to replace, and using simple javascript, you can achieve this.

HTML

<div id="container-one">
    <p>
        <span id="inner-one-1"></span>
        <webview src="https://i.sstatic.net/Ed1aw.jpg"></webview>
    </p>
    <p>
       <span id="inner-one-2">Text</span>
    </p>
</div>

<div id="container-two">
    <p>
        <span id="inner-two-1">Cool intro</span>
        <webview src="https://i.sstatic.net/Ed1aw.jpg"></webview>
    </p>
    <p>
       <span id="inner-two-2">Long text</span>
    </p>
</div>

<button id="click">Click Me!</button>

JS

document.getElementById("click").onclick = function() {
    document.getElementById("inner-one-2").innerHTML = document.getElementById("inner-two-2").innerHTML;
    document.getElementById("inner-one-1").innerHTML = document.getElementById("inner-two-1").innerHTML;
}

DEMO HERE

Lyckman answered 29/3, 2014 at 10:40 Comment(6)
I update my question with more details, this is not the answer I wanted but thanks for your help.Vocalism
So all you want is to add the text in the first paragraph but replace the second?Lyckman
Container2 is a new version of container1 edited by a user, so Container2 can have anything in it: images, links, new paragraphs.Vocalism
and...? what's wrong with my code, what is it not doing that you want to do?Lyckman
Working with id seems a really dirty way to do this, it works but a solution working with childrens of the container would be really better.Vocalism
Your idea is great, but it's still static. Container2 can have anything in it!Vocalism
C
2

you need to get the text node and replace the content, like

$('button').on('click', function () {
    // this block is for not to update the webview
    // get the first text node
    var txt = $('#container-one > p:first').contents().first().get(0);

    if (txt.nodeType === 3) { // Node.TEXT_NODE
        txt.nodeValue = $('#container-two > p:first').text();
    }

    // update rest of the elements
    $('#container-two').children().each(function (i) {
        if (i !== 0 && $('#container-one').children()[i]) {
            $($('#container-one').children()[i]).html($(this).html());
        }
        if (!$('#container-one').children()[i]) {
            $('#container-one').append($(this).clone());
        }
    });
});

DEMO

Clew answered 29/3, 2014 at 11:6 Comment(2)
This answer is also static, what if Container2 has four paragraphs?Vocalism
@armandG. see my updated code, hope this is what you are looking forClew
M
2

please try it.

var container_one = $("#container-one").children();
var container_two = $("#container-two").children();


$.each(container_one, function(index, element){
  var cont_one_html = $(this).html();
  var cont_two_html = $(container_two[index]).html();
  if(cont_one_html != cont_two_html){
    $(this).html(cont_two_html);
  }
});

please have a look on image enter image description herefor more understanding.

Maleficent answered 29/3, 2014 at 11:10 Comment(2)
This is great! The only thing is that if a user changes something in the paragraph it will be updated, even if the webview in the paragraph has not been changed. Could it works with children().children() to be smarter?Vocalism
exactly, this code will not work, you have to update some part of this code. I can not get what is in your mind. if you will provide your code only then i can help you.Maleficent
V
1

Have a try and see if this works for you.

var first = $('container-one p:first');
first.html($('container-two p:first').html() + first.html());

$('container-one p:last').html($('container-two p:last').html());
Vacua answered 29/3, 2014 at 10:44 Comment(3)
Container2 is a new version of container1 edited by a user, so Container2 can have anything in it: images, links, new paragraphs. It's not static at all.Vocalism
html() will take any content as long as it recides inside the p element.Vacua
An example: If a user adds a new paragraph your code doesn't modify the second paragraph, even if it has new content. Your code work with a specific disposition of new content, this is the problem (I'm sorry my question wasn't clear at the beginning).Vocalism
O
1

Use this:

function update(s){
   document.getElementById("container-one").innerHTML=s.innerHTML;
}

setInterval(function(){
   update(document.getElementById("container-two"));
},1000);

What this does is it updates the content once every second.

To show that it can handle dynamic content, I have made the second div editable.

Demo:http://jsfiddle.net/5RLV2/2

Ossifrage answered 29/3, 2014 at 11:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.