bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
37.99k stars 1.29k forks source link

Extension morphdom-swap doesn't work? #1663

Open metametadata opened 1 year ago

metametadata commented 1 year ago

I can get alpine-morph and idiomorph extensions to work, but not morphdom-swap.

Demo code, https://jsfiddle.net/ymq5sjbr/1:

<script src="https://demo.htmx.org"></script>

<script src="https://unpkg.com/htmx.org@1.9.4"></script>

<script src="https://unpkg.com/morphdom@2.3.3/dist/morphdom-umd.min.js"></script>
<script src="https://unpkg.com/htmx.org@1.9.4/dist/ext/morphdom-swap.js"></script>

<form id="a" hx-ext="morphdom-swap" hx-swap="morphdom" hx-post="/foo" >
  <button>
  Submit
  </button>
  <input id="file-input" type="file"><input/>
</form>

<template url="/foo">
  <form id="a" hx-ext="morphdom-swap" hx-swap="morphdom" hx-post="/foo" >
    <button>
    Submit
    </button>
    <input id="file-input" type="file"><input/>
  </form>
</template>

Steps

1) Select some file in the input. 2) Press Submit.

Expected

Selected file stays in the input.

Actual

Input is empty.

metametadata commented 1 year ago

I looked in morphdom-swap.js tests and they seem to cover that swapping happens, but not morphing. So I've tried to write the test to prove that morphing really happens by asserting that input value is preserved:

// test/ext/morphdom-swap.js
it('morphdom', function () {
    this.server.respondWith("GET", "/test", '<input type="text" id="a"></input>');
    var el = make('<input type="text" id="a" hx-get="/test" hx-ext="morphdom-swap" hx-swap="morphdom" hx-trigger="click"></input>')
    el.value = 'foo';

    // Act
    el.click();
    this.server.respond();

    // Assert
    byId("a").outerHTML.should.equal('<input type="text" id="a" class="">');
    byId("a").value.should.equal('foo');
});

It fails with AssertionError: expected '' to equal 'foo'.

But the similar test for alpine-morph extension passes:

// test/index.html
<script defer src="https://unpkg.com/alpinejs@3.12.3/dist/cdn.min.js"></script>
<script src="https://unpkg.com/@alpinejs/morph@3.12.3/dist/cdn.min.js"></script>
<script src="../src/ext/alpine-morph.js"></script>

// test/ext/morphdom-swap.js
it('alpine-morph', function () {
    this.server.respondWith("GET", "/test", '<input type="text" id="a"></input>');
    var el = make('<input type="text" id="a" hx-get="/test" hx-ext="alpine-morph" hx-swap="morph" hx-trigger="click"></input>')
    el.value = 'foo';

    // Act
    el.click();
    this.server.respond();

    // Assert
    byId("a").outerHTML.should.equal('<input type="text" id="a" class="">');
    byId("a").value.should.equal('foo');
});
alexpetros commented 1 year ago

Could be a bug—if you can reproduce and want to PR a fix go for it.