fix : form태그 내부 값 가져오는 부분 수정
parent
49ccf695b0
commit
c884081cb5
@ -0,0 +1,808 @@
|
|||||||
|
var wctx = {
|
||||||
|
path:"",
|
||||||
|
url:function(path) {
|
||||||
|
return this.path + path;
|
||||||
|
},
|
||||||
|
home:function() {
|
||||||
|
top.location.href = wctx.url("/");
|
||||||
|
},
|
||||||
|
current:function() {
|
||||||
|
let str = top.location.href.replace(top.location.origin + wctx.path, "");
|
||||||
|
let pos = str.indexOf("?");
|
||||||
|
return pos < 0 ? str : str.substr(0, pos);
|
||||||
|
},
|
||||||
|
trace:true
|
||||||
|
};
|
||||||
|
|
||||||
|
function log(msg) {
|
||||||
|
console.log.apply(console, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function debug(msg) {
|
||||||
|
if (wctx && wctx.trace)
|
||||||
|
console.log.apply(console, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function trim(s) {
|
||||||
|
if (null == s || undefined == s) return "";
|
||||||
|
if ("string" != typeof(s)) return s;
|
||||||
|
return s.replace(/^\s+/, "").replace(/\s+$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEmpty(v) {
|
||||||
|
if (v == undefined
|
||||||
|
|| v == "undefined"
|
||||||
|
|| v == null
|
||||||
|
|| v == "null"
|
||||||
|
) return true;
|
||||||
|
|
||||||
|
switch (typeof(v)) {
|
||||||
|
case "string": return "" == trim(v);
|
||||||
|
case "boolean": if (false == v) return false;
|
||||||
|
case "number": if (0 == v) return false;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ifEmpty(v, nv) {
|
||||||
|
if (!isEmpty(v)) return v;
|
||||||
|
if (typeof(nv) == "function")
|
||||||
|
return nv.apply();
|
||||||
|
else
|
||||||
|
return nv;
|
||||||
|
}
|
||||||
|
|
||||||
|
function notEmpty(obj, msg) {
|
||||||
|
if (isEmpty(obj))
|
||||||
|
throw msg;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toQuery(map, encode) {
|
||||||
|
if (isEmpty(map)) return "";
|
||||||
|
|
||||||
|
var query = [];
|
||||||
|
for (var key in map) {
|
||||||
|
var v = map[key];
|
||||||
|
if (v != null && v == undefined) continue;
|
||||||
|
if (v != null)
|
||||||
|
switch (typeof(v)) {
|
||||||
|
case "object":
|
||||||
|
case "function": continue;
|
||||||
|
}
|
||||||
|
if (isEmpty(v))
|
||||||
|
query.push(key);
|
||||||
|
else
|
||||||
|
query.push(key + "=" + (encode != false ? encodeURIComponent(v) : v));
|
||||||
|
}
|
||||||
|
return query.join("&");
|
||||||
|
}
|
||||||
|
|
||||||
|
function uuid() {
|
||||||
|
var hexDigits = "0123456789abcde",
|
||||||
|
result = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < 36; ++i)
|
||||||
|
result[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
|
||||||
|
result[14] = "4";
|
||||||
|
result[19] = hexDigits.substr((result[19] & 0x3) | 0x8, 1);
|
||||||
|
result[8] = result[13] = result[18] = result[23] = "-";
|
||||||
|
|
||||||
|
return result.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function wait(show) {
|
||||||
|
if (show == false)
|
||||||
|
$(".wait").hide();
|
||||||
|
else
|
||||||
|
$(".wait").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
var dialog = {
|
||||||
|
title:"XIT",
|
||||||
|
template:null,
|
||||||
|
open:function(conf) {
|
||||||
|
if (this.template)
|
||||||
|
this.create(conf);
|
||||||
|
else {
|
||||||
|
var self = this;
|
||||||
|
ajax.get({
|
||||||
|
url:wctx.url("/resources/html/dialog.html"),
|
||||||
|
success:function(resp) {
|
||||||
|
self.template = resp;
|
||||||
|
self.create(conf);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close:function(id) {
|
||||||
|
$("#close" + id).click();
|
||||||
|
},
|
||||||
|
create:function(conf) {
|
||||||
|
conf = conf || {};
|
||||||
|
let id = conf.id || "dlg-" + uuid(),
|
||||||
|
backdropID = id + "-backdrop",
|
||||||
|
size = conf.size || "",
|
||||||
|
tmpl = this.template
|
||||||
|
.replace(/{id}/g, id)
|
||||||
|
.replace(/{title}/g, conf.title || dialog.title);
|
||||||
|
if (size)
|
||||||
|
size = " modal-" + size;
|
||||||
|
tmpl = tmpl.replace(/{size}/, size);
|
||||||
|
dlg = $(tmpl).appendTo("body");
|
||||||
|
|
||||||
|
dlg.find(".modal-body").html(conf.content || "").fadeIn();
|
||||||
|
|
||||||
|
dlg.on("hidden.bs.modal", function() {// on dialog close
|
||||||
|
$("#" + id +",#" + backdropID).remove(); // removes the dialog and its backdrop
|
||||||
|
if (conf.onClose)
|
||||||
|
conf.onClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (conf.onOK) {
|
||||||
|
let footer = dlg.find(".modal-footer");
|
||||||
|
footer.show();
|
||||||
|
footer.find("button").unbind("click").click(function() {
|
||||||
|
if (conf.getData) {
|
||||||
|
var selected = conf.getData.apply();
|
||||||
|
if (!selected) return;
|
||||||
|
|
||||||
|
conf.onOK(selected);
|
||||||
|
dialog.close(id);
|
||||||
|
} else {
|
||||||
|
conf.onOK();
|
||||||
|
dialog.close(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (conf.timeout)
|
||||||
|
setTimeout(function(){dialog.close(id);}, conf.timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
dlg.draggable().modal("show");
|
||||||
|
$(".modal-backdrop").each(function() { // gives id to its backdrop
|
||||||
|
let backdrop = $(this);
|
||||||
|
if (!backdrop.prop("id"))
|
||||||
|
backdrop.prop("id", backdropID);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (conf.init)
|
||||||
|
conf.init();
|
||||||
|
},
|
||||||
|
alert:function(conf) {
|
||||||
|
var container = "<div class='container-fluid text-center' style='font-size:1.4em;'>{content}</div>";
|
||||||
|
if ("string" == typeof(conf)) {
|
||||||
|
conf = {
|
||||||
|
content:container.replace(/{content}/g, conf)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
conf.content = container.replace(/{content}/g, conf.content);
|
||||||
|
}
|
||||||
|
conf.timeout = 2200;
|
||||||
|
this.open(conf);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function onError(xhr, options, error) {
|
||||||
|
if (xhr.readyState == 0)
|
||||||
|
return dialog.alert("서버에 접근할 수 없습니다.");
|
||||||
|
|
||||||
|
var resp = JSON.parse(xhr.responseText);
|
||||||
|
if (resp.handler)
|
||||||
|
return eval(resp.handler);
|
||||||
|
|
||||||
|
var msgs = [];
|
||||||
|
for (key in resp)
|
||||||
|
msgs.push(resp[key])
|
||||||
|
msgs = msgs.join("<br />");
|
||||||
|
if (msgs)
|
||||||
|
dialog.alert(msgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ajax = {
|
||||||
|
request:function(options) {
|
||||||
|
options.beforeSend = function(xhr) {
|
||||||
|
if (wctx.csrf)
|
||||||
|
xhr.setRequestHeader(wctx.csrf.header, wctx.csrf.token);
|
||||||
|
if (!options.silent)
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
if (!options.type) {
|
||||||
|
if (options.data)
|
||||||
|
options.type = "POST";
|
||||||
|
}
|
||||||
|
|
||||||
|
var success = options.success;
|
||||||
|
options.success = function(resp) {
|
||||||
|
if ("string" == typeof resp)
|
||||||
|
resp = trim(resp);
|
||||||
|
|
||||||
|
var stacktrace = resp.stacktrace;
|
||||||
|
delete resp.stacktrace;
|
||||||
|
|
||||||
|
debug("response", resp);
|
||||||
|
|
||||||
|
if (!resp.failed)
|
||||||
|
return success(resp);
|
||||||
|
|
||||||
|
dialog.alert({
|
||||||
|
content:resp.message,
|
||||||
|
onClose:"sessionExpired" == resp.status ? wctx.home : undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
debug("stacktrace", stacktrace);
|
||||||
|
};
|
||||||
|
var handleError = options.error || onError;
|
||||||
|
options.error = function(xhr, options, error) {
|
||||||
|
wait(false);
|
||||||
|
|
||||||
|
debug("error", xhr, options, error);
|
||||||
|
handleError(xhr, options, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
var handleComplete = options.complete || function(){};
|
||||||
|
options.complete = function() {
|
||||||
|
wait(false);
|
||||||
|
handleComplete();
|
||||||
|
};
|
||||||
|
debug("request", options);
|
||||||
|
$.ajax(options);
|
||||||
|
},
|
||||||
|
get:function(options) {
|
||||||
|
options.type = "GET";
|
||||||
|
ajax.request(options);
|
||||||
|
},
|
||||||
|
post:function(options) {
|
||||||
|
options.type = "POST";
|
||||||
|
ajax.request(options);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var json = {
|
||||||
|
with:function(options) {
|
||||||
|
options.dataType = "json";
|
||||||
|
if (typeof(options.data) == "string") {
|
||||||
|
options.contentType = "application/json; charset=UTF-8";
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
get:function(options) {
|
||||||
|
ajax.get(json.with(options));
|
||||||
|
},
|
||||||
|
post:function(options) {
|
||||||
|
ajax.post(json.with(options));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function upload(options) {
|
||||||
|
options.enctype = "multipart/form-data";
|
||||||
|
options.processData = options.contentType = false;
|
||||||
|
var data = options.data,
|
||||||
|
formData = new FormData();
|
||||||
|
for (var key in data) {
|
||||||
|
var val = data[key];
|
||||||
|
if (!Array.isArray(val))
|
||||||
|
formData.append(key, val);
|
||||||
|
else {
|
||||||
|
for (var i = 0; i < val.length; ++i)
|
||||||
|
formData.append(key, val[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options.data = formData;
|
||||||
|
ajax.post(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.onEnterPress = function(handler) {
|
||||||
|
return this.each(function(){
|
||||||
|
$(this).keypress(function(evt){
|
||||||
|
if (!handler || evt.which != 13) return;
|
||||||
|
handler.apply();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function labelFor(input) {
|
||||||
|
var selector = "label[for='{id}']",
|
||||||
|
key = "string" == typeof(input) ? input
|
||||||
|
: $(input).attr("id") || $(input).attr("name");
|
||||||
|
if (!key) return "";
|
||||||
|
|
||||||
|
selector = selector.replace(/{id}/gi, key);
|
||||||
|
return $(selector).text();
|
||||||
|
}
|
||||||
|
|
||||||
|
function validationFailureHandler() {
|
||||||
|
var handler = {
|
||||||
|
notice:function(msg, input) {
|
||||||
|
dialog.alert({
|
||||||
|
content:msg,
|
||||||
|
onClose:function(){input.focus();}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
valueMissing: function(input) {
|
||||||
|
handler.notice(labelFor(input) + "를(을) 입력하십시오.", input);
|
||||||
|
},
|
||||||
|
typeMismatch: function(input) {
|
||||||
|
handler.notice(input.value + "는 " + labelFor(input) + "의 형식에 맞지 않습니다.", input);
|
||||||
|
},
|
||||||
|
tooLong: function(input) {
|
||||||
|
handler.notice(input.value + " 값이 너무 깁니다.", input);
|
||||||
|
},
|
||||||
|
patternMismatch: function(input) {
|
||||||
|
handler.notice(input.value + "는 " + labelFor(input) + "의 형식에 맞지 않습니다.", input);
|
||||||
|
},
|
||||||
|
rangeOverflow: function(input) {
|
||||||
|
handler.notice(labelFor(input) + "의 값은 " + input.max + "보다 작아야 합니다.", input);
|
||||||
|
},
|
||||||
|
rangeUnderflow: function(input) {
|
||||||
|
handler.notice(labelFor(input) + "의 값은 " + input.min + "보다 커야 합니다.", input);
|
||||||
|
},
|
||||||
|
stepMismatch: function(input) {
|
||||||
|
handler.notice(labelFor(input) + "의 값은 " + input.step + "씩 증가 또는 감소해야 합니다.", input);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Returns the result of validation on the input object.<br />
|
||||||
|
* The types of validation checks are those defined by input objects' basic validity property, which are
|
||||||
|
* <ul><li>valueMissing</li>
|
||||||
|
* <li>typeMismatch</li>
|
||||||
|
* <li>tooLong</li>
|
||||||
|
* <li>patternMismatch</li>
|
||||||
|
* <li>rangeOverflow</li>
|
||||||
|
* <li>rangeUnderflow</li>
|
||||||
|
* <li>stepMismatch</li>
|
||||||
|
* </ul>
|
||||||
|
* To be effective, the input object must be set with attributes
|
||||||
|
* <ul><li>required</li>
|
||||||
|
* <li>type</li>
|
||||||
|
* <li>maxLength</li>
|
||||||
|
* <li>pattern</li>
|
||||||
|
* <li>max</li>
|
||||||
|
* <li>min</li>
|
||||||
|
* <li>step</li>
|
||||||
|
* </ul>
|
||||||
|
* On failure, failureHandler takes over.<br />
|
||||||
|
* The default handler from <code>validationFailureHandler()</code> displays a message
|
||||||
|
* and puts the focus back to the input object.<br />
|
||||||
|
* For the handler to display a message appropriate for the failure,
|
||||||
|
* it is recommended to have a label associated with the input object.
|
||||||
|
* @param input input object
|
||||||
|
* @param failureHandler object that handles validation failure.<br />
|
||||||
|
* If not provided, the default handler from <code>validationFailureHandler()</code> is used.
|
||||||
|
* @returns
|
||||||
|
* <ul><li>true if the value of the input object is valid</li>
|
||||||
|
* <li>false otherwise</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
function validInput(input, failureHandler) {
|
||||||
|
var validity = input.validity;
|
||||||
|
if (!validity || validity.valid) return true;
|
||||||
|
|
||||||
|
for (var key in validity) {
|
||||||
|
if (!validity[key]) continue;
|
||||||
|
|
||||||
|
if (!failureHandler)
|
||||||
|
failureHandler = validationFailureHandler();
|
||||||
|
var handler = failureHandler[key];
|
||||||
|
if (handler)
|
||||||
|
handler(input);
|
||||||
|
else {
|
||||||
|
log("Handler not found for validation failure of " + key);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**Returns the result of input validation on the selected input objects.<br />
|
||||||
|
* The types of validation checks are those defined by input objects' basic validity property, which are
|
||||||
|
* <ul><li>valueMissing</li>
|
||||||
|
* <li>typeMismatch</li>
|
||||||
|
* <li>tooLong</li>
|
||||||
|
* <li>patternMismatch</li>
|
||||||
|
* <li>rangeOverflow</li>
|
||||||
|
* <li>rangeUnderflow</li>
|
||||||
|
* <li>stepMismatch</li>
|
||||||
|
* </ul>
|
||||||
|
* To be effective, the input objects must be set with attributes
|
||||||
|
* <ul><li>required</li>
|
||||||
|
* <li>type</li>
|
||||||
|
* <li>maxLength</li>
|
||||||
|
* <li>pattern</li>
|
||||||
|
* <li>max</li>
|
||||||
|
* <li>min</li>
|
||||||
|
* <li>step</li>
|
||||||
|
* </ul>
|
||||||
|
* On failure, failureHandler takes over.<br />
|
||||||
|
* The default handler from <code>validationFailureHandler()</code> displays a message
|
||||||
|
* and puts the focus back to the offending input object.<br />
|
||||||
|
* For the handler to display a message appropriate for the failure,
|
||||||
|
* it is recommended to have labels associated with input objects.
|
||||||
|
* @param failureHandler object that handles validation failure.<br />
|
||||||
|
* If not provided, the default handler from <code>validationFailureHandler()</code> is used.
|
||||||
|
* @returns
|
||||||
|
* <ul><li>true if the input values of the selected objects are valid</li>
|
||||||
|
* <li>false otherwise</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
$.fn.validInputs = function(failureHandler) {
|
||||||
|
var valid = true;
|
||||||
|
this.each(function(){
|
||||||
|
var input = $(this);
|
||||||
|
if (!(valid = validInput(input[0], failureHandler))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.getValues = function(propertyMapper) {
|
||||||
|
var inputValues = {};
|
||||||
|
this.each(function() {
|
||||||
|
var input = $(this),
|
||||||
|
key = input.prop("id") || input.prop("name"),
|
||||||
|
value = input.val();
|
||||||
|
if (isEmpty(key) || value === undefined) return;
|
||||||
|
|
||||||
|
var type = input.prop("type");
|
||||||
|
if ("file" == type) {
|
||||||
|
value = input.get(0).files;
|
||||||
|
} else if (["checkbox", "radio"].indexOf(type) > -1) {
|
||||||
|
if (!input.is(":checked")) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stored = inputValues[key];
|
||||||
|
if (stored === undefined) {
|
||||||
|
inputValues[key] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(stored)) {
|
||||||
|
if (!Array.isArray(value))
|
||||||
|
stored.push(value);
|
||||||
|
else
|
||||||
|
stored = stored.concat(value);
|
||||||
|
} else {
|
||||||
|
var array = [stored];
|
||||||
|
if (!Array.isArray(value))
|
||||||
|
array.push(value);
|
||||||
|
else
|
||||||
|
array = array.concat(value);
|
||||||
|
inputValues[key] = array;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (propertyMapper) { // propertyMapper = {property:valueProvider, ...}
|
||||||
|
for (var property in propertyMapper) {
|
||||||
|
var valueProvider = propertyMapper[property],
|
||||||
|
value = undefined;
|
||||||
|
switch (typeof(valueProvider)) {
|
||||||
|
case "string":
|
||||||
|
value = inputValues[valueProvider];
|
||||||
|
break;
|
||||||
|
case "function":
|
||||||
|
value = valueProvider(inputValues);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (value === undefined) continue;
|
||||||
|
|
||||||
|
delete inputValues[valueProvider];
|
||||||
|
inputValues[property] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param config
|
||||||
|
* {start:0,
|
||||||
|
* fetchSize:10,
|
||||||
|
* totalSize:135,
|
||||||
|
* links:3,
|
||||||
|
* first:function(index, label){return "..."},
|
||||||
|
* previous:function(index, label){return "..."},
|
||||||
|
* link:function(index, label){return "..."},
|
||||||
|
* current:function(index, label){return "..."},
|
||||||
|
* next:function(index, label){return "..."},
|
||||||
|
* last:function(index, label){return "..."}
|
||||||
|
* }
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
function paginate(config) {
|
||||||
|
var rc = config.totalSize || 0;
|
||||||
|
// if (!rc) return "";
|
||||||
|
|
||||||
|
var fetchCount = config.fetchSize || 0;
|
||||||
|
// if (!fetchCount) return "";
|
||||||
|
|
||||||
|
var fetch = {
|
||||||
|
all:0,
|
||||||
|
none:-1,
|
||||||
|
count:function(elementCount, size) {
|
||||||
|
if (!elementCount || size == fetch.all) return 1;
|
||||||
|
return parseInt((elementCount / size) + ((elementCount % size) == 0 ? 0 : 1));
|
||||||
|
},
|
||||||
|
end:function(elementCount, size, start) {
|
||||||
|
if (size < fetch.all) throw "Invalid size: " + size;
|
||||||
|
if (elementCount < 0) throw "Invalid elementCount: " + elementCount;
|
||||||
|
var last = elementCount - 1;
|
||||||
|
if (size == fetch.all) return last;
|
||||||
|
return Math.min(last, start + size -1);
|
||||||
|
},
|
||||||
|
page:function(current, count) {
|
||||||
|
return parseInt(count < 1 ? 0 : current / count);
|
||||||
|
},
|
||||||
|
band:function(page, visibleLinks) {
|
||||||
|
return parseInt(visibleLinks < 1 ? 0 : page / visibleLinks);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var lc = fetch.count(rc, fetchCount);
|
||||||
|
if (lc < 2) return "";
|
||||||
|
|
||||||
|
var links = ifEmpty(config.links, fetch.all),
|
||||||
|
page = fetch.page(ifEmpty(config.start, 0), fetchCount),
|
||||||
|
band = fetch.band(page, links),
|
||||||
|
tags = {
|
||||||
|
link:function(tag, index, label) {
|
||||||
|
return !tag ? "" : tag(index, label);
|
||||||
|
},
|
||||||
|
first:function() {
|
||||||
|
return band < 2 ? "" : tags.link(config.first, 0, 1);
|
||||||
|
},
|
||||||
|
previous:function() {
|
||||||
|
if (band < 1) return "";
|
||||||
|
var prevBand = band - 1,
|
||||||
|
prevPage = (prevBand * links) + (links - 1),
|
||||||
|
fromRec = prevPage * fetchCount;
|
||||||
|
return tags.link(config.previous, fromRec, prevPage + 1);
|
||||||
|
},
|
||||||
|
visibleLinks:function() {
|
||||||
|
var s = "",
|
||||||
|
fromPage = links == fetch.all ? 0 : band * links,
|
||||||
|
toPage = links == fetch.all ? lc : Math.min(lc, fromPage + links);
|
||||||
|
for (var i = fromPage; i < toPage; ++i) {
|
||||||
|
var fromRec = i * fetchCount,
|
||||||
|
label = i + 1;
|
||||||
|
s += tags.link(i == page ? config.current : config.link, fromRec, label);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
},
|
||||||
|
next:function(bandCount) {
|
||||||
|
bandCount = parseInt(bandCount);
|
||||||
|
if (bandCount - band < 2) return "";
|
||||||
|
|
||||||
|
var nextBand = band + 1,
|
||||||
|
page = nextBand * links,
|
||||||
|
fromRec = page * fetchCount;
|
||||||
|
return tags.link(config.next, fromRec, page + 1);
|
||||||
|
},
|
||||||
|
last:function(bandCount) {
|
||||||
|
bandCount = parseInt(bandCount);
|
||||||
|
var lastBand = bandCount - 1;
|
||||||
|
if (lastBand - band < 2) return "";
|
||||||
|
|
||||||
|
var pages = lastBand * links,
|
||||||
|
fromRec = pages * fetchCount;
|
||||||
|
return tags.link(config.last, fromRec, pages + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tag = "";
|
||||||
|
if (links != fetch.all) {
|
||||||
|
tag += tags.first();
|
||||||
|
tag += tags.previous();
|
||||||
|
}
|
||||||
|
tag += tags.visibleLinks();
|
||||||
|
if (links != fetch.all) {
|
||||||
|
var bandCount = parseInt(lc / links);
|
||||||
|
bandCount += lc % links == 0 ? 0 : 1;
|
||||||
|
tag += tags.next(bandCount);
|
||||||
|
tag += tags.last(bandCount);
|
||||||
|
}
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.paginate = function(config) {
|
||||||
|
return this.each(function(){
|
||||||
|
var tag = paginate(config),
|
||||||
|
container = $(this);
|
||||||
|
if (tag)
|
||||||
|
container.html(tag).show();
|
||||||
|
else {
|
||||||
|
if (config.hideIfEmpty != false)
|
||||||
|
container.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.setPaging = function(config) {
|
||||||
|
config.links = 5;
|
||||||
|
config.first = function(index, label) {return '<li onclick="{func};" class="page-item first"><a class="page-link"><i class="tf-icon bx bx-chevrons-left"></i></a></li>'.replace(/{func}/, config.func.replace(/{index}/, label));};
|
||||||
|
config.previous = function(index, label) {return '<li onclick="{func}" class="page-item prev"><a class="page-link"><i class="tf-icon bx bx-chevron-left"></i></a></li>'.replace(/{func}/, config.func.replace(/{index}/, label));};
|
||||||
|
config.link = function(index, label) {return '<li onclick="{func}" class="page-item"><a class="page-link">{label}</a></li>'.replace(/{func}/, config.func.replace(/{index}/, label)).replace(/{label}/, label);};
|
||||||
|
config.current = function(index, label) {return '<li class="page-item active"><a class="page-link">{label}</a></li>'.replace(/{label}/, label);};
|
||||||
|
config.next = function(index, label) {return '<li onclick="{func}" class="page-item next"><a class="page-link"><i class="tf-icon bx bx-chevron-right"></i></a></li>'.replace(/{func}/, config.func.replace(/{index}/, label));};
|
||||||
|
config.last = function(index, label) {return '<li onclick="{func}" class="page-item last"><a class="page-link"><i class="tf-icon bx bx-chevrons-right"></i></a></li>'.replace(/{func}/, config.func.replace(/{index}/, label));};
|
||||||
|
|
||||||
|
return this.each(function(){
|
||||||
|
let tag = paginate(config),
|
||||||
|
container = $(this);
|
||||||
|
if (tag)
|
||||||
|
container.html(tag.replace(/{func}/g, config.func)).show();
|
||||||
|
else {
|
||||||
|
if (config.hideIfEmpty != false)
|
||||||
|
container.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
let list = config.list;
|
||||||
|
let pagingInfo = list.empty ? "" :
|
||||||
|
numberFormat.format(config.start + 1)
|
||||||
|
+ " ~ "
|
||||||
|
+ numberFormat.format(config.start + list.length)
|
||||||
|
+ " / " + numberFormat.format(config.totalSize);
|
||||||
|
$("#"+ config.prefix + "PagingInfo").html(pagingInfo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.setCurrentRow = function(val) {
|
||||||
|
if (!val) return;
|
||||||
|
|
||||||
|
return this.each(function() {
|
||||||
|
var e = $(this);
|
||||||
|
e.find("tr").each(function(){
|
||||||
|
var tr = $(this),
|
||||||
|
current = val == tr.attr("data-key");
|
||||||
|
if (current)
|
||||||
|
tr.addClass("current-row");
|
||||||
|
else
|
||||||
|
tr.removeClass("current-row");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class FormFields {
|
||||||
|
constructor(selector) {
|
||||||
|
this.form = document.querySelector(this.selector = selector);
|
||||||
|
this.children = ["input", "select", "textarea"].map(tag => this.selector + " " + tag).join(",");
|
||||||
|
this.datamap = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
set(obj) {
|
||||||
|
document.querySelectorAll(this.children).forEach(input => {
|
||||||
|
let prop = input.getAttribute("data-map")
|
||||||
|
|| input.name
|
||||||
|
|| input.id;
|
||||||
|
if (!prop) return;
|
||||||
|
|
||||||
|
let dataItem = obj instanceof DataItem,
|
||||||
|
value = dataItem ? obj.getValue(prop) : obj[prop];
|
||||||
|
|
||||||
|
if ("radio" == input.type) {
|
||||||
|
if (value && value == input.value)
|
||||||
|
input.checked = true;
|
||||||
|
} else {
|
||||||
|
input.value = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get() {
|
||||||
|
let obj = {};
|
||||||
|
document.querySelectorAll(this.children).forEach(input => {
|
||||||
|
let property = input.name || input.id;
|
||||||
|
let value = input.value;
|
||||||
|
if ("radio" == input.type) {
|
||||||
|
if (input.checked)
|
||||||
|
obj[property] = value;
|
||||||
|
} else {
|
||||||
|
obj[property] = value;
|
||||||
|
}
|
||||||
|
// log(property, value, "radio" == input.type ? "radio" : "", input.checked ? "checked" : "");
|
||||||
|
});
|
||||||
|
return obj;
|
||||||
|
//return Object.fromEntries(new FormData(this.form).entries());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
$.datepicker.setDefaults({
|
||||||
|
dateFormat:"yy-mm-dd",
|
||||||
|
yearSuffix:"년",
|
||||||
|
monthNames:["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
|
||||||
|
dayNames:["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"],
|
||||||
|
dayNamesMin:["일", "월", "화", "수", "목", "금", "토"],
|
||||||
|
showMonthAfterYear:true,
|
||||||
|
showOtherMonths:true,
|
||||||
|
selectOtherMonths:true,
|
||||||
|
nextText:"다음 달",
|
||||||
|
prevText:"이전 달"
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param fromSource 시작값을 갖는 input의 selector
|
||||||
|
* @param toSource 종료값을 갖는 input의 selector
|
||||||
|
*/
|
||||||
|
function inputsInRange(fromSource, toSource) {
|
||||||
|
var from = $(fromSource),
|
||||||
|
to = $(toSource),
|
||||||
|
compare = function() {
|
||||||
|
var fromVal = from.val() || "",
|
||||||
|
toVal = to.val() || "",
|
||||||
|
ok = toVal >= fromVal;
|
||||||
|
if (ok) return;
|
||||||
|
|
||||||
|
if ($(this)[0] == from[0])
|
||||||
|
to.val(from.val())
|
||||||
|
else
|
||||||
|
from.val(to.val());
|
||||||
|
};
|
||||||
|
from.change(compare);
|
||||||
|
to.change(compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ignore() {
|
||||||
|
console.log.apply(console, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileInput(conf) {
|
||||||
|
conf = conf || {};
|
||||||
|
var name = conf.name || "upload",
|
||||||
|
tag = "<input type='file' name='{name}'{multiple}{accept} style='display:none;'>"
|
||||||
|
.replace(/{name}/, name)
|
||||||
|
.replace(/{multiple}/, conf.multiple ? " multiple" : "")
|
||||||
|
.replace(/{accept}/, conf.accept ? " accept='" + conf.accept + "'" : ""),
|
||||||
|
obj = {
|
||||||
|
name:name,
|
||||||
|
input:null,
|
||||||
|
files:[],
|
||||||
|
|
||||||
|
select:function(onSelect) {
|
||||||
|
if (!obj.input) {
|
||||||
|
var input = obj.input = $(tag);
|
||||||
|
$("body").append(input);
|
||||||
|
input.change(function(){
|
||||||
|
var files = $(this).get(0).files,
|
||||||
|
length = files.length,
|
||||||
|
selected = [];
|
||||||
|
for (var i = 0; i < length; ++i) {
|
||||||
|
var file = files[i];
|
||||||
|
file.id = name + (obj.files.length);
|
||||||
|
selected.push(file);
|
||||||
|
obj.files.push(file);
|
||||||
|
}
|
||||||
|
onSelect(selected);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
obj.input.click();
|
||||||
|
},
|
||||||
|
|
||||||
|
getFiles:function() {
|
||||||
|
return obj.files;
|
||||||
|
},
|
||||||
|
|
||||||
|
remove:function(id){
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
var files = obj.files;
|
||||||
|
for (var i = 0; i < files.length; ++i) {
|
||||||
|
var file = files[i];
|
||||||
|
if (id == file.id) {
|
||||||
|
files.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clear:function(){
|
||||||
|
if (obj.input)
|
||||||
|
$(obj.input).remove();
|
||||||
|
obj.input = null;
|
||||||
|
obj.files.forEach(function(file){delete file;});
|
||||||
|
obj.files = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return obj;
|
||||||
|
}
|
Loading…
Reference in New Issue