Detail edit

This commit is contained in:
Tim Holloway 2021-12-30 10:22:17 -05:00
parent e624eae79d
commit 94c64b6bde
9 changed files with 346 additions and 68 deletions

13
pom.xml
View File

@ -21,6 +21,14 @@
<relativePath /> <!-- lookup parent from repository -->
</parent>
<repositories>
<repository>
<id>Primefaces</id>
<name>Primefaces repo</name>
<url>https://repository.primefaces.org</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@ -45,6 +53,11 @@
<groupId>org.joinfaces</groupId>
<artifactId>primefaces-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.primefaces.themes</groupId>
<artifactId>all-themes</artifactId>
<version>1.0.10</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>

View File

@ -849,6 +849,14 @@ public class RecipeDetailBean implements Serializable {
catToAdd = "";
}
public void getAjaxSuggestCategory() {
if (!this.category.isBlank()) {
this.category += ", ";
}
this.category += catToAdd;
catToAdd = "";
}
// ***
Part imageFile = null;

View File

@ -5,14 +5,15 @@
xmlns:tc="http://myfaces.apache.org/tobago/component"
>
<f:view>
<h:head>
<h:head>
<title><ui:insert name="title">Gourmet Recipe Manager (web version)</ui:insert></title>
<link rel="icon" type="image/vnd.microsoft.icon"
href="#{pageContext.contextPath}/favicon.ico"
/>
<h:outputStylesheet name="css/style.css" />
</h:head>
<h:body>
</h:head>
<h:body>
<h1>
<ui:insert name="title">Gourmet Recipe Manager (web version)</ui:insert>
</h1>
@ -21,9 +22,9 @@
</ui:insert>
(C) 2021 Tim Holloway, Licensed under the <a
href="http://www.apache.org/licenses/LICENSE-2.0"
>Apache License, Version 2.0</a>.
href="http://www.apache.org/licenses/LICENSE-2.0"
>Apache License, Version 2.0</a>.
<p>Based on Gourmet Recipe Manager by T. Hinkle</p>
</h:body>
</h:body>
</f:view>
</ui:composition>

View File

@ -9,3 +9,7 @@ spring:
hibernate:
ddl-auto: none
database-platform: org.sqlite.hibernate.dialect.SQLiteDialect
jsf:
primefaces:
theme: bluesky

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>PrimeFaces DataTable Example</title>
</h:head>
<h:body>
<p:dataTable var="car" value="#{carsView.cars}">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
</h:body>
</html>

View File

