jQuery Request Form Project
Combine a native form, local checks and an honest HTTP fixture response.
Your brief
Create a request for a title and one or two copies. Reject an empty title and invalid quantity before starting the request. Disable only the submit action while pending, then release it on success or failure. The server fixture repeats validation and returns a local receipt without saving anything. This project is deliberately a request lifecycle exercise rather than a complete authenticated booking system. Review keyboard submission as well as the visible button.
Run in a separate local browser lab
Save this complete HTML source as index.html in an empty folder. Put the pinned full jQuery 4.0.0 file beside it and preserve the MIT licence notice. The document includes its own CSS and JavaScript. Bhylu’s shared website theme does not load jQuery globally.
This example requires HTTP. Save the original loopback fixture server in the same folder. With Node 22, run node lab-server.mjs there and open http://127.0.0.1:8127. Stop it with Ctrl+C. The fixed endpoints use fictional data and never save requests. File URLs do not reproduce this contract.
jQuery examples do not run in Bhylu’s current playground: it blocks external libraries and network access. No Apache, MySQL or website configuration change is needed. Review the full-build setup before using Ajax, effects or plugins.
Worked solution
Show the worked solution
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>jQuery Build a Validated Request With Pending and Recovery States</title>
<style>
:root {
font:
18px/1.6 system-ui,
sans-serif;
color: #16304e;
background: #fff;
color-scheme: light;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
main {
max-width: 50rem;
margin: auto;
padding: 1.25rem;
}
h1 {
font-size: 1.8rem;
line-height: 1.2;
}
h2 {
font-size: 1.3rem;
}
button,
input,
select,
textarea {
font: inherit;
max-width: 100%;
}
button {
margin: 0.2rem;
padding: 0.4rem 0.7rem;
background: #034fa0;
color: white;
border: 1px solid #034fa0;
border-radius: 0.3rem;
}
button:disabled {
opacity: 0.6;
}
label {
display: block;
margin: 0.5rem 0;
}
input:not([type='checkbox']),
select,
textarea {
display: block;
padding: 0.3rem;
}
a {
color: #034fa0;
}
output {
display: block;
}
article,
section,
fieldset {
padding: 0.75rem;
margin-block: 0.75rem;
border: 1px solid #a9bcd1;
}
ul {
padding-left: 1.5rem;
}
:focus-visible {
outline: 3px solid #0078d4;
outline-offset: 3px;
}
.chosen {
border: 3px solid #0078d4;
}
.highlight {
font-weight: 700;
}
.muted {
opacity: 0.7;
}
pre {
white-space: pre-wrap;
overflow-wrap: anywhere;
}
:root[data-theme='dark'] {
color: #d6e7fb;
background: #061d30;
color-scheme: dark;
}
:root[data-theme='dark'] a {
color: #8ecbff;
}
</style>
</head>
<body>
<main>
<h1>Neighbourhood book swap</h1>
<form id="request">
<label
>Title<input
name="title"
value="River Paths"
required
maxlength="80" /></label
><label>Copies<input name="copies" value="1" required /></label
><button type="submit">Send local fixture request</button>
</form>
<output>No request yet</output>
</main>
<script src="jquery.min.js"></script>
<script>
jQuery(function ($) {
$('#request').on('submit.request', function (event) {
event.preventDefault();
const $form = $(this);
const title = String($form.find('[name=title]').val()).trim(),
copies = String($form.find('[name=copies]').val()).trim();
if (!title || title.length > 80 || !/^[12]$/.test(copies)) {
$('output').text('Check title and copies');
return;
}
const $button = $form.find('button').prop('disabled', true);
$('output').text('Sending local fixture request');
$.ajax({
url: '/api/request',
method: 'POST',
dataType: 'json',
data: { title, copies },
timeout: 2000,
})
.done(function (data) {
$('output').text(data.message);
})
.fail(function () {
$('output').text('Request failed; review before retrying');
})
.always(function () {
$button.prop('disabled', false);
});
});
});
</script>
</body>
</html>
Expected result
Valid data receives a Not saved receipt. Invalid copies are rejected locally and the action remains usable.
The fixture tests a transport and validation boundary, not durable booking, CSRF protection for authenticated users or an idempotent production workflow. A real service must define duplicate-submission and timeout behaviour, including the possibility that a write succeeded before its response was lost. Do not make every failure an automatic retry. Keep pending and result messages available without moving focus unnecessarily.
Extend and test
Add field-specific error associations and a controlled server-failure fixture. Verify the button is released and an earlier receipt is not mistaken for the new result.
Use jQuery’s official API documentation for exact method and return contracts.