반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

체크박스 customize 하기

2012. 11. 27. 06:29 | Posted by 솔웅


반응형

Customize checkboxes



이 전 글에서 어떻게 jQuery Mobile 이 오리지널 HTML 코드를 jQuery Mobile 형식에 맞는 HTML 코드로 바꾸는지에 대해 살펴 보았습니다. 아래 예제에서는 체크박스의 display 를 바꾸기 위해 jQuery Mobile 에서 사용하는 CSS 클래스들을 수정해 보겠습니다.


Styling the checkboxes


<!DOCTYPE html>


<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

  

  <style type=text/css>

    .ui-controlgroup .ui-checkbox label {

      font-size : 25px;

      font-style : italic;

    }

    .ui-checkbox .ui-btn {

      text-align : right;

    }

  </style>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Choose an apartment: </span>

    <div data-role=controlgroup>

      <label for=id1> 1 bedroom </label>

      <input type=checkbox id=id1 name=p1 />

      <label for=id2> 2 bedrooms </label>

      <input type=checkbox id=id2 name=p2 />

      <label for=id3> 3 bedrooms </label>

      <input type=checkbox id=id3 name=p3 />

      <label for=id4> 4 bedrooms </label>

      <input type=checkbox id=id4 name=p4 />

      <label for=id5> 5 bedrooms </label>

      <input type=checkbox id=id5 name=p5 />

    </div>

  </div>

</div>


</body>

</html>




tistory487_01.html


반응형


반응형
Manage events on checkboxes



jQuery Mobile 은 checkbox들의 change event 를 관찰하고 있습니다. checkbox는 두가지 state 를 가지고 있습니다. (checked or not) 이 이벤트는 사용자가 checkbox를 click 했을 때 나타납니다. click event 이벤트도 있습니다. 하지만 이 click event 이벤트는 아래에서 사용되지 않습니다.


Using the change event on checkboxes


<!DOCTYPE html>


<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Choose an apartment: </span>

    <div data-role=controlgroup>

      <label for=id1> 1 bedroom </label>

      <input type=checkbox id=id1 name=p1 />

      <label for=id2> 2 bedrooms </label>

      <input type=checkbox id=id2 name=p2 />

      <label for=id3> 3 bedrooms </label>

      <input type=checkbox id=id3 name=p3 />

      <label for=id4> 4 bedrooms </label>

      <input type=checkbox id=id4 name=p4 />

      <label for=id5> 5 bedrooms </label>

      <input type=checkbox id=id5 name=p5 />

    </div>

  </div>

</div>


</body>

</html>


<script>


$(":checkbox").bind ("change", function (event)

{

  alert ($(this).attr ("checked"));

});


</script>


tistory486_01.html





click event는 직접적으로 사용되지 않을까요?  jQuery Mobile 은 original HTML code를 transform 하는 것을 기억하세요. 그러니까 <input> element가 아니라  ui-checkbox CSS class가 있는 <div> element에서 click event를 receive 하게 됩니다. 그래서 <div> element에서 일어나는 클릭은 <input> element 에서 change event를 유발합니다. 그리고 이 change event를 사용하구요.


반응형


반응형
Insert and delete a checkbox in an existing list



checkbox 추가하고 제거하는데 jQuery 의 standard methods 를 사용합니다.


Insertion and removal of checkboxes


<!DOCTYPE html>


<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Choose an apartment: </span>

    <div data-role=controlgroup>

      <label for=id1> 1 bedroom </label>

      <input type=checkbox id=id1 name=p1 />

      <label for=id2> 2 bedrooms </label>

      <input type=checkbox id=id2 name=p2 />

      <label for=id3> 3 bedrooms </label>

      <input type=checkbox id=id3 name=p3 />

      <label for=id4> 4 bedrooms </label>

      <input type=checkbox id=id4 name=p4 />

      <label for=id5> 5 bedrooms </label>

      <input type=checkbox id=id5 name=p5 />

    </div>

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "<label for=id0> Studio </label>";

html += "<input type=checkbox id=id0 name=p0 />";


$("input#id1").after (html);

$("input#id1, label[for=id1]").remove ();


</script>






tistory485_01.html



위와 같이 만들었는데요. 이게 항상 제대로 작동한다는 보장은 없습니다. 여기서는 제대로 작동될 겁니다. 왜냐하면 여기서는 check box가 추가되고 제거될 떄 jQuery Mobile 에 의해서 HTML이 변환되지 않았으니까요. HTML 이 jQuery Mobile 에 의해 변환 될 때가 있을 겁니다. 이럴 때는 다른 방법을 사용해야 이 방법을 구현할 수 있습니다.


Insertion and removal of checkboxes in a window already created


<!DOCTYPE html>


<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Choose an apartment: </span>

    <div data-role=controlgroup>

      <label for=id1> 1 bedroom </label>

      <input type=checkbox id=id1 name=p1 />

      <label for=id2> 2 bedrooms </label>

      <input type=checkbox id=id2 name=p2 />

      <label for=id3> 3 bedrooms </label>

      <input type=checkbox id=id3 name=p3 />

      <label for=id4> 4 bedrooms </label>

      <input type=checkbox id=id4 name=p4 />

      <label for=id5> 5 bedrooms </label>

      <input type=checkbox id=id5 name=p5 />

    </div>

  </div>

</div>


</body>

</html>


<script>


$("#id1").bind ("checkboxradiocreate", function (event)

{

  var html = "";

  html += "<label for=id0> Studio </label>";

  html += "<input type=checkbox id=id0 name=p0 />";

  

  $(this).parent ("div.ui-checkbox").after (html);   // insertion

  $(this).parent ("div.ui-checkbox").remove ();      // suppression

  $("#id0").checkboxradio ();

  $("div:jqmData(role=controlgroup)").controlgroup ();

});


</script>


tistory485_02.html



첫번째 체크박스를 만들 때 우리는 checkboxradiocreate event 에 의해 생성되는 것을 기다려야 합니다. jQuery Mobile 에 의해 HTML 코드가 이미 변환되었고 이 체크박스는 이제 ui-checkbox CSS class 가 있는 <div> element 로 그룹화  됩니다. 체크박스를 삽입할 때는 삽입되는 엘리먼트에 checkboxradio () method 를 사용해야 합니다. 그렇게 해서 HTML 로 convert 해야 되는거죠. 또한 삽입되는 엘리먼트는 모든 체크박스들이 그룹화시키는 <div> element 와 맞는 structure 를 가져야 합니다. 그래서 <div> element 에 controlgroup () method 를 사용하는 겁니다.


새 체크박스를 생성하기위해 controlgroup () method를 사용할 수도 있습니다. 그리고 refresh 하시면 됩니다.

그렇게 하기 위해 아래 코드 대신


Using standard methods on the components (first way)


$("#id0").checkboxradio ();
$("div:jqmData(role=controlgroup)").controlgroup ();



아래 코드를 사용하시면 됩니다.


Use the create event on the window (2nd way)


$("#home").trigger ("create");


반응형


반응형
Assign and retrieve the value of a checkbox



Checkbox already present in the HTML


checkbox를 select 하거나 deselect 하는 것을 관리하기 위해 checkbox 가 있는 <input> element 에 checked attribute 를 사용했습니다.

  • <input> element에서 사용하는 attr ("checked", "checked") method 는 checkbox를 select 하는데 사용됩니다. attr ("checked", "") method는 checkbox를 deselect 하는데 사용합니다.

  •  attr ("checked") method는 checked attribute 의 값을 retrieve 하는데 사용됩니다. return 값은 jQuery 의 버전에 따라 다른데요. jQuery 1.5에서는 box가 체크돼 있으면 값이 true 될겁니다. 체크돼 있지 않으면 false 가 되겠죠. jQuery 1.6 는 체크돼 있으면 값이 "checked"가 됩니다.  체크돼 있지 않으면 undefined가 되구요.

Check the "2 bedrooms" checkbox


$("input#id2").attr ("checked", "checked");


Uncheck the "2 bedrooms" checkbox


$("input#id2").attr ("checked", "");


Is the "2 bedrooms" checkbox checked?


alert ($("input#id2").attr ("checked")); 
   // true / "checked" (if checked), false / undefined (if unchecked)

 


아래 예제에서는 위의 예제들을 활용하는 방법을 보여줍니다.


Selecting and deselecting a checkbox


<!DOCTYPE html>


<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Choose an apartment: </span>

    <div data-role=controlgroup>

      <label for=id1> 1 bedroom </label>

      <input type=checkbox id=id1 name=p1 />

      <label for=id2> 2 bedrooms </label>

      <input type=checkbox id=id2 name=p2 />

      <label for=id3> 3 bedrooms </label>

      <input type=checkbox id=id3 name=p3 />

      <label for=id4> 4 bedrooms </label>

      <input type=checkbox id=id4 name=p4 />

      <label for=id5> 5 bedrooms </label>

      <input type=checkbox id=id5 name=p5 />

    </div>

  </div>

</div>


</body>

</html>


<script>


$("#id2").attr ("checked", "checked");

alert ($("#id2").attr ("checked"));     // Displays true or checked

alert ($("#id3").attr ("checked"));     // Displays false or undefined


</script>






tistory484_01.html



Checkbox dynamically created


attr ("checked") and attr ("checked", "checked" / "") methods 들은 체크박스에 값을 할당하거나 retrieve 할 때 사용됩니다. 체크박스를 refresh 할 때는 checkboxradio ("refresh") method 를 사용합니다.

jQuery 로 여러개의 체크박스를 생성한 경우를 가정해 봅시다.  checkboxradiocreate event 에서 2 bedrooms and 3 bedrooms 를 체크하고 싶습니다.


Check the "2 bedrooms" and "3 bedrooms" in the list


<!DOCTYPE html>


<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Choose an apartment: </span>

  </div>

</div>


</body>

</html>


<script>


var html = "";

html += "<div data-role=controlgroup>";

html +=   "<label for=id1> 1 bedroom </label>";

html +=   "<input type=checkbox id=id1 name=p1 />";

html +=   "<label for=id2> 2 bedrooms </label>";

html +=   "<input type=checkbox id=id2 name=p2 />";

html +=   "<label for=id3> 3 bedrooms </label>";

html +=   "<input type=checkbox id=id3 name=p3 />";

html +=   "<label for=id4> 4 bedrooms </label>";

html +=   "<input type=checkbox id=id4 name=p4 />";

html +=   "<label for=id5> 5 bedrooms </label>";

html +=   "<input type=checkbox id=id5 name=p5 />";

html += "</div>";


$("#home div:jqmData(role=content)").append (html);


$("input").bind ("checkboxradiocreate", function (event)

{

  if (this.id == "id2" || this.id == "id3") 

    $(this).attr ("checked", "checked").checkboxradio ("refresh");

});

</script>




tistory484_02.html




여기서는 checkboxradio ("refresh") method를 사용해야 합니다. 왜냐하면 checkbox는 생성되고 나서 affect 될 수 있기 때문이죠. (예를 들어 checkboxradiocreate event 같은). 만약 생성되기 전에 만들면 (이벤트 이전이 되겠죠) 그러면 이 메소드 call 은 소용없습니다. 그리고 Firebug에서 보시면 jQuery 에러를 만들어 냅니다. 왜냐하면 non-authorized context 안에서 이 메소드가 사용되기 때문이죠.




반응형


반응형

프로젝트를 진행하다 보면 여러 요청 사항들이 이루어 지도록 구현해야 하는 상황이 많이 있지요.


그 중에서는 별로 구현해 봤자 크게 유용하지 않은 것들도 있습니다. 프로그래머 입장에서 봤을 때 말이죠.


이번에 jQuery Mobile 프로젝트를 진행하는데 그래픽 디자이너가 아래 와 같이 만들어 버렸습니다.




음 이건....


왼쪽의 arrow button 이 문제인데요. 왜냐하면 jQuery Mobile 에서는 저런 arrow button 을 지원하지 않거든요. 저런 버튼은 iPhone 이나 iPad 같은 iOS 기기에서 지원하는 위젯이거든요.



아마 디자이너가 아이폰에서 저런 arrow-back button 을 보고 디자인을 한 것 같습니다.

일단 저런 요청이 들어왔으니까 저는 한번 시도해 보기로 했습니다.

jQuery Mobile 에서 arrow button 구현하기.


아래 버튼이 제가 구현한 것인데요.




CSS 로 긴 사각형을 만들고 왼쪽에 작은 사각형을 만든 다음에 이걸 45도 돌린 겁니다.

여기서 작은 사각형을 돌리고 나서 오른쪽에 있는 버튼이랑 잘 어울려야 하거든요.

그래서 Gradient 를 45도 rotate 하고 난 상태에서 오른쪽 사각형이랑 어울리도록 하는 것이 관건입니다.




<html>
<head>
<style type=text/css>
#ios-arrow-left {
    display : block;
    position:absolute;
    z-index : 0;
    left:50px;
    top:50px;   
    height:30px;
    width:100px;
    padding: 0 10px 0 6px;

    font-weight:
            bold;
    color:
            #fff /*{f-bup-color}*/;
    text-shadow:
            0 /*{f-bup-shadow-x}*/
            1px /*{f-bup-shadow-y}*/
            0 /*{f-bup-shadow-radius}*/
            #294d05 /*{f-bup-shadow-color}*/;
           
    border-radius: 5px;

    background:
        #b9f07f; /* Old browsers */
    background:
        -moz-linear-gradient(
            top, 
            #b9f07f 0,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* FF3.6+ */
    background:
        -webkit-gradient(
            linear,
            left top,
            left bottom,
            color-stop(0,#b9f07f),
            color-stop(9%,#8fbd36),
            color-stop(94%,#387800),
            color-stop(97%,#74a814),
            color-stop(100%,#387800)); /* Chrome,Safari4+ */
    background:
        -webkit-linear-gradient(
            top, 
            #b9f07f 0,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* Chrome10+,Safari5.1+ */
    background:
        -o-linear-gradient(
            top, 
            #b9f07f 0,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* Opera 11.10+ */
    background:
        -ms-linear-gradient(
            top, 
            #b9f07f 0,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* IE10+ */
    background:
        linear-gradient(
            to bottom, 
            #b9f07f 0,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* W3C */
           
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b9f07f', endColorstr='#387800',GradientType=0 ); /* IE6-9 */
}

#ios-arrow-left:before {

    position:absolute;
    content : ' ';
    left:-7px;
    top:4px;
    height : 21px;
    width: 20px;
    z-index : 1;

    -moz-transform :
        rotateZ(45deg) skewY(-0deg) skewX(-0deg);
    -o-transform :
        rotateZ(45deg) skewY(-0deg) skewX(-0deg);
    -webkit-transform :
        rotateZ(45deg) skewY(-0deg) skewX(-0deg);
    transform :
        rotateZ(-0deg) skewY(-0deg) skewX(-0deg);
   
    background: #b9f07f; /* Old browsers */
    background:
        -moz-linear-gradient(
            -45deg, 
            #b9f07f 0%,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* FF3.6+ */
    background:
        -webkit-gradient(
            linear,
            left top,
            right bottom,
            color-stop(0%,#b9f07f),
            color-stop(9%,#8fbd36),
            color-stop(94%,#387800),
            color-stop(97%,#74a814),
            color-stop(100%,#387800)); /* Chrome,Safari4+ */
    background:
        -webkit-linear-gradient(
            -45deg, 
            #b9f07f 0%,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* Chrome10+,Safari5.1+ */
    background:
        -o-linear-gradient(
            -45deg, 
            #b9f07f 0%,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* Opera 11.10+ */
    background:
        -ms-linear-gradient(
            -45deg, 
            #b9f07f 0%,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* IE10+ */
    background:
        linear-gradient(
            135deg, 
            #b9f07f 0%,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* W3C */
    filter: progid:
        DXImageTransform.Microsoft.gradient(
            startColorstr='#b9f07f',
            endColorstr='#387800',
            GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
}

#ios-arrow-left:hover {
    background:
            #b9007f /*{f-bup-background-color}*/;
    border:
            1px solid #5f666b /*{f-bup-border}*/;
    background:
            #b9f07f /*{f-bup-background-color}*/;
    font-weight:
            bold;
    color:
            #fff /*{f-bup-color}*/;
    text-shadow:
            0 /*{f-bup-shadow-x}*/
            1px /*{f-bup-shadow-y}*/
            0 /*{f-bup-shadow-radius}*/
            #294d05 /*{f-bup-shadow-color}*/;
    background:
            #387800; /* Old browsers */
    background: -moz-linear-gradient(
            top, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* FF3.6+ */
    background: -webkit-gradient(
            linear,
            left top,
            left bottom,
            color-stop(0%,#387800),
            color-stop(9%,#74a814),
            color-stop(94%,#387800),
            color-stop(100%,#b9f07f)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(
            top, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(
            top, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(
            top, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* IE10+ */
    background: linear-gradient(
            to bottom, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient(
            startColorstr='#387800',
            endColorstr='#b9f07f',
            GradientType=0 ); /* IE6-9 */
}

#ios-arrow-left:hover:before
{

    position:absolute;
    content : ' ';
    left:-9px;
    top:4px;
    height : 21px;
    width: 20px;
    z-index : 1;

    -moz-transform :
        rotateZ(45deg) skewY(-0deg) skewX(-0deg);
    -o-transform :
        rotateZ(45deg) skewY(-0deg) skewX(-0deg);
    -webkit-transform :
        rotateZ(45deg) skewY(-0deg) skewX(-0deg);
    transform :
        rotateZ(-0deg) skewY(-0deg) skewX(-0deg);
       
        border-bottom:
            1px solid #5f666b;
        border-left:
            1px solid #5f666b;           

   
    background: #387800; /* Old browsers */
    background:
        -moz-linear-gradient(
            -45deg, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* FF3.6+ */
    background: -webkit-gradient(
            linear,
            left top,
            left bottom,
            color-stop(0%,#387800),
            color-stop(9%,#74a814),
            color-stop(94%,#387800),
            color-stop(100%,#b9f07f)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(
            -45deg, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* Chrome10+,Safari5.1+ */
    background:
        -o-linear-gradient(
            -45deg, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* Opera 11.10+ */
    background:
        -ms-linear-gradient(
            -45deg, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* IE10+ */
    background:
        linear-gradient(
            -45deg, 
            #387800 0%,
            #74a814 9%,
            #387800 94%,
            #b9f07f 100%); /* W3C */
    filter: progid:
        DXImageTransform.Microsoft.gradient(
            startColorstr='#b9f07f',
            endColorstr='#387800',
            GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
}
  </style>
</head>

<body>
<div id="ios-arrow-left"></div>
</body>
</html>



iosBtn.html


#ios-arrow-left 부분이 오른쪽의 큰 사각형 부분입니다.

그 다음 #ios-arrow-left:before 부분이 그 사각형 왼쪽에 작은 사각형을 만든건데요.

rotateZ(45deg) skewY(-0deg) skewX(-0deg); 으로 사각형을 45도 돌립니다.

그리고 Gradient 부분을 보면

        -webkit-linear-gradient(
            -45deg, 
            #b9f07f 0%,
            #8fbd36 9%,
            #387800 94%,
            #74a814 97%,
            #387800 100%); /* Chrome10+,Safari5.1+ */


여기서도 45도 돌려서 gradient 가 그려지도록 만들었습니다.

그러면 45도 돌린 후에는 오른쪽 사각형이랑 제대로 gradient 가 어울리겠죠.


그 다음 #ios-arrow-left:hover 와 #ios-arrow-left:hover:before 부분은 마우스를 올렸을 효과를 구현했습니다.


구현하고 보니까 크롬하고 사파리에서만 돌아가던데요.

(Firefox 와 Opera 같은데서는 작은 사각형의 rotate 가 안되더라구요.)


이번 프로젝트의 target device 는 main 이 blackberry (ver 6,7) 이구요. sub 로 iPad와 iPhone 을 대상으로 합니다.

회사 내부의 특정 business 를 위한 모바일 웹인데 담당자들이 주로 사용하는 디바이스들이 블랙베리랑 iOS 디바이스들이거든요.

이 두 종류의 디바이스에서는 제대로 적용이 됩니다.


그런데 이 효과는 적용하지 않기로 했습니다.

User Experience 부분에서 문제가 있어서 입니다. hover 는 mouseup 이벤트에 해당하는 거고 요즘 사용하는 touch screen 모바일 기기에서는 다른 여러 다양한 이벤트들이 발생하기 때문이거든요.

오른쪽 큰 사각형은 버튼으로 설정이 되서 jQuery Mobile 이 각 이벤트마다 알아서 CSS 처리를 하는데 이 작은 사각형은 그러지 못해서 편안한 UX 를 위해서는 이 touch screen 의 해당 이벤트를 catch 해서 그에 맞는 UI 를 구현해야 하거든요.


이 작은 효과를 내기 위해서 개발에 소요되는 시간이 너무 깁니다.

완전 Time consuming job 이죠.

당연히 jQuery Mobile 에서 지원하지 않는 부분을 매뉴얼로 구현하니까 일일이 이벤트 발생시마다 컨트롤 해야 되는 거겠죠.


처음 이 디자인을 받았을 때 부터 그럴거라고 생각을 했었지만 디자이너와 프로젝트 리더와 프로젝트 매니저를 설득하고 좀 더 효율적이고 유저에게도 도움을 주는 방향으로 프로젝트를 진행해 나갈 수 있게 하려면 충분한 근거를 제시하면서 제 의견을 얘기해야 되겠기에 일단 여기까지 구현하고 직접 디바이스에서 실행하면서 그 장단점을 발표했습니다.


그 결과 이 방법 보다는 버튼 안에 < 이미지를 넣는 방법이 더 효율적이라는 의견을 도출해 냈죠.


그 미팅에 디자이너는 참석하지 않았는데요.

오늘은 추수감사절이라 휴일이고 내일 가서 디자이너에게 자세히 설명하고 버튼안에 들어갈 이미지를 부탁해야 겠습니다.


사실 오늘 그 디자이너 집에 초대받아서 점심 먹고 왔거든요.


여기 추수감사절은 칠면조 요리를 먹는게 전통이지만 그 디자이너가 얼마전에 인도에서 와서 토종 인도 요리로 먹고 왔습니다.



저기 레몬 얹혀 있는 건 수육인데 그건 저희 집에서 준비해 간 거였어요.

마침 그 집안은 목요일에는 고기를 안 먹는다 그래서 한 점도 안 먹었어요. ^^

저 동그란 거는 뿌리라는 요리이고 큰 접시에 담긴건 컬리 플라우어 커리(카레)와 브지인가 브르지인가 하는 계란요리하고 감자요리가 담겨져 있습니다. 그리고 노란 스프같은 건요.

사실 이게 우리나라에서 먹는 커리(카레) 랑 제일 비슷하지만 카레는 아니고 달 이라는 음식입니다.

왼쪽 위에 하얀 접시로 덮여진 것이 밥이구요.


내일은 추수감사절 다음날인 Black Friday 입니다.

저희 회사에서는 휴일은 아니고 대부분 재택근무를 하는데요.

저는 이 디자이너가 미팅이 있어서 회사에 나간다고 해서 같이 나갈려구요.


이 기능을 구현하려고 이것 저것 구글링을 했었는데요.


저 위에 사용한 소스는 아래 싸이트에 있는 소스를 참조한 겁니다.

http://cssnerd.com/2011/11/30/the-best-pure-css3-ios-style-arrow-back-button/


그리고 이미지를 사용해서 구현한 소스도 있는데요.




이 방법은 처음부터 대상에서 제외 했습니다.

기본적으로 이번 프로젝트에서는 버튼을 만들 때 이미지를 사용하지 않거든요.

이 방법을 사용하면 다른 버튼과 조화를 이루는 방법에 아주 많은 공수가 들어갈 겁니다.


아래 정보가 있는 싸이트와 파일을 올립니다.

http://taitems.tumblr.com/post/7240874402/ios-inspired-jquery-mobile-theme-jquery-mobile



iOS-Inspired-jQuery-Mobile-Theme-master.zip



그리고 또 한군데 발견한 곳은

http://appcropolis.com/how-to-make-iphone-back-button-in-jquery-mobile/

입니다.


이 글은 자세히 읽어보지는 못했습니다. 별로일 것 같아서요.

혹시 이 소스 분석해 보시고 저 위에 있는 두가지 방법보다 좋은 것 같으면 알려 주세요.


일단 저 arrow button 효과는 이번 프로젝트에서는 사용하지 않을 거지만 덕분에 좋은 공부를 했고 좋은 자료를 이 블로그에 남길 수 있게 됐습니다.


나중에 진짜 필요한 상황이 오면 큰 도움이 되겠죠.


여러분들도 좋은 하루 보내시고 즐코딩하세요.

반응형


반응형

Posted on . Written by


오늘의 튜토리얼은 코로나 Ambassador 이면서 Mobile App Development with Corona: Getting Started.”의 저자인 Brian Burton 의 글입니다. 이글은  Burton’s Media Group에서 발표된 내용입니다.


제가 자주 하는 질문 중 하나가 remote server 에서 어떻게 데이터를 mobile app 으로 전달할 수가 있는가 입니다. (대개 그 데이터는 데이터베이스에 저장되 있겠죠.)

이와 관련해서 가장 좋은 방법을 소개해 드리려고 많이 연구했습니다. 아마 얼마나 많은 방법들을 제가 시도해 봤는지 알려드리려면 시리즈를 연재해야 될 겁니다. 데이터를 가지고 올 수 있는 방법은 아주 많이 있고 또 여러 possibilities 들도 많이 있습니다. 모두 찾아내려면 아마 끝이 안 날 겁니다. 그래서 이것들을 더 찾아내고나서 몇달 후에 얘기하는 것보다 리모트 서버에서 모바일 앱으로 데이터를 전달하는 한가지 방법이라도 우선 소개해 드리는게 좋을 것 같습니다.


The Process


간단하게 하기 위해 표준 3-tier architecture 를 사용할 겁니다.




Remote Database


이 튜토리얼에서는 리모트 서버에 MySQL을 만들어 둘 겁니다. 3개의 필드를 가지고 있는 1개의 테이블을 사용하겠습니다. (id, Movie (title), Year (영화가 릴리즈 된 해)




Logic or Middleware


MySQL 데이트베이스로부터 데이터를 pull 해 오기 위한 middleware 로 PHP를 사용하겠습니다.  그리고 그 데이터를 모바일 디바이스에 return 하기 전에 JSON format 으로 encoding 할 겁니다.


<?php
$host="localhost"; //replace with your hostname
$username="database_example"; //replace with your username
$password="Password"; //replace with your password
$db_name="MyMovies"; //replace with your database
$con=mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name") or die ("cannot select DB");
$sql = "select * from BestMovies"; //replace with your table name
$result = mysql_query($sql);
$json = array();
if(mysql_num_rows($result)){while($row=mysql_fetch_row($result)){
$json[]=$row;
}
}
mysql_close($db_name);
echo json_encode($json);
?>

Client


아래는 remote server 로부터 정보를 가져오고 JSON 형식으로 된 그 정보를 decode 하는 코로나 소스코드 입니다. 이 파일을 local SQLite file로 저장하세요. 그리고 나서 SQLite 의 content 로 화면에 load 하세요. 데이터베이스는 persistent 입니다. 그러니까 이 코드를 여러번 실행해서 remote database를 call 하면 SQLite 데이터베이스에 new data 를 계속 추가할 겁니다.


local sqlite3 = require ("sqlite3")
local myNewData
local json = require ("json")
local decodedData

local SaveData = function ()

  --Save new data to a sqlite file
  --open SQLite database, if it doesn't exist, create database
  local path = system.pathForFile("movies.sqlite", system.DocumentsDirectory)
  db = sqlite3.open( path )
  print(path)
      
  --setup the table if it doesn't exist
  local tablesetup = "CREATE TABLE IF NOT EXISTS mymovies
(id INTEGER PRIMARY KEY, movie, year);"
  db:exec( tablesetup )
  print(tablesetup)
    
  --save data to database
  local counter = 1
  local index = "movie"..counter
  local movie = decodedData[index]
  print(movie)

  while ( movie ~= nil ) do
    local tablefill ="INSERT INTO mymovies
VALUES (NULL,'"
.. movie[2] .. "','" .. movie[3] .."');"
    print(tablefill)
    db:exec( tablefill )
    counter=counter+1
    index = "movie"..counter
    movie = decodedData[index]
  end
 
  --everything is saved to SQLite database; close database
  db:close()
      
  --Load database contents to screen
  --open database
  local path = system.pathForFile("movies.sqlite", system.DocumentsDirectory)
  db = sqlite3.open( path )
  print(path)
        
  --print all the table contents
  local sql = "SELECT * FROM mymovies"
  for row in db:nrows(sql) do
    local text = row.movie.." "..row.year
    local t = display.newText( text, 20, 30 * row.id, native.systemFont, 24 )
    t:setTextColor( 255,255,255 )
  end
  db:close()

end


local function networkListener( event )

  if ( event.isError ) then
    print( "Network error!")
  else
    myNewData = event.response
    print ("From server: "..myNewData)
    decodedData = (json.decode( myNewData))
    SaveData()
  end

end
network.request( "http://www.BurtonsMediaGroup.com/myMovies.php",
"GET", networkListener )


여기까지가 기본적인 튜토리얼 입니다. 유튜브에 좀 더 자세하게 설명한 비디오를 올렸습니다.

보시려면 유튜브를 참조하세요.




반응형

코로나 : New public release 발표

2012. 11. 21. 19:59 | Posted by 솔웅


반응형
Posted on . Written by


지난주 새로운 공개버전 릴리즈에 대해 넌지시 얘기 드렸었습니다. 오늘 latest Corona public release버전이 공개 돼 누구나 다운로드 받아서 사용할 수 있게 됐습니다.


이번 공개 버전에는 수 많은 기능들과 개선 사항들 그리고 에러 수정이 있습니다. 자세한 내용들은  2012.971 release notes 에서 보실 수 있습니다.


모바일 industry 는 holiday season을 앞두고 가을에 새로운 디바이스들을 release 하는 경향이 있습니다. 이번 시즌에는 iPhone 5, Kindle Fire HD7" 와 8.9", Nook HD 와 HD+ 그리고 iPad Mini 등이 있습니다. 정말 많은 device 들이 발표 됐네요!


그래서 저희들은 이번 릴리즈에 이 새로운 device 들과 그에 따라 발표되는 새로운 OS update에 주로 포커스를 맞춰서 작업했습니다. 이번 public release에 앞서 저희들은 실시간으로 daily builds를 통해서 이 작업을 했었습니다. iOS 6 의 GameCenter orientation 버그와 Nook HD compatibility, iOS 6 Beta 용 device builds 등등 이 그것입니다.




또한 많은 분들이 요청하셨던 안드로이드 관련 주요 기능 지원에 대해서도작업을 했구요. 그 중에 두가지만 얘기하자면 map views and notifications 가 있습니다. (예 그리고 remote push 가 곧 지원될 겁니다.) 이와 관련해서 저희들은 모든 안드로이드 flavor들에도 이 기능들이 원활히 작동되도록 만들었습니다. 사실 이 작업이 아주 많은 일을 해야 되는 부분 입니다. 만약 여러분이 Android SDK 를 사용한다면 맵에 대해서는 별도로 3번의 코딩을 해야 합니다. 왜냐하면 구글은 Google Play 를 통한 Android device들에 대해서만 맵을 지원하거든요. (아마존이나 Barnes and noble 앱 스토어용 앱은 별도로 작업해야 합니다.) 하지만 Corona SDK 에서는 한번의 코딩에서 이런 다양한 안드로이드 flavor 들에서 작동이 되도록 만들었습니다.


이쪽 바닥은 아주 빛의 속도로 움직이고 있기 때문에 저희들도 이 속도에 맞춰서 engineering process들을 잡아가고 있습니다. 그래서 모든 변화에 거의 동시간으로 여러분께 해당 기능 지원이 가능한 버전을 선사해 드리고 있습니다. 기존에 계획했던 것들도 시장이 상황이 많이 변하면 재빠르게 거기에 맞춰서 계획을 수정하고 대응해 나가고 있는 상황입니다.





daily builds에서 가장 중요한 부분은 버그를 잡는 부분입니다. 이상한 점이 발견되면 바로 다음번 daily build에서 이 사항들을 수정하고 있습니다. 이것이 저희의 방침입니다. 작년과 비교하면 daily build 의 quality 는 확실히 나아졌고 일관성을 꾸준히 유지해 가고 있습니다.


여러분 모두가 다음번 daily build 에서 함께 했으면 합니다.


다음 daily builds 는 담주 월요일(11/26) 저녁이 될 겁니다.



반응형

Ajax 로 checkbox 만들어 넣기

2012. 11. 21. 05:48 | Posted by 솔웅


반응형
Insert checkboxes by Ajax



이전에 했던 것 처럼 checkbox를 HTML 코드에 직접 생성해 넣지 않고 Ajax를 통해서 서버로부터 HTML 코드를 받아오는 방법이 있습니다.


Insert checkboxes by Ajax



<!DOCTYPE html>


<html> 

<head> 

  <meta name=viewport content="user-scalable=no,width=device-width" />

  <link rel=stylesheet href=jquery.mobile/jquery.mobile.css />

  <script src=jquery.js></script>

  <script src=jquery.mobile/jquery.mobile.js></script>

</head> 


<body> 


<div data-role=page id=home>

  <div data-role=header>

    <h1>Home</h1>

  </div>


  <div data-role=content>

    <span> Choose an apartment: </span>

  </div>

</div>


</body>

</html>


<script>


$.ajax (

  url : "action.php", 

  complete : function (xhr, result)

  {

    if (result != "success") return;

    var response = xhr.responseText;

    $("#home div:jqmData(role=content)").append (response);

    

    $("input").checkboxradio ();

    $("input").closest ("div:jqmData(role=controlgroup)").controlgroup ();

  }

});  


</script>



checkboxradio () controlgroup () methods 를 사용했습니다.
checkboxradio () method는 <input> and <label> HTML elements를 checkbox (ui-checkbox class)와 연관이 있는 <div>로 변환하는데 사용합니다.  감싸여진 <div> 에서 controlgroup () method를 call 하면 그 checkbox들을 그룹화 할 수 있습니다.



action.php file


<?
$html = "";
$html .= "<div data-role=controlgroup>";
$html .=   "<label for=id1> 1 bedroom </label>";
$html .=   "<input type=checkbox id=id1 name=p1 />";
$html .=   "<label for=id2> 2 bedrooms </label>";
$html .=   "<input type=checkbox id=id2 name=p2 />";
$html .=   "<label for=id3> 3 bedrooms </label>";
$html .=   "<input type=checkbox id=id3 name=p3 />";
$html .=   "<label for=id4> 4 bedrooms </label>";
$html .=   "<input type=checkbox id=id4 name=p4 />";
$html .=   "<label for=id5> 5 bedrooms </label>";
$html .=   "<input type=checkbox id=id5 name=p5 />";
$html .= "</div>";
echo utf8_encode ($html);
?>



action13.php

tistory479_01.html


checkboxradio () controlgroup () methods 를 calling 하면 create evnet 의 triggering 에 의해 replace 될 수 있다는 것을 잘 봐 두세요.  그래서 아래 코드 대신에


Using standard methods of the components (first way)


$("input").checkboxradio ();


$("input").closest ("div:jqmData(role=controlgroup)").controlgroup ();


아래 코드를 사용할 수 있습니다.


Using the create event on the window (2nd way)


$("#home").trigger ("create");


The create event will be received by the document object in jQuery Mobile, and internal treatment of this event searches for HTML elements to transform into jQuery Mobile components. Thus triggering a single create event processes checkboxes and the group that includes them.


create event 는 jQuery Mobile안에 있는 document object 에 의해 receive 될 겁니다. 그리고 이 이벤트는 HTML element를 jQuery Mobile component로 변환하도록 합니다. 그러니까 single create event를 triggering 하면 checkboxes 와 the group 작업을 수행합니다.


반응형

CSS color 작업을 보다 편리하게....

2012. 11. 21. 01:23 | Posted by 솔웅


반응형

제가 원래 프로그래머라서 웹개발하다가 색상 맞추고 이쁘게 꾸미고 뭐 그런일을 해야 되면 짜증나거든요.


그냥 원하는 기능이 돌아가도록 프로그래밍 하는 것만 하면 좋을 텐데...

하다보면 그렇지 않을 때도 많아요.

더군다나 HTML5, CSS3 로 발전하면서 거의 그래픽 디자이너와 프로그래머의 경계가 더 많이 겹치게 되서 더 그렇죠.


오늘도 그런 작업을 해야 됐는데....


디자이너인 Sandesh 에게 부탁했더니 아래 싸이트에서 CSS gradient 를 간단하게 해서 주더라구요.


http://www.colorzilla.com/




Chrome이나 Firefox에 플러그인으로 설치해서 사용하는 colorpicker, color analyzer 같은 것들이 있구요.


웹에서 곧바로 CSS Gradient 를 만드는 툴이 있네요.

아주 간편하고 좋습니다.





그럼 모두들 즐코딩 바래요.....


반응형


반응형
Turning an HTML element into a jQuery Mobile checkbox




Firebug 에서 봐 보세요. 이전 글에서 checkbox 들이 포함되고 나서 jQuery Mobile 에 의해 생성된 HTML 코드입니다.




<div> element 에 ui-controgroup CSS class 가 있습니다. 그리고 각 checkbox들은 <div> 에  ui-checkbox class 를 가지고 있습니다. 모두 그룹화 돼 있습니다. 그 안에는 <span> elements 를 가지고 있는 <label> element 가 있구요. <input> element 는 checkbox 에 해당하는 겁니다.




반응형