@ -0,0 +1,307 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition template="/WEB-INF/layout/layout.xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jstl"
>
<ui:define name="title">Gourmet Recipe Manager</ui:define>
<ui:define name="content">
<style>
.ingSel {
width: 3em;
text-align: center;
}
.ingAmt {
width: 4em;
text-align: right;
}
.ingItem {
width: 20em;
text-align: left;
}
</style>
<h:messages />
<p:panel id="editorPanel"
header="#{recipeDetailBean.recipe.title}"
>
<h:form id="form1">
<p:tabView id="tabGroupClient" orientation="left"
activeIndex="#{userSession.detailTab}"
>
<p:tab id="overviewTab" title="Description">
<p:panelGrid columns="2">
<f:facet name="header">Description</f:facet>
<p:outputLabel for="@next"
value="Title"
/>
<p:inputText id="rtitle" size="30"
required="true" focus="true"
value="#{recipeDetailBean.recipe.title}"
>
<f:ajax execute="rtitle"
render="editorPanel"
/>
</p:inputText>
<p:outputLabel for="@next"
value="Category"
/>
<p:inputText id="rcategory"
label="Category"
value="#{recipeDetailBean.category}"
tip="One or more categories, separated by commas (ex: Entree, Soup)"
>
<f:ajax execute="rcategory"
render="rcategory"
/>
</p:inputText>
<p:button value="&lt;- Suggest">
</p:button>
<p:selectOneMenu id="bxCat"
value="#{recipeDetailBean.catToAdd}"
tip="Recipe category suggestions, based on previous selections"
>
<f:selectItems
value="#{recipeDetailBean.suggestCategory}"
/>
</p:selectOneMenu>
<p:outputLabel for="@next"
value="Cuisine"
/>
<p:autoComplete id="rcuisine"
value="#{recipeDetailBean.recipe.cuisine}"
autocomplete="#{recipeDetailBean.cuisinePartial}"
/>
<p:outputLabel for="@next"
value="Rating"
/>
<p:rating id="rrating" max="10"
value="#{recipeDetailBean.recipe.rating}"
/>
<p:outputLabel for="@next"
value="Source"
/>
<p:inputText id="rsource" size="30"
value="#{recipeDetailBean.recipe.source}"
/>
<p:outputLabel for="@next"
value="URL"
/>
<p:inputText id="rurl" size="30"
value="#{recipeDetailBean.recipe.link}"
/>
<p:outputLabel for="@next"
value="Description"
/>
<p:inputTextarea id="description"
rows="10" escape="false"
value="#{recipeDetailBean.recipe.description}"
/>
<div id="picture">
<img id="bigPix"
src="/img/picture/?dt=#{recipeDetailBean.currentTime}"
/>
<!-- #{recipeDetailBean.recipe.id} -->
<p:fileUpload id="ctlUpload"
mode="simple"
label="Upload image"
value="#{recipeDetailBean.imageFile}"
>
<!-- <f:ajax
listener="recipeDetailBean.ajaxUploadImage"
execute="ctlUpload"
render="picture"
/> -->
</p:fileUpload>
<p:button id="ctlDelImg"
value="Delete Image"
>
<!-- <f:ajax
listener="recipeDetailBean.ajaxDeleteImage"
execute="ctlDelImg"
immediate="true" render="picture"
/> -->
</p:button>
</div>
</p:panelGrid>
</p:tab>
<p:tab id="ingredientsTab"
title="Ingredients"
>
<p:panel header="Ingredients">
<!-- NOTE: disabled doesn't work from AJAX render. Swap images -->
<h:panelGroup id="ingButtons">
<p:button value="Up" id="ctlUp">
<!-- <f:ajax
listener="recipeDetailBean.ajaxMoveUp"
execute="ingredientTable"
render="ingredientTable"
/> -->
</p:button>
<p:button value="Down"
id="ctlDown"
>
<!-- <f:ajax
listener="recipeDetailBean.ajaxMoveDown"
execute="ingredientTable"
render="ingredientTable"
/> -->
</p:button>
<p:button value="Add Group"
disabled="true"
/>
<p:button
value="Add Recipe As Ingredient"
disabled="true"
/>
<p:button
value="Import Ingredients"
disabled="true"
/>
<p:button value="Paste" />
<p:button value="Delete"
id="ctlDelete"
immediate="true"
disabled="not #{recipeDetailBean.selectionActive}"
>
<!-- <f:ajax
listener="recipeDetailBean.ajaxDeleteItems"
immediate="true"
render="ingredientTable"
/> -->
</p:button>
</h:panelGroup>
<h:panelGrid columns="1"
id="ingredientsDiv"
style="height: 420px;"
columnClasses="alignTop"
>
<p:dataTable id="ingredientTable"
style="width: 100%"
value="#{recipeDetailBean.ingredients}"
var="item"
>
<p:column label="Sel."
align="center"
style="width: 2em"
>
<p:selectBooleanCheckbox
id="selected"
value="#{item.selected}"
>
<!-- <f:ajax immediate="true"
render="ingredientTable"
/> -->
</p:selectBooleanCheckbox>
</p:column>
<p:column label="Amt"
style="width: 4em; text-align: right"
>
<p:inputText id="ingAmt" size="5"
value="#{item.displayAmount}"
rendered="#{not item.ingGroup}"
>
</p:inputText>
</p:column>
<p:column label="Units"
style="width: 6em"
>
<p:inputText id="ingUnit"
value="#{item.unit}" size="10"
rendered="#{not item.ingGroup}"
>
</p:inputText>
</p:column>
<p:column label="Item" style="width: 22em">
<p:inputText id="ingItem" size="20"
value="#{item.item}"
>
</p:inputText>
</p:column>
<p:column label="Optional"
align="center"
styleClass="ingSel"
>
<p:selectBooleanCheckbox
id="ingOpt"
value="#{item.optionalCB}"
rendered="#{not item.ingGroup}"
/>
</p:column>
<p:column label="Key">
<p:inputText id="ingKey"
value="#{item.ingkey}" size="12"
rendered="#{not item.ingGroup}"
/>
</p:column>
<p:column
label="Shopping Category"
>
<p:inputText id="shopCat"
value="#{item.shopCat}"
rendered="#{not item.ingGroup}"
tip="Note that changing Shopping category for an ingredient key changes it for all users of that key."
>
<p:autoComplete
minimumCharacters="1"
completeMethod="#{recipeDetailBean.shopcatPartial}"
>
</p:autoComplete>
</p:inputText>
</p:column>
</p:dataTable>
</h:panelGrid>
<h:panelGroup id="addIng">
<p:inputText
label="Add Ingredient: "
id="ctlAddIng" focus="true"
value="#{recipeDetailBean.ingredientText}"
tip="You can paste in multiple ingredients here!"
/>
<p:button value="+ Add"
defaultCommand="true"
>
<!-- <f:ajax execute="ctlAddIng"
render="ingredientTable ctlAddIng"
listener="recipeDetailBean.ajaxAddIngredient"
/> -->
</p:button>
</h:panelGroup>
</p:panel>
</p:tab>
<p:tab id="instructionsTab"
title="Instructions"
>
<p:panel header="Instructions">
<div id="insection">
<p:textEditor
id="ctlInstructions"
height="320" escape="false"
value="#{recipeDetailBean.recipe.instructions}"
/>
</div>
</p:panel>
</p:tab>
<p:tab id="notesTab" title="Notes">
<p:panel header="Notes">
<p:textEditor id="ctlNotes"
height="320" escape="false"
value="#{recipeDetailBean.recipe.modifications}"
/>
</p:panel>
</p:tab>
</p:tabView>
<p:button id="doSave" value="Save"
disabled="{recipeDetailBean.dirty}"
action="#{recipeDetailBean.doSave}"
/>
<p:commandButton id="doCancel" value="Cancel"
immediate="true" action="/main.jsf"
/>
</h:form>
</p:panel>
</ui:define>
</ui:composition>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>PrimeFaces DataTable Example Foo</title>
</h:head>
<h:body>
<p:dataTable var="car" value="#{categoryView.categories}">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Category">
<h:outputText value="#{car.category}" />
</p:column>
</p:dataTable>
</h:body>
</html>

View File

@ -40,7 +40,7 @@
<img id="bigpix"
src="/img/picture/#{recipeDetailBean.recipe.id}"
/>
<p:panelGrid columns="2">
<p:panelGrid id="pnlDetails" columns="2">
<p:commandButton value="&lt;- Back"
styleClass="ui-button-arrow-left"
action="main.jsf"
@ -85,7 +85,7 @@
/>
</h:commandLink>
<!-- -->
<p:panelGrid columns="1">
<p:panelGrid id="pnlInstr" columns="1" style="width: 100%">
<f:facet name="header">
<h:outputText
styleClass="subtitle"
@ -101,7 +101,7 @@
action="#{recipeDetailBean.editInstructions}"
/>
</p:panelGrid>
<p:panelGrid columns="1">
<p:panelGrid id="pnlNotes" columns="1" style="width: 100%">
<f:facet name="header">
<h:outputText
styleClass="subtitle"
@ -150,14 +150,14 @@
/>
</f:facet>
<p:column label="Amt"
style="width: 4em; text-align: right"
style="width: 3em; text-align: right"
>
<h:outputText
value="#{ingredient.displayAmount}"
/>
</p:column>
<p:column label="Units"
style="width: 8em"
style="width: 4em"
>
<h:outputText
value="#{ingredient.unit}"

View File

@ -12,8 +12,8 @@
<h:messages />
<img id="bigpix"
SRC="/img/picture/#{recipeDetailBean.recipe.id}"
/>
<p:button value="&lt;- Back" action="main" />
/>&nbsp;&nbsp;
<p:commandButton value="&lt;- Back" action="main.jsf" />
<p:panelGrid columns="2">
<h:outputLabel for="@next" value="Category: " />
<h:outputText