test('<input checkbox> two-way - DOM - with truthy and falsy values binds to checkbox (#1700)', function() { var data = new SimpleMap({ completed: 1 }), frag = stache('<input type="checkbox" el:checked:bind="completed"/>')(data); domMutateNode.appendChild.call(this.fixture, frag); var input = this.fixture.getElementsByTagName('input')[0]; equal(input.checked, true, 'checkbox value bound (via attr check)'); data.attr('completed', 0); stop(); testHelpers.afterMutation(function() { start(); equal(input.checked, false, 'checkbox value bound (via attr check)'); }); });
test("<input text> two-way - DOM - input text (#1700)", function() { var template = stache("<input value:bind='age'/>"); var map = new SimpleMap(); var frag = template(map); var ta = this.fixture; ta.appendChild(frag); var input = ta.getElementsByTagName("input")[0]; equal(input.value, "", "input value set correctly if key does not exist in map"); map.attr("age", "30"); stop(); testHelpers.afterMutation(function() { start(); equal(input.value, "30", "input value set correctly"); map.attr("age", "31"); stop(); testHelpers.afterMutation(function() { start(); equal(input.value, "31", "input value update correctly"); input.value = "32"; domEvents.dispatch(input, "change"); stop(); testHelpers.afterMutation(function() { start(); equal(map.attr("age"), "32", "updated from input"); }); }); }); });
test("<input checkbox> checkboxes with checked:bind bind properly (#628)", function() { var data = new SimpleMap({ completed: true }), frag = stache('<input type="checkbox" checked:bind="completed"/>')(data); domMutateNode.appendChild.call(this.fixture, frag); var input = this.fixture.getElementsByTagName('input')[0]; equal(input.checked, data.get('completed'), 'checkbox value bound (via attr check)'); data.attr('completed', false); equal(input.checked, data.get('completed'), 'checkbox value bound (via attr uncheck)'); input.checked = true; domEvents.dispatch(input, 'change'); equal(input.checked, true, 'checkbox value bound (via check)'); equal(data.get('completed'), true, 'checkbox value bound (via check)'); input.checked = false; domEvents.dispatch(input, 'change'); equal(input.checked, false, 'checkbox value bound (via uncheck)'); equal(data.get('completed'), false, 'checkbox value bound (via uncheck)'); });
testHelpers.afterMutation(function() { start(); equal(input.value, "30", "input value set correctly"); map.attr("age", "31"); stop(); testHelpers.afterMutation(function() { start(); equal(input.value, "31", "input value update correctly"); input.value = "32"; domEvents.dispatch(input, "change"); stop(); testHelpers.afterMutation(function() { start(); equal(map.attr("age"), "32", "updated from input"); }); }); });
testIfRealDocument('<select> - previously non-existing select value gets selected from a list when it is added (#1762)', function() { // this breaks with VDOM can-stache-bindings#258 because of selectedIndex var template = stache('<select el:value:bind="{person}">' + '<option></option>' + '{{#each people}}<option value="{{.}}">{{.}}</option>{{/each}}' + '</select>' + '<input type="text" size="5" el:value:bind="person">' ); var people = new DefineList([ "Justin", "Zed", "Tom", "Paula" ]); var vm = new SimpleMap({ person: 'Brian', people: people }); stop(); vm.on('person', function(ev, newVal, oldVal) { ok(false, 'person attribute should not change'); }); var frag = template(vm); equal(vm.attr('person'), 'Brian', 'Person is still set'); testHelpers.afterMutation(function() { people.push('Brian'); testHelpers.afterMutation(function() { var select = frag.firstChild; ok(select.lastChild.selected, 'New child should be selected'); start(); }); }); });
QUnit.test("vm:prop:to/:from/:bind work (#280)", function() { var vm1 = new SimpleMap({ value: 'vm1' }); var vm2 = new SimpleMap({ value: 'vm2' }); var vm3 = new SimpleMap({ value: 'vm3' }); MockComponent.extend({ tag: "comp-1", viewModel: vm1 }); MockComponent.extend({ tag: "comp-2", viewModel: vm2 }); MockComponent.extend({ tag: "comp-3", viewModel: vm3 }); var template = stache( "<comp-1 vm:value:to='scope1'/>" + "<comp-2 vm:value:from='scope2'/>" + "<comp-3 vm:value:bind='scope3'/>" ); var scope = new SimpleMap({ scope1: 'scope1', scope2: 'scope2', scope3: 'scope3' }); template(scope); // vm:value:to equal(scope.attr('scope1'), 'vm1', 'vm:value:to - scope value set from vm'); vm1.attr('value', 'vm4'); equal(scope.attr('scope1'), 'vm4', 'vm:value:to - scope updated when vm changes'); scope.attr('scope1', 'scope4'); equal(vm1.attr('value'), 'vm4', 'vm:value:to - vm not updated when scope changes'); // vm:value:from equal(vm2.attr('value'), 'scope2', 'vm:value:from - vm value set from scope'); scope.attr('scope2', 'scope5'); equal(vm2.attr('value'), 'scope5', 'vm:value:from - vm updated when scope changes'); vm2.attr('value', 'vm5'); equal(scope.attr('scope2'), 'scope5', 'vm:value:from - scope not updated when vm changes'); // vm:value:bind equal(vm3.attr('value'), 'scope3', 'vm:value:bind - vm value set from scope'); scope.attr('scope3', 'scope6'); equal(vm3.attr('value'), 'scope6', 'vm:value:bind - vm updated when scope changes'); vm3.attr('value', 'vm6'); equal(scope.attr('scope3'), 'vm6', 'vm:value:bind - scope updated when vm changes'); });
QUnit.test('event bindings should be removed when the bound element is', function (assert) { var done = assert.async(); var template = stache('<div>{{#if isShowing}}<span foo:from="bar"></span><hr/>{{/if}}</div>'); var viewModel = new SimpleMap({ isShowing: true, bar: 'baz' }); var isTarget = function (target) { return target.nodeName === 'SPAN'; }; var attributeChangeCount = 0; var isAttributeChangeTracked = false; var onNodeAttributeChange = domMutate.onNodeAttributeChange; domMutate.onNodeAttributeChange = function (node) { if (!isTarget(node)) { return onNodeAttributeChange.apply(null, arguments); } attributeChangeCount++; isAttributeChangeTracked = true; var disposal = onNodeAttributeChange.apply(null, arguments); return function () { attributeChangeCount--; return disposal(); }; }; var removalCount = 0; var isRemovalTracked = false; var onNodeRemoval = domMutate.onNodeRemoval; domMutate.onNodeRemoval = function (node) { if (!isTarget(node)) { return onNodeRemoval.apply(null, arguments); } removalCount++; isRemovalTracked = true; var disposal = onNodeRemoval.apply(null, arguments); return function () { removalCount--; return disposal(); }; }; var fragment = template(viewModel); domMutateNode.appendChild.call(this.fixture, fragment); // We use the also effected hr so we // can test the span handlers in isolation. var hr = this.fixture.firstChild.lastChild; var removalDisposal = domMutate.onNodeRemoval(hr, function () { removalDisposal(); domMutate.onNodeAttributeChange = onNodeAttributeChange; assert.ok(isAttributeChangeTracked, 'Attribute foo:from="bar" should be tracked'); assert.equal(attributeChangeCount, 0, 'all attribute listeners should be disposed'); domMutate.onNodeRemoval = onNodeRemoval; assert.ok(isRemovalTracked, 'Element span should be tracked'); assert.equal(removalCount, 0, 'all removal listeners should be disposed'); done(); }); viewModel.attr('isShowing', false); });
function(){ equal(vm.swap, 3, "swap - updated binding key"); map.attr("nextPage",4); equal(vm.swap, 4, "swap - updated binding"); }
function(){ equal(vm.next, 3, "re-initialized with binding"); equal(vm.swap, true, "swap - updated binidng"); //equal(vm.get("checked"), "", "attr - has binding set again"); map.attr("swapName", "nextPage"); },
testHelpers.afterMutation(function() { start(); equal(map.attr("age"), "32", "updated from input"); });
testHelpers.afterMutation(function(){ equal(select.selectedIndex, 0, "selectedIndex is 0 because no value exists on the map"); equal(map.attr("value"), "One", "The map's value property is set to the select's value"); start(); });