Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

These changes contain a almost fully functional implementation of the…

… Book page for the books project that uses

the click framework.
  • Loading branch information...
commit 8c5972a8ae3abb9aa91ef34634945a93471f828e 1 parent 5104bd1
ccorsi authored
5 persistence/books/web/click/.project
View
@@ -3,9 +3,10 @@
<name>BooksClick</name>
<comment></comment>
<projects>
- <project>BooksXML</project>
- <project>BooksPersistenceBase</project>
<project>BooksCommonWeb</project>
+ <project>BooksJavaScripts</project>
+ <project>BooksPersistenceBase</project>
+ <project>BooksXML</project>
</projects>
<buildSpec>
<buildCommand>
103 persistence/books/web/click/JOURNAL
View
@@ -7,7 +7,7 @@ using the Click web framework for the Books persistent layer.
Created a dynamic web project that will be using the Apache Click web framework.
-The Eclipse IDE plugin for Click 2.2.0 has as of this date not been released. There is a version for the
+The Eclipse IDE plug-in for Click 2.2.0 has as of this date not been released. There is a version for the
Click 2.1.0 release but that is not what I using. By forcing me to look at how to configure click.xml and
web.xml files. It provides will a unique advantage of understanding better how these configuration files are
setup and why that are setup this way.
@@ -62,10 +62,10 @@ and BooksClick projects.
===========
While trying to add logging statements within the different Click specific implementations. I noticed that the
-ServletContext associated to the ConfigService class was not initialized during the onInit callback but that it
-was initialized during the onDestroy callback. When I have time, I will try to determine why this is the case.
+ServletContext associated to the ConfigService class was not initialized during the onInit call-back but that it
+was initialized during the onDestroy call-back. When I have time, I will try to determine why this is the case.
It could be possible that this is a click or tomcat bug. The logging mechanism should already be enabled during
-this callback.
+this call-back.
2010-09-19:
===========
@@ -83,7 +83,7 @@ able to submit the select book to edit.
2010-09-20:
===========
-In the process of trying to create a simple table with a hypelink to the book that a user would
+In the process of trying to create a simple table with a hyper-link to the book that a user would
like to edit, I noticed a few things that required my changes. Some of these hacks can be
wrong but at this time that is what I was able to do to get my page up and running. I hope to
correct this hack and replace it with the correct approach to generate a table to contains page
@@ -119,9 +119,96 @@ been remove which is good.
I've completed the initial book page but currently it only displays information about the
type of book page we are displaying, a new or edit book page. The home page needs to updating
such that it will contain the ability to create a new book and edit a new book. The BookPage
-instane will then be used to populate both types of requests depending on the parameters passed
-to the BookPage. The parameter "action" will determine the type of page. The paramerer "bookId"
+instance will then be used to populate both types of requests depending on the parameters passed
+to the BookPage. The parameter "action" will determine the type of page. The parameter "bookId"
will be defined a request to edit a book. This will contain the identification of the book that
we are going to be updating.
-
+I've added some code to display a subset of the fields of the a selected book to be created or
+updated. I was initially having trouble getting the submit button to function properly and
+after several attempts to get the submit process to call the assigned callback. I decided to
+update the form action attribute depending on what I expect the form to do. Using the submit
+button names and the action attribute. I was able to process a new or update action correctly.
+
+My next step was to try and create a simple update the book subtitles. I figured that a simple
+add and remove submit buttons should do the trick. Alas, I was wrong, it is true that those
+buttons causes the form to process the request but the problem is that I'm unable to clear the
+field that contained the subtitle that was added. I've tried to set the value to an empty string
+but that did not work. Maybe this is a bug with Click. Maybe, I'll send this issue to the developer
+list. I just tried to clear the value during the onRender call-back and I was able to clear the
+value for the subtitle text field. I also had the issue that my title for the page was also clearer
+and I used the same technique by updating the title field in the onRender call-back and I was able
+to preserve the correct title setting. Why does the Click framework override these values? Is it
+possible that it is caching the values and it is reusing the cached values. This could be possible
+and I will need to determine if there is a parameter that allows me to disable caching for this
+page.
+
+2010-09-22:
+===========
+
+Making changes to the book page to add the remaining fields required to be able to create or update
+a book. Replacing the automatic generating of the table field to tag specific entries within the
+book page. This is being done to mimic the same interface that the was implemented with the ZK
+framework.
+
+Added most of the same interface as in the ZK example and also included some work on integer input
+validation javascript for the number of pages input field.
+
+ 2010-09-23:
+ ===========
+
+ Completed the remaining fields required for the new/edit book windows. Working on the ability to
+ create an embedded window for the author,editor,translator,illustrator and gender windows that are
+ used to create new instances of those fields. When the open window is closed, the updates will be
+ propagated to the server and the parent window.
+
+ 2010-09-27:
+ ===========
+
+ Created the javascript code that updates the web page create author action. This code works properly
+ with FireFox 3.6 but it fails miserably for IE7. After multiple days of determining what is wrong and
+ how to work around this issue. I noticed that the element setAttribute method does not work on IE7.
+ Searching the internet confirmed that this is the case. I decided to create the form without using
+ the element objects but by creating the html string and replacing the innerHTML. That approach did
+ not work. I can not believe the IE7 doesn't even implement some basic functions. This is something
+ that I can not understand. Oh well, I going to try and use the xmlhttprequest object and see if that
+ solution will work.
+
+ After using the xmlhttprequest object with IE7, I noticed something interested with how IE7 works with
+ respect to DOM objects. It looks like IE7 does not allow you to update an element innerHTML property
+ once this has been set! While firefox allows you to update this property. To workaround this issue,
+ you need to create a new element with the same tag name as the element innerHTML property you want
+ to replace and set the new element innerHTML property. You then replace the old element with the
+ new element. This process works for IE7 using the xmlhttprequest object.
+
+ 2010-09-28:
+ ===========
+
+ Here goes another wasteful day trying to figure out how to get the javascript code work for IE and
+ firefox. I now have it generating the form for the create author in IE but if I click on the
+ create or cancel button an exception is generated. I output the generated html and it is different
+ than the one that is sent over the wire! Now that IE is partially working, firefox implementation
+ is failing all together. I should of kept the firefox version since this was working.
+
+ Well after many days of figuring out how to produce the same effect on firefox and IE7, I've finally
+ succeeded in doing just that. I was able to get the create author/editor/translator/illustrator
+ buttons to replace the current column with a form that you enter its name and last name information
+ that will be sent to the server to update the current session author/editor/translator/illustrator
+ persons and the databases person information. I will then proceed to add the newly created person
+ to the selection list. This is my next step to try and complete this current work, wish me luck.
+
+ I was able to add the required javascript code to move selected person from one list to the other.
+ My next task will be to send those updates to the server and have the server update the book
+ instance while the client javascript updates the controls.
+
+2010-09-30:
+===========
+
+Before adding the required code to send the updates to the server, I am removing javascript code that is
+not going to be used any longer.
+
+Completed the removal of dead JavaScript code and tested that all of the current functionality is
+working correctly.
+
+Added the initial work of populating the controls with the editing books properties. The current
+updates have been tested successfully.
184 persistence/books/web/click/WebContent/book.htm
View
@@ -4,8 +4,190 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>$title</title>
+<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js" type="text/javascript">
+</script>
+<script type="text/javascript" src="scripts/books.js">
+
+</script>
+ <script type="text/javascript">
+
+ var value;
+
+ function storeValue(id) {
+ var element = document.getElementById(id);
+ if (element) {
+ if (/^\d+$/.test(element.value)) {
+ // alert('setting value to ' + element.value);
+ value = element.value;
+ } else {
+ isInteger(id);
+ }
+ }
+ }
+
+ function isInteger(id) {
+ var element = document.getElementById(id);
+ if (element) {
+ if (element.value) {
+ if (!/^\d+$/.test(element.value)) {
+ // alert('reseting value to ' + value);
+ element.value = value;
+ }
+ }
+ }
+ }
+
+ function displayEvent(event,id) {
+ var element = document.getElementById(id);
+ if (element) {
+ alert(event + ' value=' + element.value);
+ } else {
+ alert(event + ' no value for id=' + id);
+ }
+ }
+
+ </script>
+<style type="css">
+#button {
+ width: 150px;
+}
+</style>
</head>
<body>
- $title
+
+<!-- Create a Table that will contain all of the required
+ inputs or this would be better to create a form -->
+$title
+
+<p />
+
+<form action="book.htm?$action">
+
+<table summary="$summary" border="1">
+ <tr>
+ <td>Title:</td>
+ <td>
+ <input style="width: 150px" type="text" name="title" value="#if($book)${book.title}#end"/>
+ </td>
+ </tr>
+ <tr>
+ <td>SubTitles:</td>
+ <td><select name="subtitles" style="width: 150px" size="2"
+ id="subtitles">
+ #if ($book)
+ #foreach ($subtitle in $book.subTitles)
+ <option>$subtitle</option>
+ #end
+ #end
+ </select></td>
+ <td>SubTitle:</td>
+ <td><input style="width: 150px" type="text" name="subtitle"/></td>
+ <td><input type="button" style="width: 150px"
+ value="Add SubTitle" onclick="add();" /><br />
+ <input type="button" style="width: 150px" value="Remove SubTitle"
+ onclick="remove();" /></td>
+ </tr>
+ <tr>
+ <td>Series:</td>
+ <td><input style="width: 150px" type="text" name="series" value="#if($book)${book.series}#end"/></td>
+ </tr>
+ <tr>
+ <td>Pages:</td>
+ <td><input style="width: 150px" type="text" value="#if($book)${book.pages}#end"
+ onfocus="storeValue('pages'); " onblur="storeValue('pages');"
+ onkeypress="storeValue('pages');" id="pages" name="pages"/>
+ </td>
+ </tr>
+ <tr>
+ <td>Authors:</td>
+ <td><select style="width: 150px" size="3" id="authors">
+ #if ($book) #foreach ($author in $book.authors)
+ <option id="$author.id">$author.fullName</option>
+ #end #end
+ </select></td>
+ <td align="center"><input type="button" value="&lt;&lt;"
+ onclick="books.add_person('authors_list','authors','author');" /> <br />
+ <input type="button" value="&gt;&gt;"
+ onclick="books.remove_person('authors','authors_list','author');" />
+ </td>
+ <td><select style="width: 150px" size="3" id="authors_list">
+ #if ($book) #foreach ($author in $book.allAuthors)
+ <option id="$author.id">$author.fullName</option>
+ #end #end
+ </select></td>
+ <td id="create_author"><input type="button" value="Create Author" onclick="books.create_author_action('create_author','authors');" />
+ </td>
+ </tr>
+ <tr>
+ <td>Editors:</td>
+ <td><select style="width: 150px" size="3" id="editors">
+ #if ($book) #foreach ($editor in $book.editors)
+ <option id="$editor.id">$editor.fullName</option>
+ #end #end
+ </select></td>
+ <td align="center"><input type="button" value="&lt;&lt;"
+ onclick="books.add_person('editors_list','editors','editor');" /> <br />
+ <input type="button" value="&gt;&gt;"
+ onclick="books.remove_person('editors','editors_list','editor');" />
+ </td>
+ <td><select style="width: 150px" size="3" id="editors_list">
+ #if ($book) #foreach ($editor in $book.allEditors)
+ <option id="$editor.id">$editor.name</option>
+ #end #end
+ </select></td>
+ <td id="create_editor"><input type="button" value="Create Editor"
+ onclick="books.create_editor_action('create_editor','editors');" /></td>
+ </tr>
+ <tr>
+ <td>Illustrators:</td>
+ <td><select style="width: 150px" size="3" id="illustrators">
+ #if ($book) #foreach ($illustrator in $book.illustrators)
+ <option id="$illustrator.id">$illustrator.fullName</option>
+ #end #end
+ </select></td>
+ <td align="center"><input type="button" value="&lt;&lt;"
+ onclick="books.add_person('illustrators_list','illustrators','illustrator');" />
+ <br />
+ <input type="button" value="&gt;&gt;"
+ onclick="books.remove_person('illustrators','illustrators_list','illustrator');" />
+ </td>
+ <td><select style="width: 150px" size="3" id="illustrators_list">
+ #if ($book) #foreach ($illustrator in $book.allIllustrators)
+ <option id="$illustrator.id">$illustrator.name</option>
+ #end #end
+ </select></td>
+ <td id="create_illustrator"><input type="button"
+ value="Create Illustrator"
+ onclick="books.create_illustrator_action('create_illustrator','illustrators');" />
+ </td>
+ </tr>
+ <tr>
+ <td>Translators:</td>
+ <td><select style="width: 150px" size="3" id="translators">
+ #if ($book) #foreach ($translator in $book.translators)
+ <option id="$translator.id">$translator.fullName</option>
+ #end #end
+ </select></td>
+ <td align="center"><input type="button" value="&lt;&lt;"
+ onclick="books.add_person('translators_list','translators','translator');" />
+ <br />
+ <input type="button" value="&gt;&gt;"
+ onclick="books.remove_person('translators','translators_list','translator');" />
+ </td>
+ <td><select style="width: 150px" size="3" id="translators_list">
+ #if ($book) #foreach ($translator in $book.allTranslators)
+ <option id="$translator.id">$translator.name</option>
+ #end #end
+ </select></td>
+ <td id="create_translator"><input type="button"
+ value="Create Translator"
+ onclick="books.create_translator_action('create_translator','translators');" />
+ </td>
+ </tr>
+</table>
+</form>
+
+$form
+
</body>
</html>
24 persistence/books/web/click/WebContent/person.htm
View
@@ -0,0 +1,24 @@
+<form id="${name}_form">
+ <table>
+ <tr>
+ <td> Name: </td>
+ <td>
+ <input type="text" id="${name}_name"></input>"
+ </td>
+ </tr>
+ <tr>
+ <td> Last Name: </td>
+ <td>
+ <input type="text" id="${name}_lname"></input>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="button" value="Create" onclick="books.actions[$idx].create();"></input>
+ </td>
+ <td>
+ <input type="button" value="Cancel" onclick="books.actions[$idx].cancel();"></input>
+ </td>
+ </tr>
+ </table>
+</form>
284 persistence/books/web/click/WebContent/scripts/books.js
View
@@ -0,0 +1,284 @@
+
+// Note that the window object needs to be passed because it will not be defined within
+// this javascript file....
+function getxmlhttprequest(window) {
+ var xmlhttp;
+ if (window.XDomainRequest) { // code for IE8+ more "secure" than XMLHttpRequest
+ xmlhttp = new XDomainRequest();
+ } else if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
+ xmlhttp = new XMLHttpRequest();
+ } else { // code for IE6, IE5
+ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+ }
+ return xmlhttp;
+}
+
+// This function will update the elements style display option to the not of its
+// current state...
+function updateDisplay(id) {
+ var element = document.getElementById(id);
+ if (element) { // Determine if the element was found...
+ if (element.style.display == "none") {
+ element.style.display = "block";
+ } else {
+ element.style.display = "none";
+ }
+ }
+}
+
+// This will update an array of ids using the updateDisplay function...
+function updateDisplays(ids)
+{
+ var id = 0;
+ while (id < ids.length) {
+ updateDisplay(ids[id]);
+ id++;
+ }
+}
+
+// Generate a global books variable that can be used to update the current window...
+var books = new books();
+
+// Main object that manages all of the books web site JavaScript functionality.
+function books() {
+ this.create_element = function(name,parent) {
+ var element = document.createElement(name);
+ if (parent) {
+ parent.appendChild(element);
+ }
+ return element;
+ };
+ // used to determine how to generate elements
+ // TODO: Replace this check with something like:
+ // this.isSetAttributesSupported = document.createElement("foo").setAttribute;
+ // This is to counteract the fact that not all browsers support the navigator object, i.e. Safari...
+ this.isIE = /Internet Explorer/.test(navigator.appName);
+ // This will contain the defined actions for the current web page
+ this.actions = [];
+ // This function is used to create and/or replace the create author
+ // button
+ this.create_author_action = function (id,select) {
+ if (this.actions[0] == null) {
+ // Generate the element to replace the current one
+ this.generate_create_person(id,'author',0,select);
+ }
+ this.actions[0].swap();
+ };
+ // This function will move the option from the person list selection to the person selection
+ // It will then send the change to the server so that the session book instance is updated
+ this.add_person = function(from,to,type) {
+ var persons_list = document.getElementById(from);
+ var persons = document.getElementById(to);
+ var option = this.move_selected_person(persons_list, persons);
+ if (option) {
+ // Send update to the server...
+ }
+ };
+ // This function will move the option from the person selection to the person list selection
+ // It will then send the change to the server so that the session book instance is updated
+ this.remove_person = function(from,to,type) {
+ var persons = document.getElementById(from);
+ var persons_list = document.getElementById(to);
+ var option = this.move_selected_person(persons, persons_list);
+ if (option) {
+ // Send update to the server....
+ }
+ };
+ // This function will move the option from one selection list to another if and only if
+ // an option was selected from the from list.
+ // It will return the moved option or null.
+ this.move_selected_person = function (from,to) {
+ if (from.selectedIndex >= 0) {
+ var option = from.options[from.selectedIndex];
+ from.removeChild(option);
+ to.appendChild(option);
+ return option;
+ } else {
+ return null;
+ }
+ };
+ // This function is used to create and/or replace the create editor
+ // button
+ this.create_editor_action = function (id,select) {
+ if (this.actions[1] == null) {
+ // Generate the element to replace the current one
+ this.generate_create_person(id,'editor',1,select);
+ }
+ this.actions[1].swap();
+ };
+ // This function is used to create and/or replace the create illustrator
+ // button
+ this.create_illustrator_action = function (id,select) {
+ if (this.actions[2] == null) {
+ // Generate the element to replace the current one
+ this.generate_create_person(id,'illustrator',2,select);
+ }
+ this.actions[2].swap();
+ };
+ // This function is used to create and/or replace the create translator
+ // button
+ this.create_translator_action = function (id,select) {
+ if (this.actions[3] == null) {
+ // Generate the element to replace the current one
+ this.generate_create_person(id,'translator',3,select);
+ }
+ this.actions[3].swap();
+ };
+ // This is the action object that will be used swap elements.
+ this.action = function(id,prefix,create_person_element,person_action_element,selectId) {
+ // this is the prefix used for the input field for the name and last name
+ this.prefix = prefix;
+ // this is the element button that was clicked to generate create dynamic form
+ this.create_person_element = create_person_element;
+ // this is the element replacing the prior element
+ this.person_action_element = person_action_element;
+ // this is the element being replaced innerHTML
+ this.innerHTML = this.person_action_element.innerHTML;
+ // current node being displayed.
+ this.currentNode = this.create_person_element;
+ // next node that will be displayed.
+ this.nextNode = this.person_action_element;
+ // this is the select element that we will add the person
+ this.selectId = selectId;
+ // Create a the create button callback
+ this.create = function () {
+ // Get the values of the different input buttons....
+ var name = document.getElementById(this.prefix + "_name");
+ var lname = document.getElementById(this.prefix + "_lname");
+ // alert("(" + name.value + "," + lname.value + ")");
+ this.swap();
+ this.select = document.getElementById(this.selectId);
+ this.option_value = name.value + " " + lname.value;
+ this.add_option();
+ this.clear_values(name,lname);
+ };
+ // This method is called to add an option to the select list
+ if (books.isIE) {
+ this.add_option = function () {
+ // Don't know what to do....
+ var option = document.createElement("option"); // new Option(this.option_value,this.option_value);
+ option.value = this.select.length + 1;
+ option.text = this.option_value;
+ option.id = this.select.length + 1;
+ this.select.options[this.select.length] = option;
+ };
+ } else {
+ this.add_option = function () {
+ var option = new Option(this.option_value,this.option_value); // document.createElement("option");
+ option.setAttribute("id", this.select.length + 1);
+ option.setAttribute("text", this.option_value);
+ option.setAttribute("value", this.select.length + 1);
+ this.select.appendChild(option); // add(option);
+ };
+ }
+ this.clear_values = function(name,lname) {
+ name.value = "";
+ lname.value = "";
+ };
+ // Create the cancel button callback
+ this.cancel = function () {
+ var name = document.getElementById(this.prefix + "_name");
+ var lname = document.getElementById(this.prefix + "_lname");
+ this.swap();
+ this.clear_values(name,lname);
+ };
+ // create the swap function depending on what type of browser we are working on.
+ if (books.isIE) {
+ // this function will swap the elements associated with this object
+ this.swap = function () {
+ // Replace current element with prior element...
+ var parentNode = this.currentNode.parentNode;
+ parentNode.removeChild(this.currentNode);
+ parentNode.appendChild(this.nextNode);
+ var currentNode = this.currentNode;
+ this.currentNode = this.nextNode;
+ this.nextNode = currentNode;
+ /*
+ parentNode.replaceChild(this.person_action_element,
+ this.create_person_element);
+ */
+ };
+ } else {
+ this.swap = function () {
+ var element = document.getElementById(id);
+ var innerHTML = element.innerHTML;
+ element.innerHTML = this.innerHTML;
+ this.innerHTML = innerHTML;
+ };
+ }
+ };
+ // Create will generate the person action for the passed name/idx....
+ this.generate_create_person_for_IE = function(id,name,idx,select) {
+ var xmlHttpRequest = getxmlhttprequest(window);
+ xmlHttpRequest.open('get','person.htm?name=' + name + '&idx=' + idx, false );
+ xmlHttpRequest.send(null);
+ var current = document.getElementById(id);
+ var next = document.createElement(current.tagName);
+ next.innerHTML = xmlHttpRequest.responseText;
+ this.actions[idx] = new this.action(id,name,current,next,select);
+ };
+ // this function is used to create the create person control.
+ this.generate_create_person = function(id,name,idx,select) {
+ if (this.isIE) {
+ this.generate_create_person_for_IE(id,name,idx,select);
+ } else {
+ // Get a reference to the element containing the create button
+ var current = document.getElementById(id);
+ // create the form element
+ var form = this.create_element("form");
+ // create the table element
+ var table = this.create_element("table",form);
+ // create the first row
+ var tr = this.create_element("tr", table);
+ // create row/col <1,1> with Name: text
+ var td = this.create_element("td", tr);
+ td.innerHTML = " Name: ";
+ // create row/col <2,1> with Last Name: text
+ td = this.create_element("td", tr);
+ var input = this.create_element("input",td);
+ var attrs = new this.attributes(input);
+ attrs.setAttr("type","text");
+ attrs.setAttr("id", name.concat("_name"));
+ // create second row
+ tr = this.create_element("tr", table);
+ td = this.create_element("td",tr);
+ td.innerHTML = " Last Name: ";
+ // create row/col <3,1> with Create button
+ td = this.create_element("td",tr);
+ input = this.create_element("input",td);
+ attrs = new this.attributes(input);
+ attrs.setAttr("type","text");
+ attrs.setAttr("id", name.concat("_lname"));
+ // create third row
+ tr = this.create_element("tr",table);
+ td = this.create_element("td",tr);
+ // create Create button
+ input = this.create_element("input",td);
+ attrs = new this.attributes(input);
+ attrs.setAttr("type","button");
+ attrs.setAttr("value", "Create");
+ attrs.setAttr("onclick", "books.actions[".concat(idx).concat("].create();"));
+ td = this.create_element("td",tr);
+ // create Cancel button
+ input = this.create_element("input",td);
+ attrs = new this.attributes(input);
+ attrs.setAttr("type", "button");
+ attrs.setAttr("value", "Cancel");
+ attrs.setAttr("onclick", "books.actions[".concat(idx).concat("].cancel();"));
+ // Create an instance of the action object that will be used to
+ // process the callback and reset the html to its previous state
+ this.actions[idx] = new this.action(id,name,current,form,select);
+ }
+ };
+ this.attributes = function(element) {
+ this.element = element;
+ this.setAttr = function (name,value) {
+ try {
+ this.element.setAttribute(name,value);
+ } catch(err) {
+ alert("Browser does not support setAttribute method".concat(err.description));
+ throw err;
+ }
+ };
+ };
+}
11 persistence/books/web/click/WebContent/welcome.html
View
@@ -11,12 +11,15 @@
#if ($msg)
<div id="header"> <span id="title">$msg</span></div>
#end
-
+
$table
+
+<div id="create">
+ $form
+</div>
- $form
-
+<!--
$create_book
-
+-->
</body>
</html>
342 persistence/books/web/click/src/org/books/page/BookPage.java
View
@@ -23,10 +23,21 @@
*/
package org.books.page;
+import java.util.Enumeration;
import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+
import org.apache.click.Page;
+import org.apache.click.control.Form;
+import org.apache.click.control.HiddenField;
+import org.apache.click.control.Option;
+import org.apache.click.control.Select;
+import org.apache.click.control.Submit;
+import org.apache.click.control.TextField;
+import org.apache.click.service.LogService;
import org.apache.click.util.Bindable;
+import org.apache.click.util.ClickUtils;
import org.books.proxy.BookProxy;
/**
@@ -43,28 +54,341 @@
*/
public class BookPage extends Page {
+ private static final String SUBTITLE = "subtitle";
+
+ private static final String SUBTITLEREMOVE = "subtitle_remove";
+
+ private static final String PAGETITLE = "page_title";
+
+ private static final String CANCEL = "cancel";
+
+ private static final String OK = "ok";
+
+ private static final String SUBTITLEADD = "subtitle_add";
+
+ private static final String BOOKID = "bookId";
+
+ private static final String SERIES = "Series";
+
+ private static final String SUBTITLES = "SubTitles";
+
+ private static final String TITLE = "title";
+
/**
*
*/
private static final long serialVersionUID = 1L;
@Bindable protected String title;
+
+ @Bindable protected Form form = null;
+
+ @Bindable protected String action = "New";
+
+ @Bindable protected BookRender book;
+
+ private String new_title = null;
+
+ private LogService logger;
public BookPage() {
+ logger = ClickUtils.getConfigService(this.getContext().getServletContext()).getLogService();
String action = this.getContext().getRequestParameter("action");
+ logger.debug("action=" + action);
if ("Edit".equals(action)) {
- this.title = "Edit Book Luciano Szekely Corsi";
- String identifier = this.getContext().getRequestParameter("bookId");
- Map<String,BookProxy> books = (Map<String,BookProxy>) this.getContext().getSessionAttribute("books");
- System.out.println("bookId=" + identifier);
- System.out.println("books=" + books);
- BookProxy book = books.get(identifier);
- System.out.println("book=" + book.getBook());
+ processEditAction();
} else if ("New".equals(action)) {
- this.title = "Create Book Luciano Szekely Corsi";
+ processNewAction();
+ } else if ("Update".equals(action)){
+ processUpdateAction();
+ } else if ("Create".equals(action)) {
+ processCreateAction();
} else {
- this.title = "Unknown Book Action Type Luciano Szekely Corsi";
+ logger.debug("No action defined");
+ this.setRedirect(HomePage.class);
}
+ logger.debug("ctor");
+ }
+
+ /**
+ *
+ */
+ private void processCreateAction() {
+ logger.debug("Create action");
+ HttpServletRequest request = this.getContext().getRequest();
+ logParameters(request);
+ this.setRedirect(HomePage.class);
+ }
+
+ /**
+ * @param request
+ */
+ private void logParameters(HttpServletRequest request) {
+ Enumeration<?> names = request.getParameterNames();
+ while (names.hasMoreElements()) {
+ Object name = names.nextElement();
+ logger.debug(name + "=" + this.getContext().getRequest().getParameter(name.toString()));
+ }
+ }
+
+ /**
+ *
+ */
+ private void processUpdateAction() {
+ logger.debug("Update action");
+ HttpServletRequest request = this.getContext().getRequest();
+ // This will get a reference to the current BookProxy associated with this session.
+ this.book = new BookRender(this.getSessionBookProxy());
+ if (request.getParameter(OK) != null) {
+ logger.debug("Processing OK request");
+ logParameters(request);
+ this.setRedirect(HomePage.class);
+ } else if (request.getParameter(CANCEL) != null) {
+ logger.debug("Processing Cancel request");
+ logParameters(request);
+ this.setRedirect(HomePage.class);
+ } else if (request.getParameter(SUBTITLEADD) != null) {
+ this.title = this.new_title = request.getParameter(PAGETITLE);
+ logger.debug("Processing subtitle add");
+ logger.debug("title="+this.title);
+ logParameters(request);
+ BookProxy book = getSessionBookProxy();
+ if (book != null) {
+ logger.debug("Updating book subtitle");
+ String subtitle = request.getParameter(SUBTITLE);
+ if (subtitle != null & subtitle.length() > 0) {
+ book.addSubtitle(subtitle);
+ }
+ this.generateForm(book, request.getParameter(BOOKID));
+ setFormLabelsForEditBook();
+ } else {
+ // Create a new instance of BookProxy and generate the
+ // required settings...
+ logger.debug("No book to update!");
+ generateForm();
+ setFormLabelsForNewBook();
+ }
+ logger.debug("title="+this.title);
+ logger.debug("subtitle value=" + ((TextField)getControl(SUBTITLE)).getValue());
+ this.setTemplate("book.htm");
+ } else if (request.getParameter(SUBTITLEREMOVE) != null) {
+ this.title = this.new_title = request.getParameter(PAGETITLE);
+ logger.debug("Processing subtitle remove");
+ logger.debug("title="+this.title);
+ logParameters(request);
+ BookProxy book = getSessionBookProxy();
+ if (book != null) {
+ logger.debug("Updating book subtitle");
+ String subtitle = request.getParameter(SUBTITLES);
+ book.getSubtitles().remove(subtitle);
+ this.generateForm(book, request.getParameter(BOOKID));
+ setFormLabelsForEditBook();
+ } else {
+ // Create a new instance of BookProxy and generate the
+ // required settings...
+ logger.debug("No book to update!!!!!");
+ generateForm();
+ setFormLabelsForNewBook();
+ }
+ logger.debug("title="+this.title);
+ this.setTemplate("book.htm");
+ } else {
+ logger.debug("unknown request");
+ logParameters(request);
+ this.setRedirect(HomePage.class);
+ }
+ }
+
+ /**
+ * @return
+ */
+ private BookProxy getSessionBookProxy() {
+ return BookProxy.class.cast(this.getContext().getSessionAttribute("book"));
+ }
+
+ /**
+ *
+ */
+ private void processNewAction() {
+ this.title = "Create Book Luciano Szekely Corsi";
+ generateForm();
+ setFormLabelsForNewBook();
this.setTemplate("book.htm");
+ // This will create a transient book
+ BookProxy book = BookProxy.createBookProxy(null);
+ this.book = new BookRender(book);
}
+
+ /**
+ *
+ */
+ @SuppressWarnings("unchecked")
+ private void processEditAction() {
+ this.title = "Edit Book Luciano Szekely Corsi";
+ String identifier = this.getContext().getRequestParameter("bookId");
+ Map<String,BookProxy> books = (Map<String,BookProxy>) this.getContext().getSessionAttribute("books");
+ logger.trace("bookId=" + identifier);
+ logger.trace("books=" + books);
+ BookProxy book = books.get(identifier);
+ logger.trace("book=" + book.getBook());
+ generateForm(book, identifier);
+ setFormLabelsForEditBook();
+ this.getContext().setSessionAttribute("book", book);
+ this.setTemplate("book.htm");
+ this.book = new BookRender(book);
+ }
+
+ private void setFormLabelsForNewBook() {
+ Submit submit = getControl(OK);
+ submit.setLabel("Create");
+ form.setActionURL("book.htm?action=Create");
+ }
+
+ private void setFormLabelsForEditBook() {
+ Submit submit = getControl(OK);
+ submit.setLabel("Update");
+ form.setActionURL("book.htm?action=Update");
+ }
+
+ private void generateForm() {
+ // TODO Auto-generated method stub
+ form = new Form();
+ form.setId("BookForm");
+ form.setActionURL("book.htm?action=Update");
+ form.setJavaScriptValidation(true);
+ TextField text = new TextField(TITLE);
+ form.add(text);
+ Select select = new Select(SUBTITLES);
+ form.add(select);
+ text = new TextField(SUBTITLE);
+ form.add(text);
+ Submit submit = new Submit(SUBTITLEADD);
+ form.add(submit);
+ submit = new Submit(SUBTITLEREMOVE);
+ form.add(submit);
+ text = new TextField(SERIES);
+ form.add(text);
+ HiddenField hidden = new HiddenField(BOOKID,"");
+ form.add(hidden);
+ hidden = new HiddenField(PAGETITLE,this.title);
+ form.add(hidden);
+ submit = new Submit(OK);
+ form.add(submit);
+ submit = new Submit(CANCEL, "Cancel");
+ form.add(submit);
+
+ }
+
+ private void generateForm(BookProxy book, String identifier) {
+ // TODO Auto-generated method stub
+ this.generateForm();
+ TextField text = this.getControl(TITLE);
+ text.setValue(book.getTitle());
+ Select select = getControl(SUBTITLES);
+ for (String subtitle : book.getSubtitles()) {
+ Option option = new Option(subtitle);
+ select.add(option);
+ }
+ text = getControl(BookPage.SERIES);
+ text.setValue(book.getSeries());
+ HiddenField bookId = getControl(BOOKID);
+ bookId.setValue(identifier);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> T getControl(String name) {
+ return (T) ((this.form != null) ? this.form.getControl(name) : null);
+ }
+
+ public boolean onOkClick() {
+ logger.debug("###################### onOkClick ##############");
+ String title = this.getContext().getRequestParameter(TITLE);
+ logger.debug("Title value is " + title);
+ this.setRedirect("home.htm");
+ // System.out.println("Title value is " + title);
+ return false;
+ }
+
+ public boolean onCancelClick() {
+ logger.debug("onCancel");
+ this.setRedirect("home.htm");
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#onDestroy()
+ */
+ @Override
+ public void onDestroy() {
+ logger.debug("onDestroy");
+ logger.debug("subtitle value=" + ((TextField)getControl(SUBTITLE)));
+ super.onDestroy();
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#onGet()
+ */
+ @Override
+ public void onGet() {
+ logger.debug("onGet");
+ logger.debug("subtitle value=" + ((TextField)getControl(SUBTITLE)));
+ super.onGet();
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#onInit()
+ */
+ @Override
+ public void onInit() {
+ logger.debug("onInit");
+ logger.debug("subtitle value=" + ((TextField)getControl(SUBTITLE)));
+ HttpServletRequest request = this.getContext().getRequest();
+ logger.debug(request.getParameterMap());
+ Enumeration<?> names = request.getHeaderNames();
+ while (names.hasMoreElements()) {
+ Object name = names.nextElement();
+ logger.debug(name + "=" + request.getHeader(name.toString()));
+ }
+ logger.debug("Remote user: " + request.getRemoteUser());
+ super.onInit();
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#onPost()
+ */
+ @Override
+ public void onPost() {
+ logger.debug("onPost");
+ logger.debug("subtitle value=" + ((TextField)getControl(SUBTITLE)));
+ super.onPost();
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#onRender()
+ */
+ @Override
+ public void onRender() {
+ logger.debug("onRender");
+ TextField text = getControl(SUBTITLE);
+ logger.debug("subtitle value=" + text);
+ // Reset the value to an empty string...
+ if (text != null) {
+ text.setValue("");
+ }
+ if (this.new_title != null) {
+ this.title = new_title;
+ }
+ super.onRender();
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#onSecurityCheck()
+ */
+ @Override
+ public boolean onSecurityCheck() {
+ logger.debug("onSecurityCheck");
+ logger.debug("subtitle value=" + ((TextField)getControl(SUBTITLE)));
+ return super.onSecurityCheck();
+ }
+
}
90 persistence/books/web/click/src/org/books/page/BookRender.java
View
@@ -0,0 +1,90 @@
+/**
+
+ BSD License
+
+ Copyright (c) 2010- , Claudio Corsi
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the distribution.
+ * Neither the name of Claudio Corsi nor the names of its contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.books.page;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.books.BooksManager;
+import org.books.proxy.BookProxy;
+import org.books.proxy.PersonProxy;
+
+import books.persistence.types.Person;
+import books.persistence.types.PersonType;
+
+/**
+ * @author Claudio Corsi
+ *
+ */
+public class BookRender {
+
+ private BookProxy proxy;
+
+ public BookRender(BookProxy proxy) {
+ this.proxy = proxy;
+ }
+
+ public String getTitle() {
+ return this.proxy.getTitle();
+ }
+
+ public Collection<String> getSubTitles() {
+ return this.proxy.getSubtitles();
+ }
+
+ public String getSeries() {
+ return this.proxy.getSeries();
+ }
+
+ public Collection<PersonProxy> getAuthors() {
+ return this.proxy.getPersons(PersonType.Author);
+ }
+
+ public Collection<PersonProxy> getEditors() {
+ return this.proxy.getPersons(PersonType.Editor);
+ }
+
+ public Collection<PersonProxy> getIllustrators() {
+ return this.proxy.getPersons(PersonType.Illustrator);
+ }
+
+ public Collection<PersonProxy> getTransalators() {
+ return this.proxy.getPersons(PersonType.Translator);
+ }
+
+ public int getPages() {
+ return this.proxy.getPages();
+ }
+
+ public Collection<Person> getAllAuthors() {
+ Collection<Person> persons = new LinkedList<Person>(BooksManager.getInstance().getPersons(PersonType.Author));
+ for (PersonProxy proxy : this.proxy.getPersons(PersonType.Author)) {
+ Person person = proxy.getPerson();
+ if (person != null) {
+ persons.remove(person);
+ }
+ }
+ return persons;
+ }
+}
36 persistence/books/web/click/src/org/books/page/HomePage.java
View
@@ -31,24 +31,22 @@
import java.util.Map;
import org.apache.click.Context;
-import org.apache.click.Control;
import org.apache.click.Page;
import org.apache.click.control.Button;
import org.apache.click.control.Column;
import org.apache.click.control.Decorator;
import org.apache.click.control.Form;
import org.apache.click.control.PageLink;
-import org.apache.click.control.Select;
import org.apache.click.control.Submit;
import org.apache.click.control.Table;
+import org.apache.click.service.LogService;
import org.apache.click.util.Bindable;
+import org.apache.click.util.ClickUtils;
import org.books.BooksManager;
-import org.books.control.BookSelect;
import org.books.proxy.BookProxy;
import org.books.proxy.PersonProxy;
import books.persistence.types.Book;
-import books.persistence.types.Person;
import books.persistence.types.PersonType;
/**
@@ -76,8 +74,10 @@
@Bindable protected Form form = new Form();
@Bindable protected Button create = new Button("Create Book");
+
+ private LogService logger;
- private Select select = new BookSelect("Books");
+ // private Select select = new BookSelect("Books");
public static class BookTableRow {
@@ -114,11 +114,12 @@ public Book getBook() {
}
public HomePage() {
- this.getContext().getServletContext().log("Inside HomePage Construction");
+ logger = ClickUtils.getConfigService(this.getContext().getServletContext()).getLogService();
+ logger.debug("Inside HomePage Construction");
// System.out.println("Inside HomePage Construction");
this.title = "Welcome Luciano Szekely Corsi";
- this.msg = "This is where we will be placing the Books Table";
+ this.msg = ""; // "This is where we will be placing the Books Table";
table.setClass(Table.CLASS_ITS);
table.setAttribute("border", "1");
@@ -186,15 +187,20 @@ public String render(Object object, Context context) {
this.addModel("msg", this.msg);
this.addModel("create_book", this.create);
- this.select.setMultiple(false);
- this.form.add(new Submit("Edit Book"));
- this.form.add(this.select);
-
- this.addModel("form", this.select);
+ // this.select.setMultiple(false);
+ Submit submit = new Submit("Create Book");
+// this.form.add(new Submit("Edit Book"));
+// this.form.add(this.select);
+ this.form.setActionURL("book.htm?action=New");
+ this.form.add(submit);
+ this.addModel("form", form);
+
+ // this.addModel("form", this.select);
+// Button createBook = new Button("Create Book");
// this.addModel("Create Book", new Button("Create Book"));
- this.getContext().getServletContext().log("Exiting HomePage Constructor");
+ logger.debug("Exiting HomePage Constructor");
}
private List<BookProxy> createRowList() {
@@ -212,7 +218,7 @@ public String render(Object object, Context context) {
*/
@Override
public void onInit() {
- this.getContext().getServletContext().log("Calling HomePage onInit method\n");
+ logger.debug("Calling HomePage onInit method");
super.onInit();
}
@@ -222,7 +228,7 @@ public void onInit() {
*/
@Override
public void onDestroy() {
- this.getContext().getServletContext().log("Calling HomePage onDestroy method\n");
+ logger.debug("Calling HomePage onDestroy method");
super.onDestroy();
}
23 persistence/books/web/click/src/org/books/page/PersonPage.java
View
@@ -24,6 +24,7 @@
package org.books.page;
import org.apache.click.Page;
+import org.apache.click.util.Bindable;
/**
* @author Claudio Corsi
@@ -36,4 +37,26 @@
*/
private static final long serialVersionUID = 1L;
+ @Bindable protected String name;
+ @Bindable protected String idx;
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#onInit()
+ */
+ @Override
+ public void onInit() {
+ name = this.getContext().getRequest().getParameter("name");
+ idx = this.getContext().getRequest().getParameter("idx");
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.click.Page#getTemplate()
+ */
+ @Override
+ public String getTemplate() {
+ return "person.htm";
+ }
+
+
+
}
2  persistence/books/web/click/src/org/books/page/WelcomePage.java
View
@@ -87,7 +87,7 @@ public void onDestroy() {
*/
@Override
public void onRender() {
- table.setRowList(new LinkedList());
+ table.setRowList(new LinkedList<Book>());
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.