4

Let's say I have a page with some html elements. Those elements are textboxes ,checkboxes ,radiobuttons and other user responsive things.

I need a possibility to transfer whole page from client1 to client2, so client2 will see everything that client1 has set into html elements.

I use WebSocket technology for that, but I don't know how to transfer that elements. If I transfer document.body.innerHTML then client2 see blank elements, instead of filled ones. enter image description here

On the page could be any amount of any html elements. Is it possible to do something like clonning elements but over websocket? Like I serialize whole document.body and transfer it to another client?

The page are simple html ones. No any server side script are used. I use self made http + websocket server that is working on same port.

Kosmo零
  • 4,001
  • 9
  • 45
  • 88
  • Well, of course you can, you can either save those values to a file on the server and the other client can look them up from that file, or use AJAX to post that data to the other client or just save them to a database. – odedta Jun 23 '15 at 12:39
  • use cookies. thats is what it was made for – Mox Jun 23 '15 at 12:39
  • You can use browser `local storage` to access data. – Vishnu Prasad Jun 23 '15 at 12:40
  • On the page could be any amount of any html elements. I can't save those all into database or cookies. Is it possible to do something like clonning elements but over websocket? Like I serialize whole `document.body` and transfer it to another client? – Kosmo零 Jun 23 '15 at 12:42
  • @odedta - I need more generic solution. the page can contain any amount of elements of any type. I need something like serialization of `document.body` – Kosmo零 Jun 23 '15 at 12:45
  • can you save the request.form? – loli Jun 23 '15 at 12:48
  • no. The pages are simple html ones. No server side scripts are used. I use self made http server + websocket server that is work on same port. I hope for a some way to serialize `document.body` and transfer it over websocket. – Kosmo零 Jun 23 '15 at 12:50

2 Answers2

2

I started something that could help you.

  • You make a loop to get element by Tag (to get all input)
  • You process them according to the type: text, checkbox, radio,... by saving the value in an attribute (in my exemple, I update the defaultvalue using the value)
  • then you send it the way you want to. In my example, i show the content using alert; but use your socket.

Maybe you need to add some processing on the the receiving page. The Text input will show the default value, but you may have to set checkbox 'checked' from the 'value' attribute. I would use a document.onload, with a for each (get element by tag)

Here is the example: Javascript get Body content into variable

<body>
<p class="first">Hello World Dude</p>
<label for="search_field">my text:</label>
<input type='text' id ='myinput' class='MyIntputField' />

  <input type="checkbox" name="vehicle" value="Bike"> I have a bike<br>
  <input type="checkbox" name="vehicle" value="Car" checked> I have a car<br>
</body>
<p id="demo" onclick='myFunction()'>Click me to send Data.</p>
<script>
function myFunction() {
    inputs = document.getElementsByTagName('input');
    for (index = 0; index < inputs.length; ++index) {
        switch (inputs[index].type){
            case "text":
                inputs[index].defaultValue = inputs[index].value;
            break;

            case "checkbox":
                 inputs[index].value = inputs[index].checked;
            break;
        }
    }

    var $mybody = $("body").html();
}

</script>
Gil Sand
  • 5,802
  • 5
  • 36
  • 78
Xavier
  • 440
  • 4
  • 11
1

You need to use outerHTML instead of innerHTML, however that wont set your input values so you have to do that manually.

// To send your html via websocket
//var ws = new WebSocket('ws://my.url.com:PORT');
//ws.onopen = function(event) { // Make sure it only runs after the web socket is open

  document.querySelector('button').addEventListener("click", function() {
    var inputs = document.querySelectorAll('input');
    Array.prototype.forEach.call(inputs, function(el, i) {
      el.setAttribute('value', el.value);
    });
    document.querySelector('button').setAttribute('data-button', true); // Attributes are rememebered
    var HTML = document.querySelector('section').outerHTML;
    document.querySelector('#result').innerHTML = HTML;
    document.querySelector('#resulttext').textContent = HTML;

    //ws.send(HTML);
  });

//};
html,
body {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
}
div {
  background: orange;
  border: 3px solid black;
}
<section>
  <div>
    <input />
  </div>
  <div>
    <input />
  </div>
  <div>
    <input />
  </div>
  <div>
    <input />
  </div>
  <div>
    <input />
  </div>
  <div>
    <button>Generate</button>
  </div>
</section>
<p id="resulttext"></p>
<p id="result"></p>
Jamie Barker
  • 8,145
  • 3
  • 29
  • 64
  • This is already something. Well, there is also `Checked` property exist. but it's the least problem. The greatest problem that those elements can have custom fields set like `elem.customField = 'black';`. I will think what to do :O – Kosmo零 Jun 23 '15 at 13:35
  • @Kosmos What do you mean by custom fields? If an element has any custom fields attached, they should be picked up by the `outerHTML` – Jamie Barker Jun 23 '15 at 13:38
  • `test_txt.customField = "black"; var outer_html = test_txt.outerHTML;` but `outer_html` value is just ``. – Kosmo零 Jun 23 '15 at 13:49
  • But I guess this is out of the scope of my question. Just additional problems that I though will be solved by some kind of serialization. I tried `JSON.stringify` on `document.body.childNodes`, but the result is way not what I need. – Kosmo零 Jun 23 '15 at 13:51
  • Sending through a single string is going to be easier, and less data will have to travel down the socket, AFAIK. If you convert it to JSON you've then got to un-convert it at the other end. I've added some to the code snippet so you can see that custom fields can be added, and remembered. – Jamie Barker Jun 23 '15 at 13:57
  • But is it possible to use `JSON` for this? Whole page html code must travel by socket in anyway, because `client2` don't have the code of the page on `client1`. `client2` has just a blank page with ability to load content of any `client1`. By doing this `var json = JSON.stringify(document.body.childNodes);` I getting this `"{"0":{},"1":{},"2":{},"3":{},"4":{}}"` in variable. Maybe there is some other way I need to use for that? – Kosmo零 Jun 23 '15 at 14:06
  • It is possible, there are other answers on Stack Overflow that answer that query though. JSON would only be necessary though if you were needing to group your data for some reason, or if it was going to be split out. – Jamie Barker Jun 23 '15 at 14:15
  • @Kosmos I added the simple code that would send your html via web socket. I've commented it out though as it won't work without a proper connection. – Jamie Barker Jun 23 '15 at 14:21
  • By looking on your example I just though about iterating through every field of every elem and using `setAttribute(current_field, its_value);` Then I will use `document.body.innerHTML` to send this, since using `setAttribute` makes custom attributes and `input`'s `value` to appear in result. – Kosmo零 Jun 23 '15 at 14:24
  • You shouldn't need to for every element. They should already be there when you call `.innerHTML` or `.outerHTML` – Jamie Barker Jun 23 '15 at 14:26
  • No, dynamically set fields does not appear in outerHTML. See third commend for you answer. And I have a lot of dynamically set fields on the page. – Kosmo零 Jun 23 '15 at 14:27
  • @Kosmos I'm setting a dynamic field in the answer that is being correctly regurgitated. You _are_ prefixing your attributes with `data-`? Otherwise they might be ignored for being invalid HTML. – Jamie Barker Jun 23 '15 at 14:40
  • Ugh, so that's the reason. I tried this: `test_txt.asd = "dsa";` and didn't saw 'asd' property in `outerHTML`. Now i understand it. Err... I tried to set `test_txt.dataAsd = "dsa";` and still don't see `data-Asd` in `outerHTML`; – Kosmo零 Jun 23 '15 at 14:42
  • @Kosmos `test_txt.setAttribute('data-Asd', 'dsa');`? – Jamie Barker Jun 23 '15 at 14:51
  • Ok, this one works. I probably need to redo all assignments from `elem.asd = 'dsa';` to `setAttribute` ones. – Kosmo零 Jun 23 '15 at 14:54
  • Correct. `elem.asd =` is assigning a property, which doesn't appear in the DOM. You will notice in my example above that I am setting the value of the input using `.setAttribute` instead of `.value =` for the same reason. – Jamie Barker Jun 23 '15 at 14:58