728x90
반응형
728x90
반응형
728x90
반응형

<CheckBox
android:id="@+id/checkBox1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/my_innerMargin"
android:drawableRight="?android:attr/listChoiceIndicatorMultiple"
android:button
="@null"
android:text="CheckBox" />

728x90
반응형
728x90
반응형

공부하는 도중 까먹지 않이 위한 메모 입니다. 정답이 아닐수도 있으니 참고하세요.

 

 

editText가 있는 화면으로 editText가 가장 높은 영역을 차지하길 바란다.

하지만 특정한 높이를 지정해 준다면 디바이스에 따라 다른 뷰가 화면 밖으로 밀려날 수 있다.

이에 디바이스의 높이에 따라 자동으로 높이를 지정해 주고 싶었다.

 

빨간색 화살표 영역이 다바이스 높이와 관계 없이

textView, button 마진 등등의 높이를 제외한 영역을 차지 하도록 하고 싶은것.

 

이때 사용하는 속성이 layout_weight

4개의 뷰에 모두 똑같이 1로 준다면, 높이가 1:1:1:1 이되는 거다.

 

그래서 이 경우는 editText에만 1주면된다.

728x90
반응형
728x90
반응형

알고는 있었지만 오늘 30분간 삽질하게 한 실수다.

1
2
3
4
5
6
7
for (int i=0; i< list.size(); i++) {
    if(Utils.isNull(list.get(i).getOrginNm())) {
        logger.info("index : "+i+" delete VO : " +list.get(i).toString());
        list.remove(i);
    }
    else logger.info("index : "+i+" not delete VO : " + list.get(i).toString());
}
cs

이걸 실행하면 원하는 결과를 얻을 수 없다.

 

원인은 list.remove(i) 를 하면서 하나가 삭제되면서 index가 달라지기 때문이다.

시작 시 list.size()가 10였는데 하나를 remove 하면 list.size()는 9이 될테니

 

1. 반복문의 실행 횟수가 의도하지 않게 변하게 되고

2. remove(i)에 사용되는 index 값에도 문제가 될 것이다.

 

또 실수할테지만.. 다음엔.. 삽질은 짧게 하자.. 

 

* 관련글

[java] ArrayList.remove(Integer index) 사용시 이상 : https://deonggi.tistory.com/152

 

728x90
반응형
728x90
반응형
1
2
3
4
5
6
SELECT membr_seq, book
    FROM (SELECT membr_seq, book
            , ROW_NUMBER() OVER(PARTITION BY membr_seq ORDER BY dt DESC) rn
        FROM book_t
    )
WHERE rn = 1
cs

 

ROW_NUMBER() OVER(PARTITION BY membr_seq ORDER BY dt DESC) rn  
membr_seq별로 dt의 내림차순으로 번호를 매겨서
번호의 1을 조회한다.

728x90
반응형
728x90
반응형

꺽은선 그래프(Line Chart)를 그려보고자 한다.

 

주의! d3.js 파일의 버전에 따라 문법이 다른 경우가 많다.

잘 모르는 사람은 웹 서핑으로 공부하기 참으로 어렵다.

그러므로 버전을 잘 확인하도록! 

나는 d3.js vesion 4.5.0 을 사용했다.

 

소스 코드 : https://www.w3schools.com/code/tryit.asp?filename=GBNU8N5FVWAF

 

1. 이 코드를 처음 대충 봤을때 가장 이해가 안 됐던 부분은 x축 가이드의 transform 좌표 였다.

1
2
3
4
5
6
7
8
// x축 가이드 생성
svg.append("g")
    .attr("class""grid")
    .attr("transform""translate(0," + chartHeight + ")")
    .call(make_x_gridlines(x)
        .tickSize(-chartHeight)
        .tickFormat("")
    )
cs

 

transform="translate(0,370)" 인데 아래 이미지를 보면 x좌표가 이상하다?

결론을 말하자면 chrom 개발자모드 에서 아래와 같이 태그 선택시

보여지는 그래프 영역 박스는 실제 좌표와 다소 차이가 있다.

아마도 태그간의 계층을 표시하는것 같다.

 

여기서 x, y축은 <g transform="translate(50,0)"></g> 태그의 영역(분홍색)에

포함되는 듯이 보이지만, 실제로는 포함되지 않는다. 

실제로 분홍색 영역의 g 태그는, 하늘색 영역의 g 태그와 같다. 즉 좌측 x 좌표는 보이는 것과 달리 같게 된다.

 

