Using JSX with jQuery
You can use JSX with jQuery if you build your client JavaScript with NakedJSX.
←Return to NakedJSX documentation
JSX elements and fragments can be passed directly to jQuery functions such as .append()
:
$('body').append(
<p css="color: fuchsia">
jQuery ❤️ NakedJSX!
</p>
);
Here is a complete example that retrieves and displays cat facts from https://catfact.ninja/fact.
First we have a file named src/index-client.jsx, which NakedJSX treats as client JavaScript for a HTML file called index.html:
src/index-client.jsx
const catFactApi = "https://catfact.ninja/fact";
const CatFactError =
({ children }) =>
<p css="color: red">
{children}
</p>
function getCatFact()
{
// Disable the button and set a temporary status message
$("#fact-get").prop('disabled', true);
$("#fact")
.empty()
// Passing a JSX element to jQuery works
.append(<p>Retrieving cat fact ...</p>);
// Retrieve a cat fact using jQuery
$.ajax(
{
url: catFactApi,
success:
function({ fact })
{
// Re-enable the button and display the fact
$("#fact-get").prop('disabled', false);
$("#fact")
.empty()
// Passing a JSX fragment to jQuery also works
.append(
<>
<p>According to {catFactApi}:</p>
<p css="margin: inherit 16px">{fact}</p>
</>
);
},
error:
function(result)
{
// Re-enable the button and display an error
$("#fact-get").prop('disabled', false);
$("#fact")
.empty()
// Passing JSX functions to jQuery works too.
.append(<CatFactError>oh no, error getting cat fact</CatFactError>);
},
});
}
Then we have src/index-page.jsx, which NakedJSX uses to build the index.html HTML file:
src/index-page.jsx
import { Page } from '@nakedjsx/core/page'
const Head =
() =>
<>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js" />
</>
const Body =
() =>
<>
<h1>jQuery plus NakedJSX</h1>
<p>This example demonstrates that jQuery and NakedJSX work well together.</p>
<button id="fact-get" onClick="getCatFact()">Get Cat Fact NOW!</button>
<div id="fact" />
</>
Page.Create('en');
Page.AppendHead(<Head />);
Page.AppendCss(`
html { font-family: sans-serif }
body { font-size: 1.25rem; max-width: 40ch; margin: 0 auto; padding: 16px; }
`);
Page.AppendBody(<Body />);
Page.Render();
With these files created, if you have Node.js installed, you can now build them into a folder called out by running an npx command from the parent directory:
# build command
$ npx nakedjsx src --out out
The result is a single file out/index.html, which contains HTML, CSS, and JavaScript built from the above code. The compiled result is visible below, and you can test it in your browser.
(Note: a minority of facts in the cat facts database appear to have some encoding issues and may display an excess of slashes or quotes. This is a data problem, not a problem with NakedJSX.)
By adding --dev
to the build command, you can launch a development build and web server that will automatically reload your browser as you save changes.
out/index.html (1666 bytes) (open in new tab)
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script><style>html{font-family:sans-serif}body{font-size:1.25rem;max-width:40ch;margin:0 auto;padding:16px}.a{color:red}.b{margin:inherit 16px}</style></head><body><h1>jQuery plus NakedJSX</h1><p>This example demonstrates that jQuery and NakedJSX work well together.</p><button id="fact-get" onclick="getCatFact()">Get Cat Fact NOW!</button><div id="fact"></div><script>"use strict";const t=Element.prototype.appendChild;function e(t,e,...n){if(e=e||{},"function"==typeof t)return e.children=n,t(e);const c=document.createElement(t);for(const[t,n]of Object.entries(e)){if(t.startsWith("on")){const e=t.toLowerCase();if(e in window){c.addEventListener(e.substring(2),n);continue}}c.setAttribute(t,n)}for(const t of n)c.appendChild(t);return c}Element.prototype.appendChild=function(e){if(Array.isArray(e)){for(const t of e)this.appendChild(t);return e}return"string"==typeof e?t.call(this,document.createTextNode(e)):e?t.call(this,e):void 0};const n="https://catfact.ninja/fact",c=({children:t})=>e("p",{class:"a"},t);window.getCatFact=function(){$("#fact-get").prop("disabled",!0),$("#fact").empty().append(e("p",null,"Retrieving cat fact ...")),$.ajax({url:n,success:function({fact:t}){$("#fact-get").prop("disabled",!1),$("#fact").empty().append([e("p",null,"According to ",n,":"),e("p",{class:"b"},t)])},error:function(t){$("#fact-get").prop("disabled",!1),$("#fact").empty().append(e(c,null,"oh no, error getting cat fact"))}})};</script></body></html>