<html>
<head>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
table { border-collapse: collapse; font-size: 9pt; }
td { padding: 7px; border: 1px solid #aaa; }
td:nth-child(odd) { background-color: #ddd; }
</style>
</head>
<body>
<table>
<tr>
<td>車牌1</td><td><input id="c1" /></td>
<td>欄位X</td><td><input id="x1" /></td>
</tr>
<tr>
<td>說明</td>
<td colspan="3">
<textarea id="t1" style="width: 100%" rows="4"></textarea>
</td>
</tr>
<tr>
<td>欄位A</td><td><input id="f1" /></td>
<td>欄位B</td><td><input id="f2" /></td>
</tr>
</table>
<button onclick="validate()">測試檢核</button>
<script>
jQuery.fn.showInvalidMessageTag = function (msg, options) {
//ver 1.1 add auto clear
options = $.extend({ autoHide: true, forceChange: false }, options);
var forceChange = options.forceChange;
if (forceChange) options.autoHide = false;
//add style block
var styleBlock = $('#invld-msg-styles');
if (!styleBlock.length) {
$("\
<style id='invld-msg-styles'>\
.ivmt-tag { font-size:10pt; position: absolute; cursor: pointer; z-index: 99999; opacity: 0.85 }\
.ivmt-tag .arw { color: #e53939; font-size: 12px; padding-left: 2px }\
.ivmt-tag .msg { background-color: #e53939; color: white; padding: 4px 12px; width: auto; margin-top: -4px; border-radius: 3px}\
.ivmt-tag .prog { width: 100%; background-color: yellow; height: 2px; opacity: 0.5; }\
.ivmt-mask-layer { position: absolute; z-index: 65535; opacity: 0.3; background-color: #888; top: 0; left: 0; width: 100vw }\
</style>").prependTo('body');
}
var elem = $(this);
var maskLayer = $('.ivmt-mask-layer');
if (forceChange && maskLayer.length) return;
var pos = elem.offset();
var bgc = '#e53939';
var tag = $('<div class="ivmt-tag" style="visibility:hidden;"><div class="arw">▲</div><div class="msg"><div class="text"></div></div>');
tag.find('.msg .text').text(msg);
if (options.autoHide) tag.find('.msg').append('<div class="prog"></div>');
tag.appendTo('body');
var tagPos = pos.top < tag.height() ? 'bottom' : 'top';
var top = pos.top + elem.height();
if (tagPos == 'top') {
top = pos.top - tag.height() + 4;
var msgBlock = tag.find('.msg');
msgBlock.css('marginTop', '0');
tag.find('.arw').text('▼').css('marginTop', '-5px').before(msgBlock);
}
if (forceChange) {
maskLayer = $('<div class=ivmt-mask-layer></div>');
maskLayer.css({ height: Math.max(window.innerHeight, document.body.scrollHeight) + 'px' }).appendTo('body');
}
if (!forceChange && options.autoHide) {
var count = 100;
var hnd = setInterval(function() {
count--;
tag.find('.prog').css('width', count + '%');
if (count <= 0) {
clearInterval(hnd);
tag.remove();
}
}, 100);
tag.hover(function() {
clearInterval(hnd);
tag.find('.prog').remove();
});
}
tag.css({ visibility: 'visible', top: top + 'px', left: pos.left + 'px' })
.add(maskLayer).click(function () {
tag.remove();
if (forceChange) {
elem.focus();
maskLayer.remove();
}
});
}
</script>
<script>
$('#c1').blur(function () {
var inp = $(this);
if (!/^[-0-9A-Z]{5,8}$/.exec(inp.val())) {
inp.showInvalidMessageTag("車牌格式有誤,請更正!", { forceChange: true });
}
});
function validate() {
$('.ivmt-tag').remove();
$('input,textarea').not('#c1').each(function () {
var inp = $(this);
if (!inp.val())
inp.showInvalidMessageTag("欄位不可空白");
});
}
</script>
</body>
</html>
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |