* Mobile JQUERY * 

- www.gseek.kr 

 

1.  html tag
    <!doctype html> : 문서형식 지정.  html5로 작성된 웹문서를 의미
   utf-8 : 한글+영문+모든 언어 사용가능
   <span> : 인라인 엘리먼트를 그룹으로 묶을 때 사용.
   element 2종류 : 블럭레벨, 인라인레벨 엘리먼트
   <article> : main content 영역을 article일 한다.
   <fieldset> : n개의 filed(input)를 그룹으로 묶음
    <legend> : fieldset에 그룹으로 묶은 라인에 lable을 넣는다.
    <lable> : 시작장애인에게 lable내용을 읽어준다.
2. css
   -  * {..} : 모든 element에 css적용 
       hi { ...}
       .css_nm {..}
       #id {..}
       #id li {...} : id 하위의 li만 적용 (#id는 부모,  li:자식)
       #id1 > #id2 {..} : id 2개의 상하 구조는 (> : 부등호)를 추가해야 됨
       p + #id {..} : p elemet와 같은 level의 id의 css적용
       header ~ p {..} : header와 같은 level의 모든 p tag의 css적용
      #id li:nth-child(n) : id하위의 n번째 li 요소에 css적용
             (#id li:first-child, #id li:last-child, 
    - padding : box(table)내부의 텍스트와의 간격
       margin   : box(table)외부와 다른 영역(텍스트, table등)과의 간격
    - css. 속성
       float : 화면 크기에 따라서 유동적으로 해당 객체가 이동됨
       clear : float 속성을 제외(clear)시킨다.
       display : 블럭레벨 엘리먼트를 옆으로 이동될 수 있도록 해준다.
                     반대로도 가능
       display:none;  display:hidden
       . none : 객체의 위치가 아에 존재하지 않음
       . hidden : 객체가 안보여지지만 해당위치는 찾이하고 있음
     - position : 웹문서 안에 원하는 위치에 요소를 배치하기 위한 속성
        1. static    : 요소를 문서의 흐름대로 배치
        2. relative : 요소를 상대적으로 배치
        3. absolute : 문서의 흐름과는 상관 없이 배치
        4. fixed : 지정한 위치에 고정해서 배치

3. 웹폰트
    - 웹폰트 정의
       . 예를 들어, 나눔고딕은 windows system font가 아니다.
         그래서 html 작성시 나눔고딕 font를 적용하게 되면 일반 사용자들은 폰트가 깨진다.
         이럴 경우 font-face를 이용해서 나눔고딕.ttf를 download받아 자동 설치 될 수 있도록 한다.
       . 즉, 웹폰트라는건 웹상세 존재 하는 font를 download받아 내 pc에 설치 후 해당 html에 적용되어 
         웹site를 적용된 font를 기준으로 볼 수 있도록 해준다.
    - @font-face{font-family:"나눔고딕";  src:url("./font/나눔고딕.ttf");  format("truetype"); }

4. javascript
    - document.write("..") : document란, 현재 문서를 의미
    - document.getElementByTagName("div")[0].firstChild.nodeValue
    - var aa = document.getElementByTagName("div")[0];
       aa.innerHTML = "good~~";
    - 

5. jQuery
   - javascript보다 10~100배 정도 느리다.
   - <script src="//code.jquery.com/jquery-latest.min.js"></script> : min이란 소스가 압축되었다는 뜻
   - jQuery = $  : selector, 선택자
   - $("*") : document문서 전체 element 얻기
   - $('#id') = jQuery('#id') ; id에 대한 element 얻기
   - $(".id") 또는 $(".id1, .id2") : class id에 대한 element 얻기
   - $("span, #id1, .id2")
   - $("[name=id1], [name=id2]") : 
   - $("[name^=d]"); : name이 d로 시작하는 element 얻기
   - $("[name$=d]"); : name이 d로 끝나는 element 얻기
   - $("[name*=d]"); : name이 d로 포함된(like) element 얻기
   - $('[name~="id1"]'); : name이 id1이 아닌 element 얻기

6. Mobile jQuery
  - 기본 event 1
    var init = function() {...});
    $(document).bind('mobileinit', init); : 제이쿼리 모바일이 초기화 될 수행 
    $(document).bind('pageinit', init); : 페이지가 초기활 될 경우 init 수행
    $(document).read(init); : 모든 초기화가 완료된 경우 init수행
   - event 2 (아래는 모두 동일 event)
      var init = function() {  $('#btn').tap(function() {  .....  });
      var init = function() {  $('#btn').on(function() {  .....  });
      var init = function() {  $('#btn').click(function() {  .....  });
      var init = function() {  $('#btn').bind(function() {  .....  });
      $(document).bind('pageinit', init);
   - 버튼text변경
     . $('btn1').prop('value', '버튼명');
     . $('btn1').attr('value', '버튼명');
     . $('btn1').val('버튼명');
     . $('btn1').text('버튼명');
     . $('btn1').refresh(); //마지막에 refresh를 해줘야 됨
   - 버튼 option변경
     . $('btn1').button('option', 'iconpos', 'top');
   - class
     . <button class="...."></button>
     . 버튼 clss종류 : ui-btn, ui-icon-heart, ui-btn-icon-notext, ui-btn-inline, ui-shadow, ui-corner-all
     . div class 종류 : 
  - mobile용 jQuery include
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
   - option 및 option속성
     . data-role, data-icon, data-iconpos, data-enhanced, footer, data-iconshadow
         , data-thme, data-inline, data-mini, data-role, data-position
     . class : ui-content, ui-body, ui-bar ui-bar-a, ui-body ui-body-a, ui-corner-all, 
     . data-icon속성 : check, carat-r, carat-l, carat-u, carat-d, delete, info, false, gear, phone, heart, lock, shop, 
     . data-iconspos 속성 : left, right, left, bottom
     . data-iconshadow 속성 : true/false
     . data-inline 속성 : true/false
     . data-mini 속성:  true/false
     . data-role 속성 : button, listview , list-divider, 
     . data-position  속성 : fixed
     . data-them 속성 : a, b, 
     . data-clear-btn : true/false
     . placeholer : "내용"
     . data-divider-theme 속성 : a
     . data-autodividers  속성 : true/false
     . data-inset 속성 : true/false
     . data-filer  속성 : true/false

   - input
     . <input typ="...">
     . type 종류 : text, search, number, date, month, week, time, email, url, checkbox, 
   - div
     . class 종류 : ui-field-contain, 

   - jQuery Grid
     . 정의 : div와 class 속성을 이용해서 grid를 만든다.
     . <div class="ui-grid-a">
            <div class="ui-block-a" style="background-color:yellow">1블럭(열/컬럼)</div>
            <div class="ui-block-b" style="background-color:red">2블럭(열/컬럼)</div>
       </div>
   - 
   - 기본 body 구조
      <body>
             <div data-role="page">
                      <div data-role="header" data-position="fixed">...</div>
                      <div data-role="main"    class="ui-content">...</div>
                      <div data-role="footer" data-position="fixed">...</div>
             </div>
      </body>
   - 
   - 
   - 
   - 


2-1 : 9장 

Posted by 농부지기
,

[ Ant - 예제 및 설명 ]

 

<!-- 
     * KeiisWebservices.war : 파일 만드는 용도 
     * 로컬,개발,운영 다른점
       1. 경로
<property name="system" value="_local" />
<property name="system"    value="_dev" />
<property name="system"    value="_app" />
       2. 로컬         : war를  /JEUS6.0/webhome/autodeply/ 밑으로 복사한다.
             개발,운영 : war를 복사하지 않는다. (개발,운영서버에 배포)
          <copy file="${war.dir}/${war.name}" toFile="C:/TmaxSoft/JEUS6.0/webhome/autodeploy/${war.name}" overwrite="true"/> 
-->

1. Project
   - 정의      : ant build에 필수 tag. 단 하나만 존재 가능
   - name    : 프로젝트이름. ant이름
   - basedir : 모든 경로를 계산하기위한 기본 경로. 
               property에서 basedir속성 설정하면 오버라이드 되지만, 없는 경우 project의 basedir속성을 참조하게 됨
               상대경로는 빌드파일이 들어있는 폴더를 기준으로 결정 
   - default : target지정이 되지 않은 경우 기본적으로 수행되는 target값. 이 target이 project초기화의 일부로 수행됨
                                                                                                                           
2. Property
   - 정의 : 환경변수 설정
   - 종류 : environment : 시스템 환경변수 사용

3. target
   - 정의 : 빌드에 필요한 단계별 과정에 해당되는 단위.
          각 과정은 다른 과정과의 의존성을 가지고 있어서 이 의존성에 의거하여 수행순서가 정해진다.
          이 의존성을 나타내는 속성이 depends이다.
   - 예) <target nmame="A"/>
        <target nmame="B" depends="A"/>
        <target nmame="C" depends="B"/>
        <target nmame="D" depends="C,B,A"/>
    - depends : target D를 실행시킨다고 가정했을 경우에, 의존성 관계에 따라 C가 먼저수행된다.
                (depends대상이 여러개인 경우, 왼쪽에서 오른쪽 순서로 수행됨)
                C가 실행되려면 B가 먼저 선행되어야 하고, B를 실행하기 위해서는 A가 선행되어야 한다.
                target D에서 선언한 depends의 C,B,A가 아니라 각 target의 선행단계가 우선적으로 수행되므로
                결국 A->B->C->D의 순서로 target이 실행되어 진다.
                수행순서를 결정하기 위해 다양한 attrubute가 있지만 depends를 많이 쓴다.
                
3. task
   - 정의 : task는 target에 속하는 더 작은 일의 단위이다. (project > target > task)
          task가 될 수 있는 것은 다양하게 있는데, 위의 예시에서 사용하는 내용을 인용하자면
          clean업무를 하고자 하는 경우 delete를 사용해서 기존의 classes파일을 지우도록 상세 업무를 주고
          compile을 할 때는 지웠던 classes폴더를 다시 만들어 준 후에, javac를 이용하여 compile을 수행하고 있다.
   - 종류 : copy, delete, javac, javadoc, mkdir, jar(또는 tar, zip)

4. javac
   - 정의 : java compile명령어
   - 속성 : srcdir      : java파일이 위치한 경로를 지정
          destdir     : 컴파일 된 class파일이 위치할 경우
          encoding    : 소스파일의 인코딩 설정  
          debug       : 컴파일 시 디버그 정보를 보여줄 것인지 설정. 기본값은 off
          optimize    : 컴파일 시 소스 최적화 여부 설정. 기본값은 off. jdk1.3이후로는 해당 플래그가 필요없음. (컴파일 시 최저고하가 필요없으므로)
          deprecation : jdk버전 업 등의 이유로 사용 중단된 소스 코드(deprecation)를 컴파일 할 것인지를 물어보는 것. 기본값은 off
          verbose     : 컴파일 시 상세한 진행상황을 보여줄 것인지를 설정. 기본값은 off
          failonerror : 빌드에 실해하는 경우 컴파일 에러를 표시할 것인지 물어봄. 기본값은 true 
          includeAntRuntime : classpath에 ant의 runtime라이브러리를 포함시킬 것인지를 확인.
                              build,sysclasspath가 설정되어있지 않으면 기본값이 yes임
                              apache ant 매뉴얼에서는 false설정을 권장함.


<project name="KeiisWebservices(war)-1.7.9(app)" basedir="." default="java.xml.rename">
<property environment="env"/>
 
<property name="axis2.home"       value="${env.AXIS2_HOME}" />
<property name="proj.webinf"       value="../war/WEB-INF" />
<property name="src.main.dir"       value="webserver" />
<property name="src.sub.dir"        value="server" />
<property name="service.name"    value="KeiisWebservices" />

<property name="system"    value="_app" /> <!-- 운영 -->
<!-- <property name="system" value="_local" /> --> <!-- 로컬 -->
<!-- <property name="system"    value="_dev" />  --> <!-- 개발 -->

<property name="axis2.root.dir" value="axis2_war" />
<property name="war.dir"    value="${axis2.root.dir}/war${system}" />   <!-- war파일위치-->
<property name="war.name"    value="KeiisWebservices.war" />

<property name="dest.dir"           value="axis2_war/${service.name}/build" />
<property name="aar.dir"            value="aar" />                               <!-- .aar 기본생성될 경로 -->
<property name="dest.dir.classes"  value="${dest.dir}/classes" />

<property name="axis2.files.dir" value="axis2_war/axis2" />
<property name="axis2.web.xml.dir" value="axis2_war/axis2/WEB-INF/" />   <!-- web.xml 경로 -->
<property name="axis2.aar.dir" value="axis2_war/axis2/WEB-INF/services" /> <!-- axis2.war 내부에  .aar 파일 위치할 경로 -->
 
    <path id="build.class.path">
        <fileset dir="${proj.webinf}/lib">
            <include name="*.jar" />
        </fileset>
        <pathelement location="${dest.dir.classes}" />
    </path>
 
    <target name="clean">
        <delete dir="${dest.dir}" />
    </target>
 
    <target name="prepare">
        <mkdir dir="${dest.dir}" />
        <mkdir dir="${dest.dir.classes}" />
        <mkdir dir="${dest.dir.classes}/META-INF" />
     <mkdir dir="${aar.dir}" />
    </target>

<!-- CommonkeyList.java, web.xml  local/dev/app 에 맞게 copy -->
    <target name="java.xml.rename" depends="clean,prepare"> 
     <copy file="../src/${src.main.dir}/${src.sub.dir}/com/CommonkeyList.java${system}"  tofile="../src/${src.main.dir}/${src.sub.dir}/com/CommonkeyList.java" overwrite="true" />
     <copy file="${axis2.web.xml.dir}/web.xml${system}"    tofile="${axis2.web.xml.dir}/web.xml" overwrite="true" />
     <antcall target="generate.aar" />
    </target>

<!-- Webservices.aar 파일 생성 -->
    <target name="generate.aar">
        <copy file="META-INF/services.xml"  tofile="${dest.dir.classes}/META-INF/services.xml" overwrite="true" />
        <javac srcdir="../src" destdir="${dest.dir.classes}" includes="${src.main.dir}/${src.sub.dir}/**" classpathref="build.class.path"></javac>
        <jar basedir="${dest.dir.classes}" destfile="${aar.dir}/${service.name}.aar" />
     <antcall target="copy.aar" />
    </target>

<!-- 생성한 Webservices.aar 파일을 원하는 위치에 copy -->
<target name="copy.aar">
<echo message="COPY RESOURCE(S) TO JEUS DIR....." />
<copy file="${aar.dir}/${service.name}.aar" toFile="${axis2.aar.dir}/${service.name}.aar" overwrite="true"/>
<antcall target="generate.war" />
</target>

<!-- axis2.war 생성,  jeus폴더에 복사 안함-->
<target name="generate.war">
<jar basedir="${axis2.files.dir}" destfile="${war.dir}/${war.name}" />
<!-- 
<echo message="COPY RESOURCE(S) TO JEUS DIR....." />
<copy file="${war.local.dir}/${war.name}" toFile="C:/TmaxSoft/JEUS6.0/webhome/autodeploy/${war.name}" overwrite="true"/>
-->

</target>

</project>

Posted by 농부지기
,

[정규식-elements 설명]

 

1. 참고site : ( http://zvon.org/comp/r/tut-Regexp.html )

 

2. elements 설명
   ^ : ^who - 첫번째 시작 문자(열)찾기
   $ : who$ - 마지막 시작 문자(열)찾기
   \ : escape
        \$ - $는 정규식 특수기호 이지만 \를 앞쪽에 붙이면서 

               \다음으로 나오는 정규식기호를 단순한 문자로 인식하게 한다.
       ^\$ - 첫번재 시작문자 $를 찾아줌
       \$$ - 마지막 문자$를 찾아줌
       \\ - \문자를  찾아줌
   . : 모든 문자를 매칭
       ...... :  . 이 6개이면 6개 문자를 매칭 (6개 문자열로 반복됨)
        \..\. : \. - 문자 .을 매칭
                .   - 이때 . 은 어떠한 문자든 매칭
                \. - 문자. 을 매칭
                \..\. - . 과 . 을 매칭하고,  . 과 . 사이의 모든 문자를 매칭
   [ ] : [oyu] - 검색하려는 문자열중에서 o, y, u가 존재시 모두 매칭
       : [dH].  - 검색하려는 문자열중에서 d,H 가 존재 하는 모두 매칭 하면서 . 에 의해서 바로 다음문자 1개를 매칭
       : [owy][you] - 검색하려는 문자열중에서 o,w,y가 존재하면서 y,o,u가 존재 하는 문자열 매칭
   [ - ] : range
         : [C-K] - 검색하려는 문자열중에서 C~K 범위의 문자가 존재시 모두 매칭
         : [C-Ka-d2-6]  - 검색하려는 문자열중에서 C~K, a~d, 2~6 범위의 문자가 존재시 모두 매칭
   [ ^ ] : not (부정)
           : [^cdGHI45] - 검색하려는 문자열중에서 c,d,G,H,I,4,5가 아닌 문자가 존재 시 모두 매칭
           : [^W-Z]  - 검색하려는 문자열중에서 W~Z가 아닌 문자가 존재 시 모두 매칭
   ( ) : (on|use|rida) - 검색하려는 문자열중에서 on, use, rida 가 존재하는 문자열을 모두 매칭
         (Mon|Tues|Fri)day - 검색하려는 문자열중에서 Monday, Tuesday, Fridday가 존재하는 문자열을 모두 매칭
         ..(id|esd|nd)ay - 검색하려는 문자열중에서 .. 문자열2개와 iday,esday, nday 가 존재문자열을 모두 매칭
                                  (검색 문자열 : Monday Tuesday Friday)
   *, +, ? : 수량 (Quantifiers)
   * : 0~n : 0~n개 존재 시 매칭
       a*b : b앞쪽에 a가 0~n개 존재 시 매칭
       .*    : . (모든문자)가 0~n개 존재 시 매칭
      -A*- : "- 앞쪽"에 A가 0~n개 존재할 수 있고 "그 앞쪽에 -" 는 반드시 1개 존재 해야 됨
                (위 설명 재 해석 : -A*-에서 "- 앞쪽"이란 -> 맨 뒤에 있는 - 를 가리킴. 
                                                             "그 앞쪽에 -" 이란 -> 맨 앞쪽에 있는 -를 가리킴)
      [-@]* :  검색 문자열중에 -, @가 0~n개 존재 시 매칭

   + : 1~n : 1~n개 존재 시 매칭
        a+b : 검색 문자열중에서 b앞쪽에 a가 1~n개 존재 시 매칭
        \*+  : 검색 문자열중에서 *문자가 1~n개 존재 시 매칭
        -@+- : - - 사이에 @가 1~n개 존재 시 매칭
        [^ ]+ : 공백이 아닌것이 1~n개 존재 시 매칭 (즉, 공백이 하나도 없으면 매칭)(공백을 제외한 모든문자가 매칭)
   ? : 0 ~ 1개 존재 시 매칭
       a?b : b앞쪽에 a가 0~1개 존재 시 매칭
       -X?XX?X : - : 앞쪽에 - 존재하면서 
                       X? : X가 0~1개 존재
                       X : X가 1개 존재
                       X? : X가 0~1개 존재
                       X : 맨뒤에 X가 하나 존재
       -@?@?@?- : - : 앞쪽에 - 존재하면서 
                             @? : @가 0~1개 존재
                             @? : @가 0~1개 존재
                             @? : @가 0~1개 존재
                             - : 맨뒤에 -가 하나 존재
   { } : 1~n개 존재 시 매칭
        .{5} : 어떠한 문자든 5글자 존재 시 매칭
        [els]{1,3} : 검색 문자열중에서 e,l,s 가 1 또는 3개 일 경우 매칭
        [a-z]{3,}  : 검색 문자열중에서 a~z까지 3개 이상 문자일 경우 매칭
        AB{0,}A = AB*A
        AB{1,}A = AB+A
        AB{0,1}A = AB?A

   r.* : 검색 문자열중에서 r - r문자가 존재 하면서 
                                         .* - .이 0~n개 존재 시 매칭
   r.*? : 검색 문자열중에서 r - r문자가 존재 하면서 
                                         .* - 
                                         ? - 수량자 뒤에 ?가 오면 기존 ? (0~1) 에 의미가 달라짐
                                            - 그래서 *? 는  *는 0~1개 인데, 이때 뒤쪽 1은 버리고, 앞쪽 0만 취해서 
                                                r은 존재 하면서 뒤쪽 문자가 없는 문자 매칭 (즉, r문자 하나만 매칭)
   r.+ : 검색 문자열중에서 r - r문자가 존재 하면서 
                                         .+ - .이 1~n개 문자 존재 시 매칭
   r.+? : 검색 문자열중에서 r - r문자가 존재 하면서 
                                         .+ - 
                                         ? - 수량자 뒤에 ?가 오면 기존 ? (1~n)에 의미가 달라짐
                                            - 그래서 +?는  +는 1~n 개 인데, 이때 뒤쪽 n은 버리고, 앞쪽 1만 취해서
                                                r은 존재 하면서 뒤쪽 문자 1개 문자 매칭 
   r.?  : 
   r.?? : 

   w,W, d, D : character classes
   \w : word(단어), alphanumeric 문자들을 매칭
   \w* : alphanumeric 문자이 0~n개 존재 시 매칭
   [a-z]\w* : a~z문자열이 존재 하면서 alphanumeric 문자이 0~n개 존재 시 매칭
   \w{5}     : alphanumeric 문자가 5 존재 시 매칭
   \W        : not word(단어가 아님), alphanumeric 문자들이 아닌 경우 매칭
   \d         : digit(숫자)
   \D        : not digit(숫자가 아님)
   b, B : word boundery
   \b         : 
   \B         : 
   \A         : 시작
        \A...   : 시작에서 3개의 문자가 매칭
   \Z          : 마지막
        \Z...  : 마지막에서 3개의 문자가 매칭

   \w+(?=X) : \w+ : alphanumeric 문자들이 1~n개 존재 하면서
                     ?=   : 뒤쪽 문자(X)가 존재 하면 매칭.  단, 문자(X)는 선택에서는 제외
   \w+        : 
   \w+(?=\w) : \w+ : alphanumeric 문자들이 1~n개 존재 하면서
                       ?=   : 뒤쪽 alphanumeric 문자(\w)가 존재 하면 매칭.  단, alphanumeric  문자(\w)는 선택에서는 제외

                  

Posted by 농부지기
,

0. 한글처리
    - 참조url : https://syriusta.tistory.com/14
    - 파이썬 코드 첫문장에 아래와 같이 한다.
       #!C:\Python34\python.exe
       #-*- coding: utf-8 -*- <-- utf-8로 문자를 처리하는 부분.

 

1. app.exec_();
    - 이벤트 루프 (Event Loop)
    - QApplication클래스의 객체를 생성한 후 exec_ 메서드를 호출하는 순간 생성된다.
    - 한번 생성된 이벤트 루프는 사용자가 윈도우를 닫을 때까지 실행되면서 위젯에서 발생한 시그널을
       처리하는 슬롯을 호출하는 역할을 한다.

 

2. Widget(위젯)
    - 사용자 인터페이스(UI, 화면)을 구성하는 핵심 요소이다.
    - QT Designer 에서 사용되는 객체(label, edit, button...)들을 의미한다.

 

3. slot (슬롯)
    - PyQt에서는 특정 시그널(event)이 발생했을 때 호출되는 함수 또는 메서드를 slot이라고 한다.

 

4. dialog (다이알로그)
    text,ok = QInputDialog.getInt(self, "나이", "나이를 입력하시오."); #int형
    text,ok = QInputDialog.getDouble(self, "나이", "나이를 입력하시오."); #double 형
    text,ok = QInputDialog.getText(self, "나이", "나이를 입력하시오."); #문자형
    text,ok = QInputDialog.getItem(self, "나이", "나이를 입력하시오."); #항목 선택
 

4.1 MessageBox (메세지 box)
    QMessageBox.about(self, "제목명", "상세내용"):

5. connect
   - 예) btn.clicked.connect(clicked_slot);
   - 시그널(event)과 슬롯(function, method)을 이벤트 루프를 생성하기 전에 연결(connect)한다.
     . 버튼 클릭 시 clicked_slot function을 호출 하도록 연결(connection)을 설정한다.
     . 설정 후 사용자가 btn 을 클릭 시 clicked_slot function을 호출 및 수행 한다.


6. class
    - class name(inherit_Calssname)
    - name : class name
    - inherit_Calssname : 상속class name

 

7. __init__
    - class 생성자 method
    - 예) def __init__(self)
          super().__init__();

 

8. 외부 모듈
    1. 브라우져 실행하기
       - import webbrowser
         url = "http://naver.com";
         webbrowser.open(url);

 

8. visible 객체 생성 1
    1. button생성
       - btnSave = QPushButton("저장", self); #버튼 객체 생성
         btnSave.move(20, 50); #move() : 버튼 위치 이동
         btnSave.clicked.counect(self.btnSave_clicked); #버튼 slot 연결

    2. Label 생성
       - self.label = QLabel("Message : ", self);
         self.label.move(20, 20);
         self.label.resize(200, 20)

    3. Edit 생성
       - self.lineEdit = QLineEdit("", self);
         self.lineEdit.move(20, 20);
         self.lineEdit.textChanged.connect(self.lineEditChanged); #텍스트값이 변경될 때 발생
         self.lineEdit.returnPressed.connect(self.lineEditReturnPressed); #에터 키를 눌렀을 때 발생
    4. Radio button 생성
       - 생성
         self.radio1 = QRadiobutton("항목1", self)
         self.radio1.move(20, 20);
         self.radio1.setChecked(True);
         self.radio1.clicked.connect(self.radioButton_clicked);
         self.radio1 = QRadiobutton("항목1", self)

         self.radio2.move(20, 40);
         self.radio2.setChecked(True);
         self.radio2.clicked.connect(self.radioButton_clicked);
         self.radio2 = QRadiobutton("항목2", self)
     - 클릭된 radion 알아내기
         def radioButton_clicked(self):
             msg = "";
             if self.radio1.isChecked():
                msg = "항목1 선택";
             if self.radio2.isChecked():
                msg = "항목2 선택";
     5. checkbox 생성
        - 생성
          self.checkBox1 = QCheckBox("항목1", self);
          self.checkBox1.move(20, 20);
          self.checkBox1setChecked(True);
          self.checkBox1.clicked.connect(self.checkBoxStateChanged);

          self.checkBox2 = QCheckBox("항목2", self);
          self.checkBox2.move(20, 40);
          self.checkBox2setChecked(True);
          self.checkBox2.clicked.connect(self.checkBoxStateChanged);

      - 클릭된 radion 알아내기
         def radioButton_clicked(self):
              msg = "";
              if self.checkBox1.isChecked():
                 msg = "항목1 선택";
              if self.checkBox2.isChecked():
                 msg = "항목2 선택";

6. QGroupBox 생성
    - 생성
        groupBox = QGroupBox("항목 그룹", self);
        groupBox.move(10, 10);
        groupBox.resize(150, 80);
    - 참고
       radio을 QGroupBox위에 위치 하기 위해서는 QGroupBox를 먼저 생성 후 radio을 만들어야 한다.
      순서가 바뀐 경우 radio button이 여러게 동시 선택된다.

 

7. QSpinBox 생성
    - 생성
       self.spinBox = QSpinBox(self);
       self.spinBox.move(40, 20);
       self.spinBox.resize(60, 20);
       self.spinBox.valueChanged.connect(self.spinBoxValueChagned);
    - 값 얻기
       def self.spinBoxValueChagned(self):
            val = self.spinBox.value();

 

9. visible 객체 생성 2
    0. 참고url : https://m.blog.naver.com/sisosw/221419144691
       1. QTableWidget 생성
          - 생성
            self.tableWidget = QTableWidget(self);
            self.tableWidget.resize(400, 300);
            self.tableWidget.setRowCount(2);
            self.tableWidget.setColumnCount(2);
            self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers);

            self.tableWidget.setItem(0, 0, QTableWidgetItem("(0,0)"));
            self.tableWidget.setItem(0, 1, QTableWidgetItem("(0,1)"));
            self.tableWidget.setItem(1, 0, QTableWidgetItem("(1,0)"));
            self.tableWidget.setItem(1, 1, QTableWidgetItem("(1,1)"));
         - Head Lable 등록
            column_headers = ["학번", "이름", "학년"];
            self.tableWidget.setHorizontalHeaderLables(column_headers);
         - row별 값 set
            students = { "no" : [ "2018001", "2018002", "2018003" ],
                             "name" : [ "홍길동", "이순신", "김성철" ],
                             "group" : [ "1학년", "2학년", "3학년" ] };
            column_idx_lookup = { "no" : 0, "name" : 1, "group" : 2 };

            for k, v in students.items():
                col = column_idx_lookup[k];
                print(k, v, col);
                for row, val in enumerate(v):
                   item = QTableWidgetItem(val);
                   if col == 2:
                      item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight);
                      self.tableWidget.setIem(row, col, item);

           self.tableWidget.resizeColumnsToConTents();
           self.tableWidget.resizeRowsToContents();

Posted by 농부지기
,

[ python 용어. 정의. 관련tool. library ]

 

1. Python Windows에 설치하기
    1. 설치파일 url
        - https://www.python.org/downloads/
        - 목록중에서 최신버전 클릭 > [ Windows X8-64 executable installer ] 클릭해서
            > python-3.7.7-amd64.exe 다운로드 (64bit) (2020.04.01기준)

    2. 설치
        - 파일명 : python-3.7.7-amd64.exe (64bit) (2020.04.01기준)
        - 설치 옵션] 
            . install Now (아래 둘다 체크)
                [v] Install launcher for all users (recommended)
                [v] Add Python 3.7 to PATH
        - 사용자 계정 제어]
            . [사용자 계정 제어] alert창이 뜨면 [Yes] 선택
             (환경에 따라서 안뜰 수 있음)
        - 설치 완료

2. Python과 Apache tomcat 연동

    - python은 tomcat과 같은 웹서버 위에서 수행 된다.

    - https://blog.ayukawa.kr/archives/1342
 
3. Python소스를 다른 웹싸이트 (브라우저)에서 실행하기
    - 참고url : https://iamaman.tistory.com/1882
                 http://pythonfiddle.com/
                 https://www.tutorialspoint.com/execute_python_online.php

 

4. python으로 안드로이드 앱 만들기
    - 참고 url : https://minhwan.kim/python-android-app-dev-with-kivy-and-buildozer/

    - windows 환경에서 안드로이드 앱만들기는 아직 어렵다.

    - linux환경에서는 가능한듯

 

5. 파이썬 개발방법 url
    - https://wikidocs.net/8 (잘되어 있음) (점프 투 파이션 책을 기준으로 만들어 졌음)

 

6. 다운로드 및 설치
    - url : https://www.python.org/downloads/
    - version : python-3.8.2.exe (2020.04.28 기준)
    - 설치 - 설치시 [v] Add Python 3.7 to PATH 를 체크
    - [설치] - [end]

 

7. PyQt5
    1. 정의
        - Windows, Linux, UNIX, Android, OS X 및 IOS 플랫폼을 지원한다.
        - 파이썬에서 GUI (Graphical User Interface) 프로그램을 할 때 사용하는 대표적인 패키지.

    2. 설치 참고url
        - 참고url : https://blog.naver.com/o12486vs2/221941480623

    3. 설치 순서
        * dos command에서 실횅
        * 아래 2번만 수행하면 됨. (1번방법은 뭔지 모르겠음)
        1. 가상환경에서 실행 : conda activate venv32
        2. pyqt인스톨 : pip install PyQt5
        3. PyCharm 에서 PyQt5 설치 (win용)
           . 참고url : https://m.blog.naver.com/PostView.nhn?blogId=sisosw&logNo=221419014406&proxyReferer=http:%2F%2Fwww.google.com%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D14%26cad%3Drja%26uact%3D8%26ved%3D2ahUKEwjhxNnR25npAhW5L6YKHaD-BY4QFjANegQIARAB%26url%3Dhttp%253A%252F%252Fm.blog.naver.com%252Fsisosw%252F221419014406%26usg%3DAOvVaw10i9nXuwcjnZfDEbTh68Xv


    4. 다양한 예제
        - https://opentutorials.org/module/544
        - http://codetorial.net/pyqt5/index.html

    5. 안드로이드 매크로 예제
        - https://m.blog.naver.com/PostList.nhn?blogId=sisosw&categoryNo=36&logCode=0
          (https://m.blog.naver.com/sisosw/221419779178)
        - https://pacific-ocean.tistory.com/121

8. QT Designer
    1. 참고 url
        - https://m.blog.naver.com/sisosw/221419779178

    2. 정의
       - 위지위그(WYSIWYG : What You See Is What You Get) 방식으로 UI화면을 만들도록 도와주는 프로그램

    3. 설치 방법1(pip로 설치하기)
        - Qt Designer는 하나의 독립적인 프로그램으로 아나콘다 배포판에 포함돼 있으며, 보통 PyQt를 설치할 때 함께 설치된다.
        - 예) C:\ProgramData\Anaconda3\Libaray\bin\designer.exe
        - 설치 : pip3 install pyqt5-tools
        - 설치 위치 : * 웹상에는 여기에 설치 된다 했는데..
                               C:\Python37\Lib\site-packages\pyqt5_tools\designer.exe
                         * 아래 3곳 폴더에 설치되었음 (designer.exe 파일에 3곳 폴더에 존재)
                         - 3개 폴더중 어떤걸 실행해야 되남? 음~~~
                            C:\Users\farmerkyh\AppData\Local\Programs\Python\Python38-32\Scripts\designer.exe
                            C:\Users\farmerkyh\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\QtDesigner\designer.exe
                            C:\Users\farmerkyh\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\pyqt5_tools\Qt\bin\designer.exe
                            - 설치 할 때 폴더를 바꾸는 방법을 알아야 할거 같은데...
              - 환경설정 path 추가
                . PATH=C:\Python37\;
                           C:\Python37\Script;
                           C:\Python37\Lib\site-packages\PyQt5;

    4. 설치 방법2(pip로 설치하기)
        - pip install PyQt5Designer
            (난, pip3 install pyqt5-tools 를 수행후 다시 pip install PyQt5Designer 도 수행 했음. 그래도 아무 문제 없는듯.)
            (pip3 install pyqt5-tools 만 수행해도 문제 없음)

    5. 설치 방법3(다운받아 설치)
        - URL : https://pypi.org/project/PyQt5Designer/
                  https://pypi.org/project/PyQt5Designer/#files 에서 PyQt5Designer-5.10.1-cp37-none-win amd64.whl(3.8MB)를 다운받아 설치
                  pip install PyQt5Designer-5.10.1-cp37-none-win amd64.whl
                  또는, 특정 폴더에 있는 경우
                  pip install C:/폴더명/PyQt5Designer-5.10.1-cp37-none-win amd64.whl

        - 버젼 : PyQt5Designer 5.14.1 (2020.05.04 기준)

9. kivy library
    1. kivy 정의
        - kivy는 파이썬 gui programming에 쓰이는 모듈이다.
        - 안드로이드 지원. (안드로이드 app 생성 가능)
        - 이슈 : kivy로 모바일 앱을 만들려는 경우 --> kivy를 apk로 만들어줘야 하는데,
                  이 라이브러리가 윈도우 지원을 안합니다.. 리눅스로만 가능해요.
                  그래서 기껏 열심히 앱 만들었는데 휴대폰에서 사용을 못합니다.

    2. kivy 설치
         - cmd 창에서 아래 명령어 수행 (python.exe 파일이 path 에 등록 되어 있으면 아무곳에서나 실행)
         - python -m pip install --upgrade pip wheel setuptools
         - python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew
         - python -m pip install kivy.deps.gstreamer
         * 만약, 3.5를 쓴다면 python -m pip install kivy.deps.angle 이것도 해줘야 됨
         - python -m pip install kivy
         * 만약, 3.0을 쓴다면
            . https://kivy.org/doc/stable/installation/installation-windows.html 여기가서
            - [Nightly wheel installation] 쪽으로 가서 아래 목록중 하나 다운받아
               -> 설치 : cmd에서 : python -m pip install <방금다운한 whle>
                  . Python 3.5, 32bit
                  . Python 3.6, 32bit
                  . Python 3.7, 32bit
                  . Python 3.5, 64bit
                  . Python 3.6, 64bit
                  . Python 3.7, 64bit

    3. android apk 만들기
        - https://blog.naver.com/mmatelee/220720071624

    4. 문법 공부
        - https://wikidocs.net/4309

    5. kivy 시작하기
        - 정의 . Kivy는 크로스 플랫폼 사용자 인터페이스의 신속한 개발을위한 오픈 소스 Python 라이브러리다.
                 . Kivy 응용 프로그램은 동일한 코드베이스를 사용하여 Linux, Windows, OS X, Android 및 iOS 용으로 개발할 수 있다.
       - https://riptutorial.com/ko/kivy
       - 설치방법 및 예제 1개 : https://riptutorial.com/ko/kivy

     6. 안드로이드에서 python 실행하기
        - https://c10106.tistory.com/1674
        - https://www.otwojob.com/member/join/step1 :

10. pyautogui library
    1. 정의
        - 그래픽 관련 class
        - 다운로드 : 참고 : 특별하게 libary를 download할 필요가 없음.
        - 설치방법 : dos command에서 : C:\>pip install pyautogui
        - 업그레이드 : dos command에서 : C:\>python -m pip install --upgrade pip

    2. 설치방법
        - dos command에서 : C:\a\programming>pip install pyautogui
        - 참고 : 특별하게 libary를 download할 필요가 없음.
    3. 설치시 error
        1. 오류 : ImportError: No module named 'PIL'
           해결방법 : image 를 install 하고, 다시 pyautogui 를 설치하면 된다.[ref. 1]
                         pip install image

11. AREPL tool
    - visual studio 에서 소스 코딩과 동시에 오른쪽에 실행된 결과를 확인 가능

 

                 

 

Posted by 농부지기
,

[ web.html 화면을 pdf로 저장하기 ]

 

1. 정의

    - webbrowser에서 보여지고 있는 상태 그래도 pdf로 저장한다.

 

2. 방법

    a. jspdf js 기능

      - jdspdf        : html, 이미지, canvas객체를 pdf로 변환해주는 라이브러리

        html2canvas : html객체를 canvas로 변환해주는 라이브러리

      - 참고 url : https://blog.naver.com/rnjsrldnd123/221526274628

      - 아래 파일 2개를 생성 후 테스트

    b. self.print();

      - 인쇄버튼 누르면 출력 또는 pdf로 저장 가능

 

