Skip to content

Commit 6c2d503

Browse files
committed
Fix #9 Add validate option
1 parent 95536dc commit 6c2d503

File tree

15 files changed

+240
-46
lines changed

15 files changed

+240
-46
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# CHANGELOG: jquery.add-input-area
22

3+
## v4.11.0
4+
#### New option
5+
`validate` option is added to fix #9.
6+
See [documentation](https://sutara79.github.io/jquery.add-input-area/#index_13).
7+
38
## v4.10.0
4-
### New option
5-
`dont_clone` option is added to fix #8 .
9+
#### New option
10+
`dont_clone` option is added to fix #8.
611
See [documentation](https://sutara79.github.io/jquery.add-input-area/#index_12).
712

813
## v4.9.0

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ https://sutara79.github.io/jquery.add-input-area/
1616
- [GitHub](https://github.com/sutara79/jquery.add-input-area): Clone or download.
1717
- [npm](https://www.npmjs.com/package/jquery.add-input-area): `npm i jquery.add-input-area`
1818
- CDN [(jsDelivr)](https://www.jsdelivr.com/):
19-
- [jquery.add-input-area.min.js (v4.10.1)](https://cdn.jsdelivr.net/npm/jquery.add-input-area@4.10.1/dist/jquery.add-input-area.min.js)
19+
- [jquery.add-input-area.min.js (v4.11.0)](https://cdn.jsdelivr.net/npm/jquery.add-input-area@4.11.0/dist/jquery.add-input-area.min.js)
2020

2121

2222
## Usage
@@ -96,7 +96,7 @@ You can use original naming convention by setting custom data attribute, "data-n
9696
|[clone_event](https://sutara79.github.io/jquery.add-input-area/#index_11)|boolean |true |If event will be copied or not. |
9797
|[maximum](https://sutara79.github.io/jquery.add-input-area/#index_05) |number |0 |Max number of wrapper of form fields. "0" means unlimited.|
9898
|[dont_clone](https://sutara79.github.io/jquery.add-input-area/#index_12) |string |null |CSS selector to avoid cloning.|
99-
99+
|[validate](https://sutara79.github.io/jquery.add-input-area/#index_13) |function |null |Validation before adding. Should return boolean. If false, adding stops.|
100100

101101

102102
## License

demo/validate/index.html

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Validate: jquery.add-input-area</title>
6+
<script src="../../node_modules/jquery/dist/jquery.min.js"></script>
7+
<script src="../../dist/jquery.add-input-area.min.js"></script>
8+
<script src="../form-serialize.js"></script>
9+
<script>
10+
/*global $*/
11+
$(function() {
12+
$('#list').addInputArea({
13+
validate: function () { // Should return boolean.
14+
// Call checkValidity() method of HTML5.
15+
// See: https://www.w3.org/TR/html50/forms.html#dom-form-checkvalidity
16+
if (!$('.form-serialize')[0].checkValidity()) {
17+
$('#submit').click();
18+
return false;
19+
}
20+
return true;
21+
}
22+
});
23+
});
24+
</script>
25+
</head>
26+
<body>
27+
<body>
28+
<h1>Validate: jquery.add-input-area</h1>
29+
<form class="form-serialize">
30+
<ol id="list">
31+
<li class="list_var">
32+
<input type="text" size="30" name="list-text_0" id="list-text_0" required>
33+
<label><input type="radio" name="list-radio_0" id="list-radio-aaa_0" required>AAA</label>
34+
<label><input type="radio" name="list-radio_0" id="list-radio-bbb_0">BBB</label>
35+
<button type="button" class="list_del">Delete</button>
36+
</li>
37+
</ol>
38+
<input type="button" value="Add" class="list_add"><br>
39+
<input type="submit" value="Send" name="submit" id="submit">
40+
</form>
41+
</body>
42+
</html>

dist/jquery.add-input-area.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.html

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ <h5 class="mt-2">
8484
<span class="lang_en">Not to copy elements</span>
8585
<span class="lang_ja">HTML要素を複製しないオプション</span>
8686
</a>
87+
<a class="list-group-item list-group-item-action" href="#index_13">
88+
<span class="lang_en">Validation</span>
89+
<span class="lang_ja">バリデーション</span>
90+
</a>
8791
</div>
8892
</div>
8993
</nav>
@@ -553,6 +557,53 @@ <h6>JavaScript</h6>
553557
$('#list').addInputArea({
554558
<span class="green">dont_clone</span>: <span class="red">'.dont_clone'</span>
555559
});
560+
</pre>
561+
</div>
562+
</section>
563+
564+
<section id="index_13" class="card">
565+
<h5 class="card-header">
566+
<span class="lang_en">Validation</span>
567+
<span class="lang_ja">バリデーション</span>
568+
</h5>
569+
<div class="card-body">
570+
<div class="btn-container">
571+
<a class="btn btn-primary" href="demo/validate/" target="_blank">
572+
Sample
573+
<svg class="octicon octicon-link-external" viewBox="0 0 12 16" version="1.1" aria-hidden="true"><path fill-rule="evenodd" d="M11 10h1v3c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h3v1H1v10h10v-3zM6 2l2.25 2.25L5 7.5 6.5 9l3.25-3.25L12 8V2H6z"></path></svg>
574+
</a>
575+
</div>
576+
<p>(since: v4.11)</p>
577+
<p class="lang_en">
578+
You can validate before adding.<br>
579+
Set <code>validate</code> option that returns boolean.
580+
</p>
581+
<p class="lang_ja">
582+
入力欄の追加の前にバリデーションを実行できます。<br>
583+
真偽値を返す<code>validate</code>オプションを設定してください。
584+
</p>
585+
<p class="lang_en">
586+
The sample above uses <a href="https://www.w3.org/TR/html50/forms.html#dom-form-checkvalidity">checkValidity()</a> method of HTML5.<br>
587+
In this case, you must create <code>&lt;form&gt;</code> and submit-button.<br>
588+
You can use other validation method as well.
589+
</p>
590+
<p class="lang_ja">
591+
上のサンプルではHTML5の<a href="https://www.w3.org/TR/html50/forms.html#dom-form-checkvalidity">checkValidity()</a>メソッドを利用しています。<br>
592+
この場合は、<code>&lt;form&gt;</code>と送信ボタンが必要です。<br>
593+
HTML5以外のバリデーションを利用することもできます。
594+
</p>
595+
<h6>JavaScript</h6>
596+
<pre>
597+
$('#list').addInputArea({
598+
<span class="green">validate</span>: function () { <span class="red">// Should return boolean.</span>
599+
// Call checkValidity() method of HTML5.
600+
if (!$('.form-serialize')[0].checkValidity()) {
601+
$('#submit').click();
602+
return false;
603+
}
604+
return true;
605+
}
606+
});
556607
</pre>
557608
</div>
558609
</section>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "jquery.add-input-area",
33
"description": "jQuery plugin to add or delete form fields.",
4-
"version": "4.10.1",
4+
"version": "4.11.0",
55
"license": "MIT",
66
"author": "Yuusaku Miyazaki <toumin.m7@gmail.com>",
77
"homepage": "https://github.com/sutara79/jquery.add-input-area",

src/fn_addInputArea.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* @arg {boolean} [option.clone_event=true] - If event will be copied or not.
1010
* @arg {number} [option.maximum=0] - Max number of wrapper of form fields. "0" means unlimited.
1111
* @arg {String} [option.dont_clone=null] - CSS selector to avoid cloning.
12+
* @arg {Function} [option.validate=null] - Validation before adding. Should return boolean. If false, adding stops.
1213
* @return {Object} jQuery object for method chaining.
1314
*/
1415
/*global $*/

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @file jquery.add-input-area
3-
* @version 4.10.1
3+
* @version 4.11.0
44
* @author Yuusaku Miyazaki <toumin.m7@gmail.com>
55
* @license MIT
66
*/

src/methods.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export default {
1717
after_add: null,
1818
clone_event: true,
1919
maximum: 0,
20-
dont_clone: null
20+
dont_clone: null,
21+
validate: null
2122
}, option);
2223
if (!option.area_del) {
2324
option.area_del = option.btn_del;
@@ -40,6 +41,11 @@ export default {
4041
* @private
4142
*/
4243
_ehAddBtn: function() {
44+
// Check validity
45+
if (this.option.validate && !this.option.validate()) {
46+
return;
47+
}
48+
4349
// Add new wrapper.
4450
this._addNewArea();
4551

test/e2e/dont-clone.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @file E2E testing
3+
*/
4+
const puppeteer = require('puppeteer');
5+
const assert = require('assert');
6+
7+
let path = 'demo/dont-clone';
8+
describe(path, function () {
9+
const appUrl = `http://localhost:${process.env.MY_PORT}/${path}`;
10+
let browser, page;
11+
12+
before(async function () {
13+
browser = await puppeteer.launch({args: ['--no-sandbox']});
14+
// browser = await puppeteer.launch({headless: false, slowMo: 250});
15+
page = await browser.newPage();
16+
page.on('console', console.log);
17+
await page.goto(appUrl, {waitUntil: 'load'});
18+
});
19+
20+
after(async function () {
21+
browser.close();
22+
});
23+
24+
describe('Option: dont_clone', function () {
25+
it('should not allow to clone', async function () {
26+
await page.click('.list_add');
27+
await page.waitFor(50);
28+
29+
let elem;
30+
elem = await page.$$('.list_var:nth-child(1) div');
31+
assert.equal(elem.length, 2);
32+
elem = await page.$$('.list_var:nth-child(2) div');
33+
assert.equal(elem.length, 1);
34+
});
35+
});
36+
});

test/e2e/validate.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @file E2E testing
3+
*/
4+
const puppeteer = require('puppeteer');
5+
const assert = require('assert');
6+
7+
let path = 'demo/validate';
8+
describe(path, function () {
9+
const appUrl = `http://localhost:${process.env.MY_PORT}/${path}`;
10+
let browser, page;
11+
12+
before(async function () {
13+
browser = await puppeteer.launch({args: ['--no-sandbox']});
14+
// browser = await puppeteer.launch({headless: false, slowMo: 250});
15+
page = await browser.newPage();
16+
page.on('console', console.log);
17+
await page.goto(appUrl, {waitUntil: 'load'});
18+
});
19+
20+
after(async function () {
21+
browser.close();
22+
});
23+
24+
describe('Validation', function () {
25+
it('should prevent from adding', async function () {
26+
await page.click('.list_add');
27+
await page.waitFor(50);
28+
let elem = await page.$$('.list_var');
29+
assert.equal(elem.length, 1);
30+
});
31+
32+
it('should prevent from adding', async function () {
33+
await page.type('#list-text_0', 'a');
34+
await page.click('.list_add');
35+
await page.waitFor(50);
36+
let elem = await page.$$('.list_var');
37+
assert.equal(elem.length, 1);
38+
});
39+
40+
it('should allow to add', async function () {
41+
await page.click('#list-radio-bbb_0');
42+
await page.click('.list_add');
43+
await page.waitFor(50);
44+
let elem = await page.$$('.list_var');
45+
assert.equal(elem.length, 2);
46+
});
47+
});
48+
});

test/lib/e2e.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @file Preparation for E2E testing
3+
*/
4+
const Mocha = require('mocha');
5+
const fs = require('fs');
6+
const path = require('path');
7+
8+
module.exports = {
9+
/**
10+
* Run E2E testing
11+
*
12+
* @return {String} Report of testing
13+
*/
14+
report: function () {
15+
console.log('\n# E2E testing');
16+
17+
const mocha = new Mocha({
18+
timeout: 5000,
19+
ui: 'bdd',
20+
reporter: 'spec'
21+
});
22+
const testDir = './test/e2e';
23+
24+
// Mocha: addFile
25+
fs.readdirSync(testDir).filter(function (file) {
26+
return file.substr(-3) === '.js';
27+
}).forEach(function (file) {
28+
mocha.addFile(
29+
path.join(testDir, file)
30+
);
31+
});
32+
33+
return new Promise((resolve, reject) => {
34+
mocha.run(failures => {
35+
resolve(failures);
36+
});
37+
});
38+
}
39+
};

test/test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
*/
44
const server = require('./lib/server.js');
55
const unit = require('./lib/unit.js');
6+
const e2e = require('./lib/e2e.js');
67
const config = require('./config.js');
78

89
config.set();
910

1011
(async () => {
1112
await server.start(process.env.MY_PORT);
12-
await unit.report(process.env.MY_UNIT_URL, process.env.MY_WAIT_TIME);
13+
await unit.report(process.env.MY_UNIT_URL);
14+
await e2e.report(process.env.MY_E2E_FILE);
1315
process.exit();
1416
})();

test/unit/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
<script src="jQuery.addInputArea/getValOfAttr.js"></script>
2929
<script src="jQuery.addInputArea/renumberFieldEach.js"></script>
3030
<script src="integration/test.js"></script>
31-
<script src="integration/dont_clone.js"></script>
3231
<script src="integration/current-target.js"></script>
3332

3433
<script>

test/unit/integration/dont_clone.js

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)