0

I'm creating a web shop in JSP for a school project.

On each product page, there's a button to add it to the cart. Originally, there is only one item added to the cart when we press the "Add" button.

I send the productId to add to the controller by adding it as parameter in the url as you can see here :

<div class="product-page">
<div class="product">
    <h1>${product.title}</h1>
    <img src="${product.imageUrl}"/>
    <div class="price"><p>${product.price}€</p></div>
</div>
<c:url var="addLineToCart" value="/product/addLineCart">
    <c:param name="productId" value="${product.id}" />
</c:url>
<a id="addToCart" type="submit" href="${addLineToCart}"><spring:message code="addCart"/></a>

What I'd like to do, is to add an input field to specify the amount of items to add in the cart. I did it here :

<div class="product-page">
<div class="product">
    <h1>${product.title}</h1>
    <img src="${product.imageUrl}"/>
    <div class="price"><p>${product.price}€</p></div>
</div>
<input type="number" name="quantity" value="1"/>
<c:url var="addLineToCart" value="/product/addLineCart">
    <c:param name="productId" value="${product.id}" />
</c:url>
<a id="addToCart" type="submit" href="${addLineToCart}"><spring:message code="addCart"/></a>

My problem is that I don't know how to pass the value from the input field in the <c:param/> property in order to add it in the URL too.

Here is how my controller looks like assuming I get the quantity to add via the URL :

@Controller
@RequestMapping(value="/product")
@SessionAttributes({Constants.CURRENT_CART})
public class ProductController {
    private ProductDAO productDAO;

    @Autowired
    public ProductController(ProductDAO productDAO){
        this.productDAO = productDAO;
    }

    @ModelAttribute(Constants.CURRENT_CART)
    public Cart cart()
    {
        return new Cart();
    }

    @RequestMapping (method = RequestMethod.GET)
    public String home(ModelMap model, @RequestParam("product") int productId,     @ModelAttribute(value=Constants.CURRENT_CART) Cart cart){
        Product product = productDAO.getById(productId);
        model.addAttribute("product", product);
        model.addAttribute("title", "Produit");
        model.addAttribute("cart", cart);
        return "integrated:product";
    }

    @GetMapping("/addLineCart")
    public String addLineCart(@ModelAttribute(value=Constants.CURRENT_CART) Cart cart,     @RequestParam("productId") int  productId, @RequestParam("quantity") int  quantity, ProductService productService)
    {
        Product product = productService.searchProduct(productId,productDAO);
        cart.addProduct(product, quantity);
        return "redirect:/product?product=" + productId;
    }
}

Thanks for your help.

  • If you want to send values from input fields, you should make the page have a **form**. Search the web to learn how. --- You could also use JavaScript to grab the value and add it to the URL, but if you don't even know how forms work, that would be beyond your current skill level. Learn how to do forms first, then you can learn how to dynamically manipulate the data using JavaScript at some later time. – Andreas Jan 03 '21 at 05:24

1 Answers1

1

The easiest way is to wrap the fields in a HTML <form> tag and submit the data to your controller. You should also replace GET with a POST since your browser might decide to cache the response to some combinations of productId and quantity and your application might exhibit some unwanted behavior as result of that (don't forget to change your @GetMapping in your controller with a @PostMapping also).

There is also the option of submiting this to the server with JavaScript as an Ajax request, or to change the value of the URL in your existing link to include the quantity when you click it and before making the request to the server, but using a form with a POST action is the easiest and cleanest solution.

Finally, <c:url> and <c:param> are server side tags. They get evaluated at the server to produce your final HTML that gets sent to the client browser. You can't get your input value from the browser into your <c:param> because you are running client code at this point, no longer server code.

Bogdan
  • 20,624
  • 2
  • 64
  • 57
  • That's what I wanted to do but my problem was that I didn't know what to use as modelAttribute. So I created a Model class (`ProductToCart`) properties : `productId` and `quantity` that I use just to pass this information from my `product.jsp` to my `ProductController`. Is it the right approach to use ? Also, I used a hidden `input` field to pass my `product.id` in the form, is it right too, or is there a way to add it directly from my controller ? – Benjamin Françoisse Jan 03 '21 at 18:07
  • 1
    You can bind your form data to a `ProductToCart` class object instead of retrieving individual fields from the request, that's no problem at all, sometimes it's even preferred if you have many inputs in your form. Using hidden fields is also OK when you want to send extra information along with any visible input fields. One observation though: you don't send data from your JSP to your controller. Your JSP gets executed and generates HTML that is then sent to the client browser. It's then from the client browser that you send data to your controller, not from the JSP. – Bogdan Jan 03 '21 at 18:49
  • Thanks a lot for your answers and for those precisions about how it works ! – Benjamin Françoisse Jan 03 '21 at 20:16