Wednesday, June 27, 2012

IE8 doesn't like to play nice with knockout JS templates

I've come across a bizarre issue with IE8 and knockout JS templates. In a project I'm working on, there is a UL list bound against knockoutJS with a foreach binding:

 <ul data-bind="foreach: choices">
<!-- ko template: {name: $data.template, data: $data} -->
<!-- /ko -->
</ul> 
Inside the template, each list item has a delete button:
<button data-bind="click: $parents[1].deleteMe">x</button>

(Noah Sussman)
This delete button works great. The view model has a deleteMe method on it, that takes the currentItem parram passed in by knockout (see http://knockoutjs.com/documentation/click-binding.html ), and calls choices.remove(currentItem). Query viewModel.choices().length in any browser (even IE 8), and it will correctly return the newer, lesser number of elements.

Unfortunately, it doesn't actually remove the item from the dom in IE8. The template will still show the deleted element, even though the deleted element is removed from the viewmodel.

The only solution I have found so far is, unfortunately, to remove the template tag and stick everything inside the UL. Unfortunately, when using multiple templates inside a loop, this can make for some messy code.

Here's a jsfiddle to test with. In IE8, when deleting an element, notice how the bound .length will decrease, while the elements remain in place. In other browsers, the LI is (correctly) removed.

http://jsfiddle.net/wx78s/

Anyone know of a better way to fix this?

Update:

While this does not solve the problem of templates-inside-a-for-loop, if all you need is a single template, there's an easy workaround.

KnockoutJS templates can include a "foreach" param inside the template itself. This works in IE8, and allows you to iterate over templates in IE8.

Tuesday, June 19, 2012

Chrome's "Print Preview" creates a PDF behind the scenes

While looking at a print preview in chrome recently (v 19 now, I believe), I noticed that the internal html for the print preview dialog simply generates a pdf on the fly. At first, I was hoping this would allow plugin-and-server-free ways of giving a "download as pdf" link, but unfortunately, it's locked down.


Chrome prevents pages from linking to everything under chrome://print, so there's no way for javascript to just call window.print(); window.location.href="chrome://print/zzz.pdf";

In the end, I was hoping there would be an easy way of at least linking to chrome's native "Save as pdf" feature, which may not be easily discoverable by computer novices. With this functionality built in, though, it would be interesting for chrome to make available a way for websites to save a pdf, or open up the print preview dialog with Save as PDF preselected. 

Good idea, or just another nonstandard javascript extension to support?