[#3840] Cleanup and documentation
This commit is contained in:
parent
ba99612ba0
commit
bd3ca03e6b
@ -12,13 +12,6 @@
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src/main/webapp"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src/test/resources"/>
|
||||
<classpathentry kind="src" path="target/generated-sources/jooq-h2"/>
|
||||
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
|
||||
@ -2,5 +2,4 @@ eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/main/webapp/library.xhtml=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
|
||||
@ -14,3 +14,14 @@ $ cd jOOQ-examples/jOOQ-javaee-example
|
||||
...
|
||||
$ mvn clean install
|
||||
```
|
||||
|
||||
After the above, you should find a `jooq-javaee-example.war` file in
|
||||
|
||||
```
|
||||
$ pwd
|
||||
/path/to/checkout/dir
|
||||
$ cd jOOQ-examples/jOOQ-javaee-example/target
|
||||
...
|
||||
```
|
||||
|
||||
You can deploy this war file in your WildFly AS or any other application server. The example will use an embedded H2 database, which should be pre-filled with the library example H2 database. It uses a non-managed `DataSource`, which is configured and consumed directly by the application itself.
|
||||
@ -72,11 +72,6 @@
|
||||
<artifactId>jooq</artifactId>
|
||||
<version>${org.jooq.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
<artifactId>commons-dbcp</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
|
||||
@ -62,36 +62,74 @@ import org.jooq.SortField;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.UpdatableRecord;
|
||||
import org.jooq.example.db.h2.tables.Author;
|
||||
import org.jooq.example.db.h2.tables.records.AuthorRecord;
|
||||
import org.jooq.example.db.h2.tables.records.BookRecord;
|
||||
import org.jooq.example.javaee.ejb.AuthorsEJB;
|
||||
import org.jooq.example.javaee.ejb.LibraryEJB;
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
/**
|
||||
* A bean to be used from JSF pages.
|
||||
* <p>
|
||||
* The bean is session scoped such that we can have session-based caches of
|
||||
* database content such as authors or books in this bean. In this simple
|
||||
* example, we haven't gone into concurrency situations where multiple sessions
|
||||
* update the library database at the same time, in case of which we might need
|
||||
* to turn on optimistic locking in jOOQ.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Named("authors")
|
||||
@Named("library")
|
||||
@SessionScoped
|
||||
public class Authors implements Serializable {
|
||||
public class Library implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@EJB
|
||||
private AuthorsEJB ejb;
|
||||
private LibraryEJB ejb;
|
||||
|
||||
// Caches from the DB
|
||||
// Various caches from the DB
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* An empty {@link AuthorRecord} that can be used to insert new authors.
|
||||
*/
|
||||
private AuthorRecord newAuthor;
|
||||
|
||||
/**
|
||||
* An empty {@link BookRecord} that can be used to insert new books.
|
||||
*/
|
||||
private BookRecord newBook;
|
||||
|
||||
/**
|
||||
* The reference to the {@link Record} that is currently being edited.
|
||||
*/
|
||||
private Record edit;
|
||||
|
||||
/**
|
||||
* The sort field for each {@link Table}.
|
||||
*/
|
||||
private Map<Table<?>, SortField<?>> sort = Stream.of(AUTHOR.ID, BOOK.ID).collect(
|
||||
toMap(f -> f.getTable(), f -> f.asc()));
|
||||
|
||||
/**
|
||||
* A cache of all {@link AuthorRecord}s currently in the database.
|
||||
*/
|
||||
private Result<AuthorRecord> authors;
|
||||
|
||||
/**
|
||||
* A copy of {@link #authors} that is always sorted alphanumerically.
|
||||
*/
|
||||
private Result<AuthorRecord> authorsAlphanumeric;
|
||||
|
||||
/**
|
||||
* A cache of all {@link BookRecord}s currently in the database.
|
||||
*/
|
||||
private Result<BookRecord> books;
|
||||
|
||||
// Data access methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
public Result<AuthorRecord> getAuthors() {
|
||||
if (authors == null)
|
||||
authors = ejb.fetchAuthors(sort.get(AUTHOR));
|
||||
@ -113,10 +151,6 @@ public class Authors implements Serializable {
|
||||
return getAuthors().intoMap(AUTHOR.ID);
|
||||
}
|
||||
|
||||
public Map<String, Field<?>> getAuthorColumns() {
|
||||
return getColumns(AUTHOR);
|
||||
}
|
||||
|
||||
public Result<BookRecord> getBooks() {
|
||||
if (books == null)
|
||||
books = ejb.fetchBooks(sort.get(BOOK));
|
||||
@ -124,36 +158,70 @@ public class Authors implements Serializable {
|
||||
return books;
|
||||
}
|
||||
|
||||
public Map<String, Field<?>> getBookColumns() {
|
||||
return getColumns(BOOK);
|
||||
}
|
||||
|
||||
private Map<String, Field<?>> getColumns(Table<?> t) {
|
||||
return Stream.of(t.fields()).collect(toMap(f -> f.getName(), f -> f));
|
||||
}
|
||||
|
||||
public Record getEdit() {
|
||||
return edit;
|
||||
}
|
||||
|
||||
public Map<String, SortField<?>> getSort() {
|
||||
return sort.entrySet().stream().collect(toMap(e -> e.getKey().getName(), e -> e.getValue()));
|
||||
}
|
||||
|
||||
public AuthorRecord getNewAuthor() {
|
||||
if (newAuthor == null)
|
||||
newAuthor = ejb.newAuthor();
|
||||
newAuthor = DSL.using(H2).newRecord(AUTHOR);
|
||||
|
||||
return newAuthor;
|
||||
}
|
||||
|
||||
public BookRecord getNewBook() {
|
||||
if (newBook == null)
|
||||
newBook = ejb.newBook();
|
||||
newBook = DSL.using(H2).newRecord(BOOK);
|
||||
|
||||
return newBook;
|
||||
}
|
||||
|
||||
// UI state methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The record being edited.
|
||||
*/
|
||||
public Record getEdit() {
|
||||
return edit;
|
||||
}
|
||||
|
||||
/**
|
||||
* A map containing <code>column name -> column</code> pairs of the
|
||||
* {@link Author} table.
|
||||
*/
|
||||
public Map<String, Field<?>> getAuthorColumns() {
|
||||
return getColumns(AUTHOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* A map containing <code>column name -> column</code> pairs of the
|
||||
* {@link Author} table.
|
||||
*/
|
||||
public Map<String, Field<?>> getBookColumns() {
|
||||
return getColumns(BOOK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map containing <code>table name -> sort field</code> pairs.
|
||||
*/
|
||||
public Map<String, SortField<?>> getSort() {
|
||||
return sort.entrySet().stream().collect(toMap(e -> e.getKey().getName(), e -> e.getValue()));
|
||||
}
|
||||
|
||||
private Map<String, Field<?>> getColumns(Table<?> t) {
|
||||
return Stream.of(t.fields()).collect(toMap(f -> f.getName(), f -> f));
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
authors = null;
|
||||
authorsAlphanumeric = null;
|
||||
books = null;
|
||||
edit = null;
|
||||
}
|
||||
|
||||
// Actions
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Sort a table by a new field.
|
||||
*/
|
||||
public void sort(TableField<?, ?> field) {
|
||||
SortField<?> previous = sort.get(field.getTable());
|
||||
sort.put(field.getTable(),
|
||||
@ -167,26 +235,26 @@ public class Authors implements Serializable {
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a record as the one being currently edited.
|
||||
*/
|
||||
public void edit(UpdatableRecord<?> record) {
|
||||
edit = record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a record back to the database.
|
||||
*/
|
||||
public void save(UpdatableRecord<?> author) {
|
||||
ejb.store(author);
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a record from the database.
|
||||
*/
|
||||
public void delete(UpdatableRecord<?> author) {
|
||||
ejb.delete(author);
|
||||
reset();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
authors = null;
|
||||
authorsAlphanumeric = null;
|
||||
books = null;
|
||||
edit = null;
|
||||
newAuthor = ejb.newAuthor();
|
||||
newBook = ejb.newBook();
|
||||
}
|
||||
}
|
||||
@ -45,7 +45,7 @@ import static org.jooq.example.db.h2.Tables.AUTHOR;
|
||||
import static org.jooq.example.db.h2.Tables.BOOK;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.ejb.Stateful;
|
||||
import javax.ejb.Stateless;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.jooq.Result;
|
||||
@ -55,20 +55,18 @@ import org.jooq.example.db.h2.tables.records.AuthorRecord;
|
||||
import org.jooq.example.db.h2.tables.records.BookRecord;
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
@Stateful
|
||||
public class AuthorsEJB {
|
||||
/**
|
||||
* A session bean that uses the configured {@link DataSource} to interact with
|
||||
* the embedded H2 database.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Stateless
|
||||
public class LibraryEJB {
|
||||
|
||||
@Resource(lookup="java:jboss/datasources/jooq-javaee-example")
|
||||
private DataSource ds;
|
||||
|
||||
public AuthorRecord newAuthor() {
|
||||
return DSL.using(ds, H2).newRecord(AUTHOR);
|
||||
}
|
||||
|
||||
public BookRecord newBook() {
|
||||
return DSL.using(ds, H2).newRecord(BOOK);
|
||||
}
|
||||
|
||||
public Result<AuthorRecord> fetchAuthors(SortField<?> sort) {
|
||||
return DSL.using(ds, H2)
|
||||
.selectFrom(AUTHOR)
|
||||
@ -84,10 +82,12 @@ public class AuthorsEJB {
|
||||
}
|
||||
|
||||
public void store(UpdatableRecord<?> record) {
|
||||
DSL.using(ds, H2).attach(record);
|
||||
record.store();
|
||||
}
|
||||
|
||||
public void delete(UpdatableRecord<?> record) {
|
||||
DSL.using(ds, H2).attach(record);
|
||||
record.delete();
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
DROP TABLE IF EXISTS book_to_book_store;
|
||||
DROP TABLE IF EXISTS book_store;
|
||||
DROP TABLE IF EXISTS book;
|
||||
DROP TABLE IF EXISTS author;
|
||||
|
||||
@ -23,43 +21,10 @@ CREATE TABLE book (
|
||||
CONSTRAINT fk_t_book_author_id FOREIGN KEY (author_id) REFERENCES author(id) ON DELETE CASCADE,
|
||||
);
|
||||
|
||||
CREATE TABLE book_store (
|
||||
name VARCHAR(400) NOT NULL,
|
||||
|
||||
CONSTRAINT uk_t_book_store_name PRIMARY KEY(name)
|
||||
);
|
||||
|
||||
CREATE TABLE book_to_book_store (
|
||||
book_store_name VARCHAR(400) NOT NULL,
|
||||
book_id INTEGER NOT NULL,
|
||||
stock INTEGER,
|
||||
|
||||
CONSTRAINT pk_b2bs PRIMARY KEY(book_store_name, book_id),
|
||||
CONSTRAINT fk_b2bs_bs_name FOREIGN KEY (book_store_name)
|
||||
REFERENCES book_store (name)
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT fk_b2bs_b_id FOREIGN KEY (book_id)
|
||||
REFERENCES book (id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO author VALUES (DEFAULT, 'George', 'Orwell', '1903-06-25');
|
||||
INSERT INTO author VALUES (DEFAULT, 'Paulo', 'Coelho', '1947-08-24');
|
||||
|
||||
INSERT INTO book VALUES (DEFAULT, 1, '1984', 1948, 1);
|
||||
INSERT INTO book VALUES (DEFAULT, 1, 'Animal Farm', 1945, 1);
|
||||
INSERT INTO book VALUES (DEFAULT, 2, 'O Alquimista', 1988, 4);
|
||||
INSERT INTO book VALUES (DEFAULT, 2, 'Brida', 1990, 2);
|
||||
|
||||
INSERT INTO book_store (name) VALUES
|
||||
('Orell Füssli'),
|
||||
('Ex Libris'),
|
||||
('Buchhandlung im Volkshaus');
|
||||
|
||||
INSERT INTO book_to_book_store VALUES
|
||||
('Orell Füssli', 1, 10),
|
||||
('Orell Füssli', 2, 10),
|
||||
('Orell Füssli', 3, 10),
|
||||
('Ex Libris', 1, 1),
|
||||
('Ex Libris', 3, 2),
|
||||
('Buchhandlung im Volkshaus', 3, 1);
|
||||
INSERT INTO book VALUES (DEFAULT, 2, 'Brida', 1990, 2);
|
||||
@ -6,7 +6,7 @@ body {
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
padding: 20px;
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
color: #eee;
|
||||
}
|
||||
@ -26,7 +26,7 @@ h3 {
|
||||
td, th {
|
||||
text-align: left;
|
||||
min-width: 50px;
|
||||
padding: 20px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
input {
|
||||
@ -35,7 +35,7 @@ input {
|
||||
|
||||
input[type=submit] {
|
||||
min-width: 50px;
|
||||
margin-right: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.div-50 {
|
||||
|
||||
@ -19,13 +19,13 @@
|
||||
<div class="div-50">
|
||||
<h2>Authors</h2>
|
||||
|
||||
<h:dataTable value="#{authors.authors}" var="a">
|
||||
<h:dataTable value="#{library.authors}" var="a">
|
||||
<h:column>
|
||||
<f:facet name="header">
|
||||
<h:commandLink action="#{authors.sort(authors.authorColumns['ID'])}">
|
||||
<h:commandLink action="#{library.sort(library.authorColumns['ID'])}">
|
||||
<h:outputText value="ID"/>
|
||||
<h:outputText value="⇧" rendered="#{authors.sort['AUTHOR'].name == 'ID' and authors.sort['AUTHOR'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{authors.sort['AUTHOR'].name == 'ID' and authors.sort['AUTHOR'].order == 'DESC'}"/>
|
||||
<h:outputText value="⇧" rendered="#{library.sort['AUTHOR'].name == 'ID' and library.sort['AUTHOR'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{library.sort['AUTHOR'].name == 'ID' and library.sort['AUTHOR'].order == 'DESC'}"/>
|
||||
</h:commandLink>
|
||||
</f:facet>
|
||||
|
||||
@ -34,48 +34,48 @@
|
||||
|
||||
<h:column>
|
||||
<f:facet name="header">
|
||||
<h:commandLink action="#{authors.sort(authors.authorColumns['FIRST_NAME'])}">
|
||||
<h:commandLink action="#{library.sort(library.authorColumns['FIRST_NAME'])}">
|
||||
<h:outputText value="First Name"/>
|
||||
<h:outputText value="⇧" rendered="#{authors.sort['AUTHOR'].name == 'FIRST_NAME' and authors.sort['AUTHOR'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{authors.sort['AUTHOR'].name == 'FIRST_NAME' and authors.sort['AUTHOR'].order == 'DESC'}"/>
|
||||
<h:outputText value="⇧" rendered="#{library.sort['AUTHOR'].name == 'FIRST_NAME' and library.sort['AUTHOR'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{library.sort['AUTHOR'].name == 'FIRST_NAME' and library.sort['AUTHOR'].order == 'DESC'}"/>
|
||||
</h:commandLink>
|
||||
</f:facet>
|
||||
|
||||
<h:outputText value="#{a.firstName}" rendered="#{authors.edit != a}"/>
|
||||
<h:inputText value="#{a.firstName}" rendered="#{authors.edit == a}"/>
|
||||
<h:outputText value="#{a.firstName}" rendered="#{library.edit != a}"/>
|
||||
<h:inputText value="#{a.firstName}" rendered="#{library.edit == a}"/>
|
||||
|
||||
<f:facet name="footer">
|
||||
<h:inputText value="#{authors.newAuthor.firstName}"/>
|
||||
<h:inputText value="#{library.newAuthor.firstName}"/>
|
||||
</f:facet>
|
||||
</h:column>
|
||||
|
||||
<h:column>
|
||||
<f:facet name="header">
|
||||
<h:commandLink action="#{authors.sort(authors.authorColumns['LAST_NAME'])}">
|
||||
<h:commandLink action="#{library.sort(library.authorColumns['LAST_NAME'])}">
|
||||
<h:outputText value="Last Name"/>
|
||||
<h:outputText value="⇧" rendered="#{authors.sort['AUTHOR'].name == 'LAST_NAME' and authors.sort['AUTHOR'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{authors.sort['AUTHOR'].name == 'LAST_NAME' and authors.sort['AUTHOR'].order == 'DESC'}"/>
|
||||
<h:outputText value="⇧" rendered="#{library.sort['AUTHOR'].name == 'LAST_NAME' and library.sort['AUTHOR'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{library.sort['AUTHOR'].name == 'LAST_NAME' and library.sort['AUTHOR'].order == 'DESC'}"/>
|
||||
</h:commandLink>
|
||||
</f:facet>
|
||||
|
||||
<h:outputText value="#{a.lastName}" rendered="#{authors.edit != a}"/>
|
||||
<h:inputText value="#{a.lastName}" rendered="#{authors.edit == a}"/>
|
||||
<h:outputText value="#{a.lastName}" rendered="#{library.edit != a}"/>
|
||||
<h:inputText value="#{a.lastName}" rendered="#{library.edit == a}"/>
|
||||
|
||||
<f:facet name="footer">
|
||||
<h:inputText value="#{authors.newAuthor.lastName}"/>
|
||||
<h:inputText value="#{library.newAuthor.lastName}"/>
|
||||
</f:facet>
|
||||
</h:column>
|
||||
|
||||
<h:column>
|
||||
<f:facet name="header">Actions</f:facet>
|
||||
|
||||
<h:commandButton value="edit" action="#{authors.edit(a)}" rendered="#{authors.edit != a}"/>
|
||||
<h:commandButton value="save" action="#{authors.save(a)}" rendered="#{authors.edit == a}"/>
|
||||
<h:commandButton value="edit" action="#{library.edit(a)}" rendered="#{library.edit != a}"/>
|
||||
<h:commandButton value="save" action="#{library.save(a)}" rendered="#{library.edit == a}"/>
|
||||
|
||||
<h:commandButton value="delete" action="#{authors.delete(a)}"/>
|
||||
<h:commandButton value="delete" action="#{library.delete(a)}"/>
|
||||
|
||||
<f:facet name="footer">
|
||||
<h:commandButton value="create" action="#{authors.save(authors.newAuthor)}"/>
|
||||
<h:commandButton value="create" action="#{library.save(library.newAuthor)}"/>
|
||||
</f:facet>
|
||||
</h:column>
|
||||
</h:dataTable>
|
||||
@ -84,13 +84,13 @@
|
||||
<div class="div-50">
|
||||
<h2>Books</h2>
|
||||
|
||||
<h:dataTable value="#{authors.books}" var="b">
|
||||
<h:dataTable value="#{library.books}" var="b">
|
||||
<h:column>
|
||||
<f:facet name="header">
|
||||
<h:commandLink action="#{authors.sort(authors.bookColumns['ID'])}">
|
||||
<h:commandLink action="#{library.sort(library.bookColumns['ID'])}">
|
||||
<h:outputText value="ID"/>
|
||||
<h:outputText value="⇧" rendered="#{authors.sort['BOOK'].name == 'ID' and authors.sort['BOOK'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{authors.sort['BOOK'].name == 'ID' and authors.sort['BOOK'].order == 'DESC'}"/>
|
||||
<h:outputText value="⇧" rendered="#{library.sort['BOOK'].name == 'ID' and library.sort['BOOK'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{library.sort['BOOK'].name == 'ID' and library.sort['BOOK'].order == 'DESC'}"/>
|
||||
</h:commandLink>
|
||||
</f:facet>
|
||||
|
||||
@ -100,45 +100,45 @@
|
||||
<h:column>
|
||||
<f:facet name="header">Author</f:facet>
|
||||
|
||||
<h:outputText value="#{authors.authorById[b.authorId].firstName} #{authors.authorById[b.authorId].lastName}" rendered="#{authors.edit != b}"/>
|
||||
<h:selectOneMenu value="#{b.authorId}" rendered="#{authors.edit == b}">
|
||||
<f:selectItems value="#{authors.authorsAlphanumeric}" var="a" itemLabel="#{a.firstName} #{a.lastName}" itemValue="#{a.id}" />
|
||||
<h:outputText value="#{library.authorById[b.authorId].firstName} #{library.authorById[b.authorId].lastName}" rendered="#{library.edit != b}"/>
|
||||
<h:selectOneMenu value="#{b.authorId}" rendered="#{library.edit == b}">
|
||||
<f:selectItems value="#{library.authorsAlphanumeric}" var="a" itemLabel="#{a.firstName} #{a.lastName}" itemValue="#{a.id}" />
|
||||
</h:selectOneMenu>
|
||||
|
||||
<f:facet name="footer">
|
||||
<h:selectOneMenu value="#{authors.newBook.authorId}">
|
||||
<f:selectItems value="#{authors.authorsAlphanumeric}" var="a" itemLabel="#{a.firstName} #{a.lastName}" itemValue="#{a.id}" />
|
||||
<h:selectOneMenu value="#{library.newBook.authorId}">
|
||||
<f:selectItems value="#{library.authorsAlphanumeric}" var="a" itemLabel="#{a.firstName} #{a.lastName}" itemValue="#{a.id}" />
|
||||
</h:selectOneMenu>
|
||||
</f:facet>
|
||||
</h:column>
|
||||
|
||||
<h:column>
|
||||
<f:facet name="header">
|
||||
<h:commandLink action="#{authors.sort(authors.bookColumns['TITLE'])}">
|
||||
<h:commandLink action="#{library.sort(library.bookColumns['TITLE'])}">
|
||||
<h:outputText value="Title"/>
|
||||
<h:outputText value="⇧" rendered="#{authors.sort['BOOK'].name == 'TITLE' and authors.sort['BOOK'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{authors.sort['BOOK'].name == 'TITLE' and authors.sort['BOOK'].order == 'DESC'}"/>
|
||||
<h:outputText value="⇧" rendered="#{library.sort['BOOK'].name == 'TITLE' and library.sort['BOOK'].order == 'ASC'}"/>
|
||||
<h:outputText value="⇩" rendered="#{library.sort['BOOK'].name == 'TITLE' and library.sort['BOOK'].order == 'DESC'}"/>
|
||||
</h:commandLink>
|
||||
</f:facet>
|
||||
|
||||
<h:outputText value="#{b.title}" rendered="#{authors.edit != b}"/>
|
||||
<h:inputText value="#{b.title}" rendered="#{authors.edit == b}"/>
|
||||
<h:outputText value="#{b.title}" rendered="#{library.edit != b}"/>
|
||||
<h:inputText value="#{b.title}" rendered="#{library.edit == b}"/>
|
||||
|
||||
<f:facet name="footer">
|
||||
<h:inputText value="#{authors.newBook.title}"/>
|
||||
<h:inputText value="#{library.newBook.title}"/>
|
||||
</f:facet>
|
||||
</h:column>
|
||||
|
||||
<h:column>
|
||||
<f:facet name="header">Actions</f:facet>
|
||||
|
||||
<h:commandButton value="edit" action="#{authors.edit(b)}" rendered="#{authors.edit != b}"/>
|
||||
<h:commandButton value="save" action="#{authors.save(b)}" rendered="#{authors.edit == b}"/>
|
||||
<h:commandButton value="edit" action="#{library.edit(b)}" rendered="#{library.edit != b}"/>
|
||||
<h:commandButton value="save" action="#{library.save(b)}" rendered="#{library.edit == b}"/>
|
||||
|
||||
<h:commandButton value="delete" action="#{authors.delete(b)}"/>
|
||||
<h:commandButton value="delete" action="#{library.delete(b)}"/>
|
||||
|
||||
<f:facet name="footer">
|
||||
<h:commandButton value="create" action="#{authors.save(authors.newBook)}"/>
|
||||
<h:commandButton value="create" action="#{library.save(library.newBook)}"/>
|
||||
</f:facet>
|
||||
</h:column>
|
||||
</h:dataTable>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user