grid에서 컬럼을 클릭, 더블클릭 하는 이벤트는 리스너로 등록을 해주어야 한다. 플렉스와 비슷하여 이해하는데 많은 시간이 걸리지 않으나, 이벤트 타입을 찾는데 시간을 너무 소비 했다. 이벤트 타입은 extjs의 API Docs를 통해 확인할 수 있으며, 자세한 정보는 Ext.view.View의 event 항목을 보면된다.
// 그리드 생성
grid = Ext.create('Ext.grid.Panel', {
	store : store,
	stateful : true,
	collapsible : true,
	stateId : 'stateGrid',
	columns : [
		/*
		* 헤더와 컬럼의 정렬이 동일할 경우 align 만 사용
		* 헤더 정렬  ->  style: 'text-align:center'
		* 컬럼 정렬  ->	 align:' { left || center || right }' 
		*/
		  { text : '직원명', 	width : 150,	sortable : false,	dataIndex : 'NAME',	style: 'text-align:center', 	align:'left'}
		, { text : '소속사무소',	width : 150,	sortable : false,	dataIndex : 'BRNM',	style: 'text-align:center', 	align:'left'}
		],
		listeners: {
 		        itemdblclick: {
 		       	/**
 			 * @grid		그리드 오브젝트
 			 * @selRow		선택한 셀의 오브젝트
 			 * @selHtml		선택한 셀의  html
 			 * 
 			 * 기본적으로 Ext.define에서 idProperty로 선언한 field가 internalId로 설정된다.  						 		 * 그 외 데이터는 selRow.data.{field}로 접근할 수 있다.
 			 */
 		            fn: function(grid, selRow, selHtml){
 		  	// your codes
 		            	}
 		        }
 		}
		autoHeight:true,
		width : 1025,
		title : '사용자 목록',
		renderTo : 'grid',
		viewConfig : {
			stripeRows : true,
			enableTextSelection : false
		}







기본적으로 extjs4에서는 헤더와 컬럼은 동일하게 정렬된다.
이를 개별로 지정하는 속성은 따로 없고, 스타일로 지정을 해 주어야 한다.

자세한 것은 바로 코드로 확인할 수 있다.

// 그리드 생성
grid = Ext.create('Ext.grid.Panel', 
{	store : store,
	stateful : true,
	collapsible : true,
	stateId : 'stateGrid',	columns : [
		/*
		* 헤더와 컬럼의 정렬이 동일할 경우 align 만 사용
		* 헤더 정렬  ->  style: 'text-align:center'
		* 컬럼 정렬  ->	 align:' { left || center || right }'
 		*/
		  { text : '직원명', 	width : 150,	sortable : false,	dataIndex : 'NAME',	style: 'text-align:center', 	align:'left'}	
		  , { text : '소속사무소',	width : 150,	sortable : false,	dataIndex : 'BRNM',	style: 'text-align:center', 	align:'left'}	
		],
		autoHeight:true,
		width : 1025,
		title : '사용자 목록',
		renderTo : 'grid',
		viewConfig : {
			stripeRows : true,
			enableTextSelection : false
		}









출처 : http://jsdo.it/nomotch/rMoU 

/**
 * 
 */

//Load the Google data JavaScript client library.
google.load('gdata', '2.x', {packages: ['analytics']});

//Load the Google Libraries jQuery and jQuery UI
//google.load('jquery', '1.5.2');
//google.load('jqueryui', '1.8.12');

//Set the callback function when the library is ready.
google.setOnLoadCallback(init);

/**
 * This is called once the Google Data JavaScript library has been loaded.
 * It creates a new AnalyticsService object, adds a click handler to the
 * authentication button and updates the button text depending on the status.
 */
function init() {
	myService = new google.gdata.analytics.AnalyticsService('gaExportAPI_acctSample_v1.0');
	scope = 'https://www.google.com/analytics/feeds';

	// Add a click handler to the Authentication button.
	jQuery('#authButton').click( function() {
		// Test if the user is not authenticated.
		if (!google.accounts.user.checkLogin(scope)) {
			// Authenticate the user.
			google.accounts.user.login(scope);
		} else {
			// Log the user out.
			google.accounts.user.logout();
			getStatus();
		}
	});
	getStatus();
}

/**
 * Utility method to display the user controls if the user is 
 * logged in. If user is logged in, get Account data and
 * get Report Data buttons are displayed.
 */
function getStatus() {
	jQuery('#getData').click(getAccountFeed);

	if (!google.accounts.user.checkLogin(scope)) {
		jQuery('#dataControls').css('display', 'none');   // hide control div
		jQuery('#authButton').html('Access Google Analytics');

	} else {
		jQuery.datepicker.setDefaults({
			showOn: 'both',
			buttonImageOnly: true,
			buttonImage: 'http://jqueryui.com/demos/datepicker/images/calendar.gif',
			buttonText: 'Calender',
			dateFormat: 'yy-mm-dd' },
			jQuery.datepicker.regional["ja"] );
		jQuery(function(){jQuery('#startDate').datepicker()});
		jQuery(function(){jQuery('#endDate').datepicker()});
		jQuery('#dataControls').css('display', 'block');  // show control div
		jQuery('#authButton').html('Logout');
	}
}

/**
 * Main method to get account data from the API.
 */
function getAccountFeed() {
	var myFeedUri =
		'https://www.google.com/analytics/feeds/accounts/default?max-results=50';
	myService.getAccountFeed(myFeedUri, handleAccountFeed, handleError);
}

/**
 * Handle the account data returned by the Export API by constructing the inner parts
 * of an HTML table and inserting into the HTML file.
 * @param {object} result Parameter passed back from the feed handler.
 */
function handleAccountFeed(result) {
	// An array of analytics feed entries.
	var entries = result.feed.getEntries();

	rows = new Array();

	var table = jQuery('').attr('id', 'outputTable');

	var header = jQuery('').attr('id', 'header').css('text-align', 'center');
	header.append('');
	header.append('');
	header.append('');
	header.append('');
	table.append(header);
	jQuery('#outputDiv').append(table);

	// Iterate through the feed entries and add the data as table rows.
	for (var i = 0, entry; entry = entries[i]; ++i) {

		// Add a row in the HTML Table array for each value.
		var row = {
				'profileId':entry.getPropertyValue('ga:profileId'),
				'title':entry.getTitle().getText(),
				'tableId':entry.getTableId().getValue()
		};

		var tableId = entry.getTableId().getValue();

		rows.push(row);
	}

	getDataFeed();

	/*
  var data = jQuery('').attr('id', 'data');
  data.append('');
  table.append(data);

  jQuery('#outputDiv').append(table);

  getDataFeed(rows[1]['tableId']);
	 */
}

/**
 * Main method to get report data from the Export API.
 */
function getDataFeed() {
	for (var i = 0, row; row = rows[i]; ++i) {
		setTimeout( function(row) {
			var myFeedUri = 'https://www.google.com/analytics/feeds/data' +
			'?start-date=' + jQuery('#startDate').val() +
			'&end-date=' + jQuery('#endDate').val() +
			'&dimensions=ga:entrances' +
			'&metrics=ga:visits,ga:pageviews' +
			'&sort=-ga:pageviews' +
			'&max-results=10' +
			'&ids=' + row['tableId'];

			myService.getDataFeed(myFeedUri, handleDataFeed, handleError);
		}, 5000, row);
	}
}

/**
 * Handle the data returned by the Export API by constructing the 
 * inner parts of an HTML table and inserting into the HTML File.
 * @param {object} result Parameter passed back from the feed handler.
 */
function handleDataFeed(result) {

	// An array of Analytics feed entries.
	var entries = result.feed.getEntries();
	var title = result.feed.getDataSources()[0].getTableName().getValue();
	console.log(title);

	// Iterate through the feed entries and add the data as table rows.
	for (var i = 0, entry; entry = entries[i]; ++i) {

		var data = jQuery('').attr('id', 'data');
		data.append('');
		data.append('');
		data.append('');
		data.append('');
		jQuery('#outputTable').append(data);
		jQuery('td#num').css('text-align', 'center');
	}
}

/**
 * Alert any errors that come from the API request.
 * @param {object} e The error object returned by the Analytics API.
 */
function handleError(e) {
	var error = 'There was an error!\n';
	if (e.cause) {
		error += e.cause.status;
	} else {
		error.message;
	}
	alert(error);
}


Profile Name ga:month ga:visits ga:pageviews
' + rows[1]['title'] + '
' + title + ' ' + entry.getValueOf('ga:month') + ' ' + entry.getValueOf('ga:visits') + ' ' + entry.getValueOf('ga:pageviews') + '

InputSource is = new InputSource(new InputStreamReader(new FileInputStream("test.xml"), "UTF-8"));

이렇게 하지 않으면 Element를 통해 읽어 들일때 end tag를 인식하지 못해 에러난다.

 
대략적 전체 코드. 
		try {
			User user = null;
			InputSource is = new InputSource(new InputStreamReader(new FileInputStream(file), "UTF-8"));
			
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if(file != null){
				Document doc = db.parse(is);
				doc.getDocumentElement().normalize();
				NodeList nodeLst = doc.getElementsByTagName("client");
				user = new User();
				for (int s = 0; s < nodeLst.getLength(); s++) {
					Node fstNode = nodeLst.item(s);
					if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
						Element fstElmnt = (Element) fstNode;

						fstNmElmntLst = fstElmnt.getElementsByTagName("name");
						fstNmElmnt = (Element) fstNmElmntLst.item(0);
						fstNm = fstNmElmnt.getChildNodes();
						user.setUserName(((Node) fstNm.item(0)).getNodeValue());

						fstNmElmntLst = fstElmnt.getElementsByTagName("id");
						fstNmElmnt = (Element) fstNmElmntLst.item(0);
						fstNm = fstNmElmnt.getChildNodes();
						user.setUserId(((Node) fstNm.item(0)).getNodeValue());

						fstNmElmntLst = fstElmnt.getElementsByTagName("pass");
						fstNmElmnt = (Element) fstNmElmntLst.item(0);
						fstNm = fstNmElmnt.getChildNodes();
						String pw = CipherFactory.getCipher().hashWithKey(user.getUserId(), ((Node) fstNm.item(0)).getNodeValue());
						user.setUserPw(pw);

						fstNmElmntLst = fstElmnt.getElementsByTagName("category");
						fstNmElmnt = (Element) fstNmElmntLst.item(0);
						fstNm = fstNmElmnt.getChildNodes();
						user.setCategoryNo(((Node) fstNm.item(0)).getNodeValue());

						fstNmElmntLst = fstElmnt.getElementsByTagName("role");
						fstNmElmnt = (Element) fstNmElmntLst.item(0);
						fstNm = fstNmElmnt.getChildNodes();

					}
				}
			}

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			logger.error(e);
		} catch (SAXException e) {
			e.printStackTrace();
			logger.error(e);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(e);
		} catch (InvalidKeyException e) {
			e.printStackTrace();
			logger.error(e);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			logger.error(e);
		}








There is either a bug in the old JSF implementation or you configured the stuff the wrong way. First upgrade your JSF implementation to the latest available at their homepage (currently 1.2_10) and see if it solves the problem. If it doesn't, then please paste the new stacktrace here along with your faces-config.xml.


1.2 이전 버전에서 발견된 bug다.. 

2.0을 사용하면 될 것 같다.


PHP에서 DB에 부담을 줄 수 있는(즉 공격을 가할 수 있는) index를 받게 되면 자동으로 \ or ' 를 붙이게 된다.

그래서 숫자를 idx로 가지게 되면 stripslashes()라는 함수로 제대로 풀어주는게 좋다.

역시 30분간 헤맨끝에 찾았다...

A에서 url 링크로 post_no=8을 넘기게 되면

B에서 $post_no= $_GET[post_no]; 이 경우 $post_no 는 8이어야 하는데 '\8\' 이렇게 되는 것.

고로 답은 stripslashers()
Java에는 field에 대한 getter/setter가 존재한다. 

이런 식으로...

String name;

public void setName(String name){
     this.name = name;
}
public String getName(){
     return this.name;
}


PHP에도 비슷한게 있는데 getter/setter를 만들지 않고 java의 map 과 비슷한 방식으로 setter/getter를 사용한다. 근데 먼저 class내에서 변수가 맹글어지고 값이 들어가는걸 한번 살펴보고...

이렇게..

class Test{
     function __construct($name){
          $this->name = $name;
     }
}

클래스가 저렇게 있을때 field가 없다! 아무것도 없다! 만약 java에서라면 에러 팡팡 터진다. name이란 변수가 없으니까!!
근데 PHP는 에러가 안난다. 왜냐 name이 없으면 만들어버린다...(뭐지...)
우선 Test 클래스에는 __set()이 정의되어 있지 않다. PHP엔진은 __set()이 없으므로 자체적으로 __set()을 실행한다...
그래서 name이 없음에도 불구하고 name이란 변수에 값이 할당될 수 있다.


그러면 이제 __set()과 __get()을 어떻게 사용하는지 보고...
class Test{
     private $map;
     function __construct($name){
          $this->name = $name;
     }

     function __set($name, $value){
          $this->map[$name] = $value;
     }
     function __get($name){
          return $this->map[$name];
     }
}

대략적인 방식은 java의 map과 동일하다. key와 value로 구성된다.
클래스에 __set()과 __get()이 정의되어 있으면 PHP엔진은 정의된 set()과 get()을 먼저 호출한다.

class Test{
     private $map;
     function __construct($name){
		// 이렇게 해도되고...
		$this->name = $name;
     }

     function __set($name, $value){
		// 이렇게 해도 되고...
          $this->map[$name] = $value;
     }
     function __get($name){
          return $this->map[$name];
     }
}

$obj = new Test("ME");

$obj->__set("yeory", "yeory");

echo $obj->name."\n";    // ME
echo $obj->__get("yeory");  // yeory
?>


장단점.. ? 변수 선언과 값의 바인딩에 있어서 유연하다. 에러 볼일이 없다....
그러나.. 클래스내에 field가 없기 때문에 __set()하는 곳에서만 선언 이름을 알 수가 있다...
그래서 대부분 정해진 Object에서만 사용하는것 같다. 그 것이 아니라면 주석으로 어떤 이름으로 값이 set 되는지를 적던가..
이게 왜 안되는 걸까??

public function setDataList($obj){
		for($i=0; $i<($this->totalCount); $i++){
			$row = mysql_fetch_object($obj);
			$dataList[$i] = $row;
		}
	}

왜 대체 왜 안되는건데 - ... 물어봐야지... ㅋ

물어보았다... 그리고 해결되었다..
오 ㅐ 해결되었는지 모르겠다..

	public function setDataList($obj){
		for($i=0; $i<($this->totalCount); $i++){
			$row = mysql_fetch_object($obj);
			$dataList[] = $row;
		}
		$this->dataList = $dataList;
	}
아나.. 나 바본가... ?


	echo "<script> var frm = document.controller; 
	frm.action = '".$nextLocation."';
	frm.result.value = ".$dataList.";	
	frm.submit();	</script>";
php에도 jsp에서 사용하는 request.setAttribute가 있을거 같은데 어딧을까...
script를 통해서 객체를 넘기는건 없는데 말이야...

php는 request가 발생될때마다 life cycle이 request 요청시 살고 response 하고나면 죽는다.
그래서 페이지 이동시는 객체를 jsp 처럼 넘기기 어렵다...
라고 경험자가 알려주었다....



Parse error: syntax error, unexpected T_VARIABLE in /home/www/php/class/dao/BbsDaoImpl.php on line 34
이건 무슨 에러인가... 아래 소스에서 에러가 난다... 대충 password 키워드 아래에 있는 것... 뭐지...
$query .= " values('".$this->bbs->getGno()."', 'A', '".$this->bbs->getName()."', ";
		$query .= "password('".$this->bbs->getPasswd()."'), '".$this->bbs->getEmail()."', ";
		$query .= "'".$this->bbs->getHomepage()."', '"$this->bbs->getSubject()."', ";
		$query .= "'".$this->bbs->getContent()."', '".$this->bbs->getCreateDate()."', ";
		$query .= "'".$this->bbs->getClientIp()."', '".$this->bbs->getHtmlTag()."')";

이클립스로 코드 옮겨보니... 연산자 . 빠졋다.. 젠장
html에서 왜 php가 변환안되는지 몰랐었음.. 

  -> Apache 설정 중 php5.conf에 html 확장자가 없없음.

클래스를 선언하고 사용하는 것이 JAVA와 전혀 다름.
   -> 생성자에 매개변수로 값을 넘겨 해당 클래스의 지역번수로 값을 바인딩 했는데 다른 메서드에서 값이 없음;;

DB연결은 php가 설치된 곳에서 연결하기 때문에 host는 localhost가 되는 거임..
   -> 왜 DB 연결이 안되는가에 대한 개삽질의 결과물..

아직 삽질은 끝나지 않았다. 내일도 계속 될 것이여..
Tomcat의 console encoding 변경 방법.

시스템 인코딩과 톰캣 인코딩이 안맞아서 로그가 다 깨져버리는 경우
Server side 언어가 분명 한글로 처리하여 DB에 쿼리를 날리는데 한글이 다 깨져서 날아가는 경우.. 



1. window에서..

<Eclipse를 사용하는 경우>

 해당 부분을 바꿔주면 된다.

또는 해당 부분에 직접 적어줘도 된다. 
-Dfile.encoding=euc-kr  -Dclient.encoding.override=euc-kr



<이클립스를 사용하지 않는 경우, 즉 톰캣을 설치하여 직접 구동할 때>

마찬 가지로 해당 부분에 아래 옵션을 넣어준다.
-Dfile.encoding=euc-kr  -Dclient.encoding.override=euc-kr



참조할만한 사이트 : http://quri.egloos.com/1589989

+ Recent posts