2. 날짜는 언제나 프로그래밍에서 골치가 아프게한다.

날짜 데이터를 d3에에 맞게 파싱하여 변경한다.

1
2
3
4
5
// dataset의 날짜 파싱을 위한 패턴, 패턴을 이용해 날짜 데이터 변경
var parseTime = d3.timeParse("%Y-%m-%d");
dataset.forEach(function(d) {
    d.DAT = parseTime(d.DAT);
});
cs

 

 

잊어버리지 않기 위한 몸부림.

분명 잊을테지만 이렇게 적어 놓으면 필요할때 쓸수는 있겠지.

728x90
반응형
728x90
반응형

모바일 화면에서 사진 같은 것을 좌우로 밀어서 사진을 바꿔주는 swiper 기능

 

1. html 파일에 swiper css 파일 추가

1
<link rel="stylesheet" href="/js/swiper.min.css">
cs

2. html 파일에 swiper.js 파일 추가

1
<script type="text/javascript" src="/js/swiper.js"></script>
cs

3. 탭 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
37
38
39
40
41
<div>
  <ul>
    <li class="tablinks active" id="tab1">Tab1</li>
    <li class="tablinks" id="tab2">Tab2</li>
    <li class="tablinks" id="tab3">Tab3</li>
  </ul>
</div>
<div class="swiper-container">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <div class="swiper-slide-sub">
        <!-- Tab1 내용 -->
        <ul>
          <li>li1</li>
          <li>li2</li>
          <li>li2</li>
        </ul>
      </div>
    </div>
    <div class="swiper-slide">
      <div class="swiper-slide-sub">
        <!-- Tab2 내용 -->
        <ul>
          <li>li1</li>
          <li>li2</li>
          <li>li2</li>
        </ul>
      </div>
    </div>
    <div class="swiper-slide">
      <div class="swiper-slide-sub">
        <!-- Tab3 내용 -->
        <ul>
          <li>li1</li>
          <li>li2</li>
          <li>li2</li>
        </ul>
      </div>
    </div>
  </div>
</div>
cs

4. javascript 파일에서 swiper 사용설정

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
$(document).ready(function () {
    init();
});
 
function init() {
 
    var swiper = new Swiper('.swiper-container', {
        autoHeight: true,
        on: {
            init: function () {
                $(".swiper-slide").css("background-color"'transparent');
                $(".swiper-slide").css("text-align"'left');
            },
            slideChange: function () {
                var slider = this;
                if (swiper.activeIndex == 0) {
                    $('#tab1').addClass('active');
                    $('#tab2').removeClass('active');
                    $('#tab3').removeClass('active');
 
                    document.body.scrollTop = 0// For Safari
                    document.documentElement.scrollTop = 0// For Chrome, Firefox, IE and Opera
 
                } else if (swiper.activeIndex == 1) {
                    $('#tab1').removeClass('active');
                    $('#tab2').addClass('active');
                    $('#tab3').removeClass('active');
 
                    document.body.scrollTop = 0// For Safari
                    document.documentElement.scrollTop = 0// For Chrome, Firefox, IE and Opera
 
                } else if (swiper.activeIndex == 2) {
                    $('#tab1').removeClass('active');
                    $('#tab2').removeClass('active');
                    $('#tab3').addClass('active');
 
                    document.body.scrollTop = 0// For Safari
                    document.documentElement.scrollTop = 0// For Chrome, Firefox, IE and Opera
 
                }
            }
        }
    });
 
    $('#tab1').click(function () {
        swiper.slideTo(0300false);
    });
    $('#tab2').click(function () {
        swiper.slideTo(1300false);
    });
    $('#tab3').click(function () {
        swiper.slideTo(2300false);
    });
 
}
 
cs

 

공식 사이트 : https://swiperjs.com/

 

Swiper - Most Modern Mobile Touch Slider

Swiper - is the free and most modern mobile touch slider with hardware accelerated transitions and amazing native behavior.

swiperjs.com

 

 

728x90
반응형

'코딩 삽질' 카테고리의 다른 글

[sql, oracle] 계정별 마지막 row  (0) 2020.02.28
[d3] Line chart sample  (0) 2020.02.07
[html, ajax] bootstrap 파일 업로드 progress bar  (2) 2019.12.17
[java] split에 마침표(dot) 사용하기  (0) 2019.12.11
[weblogic] 500 에러  (2) 2019.12.10
728x90
반응형

파일을 서버에 업로드할 때 파일용량으로 프로그레스 바를 표시하려고 한다.

 

 

위와 같은 화면이다.

 

단순한 필요 요소만 언급하면 아래와 같다.

 

1. css 파일 필요 (파일명 : progressBar.css)

1
2
3
.progress { position:relative; width:100%; border: 1px solid #ddd; padding: 1px; border-radius: 3px; }
.bar { background-color: #337ab7; width:0%; height:20px; border-radius: 3px; }
.percent { position:absolute; display:inline-block; top:1px; left:48%; }
cs

 

2. html 파일에 css 파일 연결

1
<link rel="stylesheet" href="/css/progressBar.css">
cs

 

3. html 파일에 progress model 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- progress Modal -->
<div class="modal fade" id="pleaseWaitDialog" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h3>Upload processing...</h3>
            </div>
            <div class="modal-body">
                <!-- progress , bar, percent를 표시할 div 생성한다. -->
                <div class="progress">
                    <div class="bar"></div>
                    <div class="percent">0%</div>
                </div>
                <div id="status"></div>
            </div>
        </div>
    </div>
</div>
cs


4. javascript에서 파일 업로드 시 모달 호출 및 프로그레스 진행

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
function insertBoard() {
 
    if (fnValidate()) {
 
        if (confirm("저장하시겠습니까?")){
 
            var formData = new FormData($("#writeFrm")[0]);
 
            /* progressbar 정보 */
            var bar = $('.bar');
            var percent = $('.percent');
            var status = $('#status');
 
            $.ajax({
                xhr: function() {
                    var xhr = new window.XMLHttpRequest();
                    xhr.upload.addEventListener("progress"function(evt) {
                        if (evt.lengthComputable) {
                            var percentComplete = Math.floor((evt.loaded / evt.total) * 100);
 
                            /* Do something with upload progress here */
                            var percentVal = percentComplete + '%';
                            bar.width(percentVal);
                            percent.html(percentVal);
 
                        }
                    }, false);
                    return xhr;
                },
                type : 'POST',
                url : getContextPath() + "/admin/board/insertboard.do",
                dataType: 'text',
                data : formData,
                processData : false,
                contentType : false,
                beforeSend:function(){
                    // progress Modal 열기
                    $("#pleaseWaitDialog").modal('show');
 
                    status.empty();
                    var percentVal = '0%';
                    bar.width(percentVal);
                    percent.html(percentVal);
 
                },
                complete:function(){
                    // progress Modal 닫기
                    $("#pleaseWaitDialog").modal('hide');
 
                },
                error:function(request,status,error){
                    alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
                },
                success:function(result, status) {
 
                    alert("저장 되었습니다.");
                    location.href = getContextPath() + "/admin/board/boardList.do?";
                }
            });
 
        } else {
            return;
        }
    } else {
        return;
    }
}
cs

필수적인 요소는 4군데

 1) /* progressbar 정보 */ 아래의 3줄

 2) $.ajax의 xhr: function() {

 3) $.ajax의 beforeSend:function(){

 4) $.ajax의 complete:function(){

 

5. spring의 Controller에서 받을때

1
2
3
4
@PostMapping(value = "/insertBoard")
public RestResponse<BoardResDTO> insertItem(MultipartHttpServletRequest request, @ModelAttribute BoardReqDTO req) throws Exception {
    return new RestResponse<>(serviceClass.insertItem(request, req));
}
cs

여기서 파일받기 위해 필요한 부분은 MultipartHttpServletRequest  입니다.

 

 

 

프로그레스바의 색상등을 변경하고자 한다면 아래 URL 정보를 참조

https://getbootstrap.com/docs/4.4/components/progress/

 

 

관련글

1. [spring] java.io.IOException: java.io.FileNotFoundException, multipartfile.transferto(file)

 

 

728x90
반응형

'코딩 삽질' 카테고리의 다른 글

[d3] Line chart sample  (0) 2020.02.07
[javascript, swiper] tab swiper 셈플소스  (0) 2019.12.19
[java] split에 마침표(dot) 사용하기  (0) 2019.12.11
[weblogic] 500 에러  (2) 2019.12.10
[html] include 절대경로, 상대경로  (0) 2019.11.24
728x90
반응형
1
2
String str = "abcd.1234";
String[] arrStr = str.split(".");
cs

이 경우 나눠지지 않음.

 

 

1
2
String str = "abcd.1234";
String[] arrStr = str.split("\\.");
cs

이렇게 해야지 배열에 2개의 string으로 나눠짐.

728x90
반응형

+ Recent posts