Suggestion list for cuisine type re-activated

version2
Tim Holloway 2 years ago
parent e5984e5d6f
commit 3b0342429f
  1. 3
      application.properties
  2. 11
      src/main/java/com/mousetech/gourmetj/AdminMainBean.java
  3. 36
      src/main/java/com/mousetech/gourmetj/RecipeDetailBean.java
  4. 3
      src/main/java/com/mousetech/gourmetj/persistence/dao/RecipeRepository.java
  5. 2
      src/main/java/com/mousetech/gourmetj/persistence/model/Ingredient.java
  6. 6
      src/main/java/com/mousetech/gourmetj/persistence/model/Recipe.java
  7. 15
      src/main/java/com/mousetech/gourmetj/persistence/service/RecipeService.java
  8. 2
      src/main/resources/META-INF/resources/detailEdit.xhtml
  9. 51
      src/main/resources/META-INF/resources/main.xhtml

@ -2,7 +2,8 @@
joinfaces.jsf.project-stage=development joinfaces.jsf.project-stage=development
joinfaces.primefaces.theme=bluesky joinfaces.primefaces.theme=bluesky
#spring.thymeleaf.enabled=false spring.thymeleaf.enabled=false
server.error.whitelabel.enabled=false
spring.datasource.url=jdbc:sqlite:/home/timh/foo/bazz/recipes.db spring.datasource.url=jdbc:sqlite:/home/timh/foo/bazz/recipes.db
#spring.datasource.username=dbuser #spring.datasource.username=dbuser

@ -131,12 +131,21 @@ public class AdminMainBean implements Serializable {
/** /**
* Remove images from recipe * Search, driven by AJAX
* @param event Notused * @param event Notused
*/ */
public void ajaxUpdateList(AjaxBehaviorEvent event) { public void ajaxUpdateList(AjaxBehaviorEvent event) {
this.doFind(); this.doFind();
} }
/**
* Reset search and display
*/
public void ajaxClearList() {
this.setSearchText("");
this.doFind();
}
/** /**
* Finder * Finder

@ -225,16 +225,17 @@ public class RecipeDetailBean implements Serializable {
if (rid != null) { if (rid != null) {
this.recipe = loadRecipe(rid); this.recipe = loadRecipe(rid);
} else { } else {
// alternative (and probably dead) version of "new // alternative (and probably dead) version of
// "new
// recipe". // recipe".
this.recipe = new Recipe(); this.recipe = new Recipe();
return; return;
} }
} }
userSession.setRecipe(this.recipe); userSession.setRecipe(this.recipe);
getIngredients().setWrappedData( getIngredients().setWrappedData(
buildIngredientFacade(recipe.getIngredientHash())); buildIngredientFacade(recipe.getIngredientHash()));
} }
/** /**
@ -245,7 +246,7 @@ public class RecipeDetailBean implements Serializable {
*/ */
private Recipe loadRecipe(Long recipeId) { private Recipe loadRecipe(Long recipeId) {
Recipe recipe = recipeService.findDetails(recipeId); Recipe recipe = recipeService.findDetails(recipeId);
if ( recipe == null ) { if (recipe == null) {
return null; return null;
} }
@ -658,7 +659,7 @@ public class RecipeDetailBean implements Serializable {
* *
* Use this to assemble the suggestion list. * Use this to assemble the suggestion list.
*/ */
private String cuisinePartial; private String cuisinePartial = "";
/** /**
* @return the cuisinePartial * @return the cuisinePartial
@ -667,13 +668,22 @@ public class RecipeDetailBean implements Serializable {
return cuisinePartial; return cuisinePartial;
} }
public List<String> cuisineSuggestions(String query) {
if (!query.equals(cuisinePartial)) {
setCuisinePartial(query);
}
return getCuisineList();
}
/** /**
* Set query for eligibility, force list to rebuild.
*
* @param cuisinePartial the cuisinePartial to set * @param cuisinePartial the cuisinePartial to set
*/ */
public void setCuisinePartial(String cuisinePartial) { public void setCuisinePartial(String cuisinePartial) {
this.cuisinePartial = cuisinePartial; this.cuisinePartial = cuisinePartial;
this.cuisineList = null; // trigger construction of new // trigger construction of new list.
// list. this.cuisineList = null;
} }
private List<String> masterCuisineList = null; private List<String> masterCuisineList = null;
@ -701,7 +711,7 @@ public class RecipeDetailBean implements Serializable {
/** /**
* @return the cuisineList built by matching the master list * @return the cuisineList built by matching the master list
* agaist the partial cuisine names. * against the partial cuisine names.
*/ */
public List<String> getCuisineList() { public List<String> getCuisineList() {
if (this.cuisineList == null) { if (this.cuisineList == null) {
@ -856,7 +866,7 @@ public class RecipeDetailBean implements Serializable {
this.category += catToAdd; this.category += catToAdd;
catToAdd = ""; catToAdd = "";
} }
// *** // ***
Part imageFile = null; Part imageFile = null;
@ -877,6 +887,7 @@ public class RecipeDetailBean implements Serializable {
/** /**
* Load/replace images. Computes thumbnail. * Load/replace images. Computes thumbnail.
*
* @param event Notused * @param event Notused
*/ */
public void ajaxUploadImage(AjaxBehaviorEvent event) { public void ajaxUploadImage(AjaxBehaviorEvent event) {
@ -886,16 +897,17 @@ public class RecipeDetailBean implements Serializable {
/** /**
* Remove images from recipe * Remove images from recipe
*
* @param event Notused * @param event Notused
*/ */
public void ajaxDeleteImage(AjaxBehaviorEvent event) { public void ajaxDeleteImage(AjaxBehaviorEvent event) {
this.recipe.setImage(null); this.recipe.setImage(null);
this.recipe.setThumb(null); this.recipe.setThumb(null);
} }
/** /**
* Return marker for image. Unlike normal JSF, I don't * Return marker for image. Unlike normal JSF, I don't care
* care if it gets multiple times and returns different values. * if it gets multiple times and returns different values.
* *
* @return "random" string * @return "random" string
*/ */

@ -29,6 +29,9 @@ public interface RecipeRepository
@EntityGraph(value="Recipe.findWorkingSet") @EntityGraph(value="Recipe.findWorkingSet")
public Recipe findDetailsById(Long recipeId); public Recipe findDetailsById(Long recipeId);
@Query(name = "Recipe.findCusines", nativeQuery = true)
List<String> FindCuisinesNative();
// final static String SQL_FIND_CATEGORIES = // final static String SQL_FIND_CATEGORIES =
// "SELECT DISTINCT category from categories" // "SELECT DISTINCT category from categories"

@ -2,6 +2,7 @@ package com.mousetech.gourmetj.persistence.model;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.NotNull;
/** /**
* The persistent class for the "ingredients" database table. * The persistent class for the "ingredients" database table.
@ -55,6 +56,7 @@ public class Ingredient implements Serializable, IngredientIF {
private String item; private String item;
@Column(name = "optional") @Column(name = "optional")
@NotNull
private Integer optional; private Integer optional;
@Column(name = "position") @Column(name = "position")

@ -17,6 +17,9 @@ import javax.persistence.*;
@NamedQueries({ @NamedQueries({
@NamedQuery(name = "Recipe.findAll", query = "SELECT r FROM Recipe r"), @NamedQuery(name = "Recipe.findAll", query = "SELECT r FROM Recipe r"),
@NamedQuery(name = "Recipe.findByTitle", query = "SELECT r FROM Recipe r WHERE r.title LIKE concat('%', :searchText,'%')") }) @NamedQuery(name = "Recipe.findByTitle", query = "SELECT r FROM Recipe r WHERE r.title LIKE concat('%', :searchText,'%')") })
@NamedNativeQuery(name = "Recipe.findCusines", query = "SELECT DISTINCT cuisine from recipe"
+ " where cuisine is not null and cuisine <> ''"
+ " ORDER BY cuisine ASC")
@NamedEntityGraph(name = "Recipe.findWorkingSet", attributeNodes = { @NamedEntityGraph(name = "Recipe.findWorkingSet", attributeNodes = {
@NamedAttributeNode(value = "categories"), @NamedAttributeNode(value = "categories"),
@NamedAttributeNode(value = "ingredientHash", subgraph = "subgraph.shopcat") }, subgraphs = { @NamedAttributeNode(value = "ingredientHash", subgraph = "subgraph.shopcat") }, subgraphs = {
@ -89,8 +92,7 @@ public class Recipe implements Serializable {
private Double yields; private Double yields;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true) @OneToMany(fetch = FetchType.EAGER, mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Category> categories = private Set<Category> categories = new HashSet<Category>();
new HashSet<Category>();
/** /**
* @param categories the categories to set * @param categories the categories to set

@ -8,6 +8,7 @@ import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.persistence.NamedEntityGraph; import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedNativeQuery;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -34,7 +35,7 @@ public class RecipeService implements Serializable {
@Inject @Inject
private RecipeRepository recipeRepository; private RecipeRepository recipeRepository;
public List<Recipe> findAll() { public List<Recipe> findAll() {
return recipeRepository.findAll(); return recipeRepository.findAll();
} }
@ -51,9 +52,17 @@ public class RecipeService implements Serializable {
return recipeRepository.findDetailsById(recipeId); return recipeRepository.findDetailsById(recipeId);
} }
/**
* final String sql = "SELECT DISTINCT cuisine from recipe"
+ " where cuisine is not null and cuisine <> ''"
+ " ORDER BY cuisine ASC";
* @return
*/
public List<String> findCuisines() { public List<String> findCuisines() {
// TODO Auto-generated method stub return recipeRepository.FindCuisinesNative();
return null;
} }

@ -73,7 +73,7 @@
/> />
<p:autoComplete id="rcuisine" <p:autoComplete id="rcuisine"
value="#{recipeDetailBean.recipe.cuisine}" value="#{recipeDetailBean.recipe.cuisine}"
autocomplete="#{recipeDetailBean.cuisinePartial}" completeMethod="#{recipeDetailBean.cuisineSuggestions}"
/> />
<p:outputLabel for="@next" <p:outputLabel for="@next"
value="Rating" value="Rating"

@ -8,32 +8,33 @@
<ui:define name="title">Gourmet Recipe Manager</ui:define> <ui:define name="title">Gourmet Recipe Manager</ui:define>
<ui:define name="content"> <ui:define name="content">
<h:form id="form1"> <h:form id="form1">
<p:panelGrid label="Find a Recipe" columns="1"> <div>
<p:panelGrid columns="3"> <span class="ui-input-icon-left"> <i
<span class="ui-input-icon-left"> <i class="pi pi-search"
class="pi pi-search" /> <p:inputText id="searchFor" size="45"
/> <p:inputText id="searchFor" width="45" placeholder="Recipe title, (todo cuisine, etc.)"
placeholder="Recipe title (todo) cuisine, etc." value="#{adminMainBean.searchText}"
styleClass="redBox" accesskey="f"
value="#{adminMainBean.searchText}"
>
<f:ajax event="change"
execute="@this" render="@form"
listener="#{adminMainBean.ajaxUpdateList}"
/>
</p:inputText>
</span>
<p:button id="find" value="Find"
defaultCommand="true"
action="#{adminMainBean.doFind}"
> >
</p:button> <f:ajax event="change" execute="@this"
<p:button value="New Recipe" render="form2:table1"
action="#{adminMainBean.doNewRecipe}" listener="#{adminMainBean.ajaxUpdateList}"
> />
</p:button> </p:inputText>
</p:panelGrid> </span>
</p:panelGrid> <p:commandButton id="find" value="Find"
defaultCommand="true"
action="#{adminMainBean.doFind}"
/>
<p:commandButton id="ctlClear" value="Clear"
immediate="true"
update="form1:searchFor form2:table1"
action="#{adminMainBean.ajaxClearList}"
/>
<p:commandButton value="New Recipe"
action="#{adminMainBean.doNewRecipe}"
/>
<p:defaultCommand target="find" />
</div>
</h:form> </h:form>
<h:form id="form2"> <h:form id="form2">
<p:dataTable id="table1" rows="30" <p:dataTable id="table1" rows="30"

Loading…
Cancel
Save