3. 이슈 및 특징

    가. jspdf를 통해서 html 객체를 바로 pdf로 변환할 수도 있지만

        , css가 깨지는 문제가 있어서 다음과 같은 순서로 작업을 진행
       1. html2canvas를 이용해 원하는 html 객체를 canvas 객체로 변환
       2. 변환된 canvas 객체를 png 이미지로 변환
       3. png 이미지를 기반으로 pdf 생성 및 로컬에 저장

    나. # html2canvas 사용 시 제가 겪은 몇 가지 문제점입니다.
       1. float:left 속성이 있는 div는 canvas에 그려지지 않음
       2. svg 이미지는 canvas에 그려지지 않음
       3. 하위 div의 display 속성이 block일 경우 그려지지 않음

 

4.1 소스 (jsPDF.html)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="zJsPDF.css">
<script type = "text/javascript" src = "http://code.jquery.com/jquery-latest.min.js"></script>
<script type = "text/javascript" src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script type = "text/javascript" src = "https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
 
<html>
  <body>
    <div id="pdf_wrap">
      <h2>
        javascript
      </h2>
      <h1>
        안녕하세요!
      </h1>
      <h2>
        저는 Mosball입니다.
      </h2>
    </div>
    <button id="create_pdf">
      pdf 생성
    </button>
  </body>
</html>
 
<<script type="text/javascript">
$('#create_pdf').click(function() {
      //pdf_wrap을 canvas객체로 변환
      html2canvas($('#pdf_wrap')[0]).then(function(canvas) {
        var doc = new jsPDF('p', 'mm', 'a4'); //jspdf객체 생성
        var imgData = canvas.toDataURL('image/png'); //캔버스를 이미지로 변환
        doc.addImage(imgData, 'PNG', 0, 0); //이미지를 기반으로 pdf생성
        doc.save('sample-file.pdf'); //pdf저장
      });
    });
</script>

 

4.2 소스(jsPDF.css)

1
2
3
4
5
6
7
8
9
10
11
12
#pdf_wrap {
  background-color:black;
  text-align:center;
}
 
#pdf_wrap > h1 {
  color:blue;
}
 
#pdf_wrap > h2 {
  color:yellow;
}

Posted by 농부지기
,

json-nexacro에서 사용하기

 

1. 사용예

    - dataset컬럼과 json컬럼간에 mapping컬럼을 만들어서 자동parsing하도록 설계

    - json컬럼 for문장을 이용해서 변수갯수 및 변수명 얻기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
this.div_sheet_btn_00_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
    //0. dataset 컬럼 : name, addr, code
    //   json 컬럼    : aa, bb, cc
    //   mappCol 변수 : dataset컬럼과 json컬럼간에 mapping column
     
    //1. dataset 컬럼명과 json객체 변수명 mapping용 json
    //   참고) add 라는 dataset에 컬럼명을 정의 하면 오류 발생
    var mappCol = {name:"aa", code:"bb", addr:"cc"};
     
    //2. json값
    var jsonVal = {aa:10, bb:20, cc:30};
     
    //3. Object.keys(변수명)을 입력하면 해당 오브젝트의 키가 배열로 반환됩니다
    //   웹브라우저 버전별로 안되는 경우 존재
    //var aColList = Object.keys(mappCol);
    //trace(Object.keys(mappCol).length;  //nexa에서는 오류 발생
     
    //4. json값을 접근하는 방법 2가지
    trace(jsonVal["aa"] + " == " + jsonVal.aa);
     
    //5. json객체를 변수 갯수 만큼 for문 수행
    for(var colId in mappCol ) {
        trace(colId + '=>' + mappCol[colId] + '==' + jsonVal[mappCol[colId]]);
        this.ds_00.setColumn(0, colId, jsonVal[mappCol[colId]]);
    }
};

 

2.

'Web. 기타 언어 > json' 카테고리의 다른 글

JSON 데이터를 자바로 파싱방법 종류  (0) 2017.03.13
Posted by 농부지기
,

myBatis-pk,sequence 생성

 

1. 이전방식-개발과정

   1. sql단, pk생성하는 sql 및 xml id 생성

   2. sql단, insert 하는 sql 및 xml id 생성

   3. java단, pk 생성하는 sql 호출

   4. java단, 생성한 pk를 얻어서 insert할 객체에 set

   5. java단, insert하는 sql 호출

  

2. 개선된 개발과정

   1. sql단, pk생성하는 sql 및 insert 하는 sql 2개를 xml id 1개로 생성

   2. java단, pk생성 및 insert하는 sql id(1개) 호출

   3. java단, 위 sql을 호출 하면 넘겨준 객체에  신규생성된 pk가 같이 넘어 온다.

 

3. xml(sql)단

1
2
3
4
5
6
7
8
9
<insert id="insertEmp" parameterType="box">
    <selectKey keyProperty="empNo" resultType="int" order="BEFORE">
        SELECT TB_EMP_SQ.NEXTVAL FROM DUAL
    </selectKey>
    INSERT INTO TB_EMP
        (empNo, EMP_NM, EMP_ADDR, EMP_TEL)
    VALUES
        (#{empNo}, #{EMP_NM}, #{EMP_ADDR}, EMP_TEL)
</insert>

 

4. java단

1
2
3
4
sqlSession.insert("EMPMapper.insertEmp", rowBox);
String newEmp = rowBox.get("empNo");
//이때 생성한 pk를 java단에서 바로 사용가능하다.
//BigDecimal newEmp = (java.math.BigDecimal)rowBox.get("empNo");

'Web. 기타 언어 > myBatis' 카테고리의 다른 글

myBatis - 사용가능한 jdbcType  (0) 2018.07.18
myBatis. Sql WHERE문에서 in 처리(2)  (0) 2018.07.17
myBatis. Sql WHERE문에서 in 처리  (0) 2017.12.05
myBatis - isEmpty, isNull  (0) 2017.12.05
myBatis. if. case 문  (0) 2017.12.05
Posted by 농부지기
,

Thymeleaf - 1. 기본개념

 

1. java단에서 메일발송

   - java단에서 메일을 보낼때 유용하게 사용될 수 있다.

   - 예전에는 java단에서 메일을 보내게 되면 html을 java소스에서 모두 typing을 해서

     String.append처리등을 해야 되서 소스 개발 및 보기가 어려웠다.

   - Thymeleaf을 이용하게 되면 편리 하게 메일발송을 할 수 있다.

 

2. 메일발송 프레임웍

   1. 메일템플릿 테이블 생성(TB_MAIL_TEMPLATE)

       - 이곳에 발송하고 싶은 html을 template을 insert해 놓는다.

       - 이 html내부에는 Thymeleaf tag들이 존재 한다.

       - tag 사용예), 메일수신자명, 일자, 기간, 본문내용 등

         (즉, 각 수신자별 다르게 보여주고 싶은 내용들을 tag로 가지고 있는다.)

   2. 메일발송테이블 생성 (TB_MAIL_SEND)

       - 업무단에서 발송하고 싶은 메일을 이 테이블에 insert해 놓는다.

   3. 업무단에서 메일발송 Logic

       - 메일 template html내부에 있는 thymeleaf Tag에 적용되는 값들을 객체로 생성한다.

       - 메일 template html내부에 적용된 tag 객체 값들을 공통 프레임웍으로 객체들을 전송한다.

   4. 공통에서 TB_MAIL_SEND 테이블에 insert하기

       - 공통 프레임웍은 TB_MAIL_TEMPLATE에 저장 된 template을 조회하여

         argument로 넘어온 thymeleaf tag객체값을 적용한다.

       - TB_MAIL_SEND테이블에 값을 저장 한다.

    5. 메일발송

       - scheduler는 TB_MAIL_SEND에 저장된 메일을 각 수신자에게 발송한다.

