미디어위키:Gadget-templateForm.js

리버티게임(개발), 모두가 만들어가는 자유로운 게임
둘러보기로 이동 검색으로 이동

참고: 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.

  • 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
  • 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
  • 인터넷 익스플로러 / 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
  • 오페라: 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);