patch from @cscortes adding the json-enc extension

This commit is contained in:
carson 2020-05-22 19:41:42 -07:00
parent 08242c7fc5
commit 3eb4a56e28
5 changed files with 182 additions and 8 deletions

View File

@ -1116,11 +1116,15 @@ var htmx = htmx || (function () {
var encodedParameters = null;
forEach(getExtensions(elt), function (extension) {
if (encodedParameters == null) {
extension.encodeParameters(xhr, filteredParameters, elt);
encodedParameters = extension.encodeParameters(xhr, filteredParameters, elt);
}
});
if (encodedParameters != null) {
return encodedParameters;
} else {
return urlEncode(filteredParameters);
}
}
function issueAjaxRequest(elt, verb, path, eventTarget) {
var target = getTarget(elt);

143
test/extensions/json-enc.js Normal file
View File

@ -0,0 +1,143 @@
//
describe("json-enc extension", function() {
beforeEach(function () {
this.server = makeServer();
clearWorkArea();
htmx.defineExtension('json-enc', {
encodeParameters : function(xhr, parameters, elt) {
xhr.requestHeaders['Content-Type'] = 'application/json';
xhr.overrideMimeType('text/json');
return (JSON.stringify(parameters));
}
});
});
afterEach(function () {
this.server.restore();
clearWorkArea();
});
it('handles basic post properly', function () {
var jsonResponseBody = JSON.stringify({});
this.server.respondWith("POST", "/test", jsonResponseBody);
var div = make("<div hx-post='/test' hx-ext='json-enc'>click me</div>");
div.click();
this.server.respond();
this.server.lastRequest.response.should.equal("{}");
})
it('handles basic put properly', function () {
var jsonResponseBody = JSON.stringify({});
this.server.respondWith("PUT", "/test", jsonResponseBody);
var div = make('<div hx-put="/test" hx-ext="json-enc">click me</div>');
div.click();
this.server.respond();
this.server.lastRequest.response.should.equal("{}");
})
it('handles basic patch properly', function () {
var jsonResponseBody = JSON.stringify({});
this.server.respondWith("PATCH", "/test", jsonResponseBody);
var div = make('<div hx-patch="/test" hx-ext="json-enc">click me</div>');
div.click();
this.server.respond();
this.server.lastRequest.response.should.equal("{}");
})
it('handles basic delete properly', function () {
var jsonResponseBody = JSON.stringify({});
this.server.respondWith("DELETE", "/test", jsonResponseBody);
var div = make('<div hx-delete="/test" hx-ext="json-enc">click me</div>');
div.click();
this.server.respond();
this.server.lastRequest.response.should.equal("{}");
})
it('handles post with form parameters', function () {
this.server.respondWith("POST", "/test", function (xhr) {
var values = JSON.parse(xhr.requestBody);
values.should.have.keys("username","password");
values["username"].should.be.equal("joe");
values["password"].should.be.equal("123456");
var ans = { "passwordok": values["password"] == "123456"};
xhr.respond(200, {}, JSON.stringify(ans));
});
var html = make('<form hx-post="/test" hx-ext="json-enc" > ' +
'<input type="text" name="username" value="joe"> ' +
'<input type="password" name="password" value="123456"> ' +
'<button id="btnSubmit">Submit</button> ');
byId("btnSubmit").click();
this.server.respond();
this.server.lastRequest.response.should.equal('{"passwordok":true}');
})
it('handles put with form parameters', function () {
this.server.respondWith("PUT", "/test", function (xhr) {
var values = JSON.parse(xhr.requestBody);
values.should.have.keys("username","password");
values["username"].should.be.equal("joe");
values["password"].should.be.equal("123456");
var ans = { "passwordok": values["password"] == "123456"};
xhr.respond(200, {}, JSON.stringify(ans));
});
var html = make('<form hx-put="/test" hx-ext="json-enc" > ' +
'<input type="text" name="username" value="joe"> ' +
'<input type="password" name="password" value="123456"> ' +
'<button id="btnSubmit">Submit</button> ');
byId("btnSubmit").click();
this.server.respond();
this.server.lastRequest.response.should.equal('{"passwordok":true}');
})
it('handles patch with form parameters', function () {
this.server.respondWith("PATCH", "/test", function (xhr) {
var values = JSON.parse(xhr.requestBody);
values.should.have.keys("username","password");
values["username"].should.be.equal("joe");
values["password"].should.be.equal("123456");
var ans = { "passwordok": values["password"] == "123456"};
xhr.respond(200, {}, JSON.stringify(ans));
});
var html = make('<form hx-patch="/test" hx-ext="json-enc" > ' +
'<input type="text" name="username" value="joe"> ' +
'<input type="password" name="password" value="123456"> ' +
'<button id="btnSubmit">Submit</button> ');
byId("btnSubmit").click();
this.server.respond();
this.server.lastRequest.response.should.equal('{"passwordok":true}');
})
it('handles delete with form parameters', function () {
this.server.respondWith("DELETE", "/test", function (xhr) {
var values = JSON.parse(xhr.requestBody);
values.should.have.keys("username","password");
values["username"].should.be.equal("joe");
values["password"].should.be.equal("123456");
var ans = { "passwordok": values["password"] == "123456"};
xhr.respond(200, {}, JSON.stringify(ans));
});
var html = make('<form hx-delete="/test" hx-ext="json-enc" > ' +
'<input type="text" name="username" value="joe"> ' +
'<input type="password" name="password" value="123456"> ' +
'<button id="btnSubmit">Submit</button> ');
byId("btnSubmit").click();
this.server.respond();
this.server.lastRequest.response.should.equal('{"passwordok":true}');
})
});

View File

@ -87,7 +87,7 @@
<script src="extensions/rails-method.js"></script>
<script src="extensions/debug.js"></script>
<script src="extensions/morphdom-swap.js"></script>
<script src="extensions/json-enc.js"></script>
<!-- events last so they don't screw up other tests -->
<script src="core/events.js"></script>

View File

@ -97,7 +97,7 @@ It can be used via [NPM](https://www.npmjs.com/) as "`htmx.org`" or downloaded o
## <a name="ajax"></a> [AJAX](#ajax)
The core feature of htmx is a set of attributes that allow you to issue AJAX requests directly from HTML:
The core of htmx is a set of attributes that allow you to issue AJAX requests directly from HTML:
* [hx-get](/attributes/hx-get) - Issues a `GET` request to the given URL
* [hx-post](/attributes/hx-post) - Issues a `POST` request to the given URL
@ -492,11 +492,13 @@ If you are interested in adding your own extension to htmx, please [see the exte
Htmx offers some officially supported extensions that are tested against the htmx code base, including:
* [`debug`](/official-extensions#debug) - an extension for htmx debugging a particular element
* [`rails-method`](/official-extensions#rails-method) - an extension for including the `_method` parameter
[that rails uses](https://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-patch-put-or-delete-methods-work-questionmark).
* [`json-enc`](/official-extensions#json-enc) - use JSON encoding in the body of requests, rather than the default `x-www-form-urlencoded`
* [`morphdom-swap`](/official-extensions#morphdom-swap) - an extension for using the
[morphdom](https://github.com/patrick-steele-idem/morphdom) library as the swapping mechanism in htmx.
* [`debug`](/official-extensions#debug) - an extension for debugging of a particular element using htmx
* [`rails-method`](/official-extensions#rails-method) - an extension for including the `_method` parameter that
[that rails uses](https://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-patch-put-or-delete-methods-work-questionmark)
for non-`POST` or `GET` HTTP methods.
See the [officially extensions](/official-extensions) page for a complete list.

View File

@ -94,3 +94,28 @@ htmx.defineExtension('morphdom-swap', {
}
});
```
### <a name="json-enc">[`json-enc`](#json-enc)
#### Description
This extension encodes parameters in JSON format instead of url format.
#### Usage
```html
<div hx-post='/test' hx-ext='json-enc'>click me</div>
```
#### Source
```javascript
htmx.defineExtension('json-enc', {
encodeParameters : function(xhr, parameters, elt) {
xhr.requestHeaders['Content-Type'] = 'application/json';
xhr.overrideMimeType('text/json');
return (JSON.stringify(parameters));
}
});
```