미디어위키:Gadget-templateForm.js
보이기
참고: 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.
- 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
- 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
- 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
function formControl() {
if (!$(".ci-form-control").length) return
function makeid(length) {
var result = "";
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
return Array.from({ length: length }, function () { return characters.charAt(Math.floor(Math.random() * charactersLength)); }).join('');
}
$(".ci-form-label").toArray().forEach(function (innerlabel) {
var $innerLabel = $(innerlabel);
var labelText = $innerLabel.text();
var name = $innerLabel.data("name");
var cases = [
{
// inputbox 타이틀로 사용되는 경우
condition: function () {
// 다음 요소가 .ci_form_section_inputs_inner_col_input_container일 때 부합
return $innerLabel.parent().next().hasClass("ci_form_section_inputs_inner_col_input_container");
},
callback: function () {
// .ci_form_section_inputs_row parent 찾기
var $row = $innerLabel.closest(".ci_form_section_inputs_row");
var $label = $row.find("label");
var $input = $row.find("input");
$input.attr("id", $input.attr("name"));
$label.attr("for", $input.attr("id")); // label의 for값을 id로 지정
$input.attr("name", name); // input박스의 name값을 name으로 지정
$input.addClass("target-ctrl") //폼 전송 버튼 클릭 시 다룰 오브젝트로 추가
},
},
{
// radiobox, checkbox 폼 타이틀로 사용되는 경우
condition: function () {
// 1회상위에 있는 요소가 .ci_form_section_title, 2회 상위가 .multiple_choice일때 부합
return $innerLabel.parent().hasClass("ci_form_title") && $innerLabel.parent().next().find(".ci_form_section_multiple_choice_list").length > 0;
},
callback: function () {
// .multiple_choice에 해당하는 부모 찾기
// ul > li > input 찾기
var $input = $innerLabel.parent().next().find("input[type=radio], input[type=checkbox]");
$input.attr("name", name);// 기존 input박스 name값을 id로 지정
}
},
{
// radiobox, checkbox 섹션 타이틀로 사용되는 경우
condition: function () {
// 1회상위에 있는 요소가 .ci_form_section_title, 2회 상위가 .multiple_choice일때 부합
return $innerLabel.parent().hasClass("ci_form_section_title") && $innerLabel.parent().parent().hasClass("multiple_choice");
},
callback: function () {
// .multiple_choice에 해당하는 부모 찾기
var $parent = $innerLabel.closest(".multiple_choice");
// ul > li > input 찾기
var $input = $parent.find("ul > li > input");
$input.attr("name", name);// 기존 input박스 name값을 id로 지정
}
},
{
// radiobox의 레이블로 사용되는 경우
condition: function () {
// 직계부모가 li고 이전 요소가 radio, checkbox input일 때
return $innerLabel.parent().is("li") && $innerLabel.prev().is("input[type=radio], input[type=checkbox]");
},
callback: function () {
// inputbox 찾기
var $input = $innerLabel.prev();
$input.attr("value", name); // name을 value로 지정
// id가 없으면 name_value_랜덤문자열로 지정
if (!$input.attr("id")) $input.attr("id", name + "_" + makeid(10));
// $innerlabel 삭제 후 $input을 가리키는 label 생성
$innerLabel.remove();
$input.after($("<label>").attr("for", $input.attr("id")).text(labelText));
$input.addClass("target-ctrl") //폼 전송 버튼 클릭 시 다룰 오브젝트로 추가
},
},
{
// textarea, select타이틀로 사용되는 경우
condition: function () {
// parent의 next에 find textarea가 있을 때
return $innerLabel.parent().next().find("textarea, select").length > 0;
},
callback: function () {
// textarea 찾기
var $parent = $innerLabel.parent();
var $textarea = $parent.next().find("textarea, select");
$textarea.attr("id", $textarea.attr("name"));
$textarea.attr("name", name); // textarea의 name값을 name으로 지정
// parent에 label 생성
$innerLabel.remove();
$parent.append($("<label>").attr("for", $textarea.attr("id")).text(labelText));
$textarea.addClass("target-ctrl") //폼 전송 버튼 클릭 시 다룰 오브젝트로 추가
}
},
];
var matchedCase = cases.find(function (c) { return c.condition(); });
if (matchedCase) matchedCase.callback();
});
$(".ci-form-control").toArray().forEach(function (formControlEl) {
var $this = $(formControlEl);
var nextPagename = $this.data("destination") || mw.config.get("wgPageName") // 다음 페이지 이름
// 현재 파라미터를 보존할지에 대한 여부
var isKeepParams = $this.data("keep-params") || false;
if ($this.data("keep-params") === "false") isKeepParams = false;
// 다음 위치에 있는 .ci-form 찾기
var formEl = $this.nextAll().toArray().find(function (el) { return $(el).hasClass("ci_form"); });
if (!formEl) return; // 다음 폼 찾을 수 없으면 종료
var $form = $(formEl);
// submit 버튼 텍스트가 submit이면 변경
var $submit = $form.find("[type=submit]");
if($submit.val() == "Submit"){
$submit.val('전송')
}
$form.find("input[type=hidden]").not(".token").remove();
$form.on("submit", function (e) {
e.preventDefault(); // 폼 전송 막기
var params = {};
// isKeepParams가 true일 경우 현재 파라미터를 보존
if (isKeepParams) {
var nowUrl = new URL(location);
nowUrl.searchParams.forEach(function (value, key) {
params[key] = value;
});
}
var initedCheckbox = {}
// 컨트롤대상 인풋박스에 대해 파라미터 추가
$form.find(".target-ctrl").toArray().forEach(function (input) {
var $input = $(input);
var name = $input.attr("name");
var value = $input.val();
var inputType = $input.attr("type");
if (inputType == "radio") {
// radio박스 타입인 경우 현재값이 체크되었을 경우에만 설정
if ($input.is(":checked")) params[name] = value;
} else if (inputType == "checkbox") {
// checkbox박스 타입인 경우 현재값이 체크되었을 경우 추가
if ($input.is(":checked")) {
// 체크박스 첫 파라미터인 경우 초기화
if (!initedCheckbox[name]) {
initedCheckbox[name] = true;
params[name] = value;
} else {
params[name] += "," + value;
}
}
} else if ($input.is("select")) {
if ($input.next().hasClass("select2")) {
// next에 .select2 있는 경우 select2-selection__rendered의 title값으로 설정
params[name] = $input.next().find(".select2-selection__rendered").attr("title");
} else {
// 없으면 현재 골라진 옵션의 인덱스값으로 설정
params[name] = $input.find("option:selected").index();
}
} else {
// 기본적으로 현재값 설정
params[name] = value;
}
})
// title 충돌 방지
delete params.title;
// mw.util.getUrl()로 파라미터를 추가한 url을 생성
url = mw.util.getUrl(nextPagename, params);
// 생성된 url로 이동
location.href = url;
});
});
}
$(formControl);