'분류 전체보기'에 해당되는 글 418건
- 2009.12.22 Flex for XML and JSON 9
- 2009.12.18 Prototype.js 기본예제
- 2009.12.18 초간단 AJAX 샘플
- 2009.12.17 다음 영화 VS 맥스무비 분석 2
- 2009.12.14 [시장동향분석] 수도권 아파트 지역별 매매가 동향
- 2009.12.12 Changing the Flex ProgressBar from red -> green
- 2009.12.11 Creating full-screen Flex applications
- 2009.12.10 Using the Application.application.parameters 3
- 2009.12.10 Maths Functions including Random 1
- 2009.12.10 [Flex 3.3] DataGrid 에서 필요없는 스크롤바 없애는 방법
Beauty and brains. Flex and Java. Or is it the other way around? Who can say? What I know is that Flex and Java work really well together to create amazing Rich Internet applications (RIAs). What is Flex you ask? Flex is an open source framework that you can use to build Flash applications using the tags-based MXML language (along with ActionScript 3).
Watch: Flex for XML and JSON screen cast presented by Jack (Quicktime MOV, 33MB)
You can get started by downloading the Flex IDE, called Flex Builder, from the Adobe site (http://adobe.com/flex). Flex Builder is a commercial product, but it has a long free trial period that will give you enough time to figure out if it's worth your money. In this article, I'm going to demonstrate how to use Flex and Java together. Java will run the server. Flex will run on the client. The protocol between the two can really be anything you want. But in this case I'll use XML first, then use Javascript Object Notation (JSON), since both of those are the standards we are seeing the most in this Web 2.0 world.
Building the Server Piece
The XML example starts with the simple JSP file shown in Listing 1.
Listing 1. xml.jsp
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">
<jsp:directive.page import="java.text.*"/>
<jsp:directive.page import="java.lang.*"/>
<jsp:directive.page contentType="text/xml"/>
<days><jsp:scriptlet>
<![CDATA[
double compa = 1000.0;
double compb = 900.0;
for (int i = 0; i<=30; i++) {
compa += ( Math.random() * 100 ) - 50;
compb += ( Math.random() * 100 ) - 50;
]]>
</jsp:scriptlet>
<day>
<num><jsp:expression>i</jsp:expression></num>
<compa><jsp:expression>compa</jsp:expression></compa>
<compb><jsp:expression>compb</jsp:expression></compb>
</day>
<jsp:scriptlet>
<![CDATA[ }
]]>
</jsp:scriptlet>
</days>
</jsp:root>
This service exports some random stock data for two companies (compa and compb) for thirty days. The first company's value starts at $1000, the second at $900, and the JSP code applies a random factor each day to the values.
When I use the 'curl' client from my command line to access the service I get back something like what's shown below:
% curl "http://localhost:8080/jsp-examples/flexds/xml.jsp"
<days><day><num>0</num><compa>966.429108587301</compa>
<compb>920.7133933216961</compb>
</day>...</days>
The root tag is the <days> tag which includes a set of <day> tags. Each of these <day> tags has a <num> tag for the day number, a <compa> value for the stock price of company A, and a <compb> tag with the stock price from company B. The values of the two stock prices change with each request as they are randomly generated.
Building the Interface
Now that we have a web service that outputs stock prices, we need a client application to view it. The first one we will build is a grid style interface that simply shows the numbers. To create the Flex project, we select Flex Project from the New menu in the Flex Builder IDE. This is shown in Figure 1.
Figure -1. The ew Flex Project dialog
From here all we need to do is give the project a name. I'll call it xmldg for 'XML Data Grid.' This will create an xmldg.mxml file that has an
Listing 2. xmldg.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"> <mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData" /> <mx:Panel title="Stock Data" width="100%" height="100%"> <mx:DataGrid dataProvider="{stockData..day}" width="100%" height="100%"> <mx:columns>
<mx:DataGridColumn dataField="compa" /> <mx:DataGridColumn dataField="compb" /> </mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Application>
This xmldg application code has two primary components. The first is the <mx:XML> tag which tells Flex that there is an XML data source out there and gives it the URL. This will create a local variable called stockData (specified by the id attribute) which the <mx:DataGrid> component can use as a dataProvider.
The rest of the code is just interface. There is an <mx:Panel> object that gives a nice little wrapper around the grid. Then the <mx:DataGrid> object that shows the data. Within the <mx:DataGrid> is a set of <mx:DataGridColumn> specification objects which tells the grid what data to show.
When we launch this from Flex Builder we should see something like what is shown in Figure 2.
Figure -2. The xmldg application in action
From here we can scroll the list, resize the window, and watch the data grid change size.
To add a little filtering capability, we will update the code with an <mx:HSlider> control, a horizontal slider, which will specify on which day the grid should start the data display.
For example, if we set the slider to 6 it will only show data from day 6 onward. The code for this is shown in Listing 3.
Listing 3. xmldg2.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData" />
<mx:Panel title="Stock Data" width="100%" height="100%" layout="vertical"
paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10"> <mx:HBox>
<mx:Label text="Start Day" />
<mx:HSlider minimum="0" maximum="30" id="dayslider" snapInterval="1" />
</mx:HBox>
<mx:DataGrid dataProvider="{stockData..day.(num >= daySlider.value )}" width="100%" height="100%"> <mx:columns>
<mx:DataGridColumn dataField="num" headerText="day" /> <mx:DataGridColumn dataField=="compa" headerText="Company A" /> <mx:DataGridColumn dataField=="compb" headerText="Company B" /> </mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Application>
There are a few more tags, but the story remains much the same. There is an <mx:Panel> tag that contains everything. Within that is an <mx:HBox> (horizontal box) tag that includes an <mx:Label> and the <mx:HSlider> control. The slider is used in the dataProvider field of the <mx:DataGrid>.
Let's have a closer look at the dataProvider attribute:
{stockData..day.(num >= daySlider.value )}
This is using ActionScript's E4X syntax to pare down the data set to the <mx:DataGrid>control to only those tags where the <num> value in the data is greater than or equal to the slider value. Flex is smart enough to watch for the change events that come from the slider to automatically update the data grid for us.
When we bring this up from Flex Builder it looks like what is shown in Figure 3.
Figure -3. The filterable grid
From here we can adjust the slider and see how that affects the data in the grid. Figure 4 shows what happens when I set the slider to 12.
Figure -4. The slider set to 12 on the data grid
This is just a simple example of what can be done using E4X in ActionScript. The E4X syntax makes dealing with XML so easy to do that you'll never want to deal with XML any other way.
Graphing
Data grids are a bit boring, at least to me. I'm a visual guy. So let's put a graph on this thing. To do that, we create a new project called xmlgph(for XML graph) and replace the xmlgph.mxml file that is created with the code in Listing 4.
Listing 4. xmlgph.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData" />
<mx:Panel title="Stock Data" width="100%" height="100%" layout="vertical"
paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10">
<mx:HBox>
<mx:Label text="Start Day" />
<mx:HSlider? minimum="0" maximum="30" id="dayslider" snapInterval="1" />
</mx:HBox>
<mx:LineChart id="chart" dataProvider="{stockData..day.(num >= daySlider.value )}"
width="100%" height="100%">
<mx:series>
<mx:LineSeries xField="num" yField="compa" displayName="Company A" />
<mx:LineSeries xField="num" yField="compb" displayName="Company B" />
</mx:series>
</mx:LineChart>
<mx:Legend dataProvider="{chart}" /> </mx:Panel>
</mx:Application>
This code is exactly like xmldg2, but the <mx:DataGrid> control has been replaced by an <mx:LineChart> control that will display a chart of the values instead of a grid. There is also an <mx:Legend> control that will display the names of the company associated with each color of line. The two <mx:LineSeries> objects are the charting equivalent of the <mx:DataGridColumn> objects. These let the line chart know what data to display on which axis.
When we launch this from Flex Builder we should see something like what is shown Figure 5.
Figure -5. The Line Chart example
Not bad, huh? And because the <x:HSlider> control is still around, we can change the starting day of the graph just by moving the slider.
In fact, with a few small changes we can allow for the graph to show a 'window' of days by providing users with two thumbs in the slider that they can move independently. The code for this is shown in Listing 5.
Listing 5. xmlgph2.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:XML source="http://localhost:8080/jsp-examples/flexds/xml.jsp" id="stockData " />
<mx:Panel title="Stock Data " width="100% " height="100% " layout="vertical "
paddingBottom="10 " paddingLeft="10 " paddingRight="10 " paddingTop="10 ">
<mx:HBox>
<mx:Label text="Date Range " />
<mx:HSlider minimum="0 " maximum="30 " id="daySlider " snapInterval="1 "
thumbCount="2 " values="[0,30] " />
</mx:HBox>
<mx:LineChart id="chart"
dataProvider="{stockData..day.(num>=daySlider.values[0] &&
num<=daySlider.values[1])}"
width="100%" height="100%">
<mx:series>
<mx:LineSeries xField="num" yField="compa" displayName="Company A" />
<mx:LineSeries xField="num" yField="compb" displayName="Company B" />
</mx:series>
</mx:LineChart>
<mx:Legend dataProvider="{chart}" /> </mx:Panel>
</mx:Application>
All we have done is add the thumbCount and values attributes to the <mx:HSlider> tag, and updated the dataProvider in the <mx:DataGrid> tag. Because this is XML, I had to encode some of the entities in the dataProvider. When we run this from Flex Builder we see something like Figure 6.
Figure -6. The windowed line chart
That about does it for the XML portion of the demonstration. From here I'll show you how to build a Flex application that consumes JSON services.
Building the JSON Server
Creating the JSON reading application starts with creating a JSON data source. Once again, we'll fall back on trusty JSP to build the JSON encoded data stream. The JSP code for the server is shown in Listing 6.
Listing 6. json.jsp
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">
<jsp:directive.page import="java.text.*"/>
<jsp:directive.page import="java.lang.*"/>
<jsp:directive.page contentType="text/json"/>
[<jsp:scriptlet>
<![CDATA[
double compa = 1000.0;
double compb = 900.0;
for (int i = 0; i<=30; i++) {
compa += ( Math.random() * 100 ) - 50;
compb += ( Math.random() * 100 ) - 50;
if ( i > 0 ) out.print( "," );
]]> </jsp:scriptlet>{"compa":<jsp:expression>compa</jsp:expression>,"compb":<jsp:expres
sion>compb</jsp:expression>}<jsp:scriptlet>
<![CDATA[ }
]]>
</jsp:scriptlet>]
</jsp:root>
This is exactly like the XML service, but instead of creating XML tags we create JSON encoded data.
When I run the 'curl' utility from the command line to get the page it looks like:
% curl "http://localhost:8080/jsp-examples/flexds/json.jsp"
[{"compa":992.2139849199265,"compb":939.89135379532}, ...]
That's just the kind of thing that a Javascript client would love to see.
Consuming JSON Services
Flex is written in ActionScript 3, the programming language of the Flash player. It's similar to Javascript, but it lacks the eval function. So how do we turn JSON text into ActionScript data? Thankfully, the free ActionScript 3 core library (http://as3corelib.googlecode.com) comes with both a JSON decoder and a JSON encoder installed.
The code in Listing 7 shows the JSONDecoder object in action.
Listing 7. jsondg.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
creationComplete="jsonservice.send()">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import com.adobe.serialization.json.JSONDecoder;
private function onJSONResult( event:ResultEvent ) : void {
var data:String = event.result.toString();
data = data.replace( /\s/g, '' );
var jd:JSONDecoder = new JSONDecoder( data );
dg.dataProvider = jd.getValue();
}
]]>
</mx:Script>
<mx:HTTPService id="jsonservice"
url="http://localhost:8080/jsp-examples/flexds/json.jsp"
resultFormat="text" result="onJSONResult(event)" />
<mx:Panel title="Stock Data " width="100% " height="100% ">
<mx:DataGrid id="dg" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="compa " />
<mx:DataGridColumn dataField="compb " /> </mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Application>
Because the server is returning JSON as text, we can't use the <mx:XML> tag to get the data. So we use the <mx:HTTPService>> tag instead. It works a lot like the <mx:XML> tag. You give it a URL of the service, and then tell it the result format (i.e. text) and the ActionScript function to call when the HTTP service replies with the data.
In this case, I set the result function to the onJSONResult
code that I specify in the <mx:Script> tag. This method takes out any whitespace and passes the JSON text onto the JSONDecoder
object. It then sets the dataProvider
on the <mx:DataGrid> control to the value returned from the JSONDecoder
.
All of this is completely secure because ActionScript has no eval
function. The JSONDecoder
class is a simple state machine parser that builds objects from the text on the fly. In the worst case, it might just take a long time if the JSON text is too large.
Where to Go from Here
Flex is based on Flash, and Flash can talk to just about anything. It can talk directly to SOAP-based web services. It can even talk binary with protocols such as the Adobe Message Format (AMF).
If this is your first time using Flex, you might want to look into using Flex to build a Flash widget that you can post on your site to present data in a visually attractive way. To make sure that the Flash application is small enough to make for a fast download, be sure to make use of the Runtime Shared Library (RSL) functionality in the new Flash player. This allows you to cache big libraries (like the Flex library) in the client and then reuse them between different Flash applications.
Flex and Java are a strong team. Java provides excellent backend support on the server. And Flex along with ActionScript 3, provide a common cross-platform GUI layer that is easy to write and easy to adopt.
Prototype.js 기본예제
기본예제 | 레퍼런스 | 코드 크게 | 소스 보이기 | 예제 숨기기 | 실행 보이기 |
prototype.js는 무엇인가?
prototype.js는 Sam Stephenson에 의해 작성된 자바스크립트 라이브러리입니다. 이 라이브러리는 매우 훌륭하게 작성된 표준기반의 코드로, 웹2.0의 특성을 나타내는 풍부한 기능과 상호작용을 필요로 하는 웹페이지를 생성하는데 개발자의 부담을 한층 덜어줄 것입니다. prototype.js는 String, Array, Event 등과 같은 표준 자바스크립트 객체들에 대한 확장과 Ajax, Enumerable, Hash, Form, Element 등 다양한 신규 객체들을 제공하고 있습니다. 또한 자바스크립트 프로그래밍에서 흔하게 사용되어지는 기능들에 대한 유틸리티 함수도 제공합니다.
prototype.js는 현재 웹어플리케이션 프로토타입 개발용으로 많은 관심을 받고있는 프레임워크인 RubyOnRails에 통합되어 있으며, script.aculo.us, Rico 등과 같은 다양한 자바스크립트 프레임워크에서도 라이브러리 형태로 사용되어지고 있습니다. Ruby 프로그래밍 언어에 친숙한 개발자는 Ruby의 내장 클래스와 이 라이브러리에 의해 구현된 구문 사이에 많은 유사성이 있음을 알게 될 것입니다.
유틸리티 함수
prototype.js는 미리 정의된 다양한 객체와 유틸리티 함수를 가지고 있습니다. 아래 유틸리티 함수들은 자바스크립트 프로그래밍에서 반복적인 타이핑과 어구를 줄이는데 유용하게 쓰입니다.
$() 함수
$() 함수는 매우 빈번하게 사용되는 DOM의 document.getElementById() 함수에 대한 편리한 단축함수입니다. DOM 함수처럼, 이것은 인자로 던져진 id를 가진 해당 엘리먼트를 반환합니다. 하지만 DOM함수와는 달리, 이것은 여러개의 id를 사용할수 있는데, 이 경우에 $()는 요청된 엘리먼트들을 가진 Array 객체를 반환하게 됩니다. 이 함수의 다른 장점으로 id 문자열이나 엘리먼트객체 자체를 인자로 가질 수 있는데, 이것은 인자 형태를 가질수 있는 다른 함수를 생성할 때 매우 유용하게 사용되어 질 수 있습니다.
소스: base.js
function $() { var elements = new Array(); for (var i = 0; i < arguments.length; i++) { var element = arguments[i]; if (typeof element == 'string') element = document.getElementById(element); if (arguments.length == 1) return element; elements.push(element); } return elements; } |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Sample</title> <script src="prototype.js" type="text/javascript"></script> </head> <body> <script> //<![CDATA[ function test1() { var d = $('myDiv1'); alert(d.innerHTML); } function test2() { var divs = $('myDiv1','myDiv2'); for(i = 0; i < divs.length; i++) { alert(divs[i].innerHTML); } } //]]> </script> <div id="myDiv1"> <p>This is a paragraph</p> </div> <div id="myDiv2"> <p>This is another paragraph</p> </div> <input type="button" value="Test1" onclick="test1();" /> <input type="button" value="Test2" onclick="test2();" /> </body> </html> |
실행 |
$F() 함수
$F() 함수는 또다른 유용한 단축함수로, 텍스트박스나 드랍다운 리스트와 같은 입력 컨트롤의 값을 반환합니다. 이 함수는 엘리먼트 id나 엘리먼트객체 자체를 인자로 가질수 있습니다.
소스: form.js
var $F = Form.Element.getValue; |
<script>
function test3() {
alert($F('userName'));
}
</script>
<input type="text" id="userName" value="Joe Doe" />
<input type="button" value="Test3" onclick="test3();" /> |
실행 |
$A() 함수
$A() 함수는 전달된 한 개의 인자를 배열로 변환합니다. Array 클래스에 대한 확장으로 이 함수는 열거가능한 목록이라면 그것을 쉽게 배열로 변환할 수 있습니다. 예를 들면, DOM 객체의 NodeLists를 효과적으로 배열로 바꾸는데 유용하게 쓰일 수 있습니다.
소스: array.js
var $A = Array.from = function(iterable) { if (!iterable) return []; if (iterable.toArray) { return iterable.toArray(); } else { var results = []; for (var i = 0; i < iterable.length; i++) results.push(iterable[i]); return results; } } |
<script>
function showOptions() {
var someNodeList = $('lstEmployees').getElementsByTagName('option');
var nodes = $A(someNodeList);
nodes.each(function(node) {
alert(node.nodeName + ': ' + node.innerHTML);
});
}
</script>
<select id="lstEmployees" size="5">
<option value="5">Buchanan, Steven</option>
<option value="8">Callahan, Laura</option>
<option value="1">Davolio, Nancy</option>
</select>
<input type="button" value="Show the options" onclick="showOptions();" /> |
실행 |
$H() 함수
$H() 함수는 결합된 배열을 열거할수 있는 Hash 객체로 변환합니다.
소스: hash.js
function $H(object) { var hash = Object.extend({}, object || {}); Object.extend(hash, Enumerable); Object.extend(hash, Hash); return hash; } |
<script>
function testHash() {
var a = {
first: 10,
second: 20,
third: 30
};
var h = $H(a);
alert(h.toQueryString());
}
</script>
<input type="button" value="Test Hash" onclick="testHash();" /> |
실행 |
$R() 함수
$R() 함수는 new ObjectRange(lowerBound, upperBound, excludeBounds)과 동일한 단축함수입니다. 이 클래스의 완전한 설명을 보기 위해 ObjectRange 클래스 문서를 참고하십시요. each 메소드를 통해 반복(iterators)의 사용법을 보여주는 간단한 예제입니다. 더 많은 메소드는 Enumerable 클래스 문서에서 볼수 있을 것입니다.
소스: range.js
var $R = function(start, end, exclusive) { return new ObjectRange(start, end, exclusive); } |
<script>
function demoDollar_R(){
var range = $R(10, 20, false);
range.each(function(value, index){
alert(value);
});
}
</script>
<input type="button" value="Sample Count" onclick="demoDollar_R();" /> |
실행 |
Try.these() 함수
Try.these() 함수는 인자처럼 많은 수의 함수를 가지고 그것들을 순서대로 차례차례 호출하도록 해줍니다. 이것은 지정된 함수들 중 하나가 성공적인 함수호출의 결과를 반환할때까지 순차적으로 함수를 수행하게 됩니다. 예를 들면, 브라우저간에 서로 다른 객체를 검사햐여 사용해야 할 경우 등에 유용하게 사용될 수 있습니다.
소스: base.js
var Try = { these: function() { var returnValue; for (var i = 0; i < arguments.length; i++) { var lambda = arguments[i]; try { returnValue = lambda(); break; } catch (e) {} } return returnValue; } } |
<script> function getValue(){ var divA = document.getElementById('divA'); return Try.these( function() { alert('function 1'); throw 'error'; }, function() { alert('function 2'); return divA.undefined.property; }, function() { alert('function 3'); return divA.innerHTML;}, function() { alert('function 4'); return 'not reached';} ); } </script> <div id="divA">This is some text</div> <input type="button" value="Test Try.these()" onclick="alert(getValue());" /> |
실행 |
Ajax 객체
위에서 언급된 유틸리티 함수들은 좋지만, 그것들은 대부분 고급 형태는 아닙니다. 대부분의 개발자은 자신만의 유사한 함수를 이미 가지고 있을수도 있습니다. 이러한 함수들은 단지 일부분에 해당되는 팁일뿐입니다.
웹2.0의 추세에 맞추어 많은 개발자들이 AJAX 기능에 관심을 가지고 있습니다. prototype.js은 AJAX 로직을 수행할 필요가 있을때 좀더 쉽게 사용하도록 도와주는 라이브러리 제공하고 있습니다. 이 라이브러리가 제공하고 있는 Ajax 객체는 AJAX 함수를 작성할 때 포함되는 트릭성격의 코드를 포장하고 단순화하기 위한 미리 정의된 객체입니다. 이 객체는 캡슐화된 AJAX 로직을 제공하는 많은 수의 클래스를 포함하고 있습니다. 그 클래스 중에 몇 개를 살펴봅니다.
Ajax.Request 클래스 사용하기
만약 개발자가 어떠한 헬퍼(helper) 라이브러리도 사용하지 않는다면, XMLHttpRequest 객체를 생성하기 위한 많은 코드를 작성할 것이고, 비동기적인 요청과 응답 처리를 반복적이고 기교을 요하는 코드를 매번 작성해야 합니다. 또한 다양한 버전의 브라우저를 지원하기 위한 부분도 처리를 해야 합니다.
이러한 AJAX 기능을 지원하기 위해, 라이브러리는 Ajax.Request 클래스를 정의하고 있습니다. 만약 특정 URL을 통해 XML 응답을 반환하는 서버 어플리케이션을 가지고 있다면, XML을 가져오기 위해 서버와 통신하는 것은 Ajax.Request 객체를 통해 쉽게 구현할 수 있습니다.
<script> function searchByAjax() { var usrkey = $F('usrkey'); if (usrkey == '') return; var url = 'http://yourserver/app/stocks.php'; var pars = 'usrkey=' + encodeURIComponent(usrkey.toUpperCase()); |
실행 |
Ajax.Request 객체의 생성자의 두번째 파라미터인 { method: 'get', parameters: pars, onComplete: showResponse }은 문자적 표기법(JSON이라고도 함)으로 나타낸 익명(anonymous) 객체입니다. 이것이 의미하는 것은 'get' 문자열을 갖는 method 프라퍼티와 HTTP 요청 쿼리문자열을 포함하는 parameters 프라퍼티, 그리고 함수 showResponse를 포함하는 onComplete 프라퍼티(메소드)를 가지는 객체를 전달한다는 것입니다. 이 파라미터는 AJAX 호출을 위한 옵션을 정의하고 있습니다. 예제에서 HTTP GET명령을 통해 첫번째 인자에서 URL을 호출하고, 변수 pars내 포함된 쿼리문자열을 전달합니다. Ajax.Request 객체는 서버측으로부터의 응답을 받은 후에 showResponse 함수를 호출할 것입니다. AJAX를 비동기적 또는 동기적으로 서버에 호출하려면, asynchronous 옵션을 true 또는 false로 주면 됩니다(디폴트 값은 true입니다). 이와 같은 이 객체내에서 정의하고 활성화시킬수 있는 다른 프라퍼티를 참조하려면 options 인자 객체를 참조하십시요.
XMLHttpRequest는 HTTP 호출을 하는 동안 진행과정을 알려주는데, Loading, Loaded, Interactive, 또는 Complete 4가지의 단계가 있습니다. Complete는 가장 공통적인 단계인데, 어드 단계에서든 Ajax.Request 객체가 사용자정의 함수를 호출할 수 있게 만들수 있습니다. 함수를 객체에게 알리기 위해, 예제의 onComplete처럼 요청 옵션내 onXXXXX로 명명된 프라퍼티(메소드)를 간단히 지정하면 됩니다. 더블어 결과를 처리하기 위해 사용될 수 있는 두개의 다른 흥미로운 옵션이 있는데, AJAX 호출이 에러없이 수행될 때 호출될 함수를 onSuccess 옵션에 명시하고, 서버에러가 발생할 때 호출될 함수는 onFailure 옵션에 지정할 수 있습니다.
prototype.js 1.4.0 버전에서는 새로운 형태의 이벤트 콜백 핸들링이 도입되었습니다. 만약 AJAX 호출이 발생하는데도 불구하고 특정 이벤트를 위해 수행되어야 하는 코드가 있다면, Ajax.Responders 객체를 사용할 수 있습니다. 에를 들면 AJAX 호출이 진행중이라는 시각적 표시를 보여줘야 하는 경우를 가정해 봅시다. 두개의 전역 이벤트 핸들러를 사용할 수 있는데, 하나는 처음 호출이 시작되었을때 아이콘을 보여주는 것이고, 다른 하나는 끝났을 때 아이콘을 숨기는 것입니다.
<script> function searchByAjax() { var usrkey = $F('usrkey'); if (usrkey == '') return; var url = 'http://yourserver/app/stocks.php'; var pars = 'sleep=1&usrkey=' + encodeURIComponent(usrkey.toUpperCase()); var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: showResponse }); } function showResponse(originalRequest) { $('result').innerHTML = '<pre>'+ originalRequest.responseText + '</pre>'; } |
실행 |
Ajax.Updater 클래스 사용하기
만약 이미 작성된 HTML을 문서를 서버측으로부터 얻을 수 있고, 그 HTML을 가지고 페이지내의 특정 부분을 바꾸고 싶다면, Ajax.Updater 클래스를 사용하여 작업을 쉽게 할 수 있습니다. 이 클래스를 이용하여 어느 엘리먼트가 AJAX 호출로부터 반환된 HTML을 채우는지만 알려주면 됩니다. 예제를 보면 코드는 onComplete 함수와 생성자에 전달된 엘리먼트 id를 제외하고 이전 예제에 비해서 매우 간단합니다.
<script> function getHTML() { var url = 'http://yourserver/app/sample_html.php'; var pars = 'someParameter=ABC'; |
실행 |
클라이언트에서 서버 에러들을 다루는 것이 어떻게 가능한지 보기 위해 코드를 조금 변경해 봅시다. 에러 보고를 위한 함수를 명시하고, onFailure 옵션을 추가합니다. 참고적으로 성공할 때와 에러가 발생할 경우 각각 업데이트될 엘리먼트(예제의 placeholder)를 구분하기 위해서, 첫번째 파라미터를 단순 엘리먼트 id에서 2개의 프로퍼티(success-모든것이 정상적일때 사용, failure-어떤것이 실패일때 사용)를 가지는 익명 객체로 변경할 수 있습니다. 이 경우에는 성공시와 오류시 각각 지정된 영역에 업데이트 될 것입니다. 다음 예제에서 failure 프라퍼티를 사용하지 않고, onFailure 옵션에서 reportError 함수를 사용하고 있습니다.
<script> function getHTML() { var url = 'http://yourserver/app/sample_html.php'; var pars = 'someParameter=ABC'; var myAjax = new Ajax.Updater( { success: 'placeholder' }, url, { method: 'get', parameters: pars, onFailure: reportError, evalScripts: true }); } |
실행 |
만약 서버 로직이 HTML 마크업과 함께 자바스크립트 코드도 반환한다면, Ajax.Updater 객체는 이 자바스크립트 코드를 evaluation 할 수 있습니다. 자바스크립트 응답을 처리하기 위해서는 객체 생성자의 마지막 인자로 프라퍼티들의 목록에 evalScripts: true;를 간단히 추가하면 됩니다. 하지만 여기에 주의해야 할 점이 있습니다. 이러한 스크립트 블럭은 본 페이지의 스크립트에 추가되지는 않을 것입니다. 아래 예제는 서버로부터 얻어온 스크립트를 포함한 HTML 인데, 스크립트 블럭에서 sayHello1 이라는 함수를 생성하지 않을 것입니다. 함수를 정상적으로 생성시키기 위해서는 sayHello2 처럼 함수생성 코드를 변경할 필요가 있습니다. 추가적으로 함수 선언을 위해 var 키워드를 사용하면 스크립트 블럭에 지역화될 함수 객체를 생성하게 되므로, 함수 객체가 window 범위에서 작동하도록 var 키워드를 사용하지 않습니다.
/* HTML from AJAX call */ <script> // sayHello1() won't work in AJAX call. function sayHello1() { alert('Hello 1'); } // sayHello2() will work in AJAX call. |
실행 |
Ajax.PeriodicalUpdater 클래스 사용하기
또 다른 유용한 클래스로, AJAX 호출을 일정한 주기로 반복해서 호출을 해야 할 경우에 유용하게 사용될 수 있는 Ajax.PeriodicalUpdater 클래스를 제공하고 있습니다.
<script>
function getNumber() {
var url = 'http://yourserver/app/sample_number.php';
var pars = 'someParameter=ABC';
var myAjax = new Ajax.PeriodicalUpdater(
'placeholder',
url,
{
method: 'get',
parameters: pars,
frequency: 2
});
}
</script>
<input type="button" value="Get Number" onclick="getNumber()" />
<p><div id="placeholder"></div></p> |
실행 |
Enumerating
프로그래머에게 루프(loop)에 친숙합니다. 잘 알다시피, 배열을 생성하고, 같은 종류의 엘리먼트로 채우고, for, foreach, while, repeat 등과 같은 루프 제어문을 생성하고, 숫자로 된 인덱스를 통해 순차적으로 각각의 엘리먼트에 접근하고, 그 엘리먼트로 작업을 수행합니다. 언제나 코드에 배열을 가지고 루프내 배열을 사용할 것이라는 것을 의미합니다. 이러한 반복을 다루기 위해 좀더 많은 기능을 가진 배열 객체가 있다면 좋지 않겠습니까? 사실, 많은 프로그래밍 언어는 배열이나 유사한 구조(collection과 list와 같은)에서 이러한 기능을 제공하고 있습니다.
prototype.js는 반복 가능한 데이터를 다룰때 사용하도록 구현된 Enumerable 객체를 제공합니다. 이 라이브러리는 더 나아가 Enumerable의 모든 메소드로 Array 클래스를 확장합니다.
루프, 루비-스타일
표준 자바스크립트에서 배열의 엘리먼트를 순차적으로 표시할 경우, 예제의 showList1처럼 작성할 수 있습니다. prototype.js를 사용하면, 루비 언어와 유사한 구문을 사용하여 showList2와 같이 작성할 수 있습니다. each 메소드에 대한 인자처럼 전달되는 이 함수는 보았습니까? 이것을 반복자(iterator) 함수라 합니다.
<script> var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Meg']; // using standard javascript function showList1(){ |
실행 |
강력해진 배열
일반적으로 한 배열내의 모든 엘리먼트들은 같은 프라퍼티와 메소드를 가진 동일 종류입니다. 예제의 새로운 배열을 가지고 iterator 함수의 장점을 살펴봅시다.
<script> function findEmployeeById(emp_id){ var listBox = $('lstEmployees') var options = listBox.getElementsByTagName('option'); options = $A(options); |
실행 |
다음 예제는 배열의 각 항목을 필터링하여 원하는 멤버만 가져오는 것입니다.
<script> function showHttpLinks(paragraph) { paragraph = $(paragraph); var links = $A(paragraph.getElementsByTagName('a')); //find links that start with 'http' var localLinks = links.findAll( function(link) { var start = link.href.substring(0,4); return start == 'http'; }); //now the link texts var texts = localLinks.pluck('innerHTML'); //get them in a single string var result = texts.inspect(); alert(result); } </script> <p id="someText"> This <a href="http://somesite.com">text</a> has a <a href="ftp://someftp.com">lot</a> of <a href="http://othersite.com">links</a>. Some are <a href="http://wherever.com/page.html">http links</a> and others are <a href="ftp://otherftp.com">ftp links</a>. </p> <input type="button" value="Find Http Links" onclick="showHttpLinks('someText')" /> |
실행 |
간단하게 테스트 할 수 있는 샘플이다.
<html>
<head>
<title>Simple Ajax Example</title>
<script language="Javascript">
function xmlhttpPost(strURL) {
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
updatepage(self.xmlHttpReq.responseText);
}
}
self.xmlHttpReq.send(getquerystring());
}
function getquerystring() {
var form = document.forms['f1'];
var word = form.word.value;
qstr = 'w=' + escape(word); // NOTE: no '?' before querystring
return qstr;
}
function updatepage(str){
document.getElementById("result").innerHTML = str;
}
</script>
</head>
<form name="f1">
<p>word: <input name="word" type="text">
<input value="Go" type="button" onclick='JavaScript:xmlhttpPost("/cgi-bin/simple-ajax-example.cgi")'></p>
<div id="result"></div>
</form>
</body>
</html>
저는 매일 접속하는 맥스무비와 다음 영화를 비교해봤어요.
<다음 영화>
1. 다음 영화 메뉴구성 & 메인페이지
메뉴 구성
다음 영화에는 영화홈, 영화정보, TV정보, 리뷰, 스타존, 포토존, 이벤트, 예매, 인기순위, 영화마니아 이렇게 10개의 메뉴가 있어요.
메인 페이지 구성
화면 상단에는 현재 상영영화가 4개, 사람들이 흥미를 끌 수 있을만한 기사, 박스오피스가 6위까지 뜨고요..
박스오피스 아래에는 예매순위와 네티즌 평점이 뜬답니다.
화면 중간에는 공감! 네티즌 리뷰가 있는데 최신 개봉작 3작품에 대해 네티즌들의 리뷰가 드러나있어요. 주목! 무비스타,
추천동영상, 시사.이벤트, 모여라! 영화마니아, 오늘의 영화뉴스, 네티즌 투표가 있으며
화면 하단에는 영화인 BEST, 영화 BEST, 예고편 BEST, 다운로드 BEST가 노출되죠.
다음 뮤직에 비해 화면 구성이 깔끔한 편이라 러셀의 마음에 쏙 들어요! 특히 필름모양으로 해놔서 시선을 끄는 화면 상단과
영화관련 BEST가 있는 하단에 눈길이 확 가네요!
메뉴가 굉장히 많긴 하지만 전부 네모난 틀에 들어있는 느낌이랄까요, 그래서 정리가 돼있는 것 같은 느낌이네요.
개인화 서비스 여부& 제안
하지만 대부분의 사이트에 있는 My 영화와 같은 메뉴가 전혀 없다는 점이 아쉽네요.
사실 영화 예매권을 등록하려고 해도 My 메뉴나 영화 예매권 등록 메뉴가 전혀 없어서
헤매다 예매 메뉴를 통해 등록해야했던 경험이 있거든요.
다운로드 왼쪽에 My 영화 메뉴를 만들어서 영화 예매 내역,
이벤트 신청.당첨 내역, 자주 가는 영화관 관리, 좋아하는 영화장르 관리,
내가 쓴 영화 리뷰 관리 등을 서비스 했으면 좋겠어요.
2. 다음 영화 영화정보
다음 영화 영화정보엔 현재 상영영화와 극장시간표, TV방영영화 편성표가 제일 상단에 위치하고 있어요.
예매를 위해 영화정보를 찾는 사람들로선 현재 상영중인 영화가 제일 먼저 눈에 뜨이기에 참 좋은 구성입니다.
그 외에도 오늘의 영화뉴스, 추천 동영상, 이번주 뭘 볼까, 추천 영화포토가 있구요.
마니아들을 위한 추천영화, 전문매거진, 마니아를 위한 정보도 볼 수 있습니다.
개인화 서비스 여부& 제안
하지만 마니아를 위한 정보만 개인화 서비스에 해당하고
다른 부분에서는 전혀 개인화 서비스를 찾아볼 수 없어서 아쉽습니다.
장르별 현재상영영화 추천도 진행되었으면 좋겠네요.
여기서 극장 시간표를 검색해볼까요?
상영시간표 조회를 누르면 예매 메뉴로 넘어갑니다.
yes 24, CGV 전용 예매로 나뉘어서 전 yes24예매로 들어와봤습니다.
지역→극장→날짜 순의 스텝으로 선택을 해야 시간표를 볼 수 있네요.
별 것 아닌것 같지만 사실 귀찮은 작업이기도 합니다.
우리나라에 영화관이 한, 두개 있는게 아니거든요.
그래서 yes24의 예매 시스템을 사용하는 점에 착안,
다음 회원이 yes24 회원일 경우 정보를 연동해
다음에서도 선호 영화관을 바로볼 수 있었으면 좋겠어요.
3. 다음 영화 TV정보
다음 영화 TV 정보에는 TV 가이드, 인기 프로그램, 공중파 시청률, 편성표, 프로그램 인기를 장르별,
채널별로 볼 수 있습니다. TV정보 메인페이지는 정말 깔끔해서 마음에 듭니다.
불필요한 텍스트를 최대한 줄이고 이미지 위주로 노출시킴으로써
효과적으로 눈길을 사로잡습니다.
개인화 서비스 여부& 제안
하지만 여기서도 개인화 서비스는 찾아볼 수 없습니다.
추천 프로그램은 현재 상영중인 인기 프로그램에 국한됩니다.
TV정보에서도 미리 좋아하는 장르나 채널을 설정해놓으면 TV정보 메인에서도
개인별 좋아하는 장르 추천작을 볼 수 있으면 좋겠어요.
4. 다음 영화 리뷰
다음 영화 리뷰는 네티즌, 블로거, 미디어 리뷰와
평점& 100자평, 전문가 20자평으로 구성되어있어요.
메인에는 최다 추천, 최다 댓글 네티즌 리뷰가 제일 상단에 노출되요.
하지만 영화정보, TV정보에 비하면 좀 지저분한 느낌이 드네요.
아무래도 리뷰 페이지라 텍스트가 많아서 그런 것 같아요^^
개인화 서비스 여부& 제안
리뷰 메뉴에는 자신이 여태까지 쓴 리뷰와 평들을 전부
볼 수 있는 개인화 서비스를 제공했으면 좋겠어요.
사실 제가 쓴 글들을 한꺼번에 보고 싶고,
또 다음 사이트가 아닌 다른데에서 사용해야 할 경우도 있는데 일일이 검색하기엔 번거롭기 때문이죠.
5. 다음 영화 스타존
스타존은 헐리우드 스타, 한중일 스타, 무비 갤러리, 드라마 갤러리,
영화인 100자평, 영화 속 명대사, 네티즌 투표로 메뉴가 구성되어 있습니다.
제일 아래엔 스타 갤러리가 국내스타/해외스타로 구분되어 있네요.
스타존도 텍스트보단 이미지가 많아 깔끔한 편이네요.
개인화 서비스 여부& 제안
스타존을 이용하면서 스타 갤러리가 굉장히 발전 가능성이 있다고 생각했습니다.
우선은 네티즌들의 청원을 통해 다음에서 스타 갤러리를 만들어주는
유저들의 기호에 맞추는 점이 좋았어요.
하지만 기왕이면 내가 좋아하는 스타를 설정해놓고,
메인에서 그 스타갤의 베스트 게시물들을 볼 수 있으면 더 좋지 않을까 생각되네요.
6. 다음 영화 포토존
다음 영화의 포토존은 포토존 홈, 명장면 키워드, 포토컬렉션 인기포토로 구성되어있어요.
그 중 명장면 키워드가 인상적인 메뉴예요.
포토존도 이미지가 많아서 굉장히 깔끔한 구성을 보이네요.
다만 키워드가 너무 적다는 흠이 있네요.
개인화 서비스 여부& 제안
포토존의 경우 딱히 개인화 서비스가 떠오르지 않네요.
스타존과 마찬가지로 좋아하는 스타를 설정해 놓으면
메인에서 그 스타의 베스트 사진들을 볼 수 있게 하는 정도?
7. 다음 영화 이벤트
이벤트 페이지의 경우 진행중 이벤트, 결과발표, 시사회권 나눔터, 이벤트 Q&A로 구성되어 있어요.
진행중 이벤트 아래에 바로 결과 발표가 있어 응모와 확인이 한 번에 가능하다는 장점이 잇구요.
진행중 이벤트는 전체, 시사회, 예매권, 경품으로 나눠져있어서
원하는 종류에 따라 이벤트 응모가 가능해서 좋네요.
개인화 서비스 여부& 제안
이벤트는 My 이벤트 혹은 좋아하는 장르, 종아하는 배우 관련 이벤트 정도가 나올 수 있겠네요.
8. 다음 영화 예매
다음 영화 예매는 앞서 다뤘듯이 yes24와 CGV 예매 시스템을 이용해요.
한 단계 거쳐야 하니 아무래도 해당 사이트에서 직접 예매하는 것보다 불편한 점은 있어요.
개인화 서비스 여부& 제안
앞서 말했듯이 예매 서비스 제공 사이트들과 정보 연동 좀 이뤄졌으면 좋겠네요.
9. 다음 영화 인기순위
다음 영화 인기순위 메인페이지도 영화정보, TV정보처럼 이미지 위주로 깔끔하게 구성되어있어요.
평점순, 박스오피스 순, 조회순 등 다양한 기준으로 볼 수 있어요.
개인화 서비스 여부& 제안
인기순위에서는 딱히 개인화 서비스를 제공하지 않아도 될 것 같아요.
10. 다음 영화 영화마니아
영화마니아는 마니아들에게는 메뉴 자체로 개인화 서비스가 될 수 있는 메뉴죠.
마니아를 위한 추천 영화, 블로그, 전문가 리뷰, 격주 잡지, 전국 예술영화관까지
한 눈에 볼 수 있으니 말이죠^^
상업영화만 다루지 않고 예술영화도 신경써서 다룬다는 점이 마음에 들어요.
개인화 서비스 여부& 제안
예술영화 내에서도 선호하는 장르나 감독은 있기 마련이죠.
그 부분을 추가해서 영화 정보를 바로 볼 수 있었으면 좋겠어요.
<맥스무비>
1. 맥스무비 메인
맥스무비는 영화예매, 공연예매, 영화정보, 뉴스, 이벤트, 강냉이로 크게 나뉘어요.
메인은 뭔가 지저분한 느낌이지만 그 와중에도 예매순위와 실제관객평점순위는 눈에 확 들어오죠.
맥스무비의 실제관객평점순위는 영화를 본 관객들만 참여할 수 있어서 그 신뢰성이 매우 높아요.
화면 하단의 설문조사는 거의 매일 진행되는데,
단순히 설문에 참여하는 것 만으로도 강냉이를 모을 수 있어 인기가 좋아요.
강냉이의 경우 맥스무비만이 가지고 있는 아이템이자 강점이라고 할 수 있는 부분인데,
맥스무비의 포인트 제도를 일컫는 용어예요.
이 강냉이를 모으는 재미로 맥스무비에 매일 들어가곤 하죠.
맥스무비는 메인에서부터 개인화 서비스를 볼 수 있어요.
메인 상단 오른쪽 페이지에 있는 이벤트 정보와 마이맥스, 정보수정, 출석부 메뉴가 있네요.
2. 맥스무비 예매
맥스무비 예매는 사전에 단골극장 옆 등록하기를 통해 5개의 선호 극장을 등록할 수 있습니다.
전국이 다 서비스되니 자신이 자주 가는 극장을 지역에 상관없이 등록하면 되구요.
그렇게 등록해 놓은 단골극장이 있으면 극장의 이름을 누르면 바로 해당 극장의 시간표가 나옵니다.
일일이 지역선택, 영화관선택, 영화제목선택을 하지 않아도 되니 편하죠^^
3. 맥스무비 영화정보
맥스무비의 영화정보는 크게 일반영화와 영화제 영화로 나뉘어요.
그 안에서 개봉년도, 제작년도, 전체등급, 장르, 제작국가로 나뉘구요. 등급별로 정보를 볼 수 있는 부분이 신기하네요.
이번주 뭘 볼까 에서는 그 주 개봉한 영화의 스틸컷, 영화정보, 비슷한 장르 추천작이 나와서 너무 좋았어요.
게다가 상업영화 뿐만 아니라 예술영화까지도 골고루 추천하고 있는것을 알 수 있죠.
게다가 추천작과 관련된 이벤트와 예매링크까지 한 번에 제공하고 있어서 편하죠.
4. 맥스무비 뉴스
맥스무비 뉴스에서는 많이 본 뉴스, 영화, 극장, 연예, 인터뷰, 영상, 포토, 카툰, 공연으로 구분되어 있어서
취향별로 뉴스를 골라 볼 수 있네요.
특히 극장뉴스는 자신이 선호하는 극장의 뉴스나, 특별전을 하는 영화관의 뉴스를 알 수 있어서 좋아요.
영화정보와 마찬가지로 구분메뉴가 많아 개인화 서비스가 용이한 모습이예요.
5. 맥스무비 순위
맥스무비 순위는 예매순위, 실제관객평점순위, 실시간검색순위, 주말상영횟수, 한국박스오피스,
외국박스오피스로 순위도 다양하게 구분되어 있어요.
아무래도 맥스무비가 영화 전문 포털이다 보니 최대한 여러 관객의 기호에 맞추려고 노력하는 모습이 보이네요.
6. 맥스무비 이벤트
이벤트 메뉴는 당첨자, 클릭퀴즈, 특별이벤트, 예매이벤트, 예매권이벤트, 4컷패러디, 출석부로 이루어져있어요.
시사회의 경우 강냉이경매와 더불어 따로 메뉴가 있기 때문에 이벤트에는 있지 않죠.
특별이벤트엔 타 회사의 이벤트를 알려주기도 하고, 규모가 큰 이벤트인 경우가 많아요.
좌측 하단 강냉이 보물지도를 통해 시사회 응모나 강냉이 경매에 쓰이는 강냉이를 모을 수 있는 방법을 알 수 있어요.
맥스무비에서 개인화가 제일 이뤄지지 않는 메뉴인 것 같네요.
7. 맥스무비 관객이 말한다
이 코너는 리뷰코너라고 할 수 있는데요.
개인적으로는 극장을 말한다 메뉴가 참 마음에 드네요.
극장 자체에 대해서 말해도 되고, 극장 주변 맛집이나 구경할 만한 곳을 네티즌들이
리뷰로서 알려주는 코너거든요. 이 코너를 통해 자신이 갈 극장이
처음이더라도 주변 정보를 알 수 있으니 도움이 많이 되네요.
8. 마이맥스
맥스무비 같은 경우는 개인화 서비스가 굉장히 잘돼있어요.
마이맥스를 누르거나 블로그관리를 누를면 서로 연결이되구요.
마이맥스에선 블로그관리, 회원정보관리, 나의티켓정보, 경매내역, 게임내역,
강냉이아이템, 나의통장, 고객센터, 회원탈퇴 메뉴를 가지고 있어요.
아래 사진은 나의 티켓정보인데요.
관람가능한예매내역부터 지난 예매내역, 취소한 예매내역,
취소 및 환불규정, 극장에서 영화 관람하는 방법, 영화 취소시 주의사항 등
자신의 예매에 관련된 모든 내용을 볼 수 있어요.
이 사진은 마이맥스 중 나의통장입니다.
여기서는 맥스무비의 포인트인 강냉이를 비롯, 예매권, 마일리지, 저금통, 할인쿠폰, VOD쿠폰, 쿠폰북,
파트너 머니에 대해 한 눈에 볼 수 있어요.
예매권은 말 그대로 영화 예매권이구요. 마일리지는 영화 예매 후 받을 수 있는 현금처럼 쓸 수 있는 거예요.
저금통은 계좌이체한 예매 내역을 취소했을 시 환불해주는 서비스입니다.
송금수수료 500원을 제한 금액을 실제 통장으로 입금해준다네요.
할인쿠폰은 영화 할인쿠폰인데, 사용 가능한 할인쿠폰, 지난 할인쿠폰, 할인쿠폰 사용 방법이 자세히 나옵니다.
VOD 쿠폰은 맥스에서 서비스하는 VOD를 한 편 무료로 볼 수 있는 쿠폰이고, 맥스 홈페이지에서 받을 수 있어요.
쿠폰북은 쿠폰북 극장이라고 따로 있는데 쿠폰북 서비스를 시행하는 극장에서 예매할 때 쓸수 있는 쿠폰이예요.
파트너머니는 맥스무비 제휴사에서 맥스무비를 사용할 수 있도록 전환한 사이버머니구요.
내가 준 평점같은 경우는 블로그에 들어가면 한 눈에 볼 수 있어요.
이상으로 다음 영화와 맥스무비의 비교를 마치겠습니다
출처 : http://blog.daum.net/enter4lifechanger/490 엔터블로그♡
■ 수도권 아파트 3.3㎡당 매매가 순위 | |||||||||
순위 | 시·군·구 | 2008년 3.3㎡당매매가 |
순위 | 시·군·구 | 2009년 3.3㎡당매매가 |
순위변동 | 3.3㎡당 매매가격 변동 |
||
1 | 강남구 | 2,839 | 1 | 강남구 | 2,944 | ─ | 105 | ||
2 | 과천시 | 2,564 | 2 | 과천시 | 2,788 | ─ | 224 | ||
3 | 용산구 | 2,551 | 3 | 서초구 | 2,583 | ↑ 1 | 193 | ||
4 | 서초구 | 2,390 | 4 | 용산구 | 2,549 | ↓ 1 | -3 | ||
5 | 송파구 | 2,190 | 5 | 송파구 | 2,355 | ─ | 165 | ||
6 | 양천구 | 1,888 | 6 | 판교신도시 | 2,343 | new | new | ||
7 | 분당신도시 | 1,777 | 7 | 양천구 | 2,052 | ↓ 1 | 164 | ||
8 | 광진구 | 1,756 | 8 | 광진구 | 1,803 | ─ | 47 | ||
9 | 중구 | 1,678 | 9 | 분당신도시 | 1,782 | ↓ 2 | 5 | ||
10 | 마포구 | 1,647 | 10 | 중구 | 1,695 | ↓ 1 | 18 | ||
11 | 성동구 | 1,578 | 11 | 마포구 | 1,665 | ↓ 1 | 18 | ||
12 | 종로구 | 1,556 | 12 | 종로구 | 1,619 | ─ | 63 | ||
13 | 동작구 | 1,514 | 13 | 성동구 | 1,605 | ↓ 2 | 27 | ||
14 | 강동구 | 1,448 | 14 | 동작구 | 1,522 | ↓ 1 | 7 | ||
15 | 영등포구 | 1,414 | 15 | 강동구 | 1,521 | ↓ 1 | 74 | ||
16 | 강서구 | 1,404 | 16 | 영등포구 | 1,470 | ↓ 1 | 55 | ||
17 | 평촌신도시 | 1,371 | 17 | 강서구 | 1,417 | ↓ 1 | 13 | ||
18 | 관악구 | 1,286 | 18 | 평촌신도시 | 1,384 | ↓ 1 | 13 | ||
19 | 성북구 | 1,269 | 19 | 관악구 | 1,299 | ↓ 1 | 12 | ||
20 | 일산신도시 | 1,267 | 20 | 성북구 | 1,269 | ↓ 1 | 1 | ||
21 | 노원구 | 1,238 | 21 | 노원구 | 1,254 | ─ | 15 | ||
22 | 동대문구 | 1,220 | 22 | 일산신도시 | 1,252 | ↓ 2 | -15 | ||
23 | 서대문구 | 1,214 | 23 | 동대문구 | 1,223 | ↓ 1 | 3 | ||
24 | 구로구 | 1,212 | 24 | 서대문구 | 1,223 | ↓ 1 | 9 | ||
25 | 동탄신도시 | 1,199 | 25 | 동탄신도시 | 1,222 | ─ | 23 | ||
26 | 도봉구 | 1,157 | 26 | 구로구 | 1,220 | ↓ 2 | 8 | ||
27 | 광명시 | 1,156 | 27 | 도봉구 | 1,155 | ↓ 1 | -2 | ||
28 | 성남시 | 1,108 | 28 | 은평구 | 1,145 | ↑ 11 | 113 | ||
29 | 강북구 | 1,096 | 29 | 하남시 | 1,113 | ↑ 6 | 47 | ||
30 | 중랑구 | 1,089 | 30 | 강북구 | 1,111 | ↓ 1 | 15 | ||
31 | 구리시 | 1,081 | 31 | 중랑구 | 1,105 | ↓ 1 | 16 | ||
32 | 군포시 | 1,074 | 32 | 성남시 | 1,102 | ↓ 4 | -6 | ||
33 | 안양시 | 1,074 | 33 | 안양시 | 1,087 | ─ | 13 | ||
34 | 용인시 | 1,070 | 34 | 구리시 | 1,081 | ↓ 3 | 0 | ||
35 | 하남시 | 1,066 | 35 | 군포시 | 1,070 | ↓ 3 | -4 | ||
36 | 중동신도시 | 1,061 | 36 | 의왕시 | 1,067 | ↓ 2 | 25 | ||
37 | 산본신도시 | 1,042 | 37 | 용인시 | 1,061 | ↓ 3 | -9 | ||
38 | 의왕시 | 1,042 | 38 | 광명시 | 1,058 | ↓11 | -98 | ||
39 | 은평구 | 1,032 | 39 | 중동신도시 | 1,043 | ↓ 3 | -18 | ||
40 | 금천구 | 1,013 | 40 | 산본신도시 | 1,024 | ↓ 3 | -18 | ||
41 | 고양시 | 992 | 41 | 금천구 | 1,020 | ↓ 1 | 7 | ||
42 | 부천시 | 975 | 42 | 부천시 | 1,004 | ─ | 30 | ||
43 | 파주신도시 | 966 | 43 | 파주신도시 | 984 | ─ | 18 | ||
44 | 인천 연수구 | 877 | 44 | 고양시 | 975 | ↓ 3 | -17 | ||
45 | 수원시 | 874 | 45 | 인천 연수구 | 933 | ↓ 1 | 55 | ||
46 | 김포신도시 | 864 | 46 | 수원시 | 885 | ↓ 1 | 11 | ||
47 | 안산시 | 857 | 47 | 안산시 | 848 | ─ | -9 | ||
48 | 의정부시 | 855 | 48 | 의정부시 | 843 | ─ | -12 | ||
49 | 광주시 | 843 | 49 | 김포신도시 | 843 | ↓ 3 | -21 | ||
50 | 인천 부평구 | 819 | 50 | 인천 남동구 | 826 | ↑ 2 | 32 | ||
51 | 남양주시 | 818 | 51 | 인천 중구 | 820 | ↑ 5 | 79 | ||
52 | 인천 남동구 | 794 | 52 | 남양주시 | 817 | ↓ 1 | -1 | ||
53 | 김포시 | 765 | 53 | 인천 부평구 | 817 | ↓ 3 | -2 | ||
54 | 인천 계양구 | 758 | 54 | 광주시 | 816 | ↓ 5 | -27 | ||
55 | 인천 서구 | 744 | 55 | 김포시 | 794 | ↓ 2 | 29 | ||
56 | 인천 중구 | 740 | 56 | 인천 계양구 | 760 | ↓ 2 | 2 | ||
57 | 시흥시 | 730 | 57 | 인천 서구 | 744 | ↓ 2 | 0 | ||
58 | 인천 남구 | 723 | 58 | 인천 남구 | 728 | ─ | 5 | ||
59 | 화성시 | 675 | 59 | 시흥시 | 719 | ↓ 3 | -11 | ||
60 | 파주시 | 644 | 60 | 화성시 | 695 | ↓ 1 | 19 | ||
61 | 인천 동구 | 644 | 61 | 인천 동구 | 666 | ─ | 23 | ||
62 | 오산시 | 604 | 62 | 파주시 | 665 | ↓ 2 | 21 | ||
63 | 양주시 | 594 | 63 | 양평군 | 659 | ↑ 6 | 177 | ||
64 | 동두천시 | 542 | 64 | 양주시 | 628 | ↓ 1 | 34 | ||
65 | 이천시 | 540 | 65 | 오산시 | 617 | ↓ 3 | 13 | ||
66 | 평택시 | 519 | 66 | 여주군 | 563 | ↑ 1 | 47 | ||
67 | 여주군 | 516 | 67 | 동두천시 | 560 | ↓ 3 | 18 | ||
68 | 가평군 | 493 | 68 | 이천시 | 540 | ↓ 3 | 0 | ||
69 | 양평군 | 482 | 69 | 평택시 | 524 | ↓ 3 | 5 | ||
70 | 포천시 | 421 | 70 | 가평군 | 507 | ↓ 2 | 14 | ||
71 | 안성시 | 403 | 71 | 포천시 | 434 | ↓ 1 | 12 | ||
72 | 강화군 | 389 | 72 | 안성시 | 424 | ↓ 1 | 21 | ||
73 | 연천군 | 327 | 73 | 강화군 | 389 | ↓ 1 | 0 | ||
74 | 연천군 | 327 | ↓ 1 | 0 | |||||
자료 : 닥터아파트(www.DrApt.com) | * 2009년은 12월 8일 현재 기준 |
Lets put a little pizazz in the Flex download ProgressBar. Really, going from, say, 0 -> 100 is great and all but maybe you need more. Like how about changing colors as it gets closer to completion?
view source |
Now that’s more like it.
The meat and potatoes of this is in the following two methods:
1 2 3 4 5 6 7 8 9 10 |
Here is a quick post on using Flash Player 9’s Full-Screen Mode in Flex. I’ve seen this appear a few times in the bugbase and on lists, but here is some simple code to let you toggle between “full screen mode” and “normal mode” in a Flex application. Note that in this example I’m listening for the applicationComplete
event in the main <mx:Application /> tag instead of the creationComplete
event. The applicationComplete
tag is called slightly after the creationComplete
event, after the Application has been completely initialized.
If you try and access the Application.application.stage
property from the creationComplete
event, you’ll get a run-time error (RTE) saying the following:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at main/init()
at main/___main_Application1_creationComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()
at mx.core::UIComponent/set initialized()
at mx.managers::LayoutManager/doPhasedInstantiation()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()
at mx.core::UIComponent/callLaterDispatcher()
The example below is pretty bare with just a few Label controls and a Button control, but it should have enough of the required code to give you a push in the right direction.
Full code after the jump.
You must have version 9,0,28,0 or greater of Flash Player installed to use full-screen mode. Download the latest version of Adobe Flash Player.
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/07/creating-full-screen-flex-applications/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" applicationComplete="init(event)">
<mx:Script>
<![CDATA[
import flash.display.StageDisplayState;
private function init(evt:Event):void {
/* Set up full screen handler. */
Application.application.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
dispState = Application.application.stage.displayState;
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = Application.application.stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
/* Do something specific here if we switched to full screen mode. */
} else {
/* Do something specific here if we switched to normal mode. */
}
}
private function toggleFullScreen():void {
try {
switch (Application.application.stage.displayState) {
case StageDisplayState.FULL_SCREEN:
/* If already in full screen mode, switch to normal mode. */
Application.application.stage.displayState = StageDisplayState.NORMAL;
break;
default:
/* If not in full screen mode, switch to full screen mode. */
Application.application.stage.displayState = StageDisplayState.FULL_SCREEN;
break;
}
} catch (err:SecurityError) {
// ignore
}
}
]]>
</mx:Script>
<mx:String id="dispState" />
<mx:Label text="width={Application.application.width}" />
<mx:Label text="height={Application.application.height}" />
<mx:Label text="displayState={dispState}" />
<mx:Button label="Toggle fullscreen" click="toggleFullScreen()" />
</mx:Application>
View source is enabled in the following example.
For more information on Full Screen Mode in Flash Player 9 (ActionScript 2.0 and ActionScript 3.0) check out the following article on the Adobe Developer Center: “Exploring full-screen mode in Flash Player 9″.
I *knew* I would have forgotten something. The real trick to using FullScreen support is to enable it in the JavaScript embed code, or <object /> and <embed /> tags… So, in your HTML wrapper, add the following property:
AC_FL_RunContent( "src", "main", "width", "100%", "height", "100%", "align", "middle", "id", "main", "quality", "high", "bgcolor", "#869ca7", "name", "main", "allowScriptAccess","sameDomain", "type", "application/x-shockwave-flash", "pluginspage", "http://www.adobe.com/go/getflashplayer", "allowFullScreen", "true" );
Or, if you are using <object /> and <embed /> tags, you can use the following syntax instead:
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="main" width="100%" height="100%" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> <param name="movie" value="main.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#869ca7" /> <param name="allowScriptAccess" value="sameDomain" /> <param name="allowFullScreen" value="true" /> <embed src="main.swf" quality="high" bgcolor="#869ca7" width="100%" height="100%" name="main" align="middle" play="true" loop="false" quality="high" allowScriptAccess="sameDomain" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"> </embed> </object>
Also, I just learnt from my co-worker Raghu’s blog (“FLEXing My Muscle” and his “Error on adding FullScreenListener in creationComplete handler” post) that you can use the SystemManager class instead of all my references to Application.application
. Thanks Raghu!
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/07/creating-full-screen-flex-applications/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" applicationComplete="init()">
<mx:Script>
<![CDATA[
import flash.display.StageDisplayState;
import mx.managers.SystemManager;
private function init():void {
/* Set up full screen handler. */
systemManager.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
dispState = systemManager.stage.displayState;
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = systemManager.stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
/* Do something specific here if we switched to full screen mode. */
} else {
/* Do something specific here if we switched to normal mode. */
}
}
private function toggleFullScreen():void {
try {
switch (systemManager.stage.displayState) {
case StageDisplayState.FULL_SCREEN:
/* If already in full screen mode, switch to normal mode. */
systemManager.stage.displayState = StageDisplayState.NORMAL;
break;
default:
/* If not in full screen mode, switch to full screen mode. */
systemManager.stage.displayState = StageDisplayState.FULL_SCREEN;
break;
}
} catch (err:SecurityError) {
// ignore
}
}
]]>
</mx:Script>
<mx:String id="dispState" />
<mx:Label text="width={Application.application.width}" />
<mx:Label text="height={Application.application.height}" />
<mx:Label text="displayState={dispState}" />
<mx:Button label="Toggle fullscreen" click="toggleFullScreen()" />
</mx:Application>
The parameters
property of the Application object points to a dynamic object that stores parameters as name-value pairs. You can access variables on the parameters object by specifying parameters.variable_name.
The following example defines the myName
and myHometown
parameters and binds them to the text of Label controls:
<?xml version="1.0"?> <!-- wrapper/ApplicationParameters.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initVars()"> <mx:Script><![CDATA[ // Declare bindable properties in Application scope. [Bindable] public var myName:String; [Bindable] public var myHometown:String; // Assign values to new properties. private function initVars():void { myName = Application.application.parameters.myName; myHometown = Application.application.parameters.myHometown; } ]]></mx:Script> <mx:VBox> <mx:HBox> <mx:Label text="Name: "/> <mx:Label text="{myName}" fontWeight="bold"/> </mx:HBox> <mx:HBox> <mx:Label text="Hometown: "/> <mx:Label text="{myHometown}" fontWeight="bold"/> </mx:HBox> </mx:VBox> </mx:Application>
When a user requests this application with the myName
and myHometown
parameters defined as flashVars
variables, Flex displays their values in the Label controls.
To view all the flashVars
properties, you can iterate over the parameters object, as the following example shows:
<?xml version="1.0"?> <!-- wrapper/IterateOverApplicationParameters.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()"> <mx:Script><![CDATA[ private function init():void { for (var i:String in Application.application.parameters) { ta1.text += i + ":" + Application.application.parameters[i] + "\n"; } } ]]></mx:Script> <mx:TextArea id="ta1" width="300" height="200"/> </mx:Application>
Flex does not recompile the application if the request variables have changed. As a result, if you dynamically set the values of the flashVars
properties or query string parameters, you do not force a recompilation.
Query string parameters must be URL encoded. The format of the string is a set of name-value pairs separated by an ampersand (&). You can escape special and nonprintable characters with a percent symbol (%) followed by a two-digit hexadecimal value. You can represent a single blank space using the plus sign (+).
The encoding for flashVars
properties and query string parameters is the same as the page. Internet Explorer provides UTF-16-compliant strings on the Windows platform. Netscape sends a UTF-8-encoded string to Adobe Flash Player.
Most browsers support a flashVars
String or query string up to 64 KB (65535 bytes) in length. They can include any number of name-value pairs.
The random function has many uses in Flash, generating basic random numbers, creating random movement, creating random colors and many others. The example above creates a random integer between -100 and 100 everytime you click the button. This tutorial will cover creating the example, and also how to incorporate the random function to achieve different results.
The basic random function is as follows:
Math.random();
This creates a random number between the values of 0.0 and 1.0. For example: 0.0105901374530933 or 0.872525005541986. Several other functions can now be used to change the number that is created for better use in your movie. These include:
Math.round();
Math.ceil();
Math.floor();
These Math functions all round a number so that it becomes an integer, or whole number. The Math.round(); function will round up or down the number or expression that is inside its brackets to the nearest whole number. The Math.ceil(); function will do the same, however it will always round up to the nearest whole number. The Math.floor(); function is the opposite of the Math.ceil(); , it will always round down to the closest whole number.
To incorporate these with the random function, you can do this:
Math.round(Math.random());
This expression will now create a random number between 0.0 and 1.0, and then round it up to the closest whole number. So in this case, the number created will always equal either 0 or 1. This expression is useful for creating a 50% chance of an event occuring, ie flipping a coin. or for use with booleans (true/false statements).
To create a random number between the values of, say 0 and 10, you could do this:
Math.round(Math.random()*10);
The *10 multiplies your random number by 10, then it is rounded by the Math.round function to an integer. To create a random number between 1 and 10, you could do this:
Math.ceil(Math.random()*10);
This way the random number is always rounded up, and cannot equal 0. Another procedure is to create random numbers between two numbers other than 0 and something else. To create a random number between 5 and 20, do this:
Math.round(Math.random()*15)+5;
Or in other words, to create a random number between the values x and y:
Math.round(Math.random()*(y-x))+x;
This will hold true for all values of x and y, ie they can be negative numbers as well as positive.
To make the example above, first create a new button, and place an instance of it onto the main stage. Create a new Dynamic text box, and give it the variable name of "display". That's the creation out of the way, and we can now do the scripting.
Select your button, and then open the actions window. You can either manually insert the following code, using the dropdown menus, or just copy and paste for now. Insert the code:
on (release) {
display = Math.round (Math.random ()*200)-100;
}
And that's it! Now test your movie and give it a try out. You'll notice that the values in the code follow the pattern set by the general formula ie if x = -100, and y =100, then y-x=200 and +x = -100.
This can have many different applications within flash. For example, to have a movieclip appear in random positions on the screen between the values of 0 and 200 you could have the following. Note: movieclip instance is called "bob".
bob._x = Math.round(Math.random()*200);
bob._y = Math.round(Math.random()*200);
Or to set the size of a movieclip randomly (between 0 and 100):
bob._width = Math.round(Math.random()*100);
bob._height = Math.round(Math.random()*100);
Or to choose a random movieclip to load, say if our movieclips have a linkage name of "bob1", "bob2" and we have 5 of them:
i = Math.ceil(Math.random()*5);
attachmovie("bob"+i, "fred"+i, 1);
So that would attach a random movie, say "bob3", into level 1 and then give it an instance name of "fred3".
Well, that's the basics of using the random function in Flash 5. Hopefully now you will be able to incorporate this into your movies to produce some even more amazing flash work. =)
<mx:DataGrid id="dg" dataProvider="{CIS}" width="296" rowCount="3" fontSize="12">
...


이렇게 원하지않는 세로스크롤바가 생깁니다.
폰트사이즈의 변경으로 row의 높이가 변경되면서 전체적인 높이가 데이터 사이즈에 맞게 변경되어야 하지만 위 그림처럼 스크롤바가 생깁니다.
스크롤 해봐도 그 아래에는 물론 데이터도 없습니다.
이럴땐 verticalScrollPolicy="off" 을 사용하면
<mx:DataGrid id="dg" dataProvider="{CIS}" width="296" rowCount="3" fontSize="12" verticalScrollPolicy="off">
...

위 그림처럼 스크롤바가 없어집니다. 그러나 이경우 마지막 3번째 row 의 높이가 다른 row의 높이보다 낮습니다.
정확히 row 의 높이(header 높이 제외)가 같게 하기 위해선
- headerHeight 의 높이 지정
- headerWordWrap 값 true 로 설정
위 두가지 방법 중 하나만 사용해도 각 row 의 높이를 같게 할 수 있습니다.