<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Journal</title>
    <link rel="alternate" type="text/html" href="http://jenrawson.com/journal/" />
    <link rel="self" type="application/atom+xml" href="http://jenrawson.com/journal/atom.xml" />
    <id>tag:jenrawson.com,2009-10-03:/journal//1</id>
    <updated>2010-04-12T16:51:21Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.32-en</generator>

<entry>
    <title>Texas Linux Fest</title>
    <link rel="alternate" type="text/html" href="http://jenrawson.com/journal/2010/04/texas-linux-fest.php" />
    <id>tag:jenrawson.com,2010:/journal//1.10</id>

    <published>2010-04-12T15:38:32Z</published>
    <updated>2010-04-12T16:51:21Z</updated>

    <summary>I had a great time at Texas Linux Fest on Saturday. There were many good presentations and a few really inspiring ones. I particularly enjoyed Max Spevack&apos;s talk on Open Source and education. </summary>
    <author>
        <name>Jen</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://jenrawson.com/journal/">
        <![CDATA[<p>He discussed bringing the "open source way of thinking" into higher education. He described the open source way of teaching and learning as an apprenticeship, where participants are paired with mentors and travel through the phases of Apprentice, Journeyman, and Master. He posed the question to the audience: should higher education incorporate this model? This concept speaks deeply to me and I think it's especially applicable in the work place. As Max pointed out, mentoring is essential for passing knowledge down from the old guard to the new, otherwise, so many lessons learned will be lost and will have to be relearned. Attending this event inspired me to get involved in an open source project and give back to the community that gives so much. </p>]]>
        
    </content>
</entry>

<entry>
    <title>Android Developer Lab</title>
    <link rel="alternate" type="text/html" href="http://jenrawson.com/journal/2010/02/android-developer-lab.php" />
    <id>tag:jenrawson.com,2010:/journal//1.8</id>

    <published>2010-02-07T18:30:57Z</published>
    <updated>2010-04-12T19:49:42Z</updated>

    <summary>Last Thursday I attended Google&apos;s Android Developer Lab in Austin, TX. I find Android intriguing because it is an open source software stack built on the Linux kernel, and has many apps that rival those on the iPhone. I was hoping to learn more about how the Android UI differs from the iPhone, how Android approaches common mobile OS problems, and how to get started developing for Android.  Given an opportunity to discover these things first-hand from Android developers, I jumped at the chance to attend the lab.</summary>
    <author>
        <name>Jen</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://jenrawson.com/journal/">
        <![CDATA[<p>I walked in to the The J. Neils Thompson Commons building at about 5:30pm with butterflies in my stomach. I wasn't sure if the lab would target beginners or advanced developers and the agenda for the evening was not made explicit in the <a href="http://sites.google.com/site/androiddevlabs/faq">Android Developer Lab <span class="caps">FAQ</span></a>.  Since I hadn't done any Android development I was counting on my Java skills to carry me through. I expected to encounter devoted Android followers, as anything Linux invariably has, so I'd anticipated feeling a bit out of place. As I approached the front entrance I saw only a handful of people milling around so I walked around to the side entrance. I opened the door and immediately realized that I was more than a little out of place- every attendee seemed to be of the male gender! I work with both male and female developers so I think I had forgotten about the imbalance of men to women in the dev community.  I swallowed hard and fumbled my way through the crowd looking for the end of the line. A little scary, but hey, I'd been the only woman in many techie crowds before and ultimately, it's not a big deal. Out of 80+ attendees, three other women were in attendance.</p>

<p>People in Austin are some of the friendliest I've encountered anywhere so the butterflies soon disappeared and I settled in. I quickly realized that the crowd had quite a varied level of experience with Android. I met a <span class="caps">PHP </span>developer interested in getting started with Android app development. I met an executive with a small mobile carrier in Mississippi, looking to learn more about the Android platform. The rows behind me consisted of devoted Android bloggers, including the creators of <a href="http://androidandme.com/">androidandme.com</a>, and experienced app developers. A representative from Motorola was in attendance to tell everyone about Motorola's <a href="http://developer.motorola.com/platforms/android/"> Android developer website</a> and <a href="http://developer.motorola.com/docstools/motodevstudio/"><span class="caps">MOTODEV</span> Studio for Android</a>, an integrated development environment with Eclipse and Android Development Tools. The skill level, interest, and experience of attendees was extremely varied. </p>

<p>The Developer Lab consisted of two parts: an introduction to Android app development and a coding lab designed to cover the basics of working with Bluetooth. The introduction generated a lot of questions from the audience and seemed to hit the mark but the lab was a bit advanced and didn't hold everyone's attention. In their defense, the presenters were faced with the challenge of engaging both new and advanced developers. The lab could have been more productive though, had they split people into groups and presented on multiple topics. In the end, I think most people got something out of the event- be it more information, inspiration, a sense of community, or a free <a href="http://www.engadget.com/2009/10/30/motorola-droid-review/">Droid phone</a> to test out applications. I walked away feeling more interested in Android, excited to check out the Droid phone and compare it to my iPhone, and inspired to learn more about the platform. For me, it was definitely worth the time to attend. Thanks to Google, Justin and his crew for an interesting evening! </p>]]>
        
    </content>
</entry>

<entry>
    <title>Create Editable Page Elements with Prototype</title>
    <link rel="alternate" type="text/html" href="http://jenrawson.com/journal/2009/10/how-to-make-any-html-element-editable.php" />
    <id>tag:jenrawson.com,2009:/journal//1.5</id>

    <published>2009-10-12T08:07:00Z</published>
    <updated>2010-02-11T14:41:01Z</updated>

    <summary>Traditionally information is gathered on a website with an HTML form. In some cases we may want to respond quickly to user input, requiring a lighter weight process than traditional form submission. With a little JavaScript &amp; Ajax we can do away with the form to create highly responsive websites. This article explains how to make HTML elements clickable, editable, and savable with the Prototype JavaScript library. Learn how to gather user input and give immediate feedback without submitting a form.

Part one of this article describes how to transform HTML elements so they can be modified by users directly on the page. Part two will describe how to store those changes in a database with Ajax and give example uses of this code.</summary>
    <author>
        <name>Jen</name>
        
    </author>
    
        <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://jenrawson.com/journal/">
        <![CDATA[<p class="block-letter"> 
The Prototype library is a lightweight JavaScript library that streamlines the behavior of JavaScript in all browsers, making DOM manipulation and Ajax requests a piece of cake. Prototype is used heavily throughout this example but if you've never used Prototype, don't  worry. This tutorial will walk you through it and provide links to documentation for more information on various methods and modules.
</p>

<p>
To get started, download a copy of Prototype from <a href="http://www.prototypejs.org/download">http://www.prototypejs.org/download</a>. Create two files, editor.js and index.html, and place them in a folder along with prototype.js. Open index.html in your favorite text editor and add the following code, which includes links to prototype.js and editor.js:
<div class="code">
  <pre>
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;

  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
  &lt;head&gt;
      &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
      &lt;script <span style="background-color: #ccffcc">src="prototype.js"</span> type="text/javascript"&gt;&lt;/script&gt;
      &lt;script <span style="background-color: #ccffcc">src="editor.js"</span> type="text/javascript"&gt;&lt;/script&gt;
      &lt;title&gt;untitled&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
 

  &lt;/body&gt;
  &lt;/html&gt;
  </pre>
</div>
</p>

<p>
In order to make elements editable, we need a way to find them from within our JavaScript. We are going to identify editable elements by setting their class attribute to  <em>editable</em>. Then we'll use Prototype to collect them into an array. Add the following lines to index.html:
<div class="code">
<pre>
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;

  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
  &lt;head&gt;
      &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;
      &lt;script src="prototype.js" type="text/javascript"&gt;&lt;/script&gt;
      &lt;script src="editor.js" type="text/javascript"&gt;&lt;/script&gt;
      &lt;title&gt;untitled&lt;/title&gt;
  &lt;/head&gt;

  &lt;body&gt;
<span style="background-color: #ccffcc">
  &lt;h1 class="editable"&gt;Hello world!&lt;/h1&gt;
  &lt;h2 class="editable"&gt;Here is a sub-header&lt;/h2&gt;
  &lt;p class="editable"&gt;Paragraph one&lt;/p&gt;
  &lt;p class="editable"&gt;Paragraph two&lt;/p&gt;
</span>
  &lt;/body&gt;
  &lt;/html&gt;
</pre>
</div>
</p>

<p>
Add the following code to editor.js:
<div class="code">
<pre>
 // when the page finishes loading, execute the findEditables function
Event.observe(window, 'load', findEditables);

function findEditables(event) {
  // collect the elements with class="editable" into an array
  var elements = $$('.editable');
  alert(elements);
}
</pre>
</div>
</p>

<p>
Take a look at <em>$$('.editable')</em>. I've made use of Prototype's $$( ) utility method, which, as the <a href="http://www.prototypejs.org/api/utility/dollar-dollar">documentation</a> states, takes an arbitrary number of CSS selectors (strings) and returns a document-order array of extended DOM elements that match any of them. I've used it to find all DOM elements with class attribute equal to <em>editable</em>. 
</p>
<p>
Open index.html in your web browser. If we've done everything correctly, an alert window will pop up with a list of elements that have the <em>editable</em> class. Remove the alert line from the findEditables function.
</p>

<p>
Now that we have a way to find editable elements from within our JavaScript we will create an <em>Editable</em> class to hold the data and methods for an editable element. We will include a constructor called <em>initialize</em>, a <em>createEditor</em> method that will create and return a form textarea, and <em>edit</em> and <em>save</em> methods that will be used as click event handlers on editable elements. We will create instances of the Editable class from within the <em>findEditables</em> function. Add the skeleton for the Editable class to editor.js:
<div class="code">
<pre>
// when the page finishes loading, execute the findEditables function
Event.observe(window, 'load', findEditables);

function findEditables(event) {
  // collect the elements with class="editable" into an array
  var elements = $$('.editable');
<div style="background-color: #ccffcc">
  // create a new Editable object for each element
  elements.each(function(el){
    new Editable(el);
  });
</div>
}  

<div style="background-color: #ccffcc">
/* 
  The Editable class transforms an html element so that 
  it can be edited when clicked. 
*/
var Editable = Class.create({
  
  /* constructor */
  initialize: function(element) {

  },
  
  createEditor: function() {
 
   },
  
  edit: function(event) {

  },
  
  save: function(event){

  }
});
</div>

</pre>
</div>
</p>
 <p>
We use Prototype's Class.create method to create the Editable class. When we call <em> new Editable(el)</em> from our findEditables function, the class's constructor <em>initialize</em> is fired. See the <a href="http://www.prototypejs.org/api/class/create">Class.create documentation</a> for more details.
</p>

<p>
Also, you may have noticed the <em> elements.each</em> function in findEditables. When we used the $$( ) Prototype utility to gather the editable elements into an array,  Prototype very conveniently extended that array to include methods from its <em>Enumerable</em> module. Enumerable includes a large set of methods that are used to manipulate collections such as arrays. The <em>each</em> function in the Enumerable module allows us to enumerate over all the elements in our array and apply a function to each one. We can quickly create an Editable object for every element in our Array. See the <a href="http://www.prototypejs.org/api/enumerable">Enumerable documentation</a> for more details. 
</p>

<p>
Now add the body to the constructor:

<div class="code">
<pre>
// when the page finishes loading, execute the findEditables function
Event.observe(window, 'load', findEditables);

function findEditables(event) {
  // collect the elements with class="editable" into an array
  var elements = $$('.editable');
  // create a new Editable object for each element
  elements.each(function(el){
    new Editable(el);
  });
}  


/* 
  The Editable class transforms an html element so that 
  it can be edited when clicked. 
*/
var Editable = Class.create({
  
  /* constructor */
  initialize: function(element) {
<div style="background-color: #ccffcc">
    this.element = $(element);
    this.editor = this.createEditor();
    this.boundEdit = this.edit.bind(this);
    this.boundSave = this.save.bind(this);
    this.element.observe('click', this.boundEdit);
</div>
  },
  
  createEditor: function() {
 
   },
  
  edit: function(event) {

  },
  
  save: function(event){

  }
});

</pre>
</div>
</p>
<p>
Inside the constructor we create several instance variables, bind the two event handlers to this instance of the Editable class,  and set a click event handler on the editable element. In line 1 the editable element is stored in the instance variable <em>this.element</em>. In line 2 the createEditor method is called, which will return a form textarea that will be used to edit the element (more to come on that in a minute).  Lines 3 and 4 <em>bind</em> this instance of the  Editable class to the event handlers <em>edit</em> and <em>save</em>. If we did not use binding then within the edit and save methods, the <em>this</em> keyword would refer to the element that the event handler is set on, i.e. the editable element. Since our handlers are methods on an instance of the Editable class, we want <em>this</em> to refer to the Editable instance. If you are new to Prototype and Binding this can be a bit difficult to understand. For a more in depth explanation, look at the <a href="http://www.prototypejs.org/api/event/observe">Event.observe documentation</a> and scroll down to the section titled "The tricky case of methods that need this".
</p>

<p>
Add the body of the createEditor method:
<div class="code">
<pre>
// when the page finishes loading, execute the findEditables function
Event.observe(window, 'load', findEditables);

function findEditables(event) {
  // collect the elements with class="editable" into an array
  var elements = $$('.editable');
  // create a new Editable object for each element
  elements.each(function(el){
    new Editable(el);
  });
}  


/* 
  The Editable class transforms an html element so that 
  it can be edited when clicked. 
*/
var Editable = Class.create({
  
  /* constructor */
  initialize: function(element) {
    this.element = $(element);
    this.editor = this.createEditor();
    this.boundEdit = this.edit.bind(this);
    this.boundSave = this.save.bind(this);
    this.element.observe('click', this.boundEdit);
  },
  
  createEditor: function() {
<div style="background-color: #ccffcc">
    // find computed width and height of element we are editing
    var dimensions = this.element.getDimensions();
    var editor = new Element('textarea');
    editor.setStyle({
      width: dimensions.width+'px', 
      height: dimensions.height+'px'
    });
    return editor;
</div> 
   },
  
  edit: function(event) {

  },
  
  save: function(event){

  }
});

</pre>
</div>
</p>
<p>
The createEditor method computes the dimensions of the element we are editing, creates a textarea with the same dimensions and returns it. This method is called from within the initialize constructor and assigns the return value (the textarea) to this.editor. 
</p>

<p>
Add the body to the edit method:
<div class="code">
<pre>
// when the page finishes loading, execute the findEditables function
Event.observe(window, 'load', findEditables);

function findEditables(event) {
  // collect the elements with class="editable" into an array
  var elements = $$('.editable');
  // create a new Editable object for each element
  elements.each(function(el){
    new Editable(el);
  });
}  


/* 
  The Editable class transforms an html element so that 
  it can be edited when clicked. 
*/
var Editable = Class.create({
  
  /* constructor */
  initialize: function(element) {
    this.element = $(element);
    this.editor = this.createEditor();
    this.boundEdit = this.edit.bind(this);
    this.boundSave = this.save.bind(this);
    this.element.observe('click', this.boundEdit);
  },
  
  createEditor: function() {
    // find computed width and height of element we are editing
    var dimensions = this.element.getDimensions();
    var editor = new Element('textarea');
    editor.setStyle({
      width: dimensions.width+'px', 
      height: dimensions.height+'px'
    });
    return editor;
   },
  
  edit: function(event) {
<div style="background-color: #ccffcc">
    this.element.stopObserving('click', this.boundEdit);
    var content = this.element.innerHTML;
    this.editor.value = content;   
    this.element.update(this.editor);
    this.editor.focus();
    Event.observe(document, 'click', this.boundSave);
</div>
  },
  
  save: function(event){

  }
});

</pre>
</div>
</p>
<p>
First, the click event handler is temporarily removed from the element to prevent the edit function from being called again. Next, the value of the editor (the textarea we created) is set to the content of the editable element. Then, the editor is placed inside the element and keyboard focus is set to the editor. If the editable element was a paragraph for example, it would now look like this:
<div class="code">
<pre>
&lt;p class="editable"&gt;
    &lt;textarea&gt;This is a paragraph&lt;/textarea&gt;
&lt;/p&gt;
</pre>
</div>
</p>
<p>
Finally, the save method is set as an event handler on the Document object so that when the user clicks anywhere on the page, the save method will execute.
</p>
<p>
Next, add the body to the save method:
<div class="code">
<pre>
// when the page finishes loading, execute the findEditables function
Event.observe(window, 'load', findEditables);

function findEditables(event) {
  // collect the elements with class="editable" into an array
  var elements = $$('.editable');
  // create a new Editable object for each element
  elements.each(function(el){
    new Editable(el);
  });
}  


/* 
  The Editable class transforms an html element so that 
  it can be edited when clicked. 
*/
var Editable = Class.create({
  
  /* constructor */
  initialize: function(element) {
    this.element = $(element);
    this.editor = this.createEditor();
    this.boundEdit = this.edit.bind(this);
    this.boundSave = this.save.bind(this);
    this.element.observe('click', this.boundEdit);
  },
  
  createEditor: function() {
    // find computed width and height of element we are editing
    var dimensions = this.element.getDimensions();
    var editor = new Element('textarea');
    editor.setStyle({
      width: dimensions.width+'px', 
      height: dimensions.height+'px'
    });
    return editor;
   },
  
  edit: function(event) {
    this.element.stopObserving('click', this.boundEdit);
    var content = this.element.innerHTML;
    this.editor.value = content;    
    this.element.update(this.editor);
    Event.observe(document, 'click', this.boundSave);
  },
  
  save: function(event){
<div style="background-color: #ccffcc">
    var eventElement = event.element();  
    if(eventElement.descendantOf(this.element) || eventElement == this.element) return;
    Event.stopObserving(document, 'click', this.boundSave);
    var content = $F(this.editor);
    content = content.gsub(/[\r\n]/, '');
    this.element.update(content);
    this.element.observe('click', this.boundEdit);    
</div>
  }
});
</pre>
</div>
</p>
<p>
In line 1 of the save method, we retrieve the element that the event occurred on, i.e. the element that the user clicked on. In line 2, we check to see if that element is the editable element or is a <em>descendant of</em> the editable element. If it is, we return because we don't want to execute the save method unless the user clicks outside of the element they are editing.
</p>
<p>
In line 3 the click event handler is removed from the Document object. In line 4, the content of the editor is stored in a local variable. <em>$F( )</em> is another handy utility method provided by Prototype that returns the value of a form control (see the <a href="http://www.prototypejs.org/api/form/element/getValue">documentation for getValue</a>). In our case it returns the value of the editor textarea. In line 5, we use a regular expression to remove new line characters from the content. Finally, the content of the editable element is updated with the new value and the click event handler is reset  on the editable element. Reload index.html in your web browser and click on one of the editable elements. You can change the content and when you click away, the element is updated with the new content.
</p>

<p>
The Editable class is almost complete. Whenever input is collected on a web page we need to consider security. We don't want users to enter HTML into our editable elements because they could break the page layout or worse, execute malicious JavaScript on our page. To see the potential harm, load index.html in your browser and enter some HTML into an editable element. Depending on what you enter, you can break the editable elements and even the whole page. Now enter the following JavaScript into an editable element:
<div class="code">
<pre>
&lt;script&gt;
alert('Hello world');
&lt;/script&gt;
</pre>
</div>
</p>
<p>
When the element is saved the JavaScript executes on the page. To avoid these two scenarios we use Prototype's <a href="http://www.prototypejs.org/api/string/escapeHTML">String.escapeHTML</a> and <a href="http://www.prototypejs.org/api/string/unescapeHTML">String.unescapeHTML</a> functions. Modify the save method as follows:
<div class="code">
<pre>
// when the page finishes loading, execute the findEditables function
Event.observe(window, 'load', findEditables);

function findEditables(event) {
  // collect the elements with class="editable" into an array
  var elements = $$('.editable');
  // create a new Editable object for each element
  elements.each(function(el){
    new Editable(el);
  });
}  


/* 
  The Editable class transforms an html element so that 
  it can be edited when clicked. 
*/
var Editable = Class.create({
  
  /* constructor */
  initialize: function(element) {
    this.element = $(element);
    this.editor = this.createEditor();
    this.boundEdit = this.edit.bind(this);
    this.boundSave = this.save.bind(this);
    this.element.observe('click', this.boundEdit);
  },
  
  createEditor: function() {
    // find computed width and height of element we are editing
    var dimensions = this.element.getDimensions();
    var editor = new Element('textarea');
    editor.setStyle({
      width: dimensions.width+'px', 
      height: dimensions.height+'px'
    });
    return editor;
   },
  
  edit: function(event) {
    this.element.stopObserving('click', this.boundEdit);
    var content = this.element.innerHTML;
    <span style="background-color: #ccffcc">content = content.unescapeHTML();</span>
    this.editor.value = content;    
    this.element.update(this.editor);
    Event.observe(document, 'click', this.boundSave);
  },
  
  save: function(event){
    var eventElement = event.element();  
    if(eventElement.descendantOf(this.element) || eventElement == this.element) return;
    Event.stopObserving(document, 'click', this.boundSave);
    var content = $F(this.editor);
    content = content.gsub(/[\r\n]/, '');  
    <span style="background-color: #ccffcc">content = content.escapeHTML();</span>
    this.element.update(content);
    this.element.observe('click', this.boundEdit);
  }
});
</pre>
</div>
</p>
<p> 
Now our web page can't be hacked with HTML or JavaScript and the Editable class is complete. Part 2 of the tutorial will describe how to use Ajax to store the new values in a database and provide some example uses of this code. 
</p>]]>
        
    </content>
</entry>

</feed>
