Skip to content

Instantly share code, notes, and snippets.

@composite
Last active December 22, 2015 00:09
Show Gist options
  • Save composite/6387332 to your computer and use it in GitHub Desktop.
Save composite/6387332 to your computer and use it in GitHub Desktop.
a jQuery plugin that have a coffee with HTML form convention.
/**
*
*
* ajax-submit 클래스 추가 시 이벤트 바인딩 (첫번째 인자가 form event 객체임에 유의.)
* <code>
* $('#form').on('ajaxbefore', function(event, jqXHR, settings)); //
* $('#form').on('ajaxcomplete', function(event, jqXHR, testStatus)); //
* $('#form').on('ajaxsuccess', function(event, responseObject, testStatus, jqXHR)); //
* $('#form').on('ajaxerror', function(event, jqXHR, testStatus, errorThrown)); //
* </code>
*/
(function ($) {
var typeptn = {
email: /^[\w-\._\+%]+@(?:[\w-]+\.)+[\w]{2,6}$/,
url: /[-a-zA-Z0-9@:%_\+.~#?&\/\/=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)?/,
tel: /^(\(?(\d{3})\)?\s?-?\s?(\d{3})\s?-?\s?(\d{4}))$/,
date: /^(19[0-9]{2}|2[0-9]{3})[-\/\.](0[1-9]|1[012])[-\/\.]([123]0|[012][1-9]|31)$/,
date2: /^(19[0-9]{2}|2[0-9]{3})(0[1-9]|1[012])([123]0|[012][1-9]|31)$/,
datetime: /^(19[0-9]{2}|2[0-9]{3})[-\/\.](0[1-9]|1[012])[-\/\.]([123]0|[012][1-9]|31) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/,
time: /^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/
},
chkevent = function (el, ev) {
if (!el) return false;
var ob = el.jquery ? el[0] : el, evs = $._data ? $._data(ob, 'events') : $.data(ob, 'events');
//console.log(evs);
return evs && evs[ev] && evs[ev].length;
};
$.conform = {
typename: {
email: 'E-mail',
url: 'Internet address',
tel: 'Phone number',
date: 'Date',
datetime: 'Date and time',
time: 'Time'
},
message: {
required: '%s is required.',
number: '%s is not valid a number.',
email: '%s is not valid email.',
url: '%s is not valid URL.',
tel: '%s is not valid phone number',
pattern: '%s is not valid on input condition.',
password: '%s does not match.'
}, onnotvalid: function(input, code) {
alert($.conform.message[code].replace(/%s/g, $('label[for=' + input.id + ']', this).text() || input.getAttribute('title') || $.conform.typename[input.type] || ''));
input.focus();
}
};
$(function () {
//일반형 폼전송
$('form.plain-submit,form.ajax-submit')['on' in $.fn ? 'on' : 'bind']('submit', function (e) {
var that = $(this), self = this, pass = true;
if (!that.hasClass('ignore-valid')) {//정의 클래스는 아무래도 테스트용
$('input[required]', this).each(function () {//필수 양식 체크
if (!this.value) {
e.preventDefault();
try { chkevent(self, 'form:failed') ? that.triggerHandler('form:failed', [this, 'required']) : $.conform.onnotvalid(this, 'required'); } catch (ex) { console.error(ex); }
return pass = false;
}
});
$('input[type]', this).each(function () {//양식 기본방식 체크
var type = this.type, ptn = typeptn[this.type];
if (type.toLowerCase() == 'number') {//숫자 형식 체크
var val = +this.value, min = +this.getAttribute('min'), max = +this.getAttribute('max'), step = +this.getAttribute('step');
if (isNaN(val) || (!isNaN(min) ? val < min : false) || (!isNaN(max) ? val > max : false) || (!isNaN(step) && step > 1 ? val % step != 0 : false)) {
e.preventDefault();
try { chkevent(self, 'form:failed') ? that.triggerHandler('form:failed', [this, 'number']) : $.conform.onnotvalid(this, 'number'); } catch (ex) { console.error(ex); }
return pass = false;
}
} else if (ptn && this.value && !ptn.test(this.value)) {//기타 형식 체크
e.preventDefault();
try { chkevent(self, 'form:failed') ? that.triggerHandler('form:failed', [this, type in $.conform.message ? type : 'pattern']) : $.conform.onnotvalid(this, type in $.conform.message ? type : 'pattern'); } catch (ex) { console.error(ex); }
return pass = false;
}
});
$('input[pattern]', this).each(function () {//양식 형식 체크
var ptn = this.getAttribute('pattern');
if (ptn) {
try {
if (!this.regex) this.regex = new RegExp(ptn);
if (this.value && !this.regex.test(this.value)) {
e.preventDefault();
try { chkevent(self, 'form:failed') ? that.triggerHandler('form:failed', [this, 'pattern']) : $.conform.onnotvalid(this, 'pattern'); } catch (ex) { console.error(ex); }
return pass = false;
}
} catch (E) { }
}
});
$('.pass-check', this).each(function () {//비밀번호 서로일치 체크
var target = $('.' + this.name + '-check').eq(0);
if (target.length && this.value && this.value != target.val()) {
e.preventDefault();
try { chkevent(self, 'form:failed') ? that.triggerHandler('form:failed', [this, 'password']) : $.conform.onnotvalid(this, 'password'); } catch (ex) { console.error(ex); }
return pass = false;
}
});
}
//미일치시 폼전송 실패.
if (!pass) {
e.preventDefault();
return false;
}
//Ajax 정의시 Ajax 요청하고 일반 폼전송 금지.
if (that.hasClass('ajax-submit')) {
e.preventDefault();
that.data('xhr', self.xhr = $.ajax({
url: this.action, type: this.method, data: that.serialize(), dataType: that.data('type'), context: self,
beforeSend: function (x, o) { try { return that.triggerHandler('ajax:before', [x, o]); } catch (ex) { console.error(ex); } },
complete: function (x, s) { try { return that.triggerHandler('ajax:complete', [x, s]); } catch (ex) { console.error(ex); } },
success: function (d, s, x) { try { return that.triggerHandler('ajax:success', [d, s, x]); } catch (ex) { console.error(ex); } },
error: function (x, s, e) { try { return that.triggerHandler('ajax:error', [x, s, e]); } catch (ex) { console.error(ex); } }
})); return false;
}
});
//SELECT 태그의 data-default 속성 지정 시 기본값에 맞추도록 자동 지정
$('select').each(function () {
var that = $(this), def = that.data('default');
if (def) {
that.find('option').each(function () {
if (this.value == def) {
this.selected = true;
return false;
}
});
}
});
$('.odd').each(function () {
$(this).children(':nth-child(even)').addClass('odd');
});
$('.first-child').each(function () {
$(this).children().eq(0).addClass('first');
});
$('.last-child').each(function () {
$(this).children(':last-child').addClass('last');
});
});
})(jQuery);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jquery.form example</title>
</head>
<body>
<h3>Plain Submit example</h3>
<form id="form1" class="plain-submit" action="/path/to/post" method="post" novalidate="">
<input type="text" name="test"/>
<button type="submit">Submit</button>
</form>
<h3>Ajax Submit example</h3>
<form id="form2" class="ajax-submit" action="/path/to/post" method="post">
<input type="text" name="test"/>
<button type="submit">Submit</button>
</form>
<!-- insert include script of jquery and jquery.form.js here. -->
<script>
$(function(){ // ajax submit event binding
$('#form2').on('form:failed', function(e, input, code){ // validation failed
alert(input.id + 'is error of ' + code);
});
$('#form2').on('ajax:success', function(e, result){ // form ajax success
console.log(result);
alert(result);
}).on('ajax:error', function(e, xhr, stat, err){ // form ajax error
console.log(arguments);
alert(stat + ' : ' + err);
});
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment