Tab for editing shopping categories completed.
This commit is contained in:
parent
1290c66055
commit
75a8487cfb
|
@ -12,7 +12,6 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.primefaces.event.ReorderEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -151,9 +150,9 @@ public class ShoppingListBean implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private List<Shopcat> shopcatList;
|
||||
private List<String> shopcatList;
|
||||
|
||||
public List<Shopcat> getShopcatList() {
|
||||
public List<String> getShopcatList() {
|
||||
if (shopcatList == null) {
|
||||
shopcatList = loadShopcatList();
|
||||
}
|
||||
|
@ -163,9 +162,9 @@ public class ShoppingListBean implements Serializable {
|
|||
@Inject
|
||||
ShopcatRepository shopcatRepository;
|
||||
|
||||
private List<Shopcat> loadShopcatList() {
|
||||
return shopcatRepository
|
||||
.findAllByOrderByShopcategoryAsc();
|
||||
private List<String> loadShopcatList() {
|
||||
return shopcatRepository.findDistinctCategoryNative();
|
||||
// .findAllByOrderByShopcategoryAsc();
|
||||
}
|
||||
|
||||
private Shopcat xeditShopcat = new Shopcat();
|
||||
|
@ -180,19 +179,19 @@ public class ShoppingListBean implements Serializable {
|
|||
}
|
||||
|
||||
public void doEditShopcat(int scId) {
|
||||
xeditShopcat = null;
|
||||
final List<Shopcat> scl = getShopcatList();
|
||||
for (Shopcat sc : scl) {
|
||||
if (sc.getId() == scId) {
|
||||
xeditShopcat = sc;
|
||||
this.oldShopcategoryName = sc.getShopcategory();
|
||||
if (sc.getPosition() == null) {
|
||||
sc.setPosition(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
log.error("SHOPCAT " + scId + " NOT FOUND");
|
||||
// xeditShopcat = null;
|
||||
// final List<Shopcat> scl = getShopcatList();
|
||||
// for (Shopcat sc : scl) {
|
||||
// if (sc.getId() == scId) {
|
||||
// xeditShopcat = sc;
|
||||
// this.oldShopcategoryName = sc.getShopcategory();
|
||||
// if (sc.getPosition() == null) {
|
||||
// sc.setPosition(0);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// log.error("SHOPCAT " + scId + " NOT FOUND");
|
||||
}
|
||||
|
||||
public void ajaxOnClickShopcatIngkey() {
|
||||
|
@ -202,12 +201,103 @@ public class ShoppingListBean implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Updates all ingredient keys for shopcat name-change.
|
||||
* Note that once done, this cannot be undone!
|
||||
* Updates all ingredient keys for shopcat name-change. Note
|
||||
* that once done, this cannot be undone!
|
||||
*/
|
||||
public void ajaxOnClickShopcat() {
|
||||
this.shopcatRepository.UpdateShopcats(
|
||||
this.oldShopcategoryName, xeditShopcat.getShopcategory());
|
||||
this.oldShopcategoryName,
|
||||
xeditShopcat.getShopcategory());
|
||||
this.shopcatList = null;
|
||||
}
|
||||
|
||||
// ===
|
||||
private String selectedShopcat;
|
||||
|
||||
/**
|
||||
* @return the selectedShopcat
|
||||
*/
|
||||
public String getSelectedShopcat() {
|
||||
return selectedShopcat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param selectedShopcat the selectedShopcat to set
|
||||
*/
|
||||
public void setSelectedShopcat(String selectedShopcat) {
|
||||
this.selectedShopcat = selectedShopcat;
|
||||
this.ingkeyList = null;
|
||||
}
|
||||
|
||||
private List<String> selectedIngkey;
|
||||
|
||||
/**
|
||||
* @return the selectedIngkey
|
||||
*/
|
||||
public List<String> getSelectedIngkey() {
|
||||
return selectedIngkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param selectedIngkey the selectedIngkey to set
|
||||
*/
|
||||
public void setSelectedIngkey(List<String> selectedIngkey) {
|
||||
this.selectedIngkey = selectedIngkey;
|
||||
}
|
||||
|
||||
private List<String> ingkeyList;
|
||||
|
||||
/**
|
||||
* @return the ingkeyList
|
||||
*/
|
||||
public List<String> getIngkeyList() {
|
||||
if (ingkeyList == null) {
|
||||
ingkeyList = loadIngkeyListFor(selectedShopcat);
|
||||
}
|
||||
return ingkeyList;
|
||||
}
|
||||
|
||||
private List<String> loadIngkeyListFor(
|
||||
String selectedShopcat2) {
|
||||
List<String> list = this.shopcatRepository
|
||||
.findByIngkeySorted(selectedShopcat2);
|
||||
return list;
|
||||
}
|
||||
|
||||
private String newShopcat;
|
||||
|
||||
/**
|
||||
* @return the newShopcat
|
||||
*/
|
||||
public String getNewShopcat() {
|
||||
return newShopcat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newShopcat the newShopcat to set
|
||||
*/
|
||||
public void setNewShopcat(String newShopcat) {
|
||||
this.newShopcat = newShopcat;
|
||||
}
|
||||
|
||||
public List<String> suggestShopcat(String query) {
|
||||
return this.shopcatList;
|
||||
}
|
||||
|
||||
public void doChangeShopcat() {
|
||||
String oldCat = this.getSelectedShopcat();
|
||||
String newCat = this.getNewShopcat();
|
||||
if (oldCat.equals(newCat)) {
|
||||
return; // effective NO-OP
|
||||
}
|
||||
newCat = newCat.trim();
|
||||
if ( StringUtils.isBlank(newCat)) {
|
||||
this.shopcatRepository
|
||||
.deleteShopcatFor(this.getSelectedIngkey());
|
||||
} else {
|
||||
this.shopcatRepository
|
||||
.updateShopcatFor(newCat, this.getSelectedIngkey());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ import org.springframework.stereotype.Repository;
|
|||
import com.mousetech.gourmetj.persistence.model.Shopcat;
|
||||
|
||||
/**
|
||||
* JpaRepository for Shopping Categories, which relate ManyToOne to Ingredient.
|
||||
* Service method is @see RecipeService
|
||||
* JpaRepository for Shopping Categories, which relate ManyToOne
|
||||
* to Ingredient. Service method is @see RecipeService
|
||||
*
|
||||
* @author timh
|
||||
* @since Dec 28, 2021
|
||||
|
@ -34,11 +34,24 @@ public interface ShopcatRepository
|
|||
@Transactional
|
||||
@Query(value = "UPDATE Shopcat set shopcategory = :newCatname WHERE shopcategory = :oldCatname")
|
||||
@Modifying
|
||||
public int UpdateShopcats(String oldCatname, String newCatname);
|
||||
public int UpdateShopcats(String oldCatname,
|
||||
String newCatname);
|
||||
|
||||
public Shopcat findShopcatByIngkey(String ingkey);
|
||||
|
||||
public void deleteByIngkey(String key);
|
||||
|
||||
public List<Shopcat> findAllByOrderByShopcategoryAsc();
|
||||
|
||||
@Query(value = "SELECT s.ingkey FROM Shopcat s WHERE s.shopcategory = :shopcat ORDER BY s.ingkey")
|
||||
public List<String> findByIngkeySorted(String shopcat);
|
||||
|
||||
@Transactional
|
||||
@Query(value = "UPDATE Shopcat set shopcategory = :newCat WHERE ingkey IN :selectedIngkey")
|
||||
@Modifying
|
||||
public void updateShopcatFor(String newCat, List<String> selectedIngkey);
|
||||
|
||||
@Transactional
|
||||
@Query(value = "DELETE Shopcat WHERE ingkey IN :selectedIngkey")
|
||||
@Modifying public void deleteShopcatFor(List<String> selectedIngkey);
|
||||
}
|
||||
|
|
|
@ -25,11 +25,15 @@
|
|||
<ui:insert name="content">
|
||||
<ui:include src="content.xhtml" />
|
||||
</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>.
|
||||
<p>Based on Gourmet Recipe Manager by T. Hinkle</p>
|
||||
<!-- -->
|
||||
<div id="footer">
|
||||
(C) 2021 Tim Holloway, Licensed under the <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>
|
||||
</div>
|
||||
<!-- -->
|
||||
<h:form id="frmTimeout">
|
||||
<p:idleMonitor
|
||||
timeout="#{userSession.sessionTimeoutInterval}"
|
||||
|
|
|
@ -1,121 +1,96 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
<html 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"
|
||||
>
|
||||
<!-- === Edit ingkey/shopcat === -->
|
||||
<h:form id="frmIsk1">
|
||||
<p:dataTable id="tblShopcats"
|
||||
style="width: 300px"
|
||||
value="#{shoppingListBean.shopcatList}"
|
||||
sortBy="#{item.shopcategory}" var="item"
|
||||
>
|
||||
<f:facet name="header">
|
||||
<h:outputText
|
||||
value="Ingredient Keys/Shopping Categories" />
|
||||
</f:facet>
|
||||
<p:headerRow>
|
||||
<p:column>
|
||||
<h:outputText id="ctlCatname"
|
||||
value="#{item.shopcategory}" />
|
||||
</p:column>
|
||||
<p:column style="width: 5em">
|
||||
<p:commandButton
|
||||
id="ctlEditCat" value="Rename"
|
||||
action="#{shoppingListBean.doEditShopcat(item.id)}"
|
||||
onclick="PF('dlgEditShopcat').show()"
|
||||
update="frmEscat:pnlData" />
|
||||
</p:column>
|
||||
</p:headerRow>
|
||||
<!-- === Edit ingkey/shopcat === -->
|
||||
<h:form id="frmIsk">
|
||||
<p:panelGrid>
|
||||
<p:row>
|
||||
<p:column>
|
||||
<h:outputText value="#{item.ingkey}"
|
||||
onclick="clickIngkeyName()" />
|
||||
<p:outputLabel for="ctlScSel"
|
||||
value="Shopping Category"
|
||||
/>
|
||||
</p:column>
|
||||
<p:column style="width: 5em">
|
||||
<p:commandButton
|
||||
id="ctlEditIngkey" value="Move"
|
||||
action="#{shoppingListBean.doEditShopcat(item.id)}"
|
||||
onclick="PF('dlgEditIngkey').show()"
|
||||
update="frmIngkey:pnlData" />
|
||||
<p:column>
|
||||
<p:outputLabel for="ctlIngkeySel"
|
||||
value="Ingredient Key"
|
||||
/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
<!-- -->
|
||||
<h:form id="frmEscat">
|
||||
<p:dialog id="dlgEditShopcat"
|
||||
widgetVar="dlgEditShopcat"
|
||||
header="Edit/Rename Shopping Category"
|
||||
closeOnEscape="true"
|
||||
>
|
||||
<p:panelGrid id="pnlData" columns="2"
|
||||
styleClass="ui-panelgrid-blank"
|
||||
>
|
||||
<p:outputLabel for="@next"
|
||||
value="Shopping Category" />
|
||||
<p:inputText id="ctlDlgShopcatName"
|
||||
label="Position" required="true"
|
||||
value="#{shoppingListBean.editShopcat.shopcategory}" />
|
||||
<p:outputLabel for="@next"
|
||||
value="Position" />
|
||||
<p:inputText
|
||||
id="ctlDlgShopcatPosition" type="number"
|
||||
required="true" size="3"
|
||||
value="#{shoppingListBean.editShopcat.position}" />
|
||||
</p:panelGrid>
|
||||
<p:panelGrid columns="2"
|
||||
style="width: 100%"
|
||||
styleClass="ui-panelgrid-blank"
|
||||
>
|
||||
<p:commandButton id="scDlgOK"
|
||||
value="OK" style="width: 6em"
|
||||
action="#{shoppingListBean.ajaxOnClickShopcat}"
|
||||
update="frmIsk1:tblShopcats"
|
||||
process="@this pnlData"
|
||||
oncomplete="PF('dlgEditShopcat').hide()" />
|
||||
<p:commandButton id="scDlgCan"
|
||||
value="Cancel" style="width: 6em"
|
||||
onclick="PF('dlgEditShopcat').hide()" />
|
||||
</p:panelGrid>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
<!-- -->
|
||||
<h:form id="frmIngkey">
|
||||
<p:dialog id="dlgEditIngkey"
|
||||
widgetVar="dlgEditIngkey"
|
||||
header="Edit/Rename Shopping Category for Ingredient Key"
|
||||
closeOnEscape="true"
|
||||
>
|
||||
<p:panelGrid id="pnlData" columns="2"
|
||||
styleClass="ui-panelgrid-blank"
|
||||
>
|
||||
<p:outputLabel for="@next"
|
||||
value="Ingredient Key" />
|
||||
<h:outputText
|
||||
id="ctlDlgIngKeyIngkey"
|
||||
value="#{shoppingListBean.editShopcat.ingkey}" />
|
||||
<p:outputLabel for="@next"
|
||||
value="Shopping Category" />
|
||||
<p:inputText
|
||||
id="ctlDlgIngkeyShopcatName" label="Position"
|
||||
required="true"
|
||||
value="#{shoppingListBean.editShopcat.shopcategory}" />
|
||||
</p:panelGrid>
|
||||
<p:panelGrid columns="2"
|
||||
style="width: 100%"
|
||||
styleClass="ui-panelgrid-blank"
|
||||
>
|
||||
<p:commandButton id="ingkDlgOK"
|
||||
value="OK" style="width: 6em"
|
||||
action="#{shoppingListBean.ajaxOnClickShopcatIngkey}"
|
||||
update="frmIsk1:tblShopcats"
|
||||
process="@this pnlData"
|
||||
oncomplete="PF('dlgEditIngkey').hide()" />
|
||||
<p:commandButton id="ingkDlgCan"
|
||||
value="Cancel" style="width: 6em"
|
||||
onclick="PF('dlgEditIngkey').hide()" />
|
||||
</p:panelGrid>
|
||||
</p:dialog>
|
||||
</h:form>
|
||||
</p:row>
|
||||
<p:row style="vertical-align: top">
|
||||
<p:column>
|
||||
<p:selectOneListbox id="ctlScSel"
|
||||
style="width: 240px"
|
||||
value="#{shoppingListBean.selectedShopcat}"
|
||||
>
|
||||
<f:selectItems
|
||||
value="#{shoppingListBean.shopcatList}"
|
||||
/>
|
||||
<p:ajax update="ctlIngkeySel" event="change" />
|
||||
</p:selectOneListbox>
|
||||
</p:column>
|
||||
<p:column>
|
||||
<h:selectManyListbox id="ctlIngkeySel"
|
||||
style="width: 240px"
|
||||
value="#{shoppingListBean.selectedIngkey}"
|
||||
label="Ingcat"
|
||||
>
|
||||
<f:selectItems
|
||||
value="#{shoppingListBean.ingkeyList}"
|
||||
/>
|
||||
<p:ajax event="change" update="ctlChangeCat"/>
|
||||
</h:selectManyListbox>
|
||||
</p:column>
|
||||
</p:row>
|
||||
<p:row>
|
||||
<p:column>
|
||||
<p:outputLabel
|
||||
value="Change shopping category to:"
|
||||
/>
|
||||
</p:column>
|
||||
<p:column>
|
||||
<p:autoComplete
|
||||
value="#{shoppingListBean.newShopcat}"
|
||||
autoSelection="false" forceSelection="false"
|
||||
maxResults="12"
|
||||
completeMethod="#{shoppingListBean.suggestShopcat}"
|
||||
/>
|
||||
</p:column>
|
||||
</p:row>
|
||||
<p:row>
|
||||
<p:column>
|
||||
<p:commandButton id="ctlChangeCat" value="Change..."
|
||||
disabled="#{empty shoppingListBean.selectedIngkey}"
|
||||
onclick="PF('dlgOkRecat').show()"
|
||||
/>
|
||||
</p:column>
|
||||
<p:column>
|
||||
<h:outputText value="" />
|
||||
</p:column>
|
||||
</p:row>
|
||||
</p:panelGrid>
|
||||
</h:form>
|
||||
<!-- -->
|
||||
<h:form id="frmDelete">
|
||||
<p:confirmDialog closable="false" id="dlgOkRecat"
|
||||
header="Confirm Change - CANNOT UNDO"
|
||||
message="OK to CHANGE Shopping Category for these Ingredient Keys?"
|
||||
severity="alert" widgetVar="dlgOkRecat"
|
||||
style="z-index: 25000"
|
||||
>
|
||||
<p:commandButton id="dlgOK" value="OK"
|
||||
oncomplete="PF('dlgOkRecat').hide()"
|
||||
action="#{shoppingListBean.doChangeShopcat}"
|
||||
update="@form:@parent:frmIsk:ctlScSel @form:@parent:frmIsk:ctlIngkeySel"
|
||||
immediate="true"
|
||||
/>
|
||||
<p:commandButton id="dlgCancel" value="Cancel"
|
||||
onclick="PF('dlgOkRecat').hide()"
|
||||
/>
|
||||
</p:confirmDialog>
|
||||
</h:form>
|
||||
</html>
|
|
@ -21,3 +21,9 @@ textarea {
|
|||
font-family: 'latoregular', 'Trebuchet MS,Arial,Helvetica,sans-serif';
|
||||
font-size: 1em
|
||||
}
|
||||
|
||||
#footer {
|
||||
position: absolute;
|
||||
bottom: 90px;
|
||||
width: 100%;
|
||||
}
|
|
@ -25,57 +25,87 @@
|
|||
}
|
||||
</style>
|
||||
<h:messages />
|
||||
<h:form id="form1">
|
||||
<p:dataTable id="tblRecipes" style="width: 600px"
|
||||
value="#{shoppingListBean.recipeList}" var="item"
|
||||
>
|
||||
<p:column headerText="Recipe">
|
||||
<h:outputText value="#{item.title}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
<!-- ====== Ingredients ============================ -->
|
||||
<p:column id="ingredientsc"
|
||||
style="width: 25%; vertical-align: top;"
|
||||
>
|
||||
<p:dataTable id="tblShopIngredients"
|
||||
style="width: 600px; margin-top: 10px"
|
||||
value="#{shoppingListBean.ingredientList}"
|
||||
sortBy="#{item.shopCat}" var="item"
|
||||
>
|
||||
<f:facet name="header">
|
||||
<h:outputText styleClass="subtitle"
|
||||
value="Ingredients"
|
||||
/>
|
||||
</f:facet>
|
||||
<p:headerRow>
|
||||
<p:column colspan="4">
|
||||
<h:outputText value="#{item.shopCat}" />
|
||||
</p:column>
|
||||
</p:headerRow>
|
||||
<p:column label="ingKey">
|
||||
<h:outputText value="#{item.ingkey}" />
|
||||
</p:column>
|
||||
<p:column label="Amt"
|
||||
style="width: 3em; text-align: right"
|
||||
<p:tabView id="tabGroupClient" orientation="left"
|
||||
dynamic="true"
|
||||
>
|
||||
<p:tab id="overviewTab" title="Shopping List">
|
||||
<h:form id="form1">
|
||||
<p:dataTable id="tblRecipes"
|
||||
style="width: 600px"
|
||||
value="#{shoppingListBean.recipeList}"
|
||||
var="item"
|
||||
>
|
||||
<h:outputText
|
||||
value="#{item.displayAmount}"
|
||||
/>
|
||||
<f:facet name="header">
|
||||
<h:outputText value="Recipes" />
|
||||
</f:facet>
|
||||
<p:column>
|
||||
<h:outputText value="#{item.title}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
<!-- ====== Ingredients ============================ -->
|
||||
<p:column id="ingredientsc"
|
||||
style="width: 25%; vertical-align: top;"
|
||||
>
|
||||
<p:dataTable id="tblShopIngredients"
|
||||
style="width: 600px; margin-top: 10px"
|
||||
value="#{shoppingListBean.ingredientList}"
|
||||
sortBy="#{item.shopCat}" var="item"
|
||||
>
|
||||
<f:facet name="header">
|
||||
<h:outputText
|
||||
styleClass="subtitle"
|
||||
value="Ingredients"
|
||||
/>
|
||||
</f:facet>
|
||||
<p:headerRow>
|
||||
<p:column colspan="4">
|
||||
<h:outputText
|
||||
value="#{item.shopCat}"
|
||||
/>
|
||||
</p:column>
|
||||
</p:headerRow>
|
||||
<p:column label="ingKey">
|
||||
<h:outputText
|
||||
value="#{item.ingkey}"
|
||||
/>
|
||||
</p:column>
|
||||
<p:column label="Amt"
|
||||
style="width: 3em; text-align: right"
|
||||
>
|
||||
<h:outputText
|
||||
value="#{item.displayAmount}"
|
||||
/>
|
||||
</p:column>
|
||||
<p:column label="Units"
|
||||
style="width: 5em"
|
||||
>
|
||||
<h:outputText
|
||||
value="#{item.unit}"
|
||||
/>
|
||||
</p:column>
|
||||
<p:column label="Item"
|
||||
style="width: 20em"
|
||||
>
|
||||
<h:outputText
|
||||
value="#{item.item}"
|
||||
/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</p:column>
|
||||
<p:column label="Units" style="width: 5em">
|
||||
<h:outputText value="#{item.unit}" />
|
||||
</p:column>
|
||||
<p:column label="Item" style="width: 20em">
|
||||
<h:outputText value="#{item.item}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</p:column>
|
||||
</h:form>
|
||||
</p:tab>
|
||||
<!-- -->
|
||||
<p:tab id="ingshopcatEditTab" title="Edit">
|
||||
<ui:include
|
||||
src="/WEB-INF/layout/misctabs/ingshopkey.xhtml"
|
||||
/>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
<h:form id="frmHome">
|
||||
<p:commandButton id="doHome" value="Home"
|
||||
icon="ui-icon-home" ajax="false" immediate="true"
|
||||
action="main.jsf"
|
||||
/>
|
||||
</h:form>
|
||||
<!-- -->
|
||||
<ui:include src="/WEB-INF/layout/misctabs/ingshopkey.xhtml"/>
|
||||
</ui:define>
|
||||
</ui:composition>
|
Loading…
Reference in New Issue
Block a user