Posted by 농부지기
,

Vue.js 3. 기본예제 (복잡한 if,for)-설문지

 

- 아래 scipt는 작동 되지 않는다. 서버에서 설문항목이 조회되어야 정상작동 된다.

- if문, for문장에 대해서 참고용으로만 보면 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="lib" uri="https://lib.fnc.com" %>
 
<div id="container">
<div id="contents">
<div class="tit_area02">
    <h2>설문 조사를 실시하고 있습니다.</h2>
    <p>고객님 설문 참여 해주세요.</p>
</div>
 
<!-- form @submit.prevent="save"-->
<div class="survey">
<dl>
    <dt>질문을 확인하시고 답변 부탁드립니다.</dt>
    <dd>
        <ul class="question">
         
            <!-- 질문 for -->
            <li v-for="quest in questList">
                <span class="tit-tx" v-text="quest.QUST_NO + '. ' + quest.ITEM_CN_S"
                        v-show="quest.LOW_OUST_YN=='N'
                                || (quest.UP_CTRL_TYPE=='10' && ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO] == quest.UP_ANS_NO)
                                || (quest.UP_CTRL_TYPE=='20' && (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO] ? (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO].indexOf(quest.UP_ANS_NO) >= 0 ? true:false) : false))">
                </span>
                 
                <!-- 답안문항 for -->
                <div class="cons" v-for="item in itemList">
                     
                    <!-- =============================================================================== -->
                    <!-- radio (10:단수선택)                                                             -->
                    <!-- =============================================================================== -->
                    <label class="label" v-if="quest.SRVY_SHEET_DTL_NO == item.SRVY_SHEET_DTL_NO && quest.CTRL_TYPE == '10'"
                            v-show="quest.LOW_OUST_YN=='N'
                                    || (quest.UP_CTRL_TYPE=='10' && ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO] == quest.UP_ANS_NO)">
                        <span class="radio">
                            <input type="radio" class="radio" v-model="ansList[quest.ANS_DTL_NO]" :value="item.SRVY_SHEET_ANS_NO">
                            <i></i>
                        </span>
                        {{circleNum[item.ANS_ORDR_SEQ]}} {{item.ANS_CN}}  <!-- ({{item.ETC_ADD_YN}}) -->
                    </label>
                     
                    <input type="text" class="input block add_txt"
                            v-if="quest.SRVY_SHEET_DTL_NO == item.SRVY_SHEET_DTL_NO && quest.CTRL_TYPE == '10' && item.ETC_ADD_YN == 'Y'"
                            v-model="ansList[item.ADD_ANS_NO]"
                            v-show="(ansList[quest.ANS_DTL_NO] == item.SRVY_SHEET_ANS_NO)
                                    &&
                                    (quest.LOW_OUST_YN=='N'
                                    || (quest.UP_CTRL_TYPE=='10' && ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO] == quest.UP_ANS_NO)
                                    || (quest.UP_CTRL_TYPE=='20' && (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO] ? (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO].indexOf(quest.UP_ANS_NO) >= 0 ? true:false) : false)))">
 
                    <!-- =============================================================================== -->
                    <!-- checkbox (20:복수선택)                                                          -->
                    <!-- =============================================================================== -->
                    <label class="label" v-if="quest.SRVY_SHEET_DTL_NO == item.SRVY_SHEET_DTL_NO && quest.CTRL_TYPE == '20'"
                            v-show="quest.LOW_OUST_YN=='N'
                                    || (quest.UP_CTRL_TYPE=='20' && (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO] ? (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO].indexOf(quest.UP_ANS_NO) >= 0 ? true:false) : false))">
                     
                        <span class="checkbox">
                            <input type="checkbox" class="checkbox" v-model="ansList[quest.ANS_DTL_NO]" :value="item.SRVY_SHEET_ANS_NO">
                            <i></i>
                             
                        </span>
                        {{circleNum[item.ANS_ORDR_SEQ]}} {{item.ANS_CN}} <!-- ({{item.ETC_ADD_YN}}) -->
                    </label>
                      
                    <input type="text" class="input block add_txt"
                            v-if="quest.SRVY_SHEET_DTL_NO == item.SRVY_SHEET_DTL_NO && quest.CTRL_TYPE == '20' && item.ETC_ADD_YN == 'Y'"
                            v-model="ansList[item.ADD_ANS_NO]"
                            v-show="(ansList[quest.ANS_DTL_NO] ? (ansList[quest.ANS_DTL_NO].indexOf(item.SRVY_SHEET_ANS_NO) >= 0 ? true:false) : false)
                                    &&
                                    (quest.LOW_OUST_YN=='N'
                                     || (quest.UP_CTRL_TYPE=='20' && (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO] ? (ansList['ANS_DTL_NO_' + quest.UP_SRVY_SHEET_DTL_NO].indexOf(quest.UP_ANS_NO) >= 0 ? true:false) : false)))">
                </div>
 
                <!-- =============================================================================== -->
                <!-- textarea                                                                        -->
                <!-- =============================================================================== -->
                <input class="textarea block add_txt_row" v-if="quest.ANS_TYPE == '20'" v-model="ansList[quest.ANS_DTL_NO]"></input></p>
<div class="text_end">설문에 끝까지 응답해 주셔서 대단히 감사합니다.</div>
<div class="btn_box"><button class="btn" type="submit">설문 참여하기</button></div>
<!-- /survey -->
<p> </p>
<!-- /contents -->
<script>
var vm = new Vue({
    el: '#container',
    data: {
        search: {surveyId:null},
        ansList  : {    },
        questList: null,
        itemList : null,
         
        circleNum : ['', '①','②','③','④','⑤','⑥','⑦','⑧','⑨']
         
    },
    created: function() {
      this.search['surveyId'] = this.urlParam("surveyId");
       
    }, 
    mounted: function() {
      this.init();
    },
    methods: {
        init: function() {
            var param = this.search;
            this.http('<c:url value="/cs/sv/survey/surveyInit.json" />', param, function(data) {
                this.questList = data.questList;
                this.itemList  = data.itemList;
                this.ansList["surveyId"] = this.search["surveyId"];
                 
                var itemJson = JSON.parse(JSON.stringify(data.itemList));
                 
                //1. main 값들 set
                this.ansList['SRVY_SHEET_NO'] = itemJson[0].SRVY_SHEET_NO;
                 
                //2. 복수선택에 대한 배열변수 선언
                var questLen = this.questList.length;
                for(var ii=0; ii<questLen; ii++){
                    if (this.questList[ii].CTRL_TYPE == '20') {
                        Vue.set(this.ansList, this.questList[ii].ANS_DTL_NO, []);
                    }
                }
            });
        },
        save: function() {
            console.log('전송 데이터 : ', this.ansList);
             
            var bValid = this.validation();
            if (bValid == false) return;
             
            this.httpBody('<c:url value="/cs/sv/survey/save.json" />', this.ansList, function(data) {
                alert(data.result);
                //close();
            });
        },
        urlParam: function(name){
            var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
            if (results==null){
               return null;
            }
            else{
               return decodeURI(results[1]) || 0;
            }
        },
        validation: function() {
             
            var questJson = JSON.parse(JSON.stringify(this.questList));
            var itemJson  = JSON.parse(JSON.stringify(this.itemList));
            var questLen  = this.questList.length;
             
            //1. 문제별 FOR문
            for(var ii=0; ii<questLen; ii++) {
                var lowOustYn  = this.questList[ii].LOW_OUST_YN;                //하위문항여부
                var qustNo     = this.questList[ii].QUST_NO;                    //문항번호
                var questDtlNo = this.questList[ii].SRVY_SHEET_DTL_NO;          //설문지상세번호
                var questAnsNo = this.ansList[this.questList[ii].ANS_DTL_NO];   //문제번호별 답
                var ansType    = this.questList[ii].ANS_TYPE;                   //답안유형
                var sizeLmit   = this.questList[ii].SIZE_LMIT;                  //사이즈한도
                 
                //1. 답변 선택 여부
                if (lowOustYn == 'N' && this.isNull(questAnsNo)  == true) {
                    alert("(" + qustNo + ") - 문항에 답변을 하지 않았습니다.");
                    return false;
                }
                 
                //2. 내가 하위문항 이면
                if (lowOustYn == 'Y' && this.isNull(questAnsNo)  == true) {
                    //내 상위의 답안번호가 체크 되었으면 - 필수 검사
                    var upCtrlType = questJson[ii].UP_CTRL_TYPE;          //상위컨트롤유형
                    var upDtlNo    = questJson[ii].UP_SRVY_SHEET_DTL_NO;  //상위설문지상세번호
                    var upAnsNo    = questJson[ii].UP_ANS_NO;             //상위답안번호
                     
                    var varUpAnsNo = "ANS_DTL_NO_" + upDtlNo;  //상위 설문지상세 변수
                     
                    //내 상위가 체크 되었는지 여부
                    var bUpSelected = false;
                    if (upCtrlType == "10") {
                        bUpSelected = this.ansList[varUpAnsNo] == upAnsNo ? true : false;
                    }else{
                        bUpSelected = this.ansList[varUpAnsNo] ? (this.ansList[varUpAnsNo].indexOf(upAnsNo) > 0 ? true : false) : false;
                    }
                    if (bUpSelected == true){
                        alert("(" + qustNo + ") - 문항에 답변을 하지 않았습니다.");
                        return false;
                    }
                }
                 
                //3. radio버튼 이면 -> 추가 답변 검사
                //
                //  ANS_DTL_NO_15  : 1
                //  ADD_ANS_NO_15_1: 난 Radio답변
                var varAddAnsNo = "ADD_ANS_NO_" + questDtlNo + "_" + questAnsNo;  //radion 문항에 대한 추가답변 변수
                var addAnsNotes = this.ansList[varAddAnsNo];
 
                if (this.questList[ii].CTRL_TYPE == '10' && this.isNull(addAnsNotes)) {
                    var itemLen = this.itemList.length;
                    for(var jj=0; jj<itemLen; jj++) {
                        var itemDtlNo  = itemJson[jj].SRVY_SHEET_DTL_NO;
                        var itemAnsNo  = itemJson[jj].SRVY_SHEET_ANS_NO;
                        if (questDtlNo == itemDtlNo && questAnsNo == itemAnsNo) {
                            var ansOrdrSeq = this.circleNum[itemJson[jj].ANS_ORDR_SEQ];
                            var etcAddYn   = itemJson[jj].ETC_ADD_YN;
                            if (etcAddYn == 'Y') {
                                alert("(" + qustNo + "- 문항, " + ansOrdrSeq + "번) 답변에 추가 설명 부탁 합니다.");
                                return false;
                            }else{
                                break;
                            }
                        }
                    }
                }
                 
                //3. checkbox버튼 이면서 추가 답변 검사
                //
                //   ANS_DTL_NO_1   : [1, 5]
                //   ADD_ANS_NO_1_1 : 난 1번에 대한 Checkbox답변
                //   ADD_ANS_NO_1_5 : 난 5번에 대한 Checkbox답변
                 
                if (this.questList[ii].CTRL_TYPE == '20') {
                    var itemLen = this.itemList.length;
                     
                    //checkbox답변 갯수 for
                    var ansLen  = questAnsNo.length; 
                    for(var kk=0; kk<ansLen; kk++) {
                         
                        var varAddAnsNo = "ADD_ANS_NO_" + questDtlNo + "_" + questAnsNo[kk];
                        var addAnsNotes = this.ansList[varAddAnsNo];
                        if (this.isNull(addAnsNotes)) {
                            //항목에 대한 for
                            for(var jj=0; jj<itemLen; jj++) {
                                var itemDtlNo  = itemJson[jj].SRVY_SHEET_DTL_NO;
                                var itemAnsNo  = itemJson[jj].SRVY_SHEET_ANS_NO;
                                if (questDtlNo == itemDtlNo && questAnsNo[kk] == itemAnsNo) {
                                    var etcAddYn   = itemJson[jj].ETC_ADD_YN;
                                    var ansOrdrSeq = this.circleNum[itemJson[jj].ANS_ORDR_SEQ];
                                    if (etcAddYn == 'Y') {
                                        alert("(" + qustNo + "-문항, " + ansOrdrSeq + "-번) 답변에 추가 설명 부탁 합니다.");
                                        return false;
                                    }else{
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                 
                //4. 주관식 인 경우
                if (ansType == "20"){
                    var textSize = questAnsNo.length;
                    if (textSize > sizeLmit) {
                        alert("(" + qustNo + "-문항)에 " + sizeLmit + "자를 넘을 수 없습니다." + "\n(현재 : " + textSize + " 자 입력)");
                        return false;
                    }
                }
                 
            }
            return true;
        },
        isNull : function(val){
            if (val=="" || val==null || val==undefined)
                return true;
            else
                return false;
        },
        // 문항 조회 여부
        //fn_questVisible : function(idx) {
        //
        //  var questJson = JSON.parse(JSON.stringify(this.questList));
        // 
        //  //1. 내가 하위문항이 아니면 return true (바로 보여주면 됨)
        //  if (questJson[idx].LOW_OUST_YN == "N") return true;
        // 
        //  //2. 내가 하위문항 이면서 && 내 상위의.하위포함여부 가 체크 되었으면 보여주기(return true)
        //  var upDtlNo    = questJson[idx].UP_SRVY_SHEET_DTL_NO;  //상위설문지상세번호
        //  var upCtrlType = questJson[idx].UP_CTRL_TYPE;          //상위컨트롤유형
        //  //var upQustNo = questJson[idx].UP_QUST_NO;
        // 
        //  if (upCtrlType == '10') {
        //      var varUpAnsNo = "ANS_DTL_NO_" + upDtlNo;  //상위 설문지상세 변수
        //      var upAnswer   = this.ansList[varUpAnsNo];
        //      return this.isNull(upAnswer) ? false : true;
        //  }else{
        //     
        //  }
        // 
        //  return false;
        //}
    }
});
 
//참고. location.href를 사용할 때는 아래처럼 하면 됨
//location.href='<c:url value="/cs/sv/survey/survey.fnc" />?surveyId=' + this.search["surveyId"];
//아래처럼도 할 수 있지만.. 위쪽으로 해야 보안등에서 더 좋음
//location.href="http://www.keiis.co.kr/cs/sv/survey/survey.fnc?surveyId=" + this.search["surveyId"];
</script>

'Web. 기타 언어 > Vue.js' 카테고리의 다른 글

Vue.js - 2. 기본 예제(radio,checkbox)  (0) 2019.07.10
Vue.js - 1. 기본 예제  (0) 2019.07.10
Vue.js - 기본개념  (0) 2019.07.10
Posted by 농부지기
,