1

My JS fiddle of the issue is here:

https://jsfiddle.net/taslar/krcfx4u5/9/

<div id="app">
  <h1>
    This should not print.
  </h1>
  <div id="pickList">
    <h2>Todos:</h2>
    <ol>
      <li v-for="todo in todos">
        <label>
        <input type="checkbox"
          v-on:change="toggle(todo)"
          v-bind:checked="todo.done">
        <del v-if="todo.done">
          {{ todo.text }}
        </del>
        <span v-else>
          {{ todo.text }}
        </span>
        <input v-model="todo.notes" />
      </label>
      </li>
    </ol>
  </div>
  <button @click="print">print</button>
</div>


new Vue({
  el: "#app",
  data: {
    todos: [
      { text: "Learn JavaScript", done: false, notes: 'What is JavaScript' },
      { text: "Learn Vue", done: false, notes: 'Doing' },
      { text: "Play around in JSFiddle", done: true, notes: 'Done' },
      { text: "Build something awesome", done: true, notes: '' }
    ]
  },
  methods: {
    toggle: function(todo){
        todo.done = !todo.done
    },
print() {
      var printWindow = window.open('', '', 'height=600,width=800');
      printWindow.document.write('<html><head><title>Print This</title>');
      printWindow.document.title = 'printthis.pdf';
      printWindow.document.write('</head><body >');
      printWindow.document.write('<div class="container">');
      var pageElement = this.$el.querySelector('#pickList');
      var html = pageElement.outerHTML;
      printWindow.document.write(html);
      printWindow.document.write('<br />');
      printWindow.document.write('<br />');
      printWindow.document.write('</div>');
      printWindow.document.write('</body></html>');
      printWindow.document.close();
      printWindow.print();
    }
}
})

The behavior I was hoping for was:

When the print button is hit the model values for the input elements would also be in the pick list.

This feels like is "should work", but the input elements are empty when I hit the print button.

I don't understand what mark-up I need to get Vue.js to write the model values on the input elements to the printWindow document.

Update (for those finding this through the internet):

Handling textarea tags was a simple matter of setting the v-html attribute.

Select tags I handled with this bit of code:

        var selectElements = Array.prototype.slice.call(pageElement.querySelectorAll('select'));
        selectElements.forEach(function (el) {
            for (var index = 0; index < el.options.length; index++) {
                option = el.options[index];
                if (option.value === el.value) {
                    option.setAttribute('selected', true);
                    return;
                }
            }
        });
1
  • pass your todo.note as html value attribute, <input v-model="todo.notes" value="todo.notes" /> Commented Jan 3, 2019 at 13:51

2 Answers 2

2

That is because when you're copying the elements, you actually do not copy their state (e.g. value of the text input, or the checked property of the checkbox). So what you need to do is to iterate through all input elements in the pageElement node, and assign the stored values as HTML attributes instead:

var pageElement = this.$el.querySelector('#pickList');
var inputElements = Array.prototype.slice.call(pageElement.querySelectorAll('input'));
inputElements.forEach(function(el) {
    if (el.type === 'text')
        el.setAttribute('value', el.value);

    if (el.type === 'checkbox' && el.checked)
        el.setAttribute('checked', '');
});

See your fixed fiddle here: https://jsfiddle.net/teddyrised/1h6e4n7z/


This also implies that you will need to update the logic above, if you have other input types, for example, <select> will need to be handled separately, and so is <textarea>.

Sign up to request clarification or add additional context in comments.

Comments

0

pass you todo.note as value attribute in your HTML tag. e.g: <input v-model="todo.notes" value="todo.notes" />

1 Comment

Thank you for the answer. That didn't work completely for me because (in my actual solution) the view model is updated via an API call so when the view is generated the inputs are empty. It did work for the components within the printable area, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.