/**
 * 체크 박스의 hidden 필드에 'Y', 'N' 값을 설정한다.<br>
 * <input type="checkbox" onclick="setCheckBoxValue(this, 'openYN');" checked />
 * <input type="hidden" id="openYN" name="open" value="Y" />
 * 
 * @param checkboxHiddenFieldName
 * @param checkboxObject
 */
function setCheckBoxValue(checkBox, idOrName) {
    var value;
    if (checkBox.checked) {
        value = "Y";
    } else {
        value = "N";
    }

    var obj = document.getElementById(idOrName);
    if (obj == null) {
    	document.getElementsByName(idOrName)[0].value = value;
    } else {
    	obj.value = value;
    }
}


/*******************************************************************************
 * ###############################################################################################
 * 공통함수
 * 
 * ###############################################################################################
 ******************************************************************************/

/*******************************************************************************
 * FUNCTION ID: byObjects DESC : 엘레멘트 배열 가져오기 EX : byObject('table', 'name',
 * 'test', 'div1');
 *  byObjects("input", "class", "form-input2", "param_"+data)
 * IN : tagName : html 태그명 attributeName : 태그의 속성명 attributeValue : 태그의 속성값
 * objName : 구해올 태그들의 상위명. 없으면 document OUT : 최초작성일 : 2010/02/01 최초작성자 : 홍석조
 * 수정이력 :
 ******************************************************************************/
function byObjects(tagName, attributeName, attributeValue, objName) {

    var doc;
    if (objName != "") {
        doc = document.getElementById(objName);
    } else {
        doc = document;
    }

    var reobjs = new Array();
    var obj = doc.getElementsByTagName(tagName.toUpperCase());
    var len = obj.length;    
    var cnt = 0;
    for ( var i = 0; i < len; i++) {
        // if(obj[i][attributeName] == attributeValue){
        if (obj[i].getAttribute(attributeName) == attributeValue) {
            reobjs[cnt++] = obj[i];
        }
    }
    return reobjs;
}

function byObject(tagName, attributeName, attributeValue, objName) {
    var doc;
    if (objName != "") {
        doc = document.getElementById(objName);
    } else {
        doc = document;
    }
    var reobjs = new Array();
    var obj = doc.getElementsByTagName(tagName.toUpperCase());
    var len = obj.length;
    var cnt = 0;
    for ( var i = 0; i < len; i++) {
        if (obj[i][attributeName] == attributeValue) {
            return obj[i];
        }
    }
}

// name을 패턴으로 검색하여 해당 태그요소만 반환하는 용도 입니다. test검증 필요
// 검색태그 : text,div
// 선택자(속성) : 속성명 id
// 이름(값) : test
function getFormChildByPtn(tag, slt, key) {
    var tag = document.getElementsByTagName(tag);
    var len = tag.length;
    var pattern = new RegExp("^" + key);
    // var El=[];
    for ( var i = 0, El = []; i < len; i++) {
        if (tag[i].id.match(pattern)) {
            El.push(tag[i]);
        }
    }
    return El;
}

// 엘레멘트 가져오기
function byId(id) {
    return document.getElementById(id);
}

// 엘레멘트 가져오기
function byName(id) {
    return document.getElementsByName(id);
}

// 익스플로워 구분
function isIe() {
    if (document.all)
        return true;
    else
        return false;
}

// 현재자신의 위치 구하기
function scrollPos() {
    if (self.pageYOffset !== undefined) {
        return {
            x : self.pageXOffset,
            y : self.pageYOffset
        };
    }
    var d = document.documentElement;
    return {
        x : d.scrollLeft,
        y : d.scrollTop
    };
}

// 앞뒤로 빈값 없애기
function trim(str) {
    var whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
    for ( var i = 0; i < str.length; i++) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(i);
            break;
        }
    }
    for (i = str.length - 1; i >= 0; i--) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}

// replaceAll 함수
String.prototype.replaceAll = function(str1, str2) {
    var temp_str = "";
    var temp_trim = this.replace(/(^\s*)|(\s*$)/g, "");

    if (temp_trim && str1 != str2) {
        temp_str = temp_trim;
        while (temp_str.indexOf(str1) > -1)
            temp_str = temp_str.replace(str1, str2);
    }

    return temp_str;
}

/*******************************************************************************
 * FUNCTION ID: getValue DESC : 엘레멘트 값을 가져오기 EX : getValue('table');
 * 
 * IN : idName : 엘레멘트 id명 OUT : 최초작성일 : 2010/02/01 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function getValue(idName) {
    var reStr = "";
    var id;
    if (typeof id == "string") {
        id = byId(idName);
    }

    if (id == null) {
        var ids = byName(idName);
        // alert(id.length);
        id = ids[0];
    }

    if (id != null) {
        // alert(id.name);
        var strType = id.type.toLowerCase();
        if (strType == "select") {
            reStr = getSelectValue(id);
        } else if (strType == "checkbox") {
            reStr = getCheckboxValue(id);
        } else if (strType == "radio") {
            reStr = getRadioValue(idName);
        } else if (strType == "button") {
            reStr = "";
        } else {
            reStr = id.value;
        }
    }
    return reStr;
}

// 셀렉트값 가져오기
function getSelectValue(obj) {
    return obj.options[obj.selectedIndex].value;
}

// 체크박스값 가져오기
function getCheckboxValue(obj) {
    if (obj.checked) {
        return obj.value;
    } else {
        return "";
    }
}

// 라디오버튼값 가져오기
function getRadioValue(obj) {
    var object = document.getElementsByName(obj);
    var objValue = "";
    if (Object != null) {
        for ( var j = 0; j < object.length; j++) {
            if (object[j].checked) {
                objValue = object[j].value;
            }
        }
    }
    return objValue;
}

// 라디오버튼값 가져오기
function isChecked(obj) {
    var object = document.getElementsByName(obj);
    if (Object != null) {
        for ( var j = 0; j < object.length; j++) {
            if (object[j].checked) {
                return true;
            }
        }
    }
    return false;
}

/*******************************************************************************
 * ###############################################################################################
 * 
 * 검증 (vaild) 관련 함수
 * 
 * ###############################################################################################
 ******************************************************************************/

function isFormValid(frm) {

    var flag = true;
    var elementsCount = frm.length;

    for ( var i = 0; i < elementsCount; i++) {
        try {
            var elObj = frm.elements[i];
            var eleName = elObj.name; // 엘리먼트명 name
            var eleValue = elObj.value; // 엘리먼트값 value
            var eleType = elObj.type; // 엘리먼트타입 text, select 등등
            var eleTitle = elObj.getAttribute("title"); // 엘리먼트제목

            if (!eleType) {
                continue;
            }
            eleType = eleType.toLowerCase();

            // 제목이 있어야 한다.
            if (eleTitle && eleTitle != "") {
                // 필수처리
                if (elObj.getAttribute("mandatory") == "Y") {
                    if (eleType == "checkbox") {
                        eleValue = getCheckboxValue(elObj);
                    }
                    if (trim(eleValue) == "") {
                        // alert("eleTitle="+eleTitle+ " eleType="+eleType+ "
                        // eleValue='"+eleValue+"'");
                        alert(eleTitle + "은 필수입니다.");
                        if (eleType != "hidden") {
                            elObj.focus();
                        }
                        flag = false;
                        break;
                    }
                }
                // 변환처리
                if (elObj.getAttribute("replaceAsis") && elObj.getAttribute("replaceAsis") != "") {
                    if (elObj.getAttribute("replaceTobe")) {
                        elObj.value = eleValue.replaceAll(elObj.getAttribute("replaceAsis"), elObj
                                .getAttribute("replaceTobe"));
                    } else {
                        elObj.value = eleValue.replaceAll(elObj.getAttribute("replaceAsis"), "");
                    }
                    // alert("eleTitle="+eleTitle+ " eleType="+eleType+ "
                    // eleValue='"+elObj.value+"'" +" asis"
                    // +elObj.getAttribute("replaceAsis"));
                }
            }
        } catch (e) {
            alert("문제가 발생해서 진행할수가 없습니다. 관리자에게 문의하십시요.");
            flag = false;
        }
    }
    return flag;
}

/*******************************************************************************
 * ###############################################################################################
 * 
 * Ajax 관련 함수
 * 
 * ###############################################################################################
 ******************************************************************************/

/*******************************************************************************
 * FUNCTION ID: getXMLHttpRequest DESC : XMLHttpRequest 객체 생성 관련함수 : IN : OUT :
 * XMLHttpRequest 객체 최초작성일 : 2008/08/01 최초작성자 : 홍석조 수정이력 :
 * 
 ******************************************************************************/
function getXMLHttpRequest() {
    var xmlreq = null;

    if (window.XMLHttpRequest) {
        xmlreq = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        try {
            xmlreq = new ActiveXObject("Msxml2.XMLHTTP"); // 익스플로워 5.0 이후
        } catch (e1) {
            try {
                xmlreq = new ActiveXObject("Microsoft.XMLHTTP"); // 익스플러워
                // 5.0이전
            } catch (e2) {
                return null;
            }
        }
    }
    return xmlreq;
}

/*******************************************************************************
 * FUNCTION ID: sendRequest DESC : 비동기 호출 (Ajax Submit) 관련함수 : getXMLHttpRequest
 * IN : url : 결과값을 리턴할 화면 Url 예) a.asp method : 메소드 예) POST, GET param : 조회할 키
 * 파라메터와값 예) code=xxx resHandlerOnSuccess : 성공했을때 실행시키는 함수 예) a function a {
 * alert("성공했습니다."); } resHandlerOnFail : 실패했을때 실행시키는 함수 예) a function a {
 * alert("실패했습니다."); } OUT : 최초작성일 : 2008/08/01 최초작성자 : 홍석조 수정이력 :
 * 
 ******************************************************************************/
function sendRequest(url, method, param, resHandlerOnSuccess, resHandlerOnFail) {
    try {
        var xmlreq = getXMLHttpRequest();

        if (xmlreq == null)
            return 1;
        xmlreq.onreadystatechange = function() {
            if (xmlreq.readyState == 4) {
                if (xmlreq.status == 200) {
                    resHandlerOnSuccess(xmlreq);
                } else {
                    resHandlerOnFail(xmlreq);
                }
            }
        }
        xmlreq.open(method, url, true);
        xmlreq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
        xmlreq.send(param);
    } catch (ex) {
        alert("javaScript 에러. sendRequest 초기화 중 에러발생." + ex);
    }
}

// ajax 호출시에 화면에 데이터를 가져오는중입니다를 보여주기
function ajaxStatsBarShow() {
    var ajaxStatsBar = document.getElementById("ajaxStatsBar");
    if (!ajaxStatsBar) {
        var ajaxStatsBar = document.createElement("div");
        // ajaxStatsBar.className = "loading";
        // ajaxStatsBar.style.cssText =
        // "height:133px;width:195px;position:absolute;";
        ajaxStatsBar.style.cssText = "height:133px;width:195px;position:absolute;background:url(images/loading_bg.gif) no-repeat left top;padding-top:20px;text-align:center;color:#000;font-size:12px;";
        ajaxStatsBar.innerHTML = "<p>데이터를 가져오는 중입니다.</p>";
        ajaxStatsBar.id = "ajaxStatsBar";
        ajaxStatsBar.noWrap = true;
        document.body.appendChild(ajaxStatsBar);
    }
    var objWidth = 0;
    var objHeight = 0;
    try {
        objWidth = parseInt(ajaxStatsBar.style.width);
        objHeight = parseInt(ajaxStatsBar.style.height);
    } catch (e) {
    }
    var ajaxStatsBar_x = (document.body.clientWidth + document.body.scrollLeft - objWidth) / 2;
    var ajaxStatsBar_y = (document.body.clientHeight + document.body.scrollTop - objHeight) / 2;
    ajaxStatsBar.style.left = ajaxStatsBar_x + "px";
    ajaxStatsBar.style.top = ajaxStatsBar_y + "px";
    ajaxStatsBar.style.display = "";
    // ajaxStatsBar.style.top = scrollPos().y + "px";
    // ajaxStatsBar.style.left = scrollPos().x + "px";
}

function ajaxStatsBarHidden() {
    var ajaxStatsBar = document.getElementById("ajaxStatsBar");
    if (ajaxStatsBar) {
        ajaxStatsBar.style.display = "none";
    }
}

/*******************************************************************************
 * FUNCTION ID: cmsCategoryInit DESC : 카테고리를 처음 생성할때의 호출 검증 웹브라우저 : IE, Safari,
 * Firefox 모두다 검증완료 관련함수 : cmsCategoryRecursive IN : ajaxUrl : ajax 호출할 페이지. 필수값
 * 예) /ajax/categoryList.jsp categoryId : 카테고리필드의 메타필드ID. 필수값 paramCode :
 * 카테고리필드의 parameter1 값, 즉 category코드값. 필수값 value : 선택되어서 넘어온 request의 값. 필수값은
 * 아님 mappingCategoryId : 카테고리필드가 두개이상일경우에 필드 둘중에 하나만 보내기 위한 hidden id값.
 * mappingValueId와 헷갈리면 안됨. 필수값 아님. mappingValueId : 카테고리가 멀티일경우 선택했을때 값을 보내기 위한
 * hidden id값. 필수값 onlyFlag : 카테고리필드가 두개이상일경우 필드하나만 선택하기위한 boolean 값. 필수값 아님.
 * 
 * OUT : 최초작성일 : 2010/06/20 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
var cmsCategoryTreeList = new Array();

function cmsCategoryInit(ajaxUrl, categoryId, paramCode, value, mappingCategoryId, mappingValueId, onlyFlag,
        disableFlag) {
    var param = "path=" + paramCode;

    var successScript = function(xmlreq) {

        cmsCategoryTreeList[categoryId] = eval('(' + xmlreq.responseText + ')');

        var data;
        for ( var x in cmsCategoryTreeList) {
            if (x == categoryId) {
                data = cmsCategoryTreeList[x];
            }
        }

        var comboObj = document.createElement("select"); // 콤보객체 생성
        // flag에 따라 콤보객체 비활성화
        if (disableFlag) {
            comboObj.disabled = true;
        }
        // comboObj.setAttribute("onchange", "cmsCategoryRecursive(categoryId,
        // this.value, '2', '');");
        // comboObj.attachEvent("onchange", "function(){
        // cmsCategoryRecursive(categoryId, this.value,'2',''); } ");
        comboObj.onchange = function() {
            cmsCategoryRecursive(categoryId, this.value, "2", "", mappingCategoryId, mappingValueId, onlyFlag,
                    disableFlag);
        }
        comboObj.id = categoryId + "_1";

        var divObj = byId("div" + categoryId); // Div객체
        divObj.appendChild(comboObj);
        var optionCnt = 0; // 옵션카운트
        comboObj.options[0] = new Option("----- 선택 -----", "");
        optionCnt++;

        for ( var i = 0; i < data.nodes.length; i++) {
            if (data.nodes[i].node.nodeUpId == paramCode) {
                // data.nodes[i].node.nodeUpId
                comboObj.options[optionCnt] = new Option(data.nodes[i].node.nodeName, data.nodes[i].node.nodeId);
                optionCnt++;
            }
        }

        // 초기 기본값이 있다면
        if (value != "") {

            // 초기값 세팅
            var tempTest = "";
            for ( var i = 0; i < data.nodes.length; i++) {
                if (data.nodes[i].node.nodeId == value) {
                    tempTest = data.nodes[i].node.nodePath;
                }
            }

            //
            var tempArr = fnCheckNullSplit(tempTest, "/");
            // 초기값 이후부터 세팅
            var tempCnt = 0;
            for ( var i = 1; i < tempArr.length; i++) {
                // 값이 같은것부터 레벨 시작
                if (tempArr[i] == paramCode) {
                    tempCnt = 2;
                    comboObj.value = tempArr[i + 1];
                    continue;
                }

                // 두번째부터는 넣어준다.
                if (tempCnt > 1) {
                    var tempId = "";
                    if (i < tempArr.length) {
                        tempId = tempArr[i + 1];
                    }
                    cmsCategoryRecursive(categoryId, tempArr[i], tempCnt, tempId, mappingCategoryId, mappingValueId,
                            onlyFlag, disableFlag);
                    tempCnt++;
                }
            }
        }
    }

    var failedScript = function() {
        alert("정보를 가져오는 함수가 실패 하였습니다. ");
    }
    sendRequest(ajaxUrl, "POST", param, successScript, failedScript);
}

/*******************************************************************************
 * FUNCTION ID: cmsCategoryRecursive DESC : 카테고리를 두번째부터 호출하는 이벤트 관련함수 :
 * cmsCategoryInit IN : categoryId : 카테고리필드의 메타필드ID. 필수값 code : 카테고리필드의
 * parameter1 값, 즉 category코드값. 필수값 depth : 카테고리레벨구조의 depth. 필수값. value : 선택되어서
 * 넘어온 request의 값. 필수값은 아님 mappingCategoryId : 카테고리필드가 두개이상일경우에 필드 둘중에 하나만 보내기
 * 위한 hidden id값. mappingValueId와 헷갈리면 안됨. 필수값 아님. mappingValueId : 카테고리가 멀티일경우
 * 선택했을때 값을 보내기 위한 hidden id값. 필수값 onlyFlag : 카테고리필드가 두개이상일경우 필드하나만 선택하기위한
 * boolean 값. 필수값 아님.
 * 
 * OUT : 최초작성일 : 2010/06/20 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function cmsCategoryRecursive(categoryId, code, depth, value, mappingCategoryId, mappingValueId, onlyFlag, disableFlag) {

    // 검색값 저장 : 저장카테고리 저장
    if (mappingCategoryId != "" && byId(mappingCategoryId)) {
        byId(mappingCategoryId).value = categoryId;
    }
    // 저장값 selectid에 저장
    if (mappingValueId != "" && byId(mappingValueId)) {
        byId(mappingValueId).value = code;
    }

    // 자신에 속해있지 않는 category들 초기화
    if (onlyFlag) {
        var selectArr = byId("categoryGroup").getElementsByTagName("div");
        if (selectArr != null) {
            for ( var i = 0; i < selectArr.length; i++) {
                if (selectArr[i].id.indexOf(categoryId) <= 0) {
                    var tempId = fnCheckNullSplit(selectArr[i].id, "_")[0];
                    tempId = tempId.substring(3, tempId.length);
                    if (byId(tempId + "_1"))
                        byId(tempId + "_1").value = ""; // 처음것만 초기화
                    // 다른것들의 하부 카테고리도 초기화
                    var depthCnt = 2;
                    while (byId(tempId + "_" + depthCnt)) {
                        byId("div" + tempId).removeChild(byId(tempId + "_" + depthCnt));
                        depthCnt++;
                    }
                }
            }
        }
    }

    // 자신에 속해있는 category들 초기화
    var divObj = byId("div" + categoryId); // Div객체
    var depthCnt = depth;
    while (byId(categoryId + "_" + depthCnt)) {
        divObj.removeChild(byId(categoryId + "_" + depthCnt));
        depthCnt++;
    }

    var data;
    for ( var x in cmsCategoryTreeList) {
        if (x == categoryId) {
            data = cmsCategoryTreeList[x];
        }
    }

    var comboObj = document.createElement("select"); // 콤보객체 생성
    // flag에 따라 콤보객체 비활성화
    if (disableFlag) {
        comboObj.disabled = true;
    }
    comboObj.id = categoryId + "_" + depth;
    comboObj.onchange = function() {
        cmsCategoryRecursive(categoryId, this.value, (parseInt(depth) + 1), "", mappingCategoryId, mappingValueId,
                onlyFlag);
    }

    var optionCnt = 0; // 옵션카운트
    comboObj.options[0] = new Option("----- 선택 -----", "");
    optionCnt++;

    var flag = false;
    for ( var i = 0; i < data.nodes.length; i++) {
        if (data.nodes[i].node.nodeUpId == code) {
            comboObj.options[optionCnt] = new Option(data.nodes[i].node.nodeName, data.nodes[i].node.nodeId);
            optionCnt++;
            flag = true;
        }
    }
    // 디폴트값 있으면 값을 집어넣는다.
    if (value != "") {
        comboObj.value = value;
    }
    // 콤보박스를 div에 보여준다.
    if (flag) {
        divObj.appendChild(comboObj);
    }
}

function getCwSpecialNode(nodes, value) {
    var tempNode;
    for ( var i = 0; i < nodes.length; i++) {
        if (nodes[i].nodeId == value) {
            tempNode = nodes[i];
            break;
        }
    }
    return tempNode;
}

function getCwSpecialChild(nodes, value) {
    var tempNode;
    for ( var i = 0; i < nodes.length; i++) {
        if (nodes[i].nodeUpId == value) {
            tempNode = nodes[i];
            break;
        }
    }
    return tempNode;
}

/*******************************************************************************
 * FUNCTION ID: cmsSpecialListInit DESC : 카테고리를 처음 생성할때의 호출 검증 웹브라우저 : IE,
 * Safari, Firefox 모두다 검증완료 관련함수 : cmsCategoryRecursive IN : ajaxUrl : ajax 호출할
 * 페이지. 필수값 예) /ajax/categoryList.jsp categoryId : 카테고리필드의 메타필드ID. 필수값 paramCode :
 * 카테고리필드의 parameter1 값, 즉 category코드값. 필수값 value : 선택되어서 넘어온 request의 값. 필수값은
 * 아님 mappingCategoryId : 카테고리필드가 두개이상일경우에 필드 둘중에 하나만 보내기 위한 hidden id값.
 * mappingValueId와 헷갈리면 안됨. 필수값 아님. mappingValueId : 카테고리가 멀티일경우 선택했을때 값을 보내기 위한
 * hidden id값. 필수값 onlyFlag : 카테고리필드가 두개이상일경우 필드하나만 선택하기위한 boolean 값. 필수값 아님.
 * disableFlag : 필드가 고정일때..
 * 
 * OUT : 최초작성일 : 2010/06/20 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
var cmsSpecialTreeList = new Array();

function cmsSpecialListInit(ajaxUrl, categoryId, paramCode, value, mappingCategoryId, mappingValueId, onlyFlag,
        disableFlag) {
    var param = "id=" + categoryId;
    // alert(value);
    var successScript = function(xmlreq) {
        // alert(xmlreq.responseText);
        cmsSpecialTreeList[categoryId] = eval('(' + xmlreq.responseText + ')');

        var data; // json 데이터
        for ( var x in cmsSpecialTreeList) {
            if (x == categoryId) {
                data = cmsSpecialTreeList[x];
            }
        }

        var depth = 2; // 처음 디폴드 뎁스 --> 건들지 마시오

        var comboObj = document.createElement("select"); // 콤보객체 생성
        // flag에 따라 콤보객체 비활성화
        if (disableFlag) {
            comboObj.disabled = true;
        }
        // 콤보객체에 옵션 삽입
        var optionCnt = 0; // 옵션카운트
        comboObj.options[0] = new Option("----- 선택 -----", "");
        optionCnt++;
        for ( var i = 0; i < data.nodes.length; i++) {
            if (data.nodes[i].nodeUpId == paramCode) {
                // data.nodes[i].node.nodeUpId
                comboObj.options[optionCnt] = new Option(data.nodes[i].nodeName, data.nodes[i].nodeId);
                optionCnt++;
            }
        }
        // 콤보객체 onchange 이벤트생성과 id 생성
        comboObj.onchange = function() {
            cmsSpecialRecursive(categoryId, this.value, "2", "", mappingCategoryId, mappingValueId, onlyFlag,
                    disableFlag);
        }
        comboObj.id = categoryId + "_1";

        // div 객체에 콤보박스 삽입
        var divObj = byId("div" + categoryId); // Div객체
        divObj.appendChild(comboObj);

        // 초기 기본값이 있다면
        if (value != "") {
            comboObj.value = value;
            var i = 0;
            // cmsSpecialRecursive(categoryId, paramCode, depth, value,
            // mappingCategoryId, mappingValueId, onlyFlag, disableFlag);
            // depth++;
            // 신규 소스
            while (true) {
                var tempNode = getCwSpecialChild(data.nodes, value);
                if (!tempNode)
                    break;
                var inputObj = byId(tempNode.nodeField);
                if (inputObj) {
                    value = inputObj.value;
                } else {
                    value = "";
                }
                if (value == "")
                    break;
                // alert("id="+categoryId+" i="+i+"
                // tempArr[i]="+tempNode.nodeId);
                cmsSpecialRecursive(categoryId, tempNode.nodeUpId, depth, value, mappingCategoryId, mappingValueId,
                        onlyFlag, disableFlag);
                depth++;
                i++;
                // 무한반복 금지
                if (i == 3) {
                    break;
                }
            }
        }
    }

    var failedScript = function() {
        alert("정보를 가져오는 함수가 실패 하였습니다. ");
    }
    sendRequest(ajaxUrl, "POST", param, successScript, failedScript);
}

/*******************************************************************************
 * FUNCTION ID: cmsCategoryRecursive DESC : 카테고리를 두번째부터 호출하는 이벤트 관련함수 :
 * cmsCategoryInit IN : categoryId : 카테고리필드의 메타필드ID. 필수값 code : 카테고리필드의
 * parameter1 값, 즉 category코드값. 필수값 depth : 카테고리레벨구조의 depth. 필수값. value : 선택되어서
 * 넘어온 request의 값. 필수값은 아님 mappingCategoryId : 카테고리필드가 두개이상일경우에 필드 둘중에 하나만 보내기
 * 위한 hidden id값. mappingValueId와 헷갈리면 안됨. 필수값 아님. mappingValueId : 카테고리가 멀티일경우
 * 선택했을때 값을 보내기 위한 hidden id값. 필수값 onlyFlag : 카테고리필드가 두개이상일경우 필드하나만 선택하기위한
 * boolean 값. 필수값 아님.
 * 
 * OUT : 최초작성일 : 2010/06/20 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function cmsSpecialRecursive(categoryId, code, depth, value, mappingCategoryId, mappingValueId, onlyFlag, disableFlag) {
    // alert("id="+categoryId+" code="+code+" depth="+depth+ "value="+value);
    // 자신에 속해있지 않는 category들 초기화
    if (onlyFlag) {
        var selectArr = byId("specialGroup").getElementsByTagName("div");
        if (selectArr != null) {
            for ( var i = 0; i < selectArr.length; i++) {
                if (selectArr[i].id.indexOf(categoryId) <= 0) {
                    var tempId = fnCheckNullSplit(selectArr[i].id, "_")[0];
                    tempId = tempId.substring(3, tempId.length);
                    if (byId(tempId + "_1"))
                        byId(tempId + "_1").value = ""; // 처음것만 초기화
                    // 다른것들의 하부 카테고리도 초기화
                    var depthCnt = 2;
                    while (byId(tempId + "_" + depthCnt)) {
                        byId("div" + tempId).removeChild(byId(tempId + "_" + depthCnt));
                        depthCnt++;
                    }
                }
            }
        }
    }

    // 자신에 속해있는 category들 초기화
    var divObj = byId("div" + categoryId); // Div객체
    var depthCnt = depth;
    while (byId(categoryId + "_" + depthCnt)) {
        divObj.removeChild(byId(categoryId + "_" + depthCnt));
        depthCnt++;
    }

    // 하단 콤보객체를 생성하는 작업중
    var data;
    for ( var x in cmsSpecialTreeList) {
        if (x == categoryId) {
            data = cmsSpecialTreeList[x];
        }
    }
    var thisNode; // 선택된 node
    var comboObj = document.createElement("select"); // 하단 콤보객체 생성
    // 콤보객체 onchange 이벤트생성과 id 생성
    comboObj.id = categoryId + "_" + depth;
    comboObj.onchange = function() {
        cmsSpecialRecursive(categoryId, this.value, (parseInt(depth) + 1), "", mappingCategoryId, mappingValueId,
                onlyFlag, disableFlag);
    }

    // 콤보객체 비활성화
    if (disableFlag) {
        comboObj.disabled = true;
    }

    // 콤보객체에 옵션 삽입
    var flag = false; // 콤보객체 하부에 코드가 있는지 여부를 확인한다.
    var optionCnt = 0; // 옵션카운트
    comboObj.options[0] = new Option("----- 선택 -----", "");
    optionCnt++;
    for ( var i = 0; i < data.nodes.length; i++) {
        // 하부코드가 있다면 옵션에 넣는다.
        if (data.nodes[i].nodeUpId == code) {
            comboObj.options[optionCnt] = new Option(data.nodes[i].nodeName, data.nodes[i].nodeId);
            // comboObj.options[optionCnt] = new
            // Option("["+data.nodes[i].nodeUpId+"]"+"["+data.nodes[i].nodeId+"]"+data.nodes[i].nodeName,
            // data.nodes[i].nodeId);
            optionCnt++;
            flag = true;
        }
        // 선택된 노드는 thisNod에 담는다.
        if (data.nodes[i].nodeId == code) {
            thisNode = data.nodes[i];
        }
    }

    // 디폴트값 있으면 콤보객체에 값을 넣는다.
    if (value != "") {
        comboObj.value = value;
    }
    // 콤보객체 비활성화
    if (disableFlag) {
        comboObj.disabled = true;
    }
    // 만약 하부에 코드옵션이 없으면 div에 넣지 않는다.
    if (flag) {
        divObj.appendChild(comboObj);
    }

    // 검색값 저장 : 저장카테고리 저장
    if (mappingCategoryId != "" && byId(mappingCategoryId)) {
        byId(mappingCategoryId).value = categoryId;
    }

    // 저장값 selectid에 저장
    if (thisNode != null && thisNode.nodeField != null) {
        if (!byId(thisNode.nodeField)) {
            var inputObj = document.createElement("input"); // input 생성
            inputObj.type = "hidden";
            // inputObj.style.display ="";
            inputObj.id = thisNode.nodeField;
            inputObj.name = thisNode.nodeField;
            divObj.appendChild(inputObj);
        }
        mappingValueId = thisNode.nodeField;
    }

    if (mappingValueId != "" && byId(mappingValueId)) {

        byId(mappingValueId).value = code;
    }
}

/*
 * 
 * function setQueryString(frm) {
 * 
 * queryString = ""; var elementsCount = frm.length;
 * 
 * for(var i = 0; i < elementsCount; i++) { eleName = frm.elements[i].name;
 * eleValue = frm.elements[i].value; eleType = frm.elements[i].type;
 * 
 * if(eleType && eleType != "button") { if(i < elementsCount) { if(eleValue !=
 * null && eleValue != "") { queryString += eleName + "=" +
 * encodeURIComponent(eleValue) + "&"; } } else { if(eleValue != null &&
 * eleValue == "") { queryString += eleName + "=" +
 * encodeURIComponent(eleValue); } } } } var temp =
 * queryString.substring(queryString.length - 1, queryString.length); if(temp ==
 * "&") { queryString = queryString.substring(0, queryString.length - 1); }
 * return queryString; }
 */

/*******************************************************************************
 * FUNCTION ID: clickCheckboxField DESC : input 체크박스 필드의 체크시에 값을 보낼때, input
 * Hidden 필드에 값을 담아서 보내는 함수. 주의 : 파라메터 인자는 첫번째만 필수고 나머지는 자유롭게 사용할수 있다. 그리고 체크를
 * 안할시에는 빈값을 보내게 된다. 관련함수 : IN : name : hidden 필드의 id. 필수값 checkName : 체크박스 필드의
 * id. 인자가 없을시에는 hidden 필드의 id 뒤에 "_check" 를 붙여서 호출한다. value : 체크박스 선택시 보낼 값.
 * 인자가 없을시에는 "Y"를 디폴트로 쓴다. OUT : 최초작성일 : 2010/06/20 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function clickCheckboxField() {
    var name = arguments[0];
    var checkName = name + "_check";
    var value = "Y";

    if (arguments.length == 2) {
        checkName = arguments[1];
    } else if (arguments.length > 2) {
        checkName = arguments[1];
        value = arguments[2];
    }

    var checkObj = byId(checkName); // 체크박스객체
    var obj = byId(name); // 숨겨진체크박스객체

    if (checkObj.checked) {
        obj.value = value;
    } else {
        obj.value = "";
    }
}

/*******************************************************************************
 * FUNCTION ID: fnCodeComboBox DESC : 코드콤보박스 생성 EX : fnCodeComboBox('3',
 * 'combo', '1', '', false); <select name="combo"> 관련함수 : sendRequest IN :
 * codeGroup : 코드그룹값. comboId : 콤보박스의 ID 값. largeCode 대분류 코드값에 맞춘 구별자는 ","로
 * 구별한다. 같은 대분류코드값을 콤보박스 2개에 사용한다면 구별자 :로 체크한다. 예) combo2:combo3 value : 콤보박스의
 * 기본값 largeCode 대분류 코드값에 맞춘 구별자는 ","로 구별한다. 같은 대분류코드값을 콤보박스 2개에 사용한다면 구별자 :로
 * 체크한다. 예) 01:05 delCode : 콤보박스의 삭제할값 largeCode 대분류 코드값에 맞춘 구별자는 ","로 구별한다. 같은
 * 대분류코드값을 콤보박스 2개에 사용한다면 구별자 :로 체크한다. 예) 01,:05 allType : 전체 사용 여부 true이거나
 * null이면 전체를 넣는다. OUT : 최초작성일 : 2008/08/01 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function fnCodeComboBox(codeGroup, comboId, value, delCode, allType) {
    var param = "codeGroup=" + escape(codeGroup);

    var successScript = function(xmlreq) {

        var data = eval('(' + xmlreq.responseText + ')'); //
        var optionCnt = 0; // 옵션카운트
        var comboArr = fnCheckNullSplit(comboId, ":"); // 등록될 콤보값
        var delCodeArr = fnCheckNullSplit(delCode, ":"); // 삭제될 코드값
        for ( var i = 0; i < comboArr.length; i++) {
            var comboObj = document.getElementById(comboArr[i]);
            if (allType) {
                comboObj.options[0] = new Option("----- 선택 -----", "");
                optionCnt++;
            }

            for ( var j = 0; j < data.nodes.length; j++) {
                if (!fnCheckArrayCompare(delCodeArr, data.nodes[j].node.nodeId)) {
                    comboObj.options[optionCnt] = new Option(data.nodes[j].node.nodeName, data.nodes[j].node.nodeId);
                    optionCnt++;
                }
            }

            if (value != null) {
                comboObj.value = value;
            }
        }
    }

    var failedScript = function() {
        alert("정보를 가져오는 fnCodeComboBox 함수가 실패 하였습니다. ");
    }
    sendRequest("/city_hall/ajax/codeList.jsp", "POST", param, successScript, failedScript);
}

/*******************************************************************************
 * FUNCTION ID: fnGetCommonComboBox DESC : 코드콤보박스 생성 주의!! 인수에 공백을 넣지 마세요..
 * 
 * 관련함수 : sendRequest IN : largeCode : 공통코드에 대분류코드값. 구별자는 ","로 구별한다. 예)
 * '동태항목구분코드,법원코드' comboId : 콤보박스의 ID 값. largeCode 대분류 코드값에 맞춘 구별자는 ","로 구별한다.
 * 같은 대분류코드값을 콤보박스 2개에 사용한다면 구별자 ":"로 체크한다. 예) 'combo1,combo2:combo3' value :
 * 콤보박스의 기본값 largeCode 대분류 코드값에 맞춘 구별자는 ","로 구별한다. 같은 대분류코드값을 콤보박스 2개에 사용한다면 구별자
 * ":"로 체크한다. 예) '01,:05' allType : 전체 사용 여부 - true이거나 null이면 전체를 넣는다. allType
 * 대분류 코드값에 맞춘 구별자는 ","로 구별한다. 같은 대분류코드값을 콤보박스 2개에 사용한다면 구별자 ":"로 체크한다.
 * 주의!!!!!!!!!!! - 반드시문자로 해주세요. '' 예) 'true,false:false' delCode : 콤보박스의 삭제할값
 * largeCode 대분류 코드값에 맞춘 구별자는 ","로 구별한다. 같은 대분류코드값을 콤보박스 2개에 사용한다면 구별자 ":"로
 * 체크한다. 콤보박스값중 2개 이상 삭제한다면 구별자 "^"로 체크한다. 예) '01,:05^06^07' OUT : 최초작성일 :
 * 2008/09/01 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function fnNewsCodeComboBox(largeCode, comboId, value, allType, delCode) {
    var param = "codeGroup=" + escape(largeCode);

    var successScript = function(xmlreq) {
        // alert(xmlreq.responseText);
        var data = eval('(' + xmlreq.responseText + ')'); // DB에서 받아온 코드값들을
        // 활성화 시킨다.

        var largeCodeArr = largeCode.split(","); // 대분류값을 ","로 배열설정
        var comboIdArr = comboId.split(","); // 콤보ID값을 ","로 배열설정

        var valueArr = fnCheckNullSplit(value, ","); // 콤보기본값을 ","로 배열설정
        var allTypeArr = fnCheckNullSplit(allType, ","); // 전체여부을 ","로 배열설정
        var delCodeArr = fnCheckNullSplit(delCode, ","); // 삭제코드값을 ","로 배열설정

        if (largeCodeArr.length != comboIdArr.length) {
            alert("분류코드갯수와 콤보박스아이디 갯수가 틀립니다. 확인해주세요.");
            return false;
        }

        /*
         * largeCode 대분류값 배열을 루프를 돌려서 콤보에 세팅한다.
         */
        for ( var i = 0; i < largeCodeArr.length; i++) // 대분류값 배열을 for문으로 돌린다.
        {
            for ( var j = 0; j < data.nodes.length; j++) // DB값도 for문으로 돌린다.
            {
                if (largeCodeArr[i] == data.nodes[j].key) // DB값을 돌려서 대분류값이
                // 같은것을 선택한다.
                {
                    // alert(largeCodeArr[i]+" = "+data.nodes[j].key);
                    var nodeGroup = data.nodes[j].nodeGroup; // DB값중 대분류와 같은
                    // 코드배열노드를
                    // Object화 시킨다.

                    var comboIdSubArr = comboIdArr[i].split(":"); // 콤보id를 구분값
                    // ":" 한번 더
                    // 배열시킨다.
                    var valueSubArr = null;
                    if (valueArr != null) {
                        valueSubArr = fnCheckNullSplit(valueArr[i], ":"); // 기본값을
                        // 구분값
                        // ":"
                        // 한번 더
                        // 배열시킨다.
                    }
                    var allTypeSubArr = null;
                    if (allTypeArr != null) {
                        allTypeSubArr = fnCheckNullSplit(allTypeArr[i], ":"); // 전체여부를
                        // 구분값
                        // ":"
                        // 한번 더
                        // 배열시킨다.
                    }
                    var delCodeSubArr = null;
                    if (delCodeArr != null) {
                        delCodeSubArr = fnCheckNullSplit(delCodeArr[i], ":"); // 삭제코드를
                        // 구분값
                        // ":"
                        // 한번 더
                        // 배열시킨다.
                    }

                    /*
                     * 콤보 id를 루프를 돌려서 코드배열 노드에 있는 코드와 코드명을 세팅한다.
                     */
                    for ( var z = 0; z < comboIdSubArr.length; z++) {
                        var comboObj = document.getElementById(comboIdSubArr[z]); // 콤보
                        // id를
                        // Object화
                        // 시킨다.
                        optionCnt = 1; // 디폴트 전체를 보임여부를 담고 있는 임시 변수 1은 보임, 0은
                        // 안보임
                        comboObj.options[0] = new Option("전체", "");
                        if (allTypeSubArr != null && eval(allTypeSubArr[z]) == false) // allType
                        // 이
                        // false면
                        // optionCnt
                        // 임시변수를
                        // 0으로
                        // 만든다.
                        {
                            optionCnt = 0;
                        }

                        /*
                         * 코드배열을 가지고 와서 루프를 돌려서 option을 생성한다. optionCnt 가 0이면
                         * 0부터 option을 생성하므로 자동으로 전체는 삭제한다.
                         */
                        for ( var y = 0; y < nodeGroup.length; y++) {

                            var delCodeSubSubArr = null;
                            if (delCodeSubArr != null) {
                                delCodeSubSubArr = fnCheckNullSplit(delCodeSubArr[z], "^"); // 삭제코드를
                                // 구분값
                                // ":"
                                // 한번 더
                                // 배열시킨다.
                            }

                            if (!fnCheckArrayCompare(delCodeSubSubArr, nodeGroup[y].node.nodeId)) {
                                comboObj.options[y + optionCnt] = new Option(nodeGroup[y].node.nodeName,
                                        nodeGroup[y].node.nodeId);
                            } else {
                                optionCnt--;
                            }

                        }

                        if (valueSubArr != null && valueSubArr[z] != null && valueSubArr[z] != "") // 콤보에
                        // 기본값을
                        // 세팅한다.
                        {
                            comboObj.value = valueSubArr[z];
                        }

                    }
                }
            }
        }
    }

    var failedScript = function() {
        alert("failed");
    }
    sendRequest("/city_hall/ajax/newCodeList.jsp", "POST", param, successScript, failedScript);
}

/*******************************************************************************
 * FUNCTION ID: fnCheckNullSplit DESC : null일때 split를 쓰면 에러가 나기때문에, null체크를 하고
 * split를 한다. 관련함수 : IN : split 값 OUT : 배열 최초작성일 : 2008/09/01 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function fnCheckNullSplit(value, otherValue) {
    var returnValue = null
    if (value != null) {
        returnValue = value.split(otherValue);
    }
    return returnValue;
}

/*******************************************************************************
 * FUNCTION ID: fnCheckArrayCompare DESC : 배열과 값을 비교해서 값이 배열값에 있는지 확인한다. 관련함수 :
 * IN : value 배열값 ,otherValue 비교할 값 OUT : 값이 있으면 true, 없으면 false 최초작성일 :
 * 2008/09/01 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function fnCheckArrayCompare(value, otherValue) {
    var returnValue = false;
    if (value != null) {
        for ( var i = 0; i < value.length; i++) {
            if (value[i] == otherValue) {
                returnValue = true;
            }
        }
    }
    return returnValue;
}

function cmsWinOpenXY(url, winName, winOptions, x, y) {
    var popUp = window.open(url, winName, winOptions + ", left=" + x + ", top=" + y);
    popUp.focus();
    return popUp;
}

/*******************************************************************************
 * FUNCTION ID: fnSetSatisfaction DESC : 만족도 등록 관련함수 : sendRequest IN : obj :
 * 라디오버튼. url : url OUT : 최초작성일 : 2008/08/01 최초작성자 : 홍석조 수정이력 :
 ******************************************************************************/
function fnSetSatisfaction(obj, url, dongId) {

    var comboObj = document.getElementsByName(obj);
    var objValue = getRadioValue(obj);

    if (comboObj == null) {
        return;
    }
    if (objValue == '') {
        alert("만족도 항목중 하나라도 선택해주세요.");
        return false;
    }

    var param = "contentId=" + url + "&satisfaction=" + objValue + "&dongId=" + dongId;
    var successScript = function(xmlreq) {
        alert(xmlreq.responseText); //
        /*
         * var data = eval('(' + xmlreq.responseText + ')'); // for (var j=0; j<data.nodes.length;
         * j++){ if (!fnCheckArrayCompare(delCodeArr,
         * data.nodes[j].node.nodeId)) { comboObj.options[optionCnt] = new
         * Option(data.nodes[j].node.nodeName, data.nodes[j].node.nodeId);
         * optionCnt++; } }
         */
    }

    var failedScript = function() {
        alert("만족도 등록에 실패 하였습니다. ");
    }
    sendRequest("/common/satisfactionWrite.jsp", "POST", param, successScript, failedScript);
}
