Populate one dropdown list based on the selection of other dropdown list using Spring Boot

I tried my best to find a solution for this but I couldn't, I am trying to make the user select a category name, and based on this selection it will load the product's properties that are associated with this category.

I can load the categories and the products but i can't load the products based on the categories and the product's price i need it to be displayed but the user can't change the price.

CartItem Controller:

  @Controller
public class CartItemsControllers {

    @Autowired
    private CartItemService shoppingCartService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private ProductRepository productRepository;

    public CartItemsControllers(CartItemService shoppingCartService, CustomerService customerService, ProductRepository productRepository) {
        this.shoppingCartService = shoppingCartService;
        this.customerService = customerService;
        this.productRepository = productRepository;
    }

    //Model

    @ModelAttribute("cartItem")
    public CartItem cartItem()
    {
        return new CartItem();
    }

    @ModelAttribute("product")
    public List<Products> initializeprodcuts(){
        List<Products> products = productRepository.findAll();
        return products ;
    }

    //create form
    @GetMapping("/cart/create")
    public String createCartItem(Model model)
    {
        CartItem cartItem = new CartItem();

        model.addAttribute("cartItem",cartItem);

        return "MakeABill";
    }

    //Save
    @PostMapping("/cart/save")
    public String saveCartItem(@ModelAttribute("cartItem") CartItem cartItem)
    {
        shoppingCartService.saveCart(cartItem);

        return "MakeABill";
    }


@GetMapping("/products/{categoryId}")
public List<Products> getCategoriesProducts(@PathVariable Long categoryId)
{
    return productRepository.findByCategoriesId(categoryId);
}

CartItem Entity:

 @Entity
@Table(name="cart_items")
@AllArgsConstructor

public class CartItem {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long cart_item_id;

    @Temporal(TemporalType.DATE)
    private Date date;

    private int product_quantity;

    @OneToMany(fetch = FetchType.LAZY,mappedBy = "product_id")//this column is the foreign key
    private Set<Products> product = new HashSet<>();

    public Date getDate() {
        return date;
    }
    public CartItem()
    {

    }

Products Entity Class:

 public class Products {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long product_id;

    private String product_name;

    private double product_price;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "categories_id") //the name of the column in the other class and that name will be a column in the class
    private Categories product_category;


    private String product_quantity;

    private String product_Section;

    private String product_ExpDate;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "cart_item_id") //the name of the column in the other class and that name will be a column in the class
    private CartItem cartItem;

ProductRepository:

    @Repository
public interface ProductRepository extends JpaRepository<Products, Long> {

    List<Products> findByCategoriesId(Long categoriesId);

}

Make A Bill HTML PAGE:

                    <form th:action="@{/cart/save}" method="post" th:object="${cartItem}">

                    <div class="row g-3">
                        <div class="col-12">
                            <h4 class="mb-3">Select A Product</h4>
                            <br>

                            <label th:for="category"> Category : </label>
                            <select class="form-control form-control-sm" id="category" autofocus th:change="getProducts()"> <!-- the name of the variable  -->
                                <option value="">Select Category</option>
                                <!-- ${product} this is the model attribute  -->
                                <!-- th:value="${product.categories_id}" value here is the id-->
                                <!-- th:text="${category.categoryName}" text is what i want to be shown that eqauls to the id-->
                                <!--<option th:each = "product: ${product}"
                                        th:value="${product.product_category.categories_id}"
                                        th:text="${product.product_category.categoryName}"

                                ></option>-->

                            </select>
                            <br>
                            <label th:for="product"> Product Name : </label>
                            <select class="form-control form-control-sm" id="product" autofocus>
                                <option value="">Select Product</option>
                                <option th:each = "product: ${product}"
                                        th:value="${product.product_name}"
                                        th:text="${product.product_name}"
                                >
                                </option>
                            </select>

                            <br>

                            <label th:for="product_price"> Product Price : </label>
                            <input class="form-control form-control-sm" id="product_price"  th:value="${product_name}" th:text="${product_price}" disabled >


                            <br>
                            <label th:for="roles"> Product Quantity : </label>
                            <input class="form-control form-control-sm" id="product_quantity"  th:field="*{product_quantity}" autofocus>

                            <br>


                            <button class="w-5 btn btn-primary " type="submit" id="add_submit">Add </button>

                        </div>

                    </div>

                </form>
<script>

    function getProducts(){

   //get the category id
   var categoryId = $('#category').val();
    $.get("/products/" + categoryId, function(data){
        var option = "";
        $.each(data, function (key, value) {
            option += "<option value = " + value.id + ">" + value.product_name +  "</option>";
        });
        $("#product").find('option').remove().end().append(option);
    });
}
</script>

I got an error here:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cartItemsControllers' defined in file [E:\Spring Boot\warehouseManagementSystem\target\classes\com\example\warehouseManagementSystem\Controllers\CartItemsControllers.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'shoppingCartImp': Unsatisfied dependency expressed through field 'productRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productRepository' defined in com.example.warehouseManagementSystem.Repository.ProductRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract java.util.List com.example.warehouseManagementSystem.Repository.ProductRepository.findByCategoriesId(java.lang.Long)! Reason: Failed to create query for method public abstract java.util.List com.example.warehouseManagementSystem.Repository.ProductRepository.findByCategoriesId(java.lang.Long)! No property categoriesId found for type Products!; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.example.warehouseManagementSystem.Repository.ProductRepository.findByCategoriesId(java.lang.Long)! No property categoriesId found for type Products!
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.10.jar:5.3.10]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.10.jar:5.3.10]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.10.jar:5.3.10]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.5.jar:2.5.5]

1 answer

  • answered 2021-10-24 13:59 Vallabh Vaidya

    You can populate products depending on selected categories using jQuery like below

    function getProducts(){
        
       //get the category id
       var categoryId = $('#category').val();
        $.get("/products/" + categoryId, function(data){
            var option = "";
            $.each(data, function (key, value) {
                option += "<option value = " + value.id + ">" + value.product_name +  "</option>";
            });
            $("#product").find('option').remove().end().append(option);
        });
    }
    

    Call getProducts() method using

    <select id="category" th:change="getProducts()">
    

    Define a Rest API endpoinnt "/products/{categoryId}" that returns list of products for given categoryId

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum