This question already has answers here:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
(5 answers)
Closed 6 years ago.
I have an selectOneMenu and when Its value at 0, I want to "Add" button does not show up. I have rendered for this situation. Here is code ;
<p:panelGrid id="pnlRegister" columns="6" style="width: 95%" >
<p:inputText id="name" class=" width100" value="#{register.name}" />
<p:selectOneMenu id="numberOfChild" value="#{register.numberOfChild}" >
<p:ajax listener="#{register.listenNumberOfChild()}" update="pnlRegister" />
<f:selectItem itemValue="0" itemLabel="0" />
<f:selectItem itemValue="1" itemLabel="1" />
<f:selectItem itemValue="2" itemLabel="2" />
<f:selectItem itemValue="3" itemLabel="3" />
<f:selectItem itemValue="4" itemLabel="4" />
<f:selectItem itemValue="5" itemLabel="5" />
</p:selectOneMenu>
<p:commandButton id="addPerson" value="Add" actionListener="#{register.openPersonDialog(1)}" rendered="#{register.visibleAddPersonButton}" >
<p:ajax event="dialogReturn" update="pnlPerson" />
</p:commandButton>
And Bean code;
public void listenNumberOfChild() {
if (numberOfChild == 0) {
visibleAddPersonButton = false;
} else {
visibleAddPersonButton = true;
}
System.out.println("ListenerNumberOfChild " + numberOfChild);
}
</panelGrid>
Now problem is, when I change numberOfChild, listener works uptades pnlRegister as expected. However server does not keep inputText values. For example before listener works, I write register.name as "John". After listener works, it does not keep it and it gets as null. I hope I could tell what I'm trying and what is problem. So do you have any suggestion ? Also I tried RequestContext.getCurrentInstance().update but same problem occured.
This is how I made it work:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<f:view>
<h:head>
<title>pfaces</title>
</h:head>
<h:form>
<p:panelGrid id="pnlRegister" columns="3" style="width: 95%">
<p:inputText id="name" value="#{register.name}"/>
<p:selectOneMenu id="numberOfChild" value="#{register.numberOfChild}">
<p:ajax process="name numberOfChild"
listener="#{register.listenNumberOfChild()}" update="pnlRegister"/>
<f:selectItem itemValue="0" itemLabel="0"/>
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
</p:selectOneMenu>
<p:commandButton id="addPerson" value="Add"
rendered="#{register.visibleAddPersonButton}"/>
</p:panelGrid>
</h:form>
<h:body>
</h:body>
</f:view>
</html>
and the backing bean:
package biz.tugay.jsfexampla;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class Register {
private boolean visibleAddPersonButton = false;
private int numberOfChild = 0;
private String name;
public boolean isVisibleAddPersonButton() {
return visibleAddPersonButton;
}
public void setVisibleAddPersonButton(boolean visibleAddPersonButton) {
this.visibleAddPersonButton = visibleAddPersonButton;
}
public int getNumberOfChild() {
return numberOfChild;
}
public void setNumberOfChild(int numberOfChild) {
this.numberOfChild = numberOfChild;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void listenNumberOfChild() {
visibleAddPersonButton = numberOfChild != 0;
System.out.println("ListenerNumberOfChild " + numberOfChild);
}
}
Here, you can see it in action: https://youtu.be/IQN3HAejhcM
Related
Hope you could help me
I am learning JSF and Primesface on my own.
I having trouble implementing the following JSF form, and make it work as I require it
Basically
I need to have one Form, and need to execute AJAX whenever a value change in the Form.
I am not able to make that Once Single Ajax call call for entrie form.
Rather I have to call it for every Data Input I have to call.
Second the Date Picker does not work or loses it formatting after selecting date.
Note I have not any additional Java Script... to the JSF.
Please refer additional image that I have attached
Further is that Possible to provide Single Ajax in case any inputs changes in the FORM, instead of each inputs tags.
What is difference between f:ajax and p:ajax
JSF 2.3 Dynamic Web Module 4.0 Redhat JBOSS 7.2 Java 1.8 Primefaces
7.0
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:form styleClass="fill" id="tinputForm">
<div style="color: #FFF; padding-left: 70px"><strong >INPUT PANEL</strong></div>
<hr/>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:outputLabel value="Server-Class"/>
<h:panelGroup layout="block" styleClass="radio">
<h:selectOneRadio value = "#{sideBarInputsBean.serverClass}" layout="pageDirection" >
<f:selectItem itemValue = "Gateway" itemLabel = "Gateway" />
<f:selectItem itemValue = "Facing Server" itemLabel = "Facing Server" />
<f:selectItem itemValue = "Server Facing" itemLabel = "Server Facing" />
<f:selectItem itemValue = "Central Server" itemLabel = "Central Server" />
<!-- <p:ajax listener="#{sideBarInputsBean.printSelectedCRadioButton()}" /> -->
<f:ajax event="click" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</h:selectOneRadio>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:outputLabel value="Choose a Parameter:"/>
<h:panelGroup layout="block" styleClass="radio">
<h:selectOneRadio value = "#{sideBarInputsBean.parameter}" layout="pageDirection" >
<f:selectItem itemValue = "IISLOG" itemLabel = "IIS Log Counter" />
<f:selectItem itemValue = "ASPNET" itemLabel = "ASP DOT Net Counters" />
</h:selectOneRadio>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:outputLabel value="Select a Server:"/>
<h:panelGroup rendered="#{sideBarInputsBean.serverClass == 'Gateway'}">
<h:panelGroup layout="block" >
<h:selectOneMenu id="CLGWServer" value="#{sideBarInputsBean.serverName}" styleClass="mymenu">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{dataForSideBarInputBean.clientGatewayList}" />
<f:ajax event="change" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</h:selectOneMenu>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup rendered="#{sideBarInputsBean.serverClass == 'Facing Server'}">
<h:panelGroup layout="block" >
<h:selectOneMenu id="CFASServer" value="#{sideBarInputsBean.serverName}" styleClass="mymenu">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{dataForSideBarInputBean.clientFacingList}" />
<f:ajax event="change" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</h:selectOneMenu>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="CustomWell" >
<h:panelGroup layout="block" styleClass="datepick">
<p:outputLabel value="Date:" />
<p:datePicker id="DateSelector" value="#{sideBarInputsBean.selectedDate}" showIcon="true" showTime="true" pattern="dd.MM.yyyy">
<f:ajax event="dateSelect" listener="#{sideBarInputsBean.printSelectedCRadioButton()}" execute="#form" render="#form :tinputForm" />
</p:datePicker>
</h:panelGroup>
</h:panelGroup>
</h:form>
Bean Code.
package cdv.mrdataanalytics.bean;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
#Named("sideBarInputsBean")
#SessionScoped
public class SideBarInputsBean implements Serializable {
private static final long serialVersionUID = 1L;
private String serverClass="Gateway";
private String parameter="IISLOG";
private String serverName="";
private Date selectedDate;
public String getServerClass() {
return this.serverClass;
}
public void setServerClass(String strClass) {
this.serverClass = strClass;
}
public String getParameter() {
return this.parameter;
}
public void setParameter(String strClass) {
this.parameter = strClass;
}
public String getServerName() {
return this.serverName;
}
public void setServerName(String strClass) {
this.serverName = strClass;
}
public Date getSelectedDate() {
return this.selectedDate;
}
public void setSelectedDate(Date date7) {
this.selectedDate = date7;
}
public void printSelectedCRadioButton() throws IOException{
System.out.println("Selected value = "+this.getServerClass());
System.out.println("Parameter value = "+this.getParameter());
System.out.println("ServerName = "+this.getServerName());
System.out.println("SelectedDate = "+this.getSelectedDate());
//ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
//ec.redirect(ec.getRequestContextPath() + "/next.xhtml?action=add");
}
}
This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 6 years ago.
I'm new to JSF and Primefaces and wanted to know what the best solution is to render a component according to radio selection (hiding and showing again)? I posted my ManagedBean and my JSF-Page-Excerpt. Thanks in advance.
My JSF-Page:
<p:dialog widgetVar="komponentErstellenDialogWV" modal="true"
id="komponentErstellenDialog" header="Komponente erstellen">
<h:form>
<p:wizard flowListener="#{userWizard.onFlowProcess}">
<p:tab id="produktAuswahlTab" title="Produkt auswählen">
<p:panel>
<h:panelGrid columns="2" columnClasses="label, value">
<h:outputText value="Produkt:" />
<p:selectOneRadio id="produktAERadio"
value="#{komponenteErstellenWizardController.produktAuswahl}">
<f:selectItem itemValue="1" itemLabel="Neu erstellen" />
<f:selectItem itemValue="2" itemLabel="Aus Liste auswählen" />
<p:ajax event="click" update="produktSelect" />
</p:selectOneRadio>
<p:selectOneMenu id="produktSelect"
rendered="#{komponenteErstellenWizardController.shouldRenderProduktSelect()}"
value="#{komponenteErstellenWizardController.komponente.produkt}">
<f:selectItems
value="#{komponenteErstellenWizardController.findAllProdukt()}"
var="currentProdukt"
itemLabel="#{currentProdukt.hersteller.concat(' ').concat(currentProdukt.name)}"
itemValue="#{currentProdukt.id}" />
</p:selectOneMenu>
</h:panelGrid>
</p:panel>
</p:tab>
</p:wizard>
</h:form>
</p:dialog>
My ManagedBean:
#ManagedBean
#SessionScoped
public class KomponenteErstellenWizardController implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
// Properties
private Komponente komponente = new Komponente();
private String produktAuswahl;
#PostConstruct
public void init() {
produktAuswahl = "1";
}
public String getProduktAuswahl() {
System.out.println("GetProduktAuswahl invoked with returning value: " + produktAuswahl);
return produktAuswahl;
}
public void setProduktAuswahl(String produktAuswahl) {
System.out.println("SetProduktAuswahl invoked with Value: " + produktAuswahl);
this.produktAuswahl = produktAuswahl;
}
public Komponente getKomponente() {
return komponente;
}
public void setKomponente(Komponente komponente) {
this.komponente = komponente;
}
// EJBs
#EJB
KomponenteFacade komponenteFacade;
#EJB
ProduktFacade produktFacade;
#EJB
ProduktArtFacade produktArtFacade;
public List<Produkt> findAllProdukt() {
return produktFacade.findAll();
}
public Boolean shouldRenderProduktSelect() {
System.out.println("Wizard Produktauswahl: " + produktAuswahl);
return "2".equals(produktAuswahl);
}
}
I updated my code according to suggestions:
Replaced faces components by primefaces components
Added a new action method "shouldRenderProduktSelect"
Still not working...
Few things..
1) Add this method to your controller:
public boolean shouldRenderSelect(){
return "2".equals(produktAuswahl);
}
2) Change the rendered attribute:
<h:selectOneMenu id="produktSelect"
rendered="#{komponenteErstellenWizardController.shouldRenderSelect()}"
3) update your html:
<p:selectOneRadio id="produktAERadio"
value="#{komponenteErstellenWizardController.produktAuswahl}">
<f:selectItem itemValue="1" itemLabel="Neu erstellen" />
<f:selectItem itemValue="2" itemLabel="Aus Liste auswählen" />
<p:ajax event="click" update="panelSelect" />
</p:selectOneRadio>
<h:panelGroup id="panelSelect">
<p:selectOneMenu id="produktSelect"
rendered="#{komponenteErstellenWizardController.shouldRenderProduktSelect()}"
...
</p:selectOneMenu>
</h:panelGroup>
The key is to wrap the selectOneMenu within and from ajax update the panelGroup, not the menu.
I want to take the input from two input fields and simultaneous compute the sum into another input field (total) that must be editable however. I tried like that (I cutted away some code useless to the question):
<p:inputText id="field1"
value="#{ModelBean.object.field1}"
onkeydown="#{BackingBean.updateTotal()}">
</p:inputText>
<p:selectOneMenu id="field2" required="true"
value="#{ModelBean.object.field2}">
<f:selectItem itemLabel="22 %" itemValue="22" />
<f:selectItem itemLabel="10 %" itemValue="10" />
<f:selectItem itemLabel="4 %" itemValue="4" />
<f:selectItem itemLabel="0 %" itemValue="0" />
</p:selectOneMenu>
<!-- TOTAL -->
<p:inputText id="total"
value="#{ModelBean.object.total}">
</p:inputText>
As you can see I delegated tho BackingBean.update() method the compute task. It updates the total value and set it into the total field of the bean. The problem that I saw in debug is that the values of my two fields to sum is null. How I can do to let the model variables filled while I am writing? And What I have to modify to let the result of the compute immediately written in the total input filed?
Rather than this you can use Ajax for this:
<p:inputText id="field1" value="#{ModelBean.object.field1}">
<f:ajax event="change" execute="#this" render="total" listener="#{BackingBean.updateTotal}"></ajax>
</p:inputText>
<p:selectOneMenu id="field2" required="true"
value="#{ModelBean.object.field2}">
<f:selectItem itemLabel="22 %" itemValue="22" />
<f:selectItem itemLabel="10 %" itemValue="10" />
<f:selectItem itemLabel="4 %" itemValue="4" />
<f:selectItem itemLabel="0 %" itemValue="0" />
<f:ajax event="change" execute="#this" render="total" listener="#{BackingBean.updateTotal}"></ajax>
</p:selectOneMenu>
<!-- TOTAL -->
<p:inputText id="total" value="#{ModelBean.object.total}">
</p:inputText>
I think you need to put ajax in both components, because to are getting sum on the basis of values of both. And if you don't want to use "Change" event than you can use some other event of ajax.
create project and include it
<?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://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputText value="Keyup: " />
<p:inputText id="counter2" value="#{listenerView.a}">
<p:ajax event="keyup" update="out" listener="#{listenerView.handleKeyEvent}"/>
</p:inputText>
<p:inputText id="counter" value="#{listenerView.b}">
<p:ajax event="keyup" update="out" listener="#{listenerView.handleKeyEvent}" />
</p:inputText>
<h:outputText id="out" value="#{listenerView.c}" />
</h:panelGrid>
</h:form>
</h:body>
</html>
package org.primefaces.showcase.view.ajax;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class ListenerView {
private String text;
private int a;
private int b;
private int c;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public void handleKeyEvent() {
c=a+b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
}
If you want to use the inserted value on the server side to do some calculations, you have to (partially) submit the form first. You may do this via AJAX like this:
<p:inputText id="field1"
value="#{ModelBean.object.field1}">
<p:ajax event="keyup" listener="#{BackingBean.updateTotal}" update="total"/>
</p:inputText>
<p:selectOneMenu id="field2" required="true"
value="#{ModelBean.object.field2}">
<f:selectItem itemLabel="22 %" itemValue="22" />
<f:selectItem itemLabel="10 %" itemValue="10" />
<f:selectItem itemLabel="4 %" itemValue="4" />
<f:selectItem itemLabel="0 %" itemValue="0" />
<p:ajax listener="#{BackingBean.updateTotal}" update="total"/>
</p:selectOneMenu>
<!-- TOTAL -->
<p:inputText id="total"
value="#{ModelBean.object.total}">
</p:inputText>
If all information which is required for the calculation is available on the current view and the calculation is quite easy, like it seems to be here, you may also consider to do the job completely on the client side via plain JavaScript.
I'm a beginner in primefaces framework, I want that my commandButton verify if the selected item is "All" to call a specific method allBooks() , and if another item is choosen: to call another method : loadBook()
<p:selectOneMenu value="#{bookBean.selectedBook.id}">
<f:selectItem itemLabel="Select a book :" itemValue="" />
<f:selectItem itemLabel="All" />
<f:selectItems value="#{bookBean.selectedBooksItems}" />
<p:ajax execute="bookSelect" event="change" listener="#{bookBean.loadBook}" />
</p:selectOneMenu>
<p:commandButton id="validate" action="#{bookBean.requestBook}" value="Validate"/>
Do it in your actionListener method
<p:selectOneMenu value="#{bookBean.selection}">
<f:selectItem itemLabel="Select a book :" itemValue="#{null}" />
<f:selectItem itemLabel="All" itemValue="#{'ALL'}" />
<f:selectItems value="#{bookBean.options}" />
<p:ajax/>
</p:selectOneMenu>
<p:commandButton actionListener="#{bookBean.loadButtonActionListener}" value="Load"/>
public void loadButtonActionListener(ActionEvent event){
if(this.selection.equals("ALL")) {
this.allBooks();
} else {
this.loadBook(this.selection);
}
}
commandButton ajaxified by default so this snippet work as you expect:
<h:form>
<p:selectOneMenu value="#{myBean.selected}">
<f:selectItem itemLabel="ALL" itemValue="ALL" />
<f:selectItem itemLabel="NONE" itemValue="NONE" />
</p:selectOneMenu>
<p:commandButton value="Validate" actionListener="#{myBean.doAction}" />
</h:form>
here is declared bean:
#Named
#RequestScoped
public class MyBean {
private String selected;
public MyBean() {
}
public String getSelected() {
return selected;
}
public void setSelected(String selected) {
this.selected = selected;
}
public void doAction() {
if (selected.equals("ALL")) {
System.out.println("ALL Called!");
} else if (selected.equals("NONE")) {
System.out.println("NONE Called");
}
}
}
UPDATE:
if you want to add ajax change event to selectOneMenu just nest this line in selectOneMenu element
<p:ajax listener="#{myBean.doAction}" />
I'm developing a webshop and I'm facing problems with getting input values from JSF components in the backing bean. I have a datatable, which dynamically loads records from a database table. I want the user to be able to select the amount of items they want to buy and click a button to add them to their shoppingcart. I'm using a dropdownbox to allow the user to select a value, but no matter what value is selected, the value I get in my backing bean is always 1. Any help would be greatly appreciated.
Here's the code for the jsf page
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="/WEB-INF/templates/basictemplate.xhtml">
<ui:define name="content">
<h:form id="form">
<p:dataTable var="necklace" value="#{necklaceBean.necklaces}" paginator="true" rows="10" id="necklaceTable" binding="#{necklaceBean.dataTableNecklaces }"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">
<f:facet name="header">
Kettingen
</f:facet>
<p:column headerText="Foto" id="picture">
<p:lightBox styleClass="imagebox">
<h:outputLink value="#{necklace.picture }" title="#{necklace.productId }">
<h:graphicImage url="#{necklace.picture }" width="175" height="116"/>
</h:outputLink>
</p:lightBox>
</p:column>
<p:column headerText="Omschrijving" id="description">
<p>
#{necklace.description}
</p>
<p>
Prijs: #{necklace.price} Euro
</p>
<p>
<p:selectOneMenu value="#{necklaceBean.amount}">
<f:selectItem itemLabel="1" itemValue="1" />
<f:selectItem itemLabel="2" itemValue="2" />
<f:selectItem itemLabel="3" itemValue="3" />
<f:selectItem itemLabel="4" itemValue="4" />
<f:selectItem itemLabel="5" itemValue="5" />
<f:selectItem itemLabel="6" itemValue="6" />
<f:selectItem itemLabel="7" itemValue="7" />
<f:selectItem itemLabel="8" itemValue="8" />
<f:selectItem itemLabel="9" itemValue="9" />
<f:selectItem itemLabel="10" itemValue="10" />
</p:selectOneMenu>
X
<p:commandButton value="Toevoegen aan winkelwagentje" action="#{necklaceBean.addNecklaceToShoppingCart}"
disabled="#{necklace.soldOut}" ajax="false" />
</p>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
</html>
And here's the backing bean:
import java.util.List;
import org.primefaces.component.datatable.DataTable;
import be.petitefolie.site.controller.controllerobjects.Product;
import be.petitefolie.site.controller.controllerobjects.ProductType;
public class NecklaceBean extends ProductBean {
private List<Product> necklaces;
private int amount;
private DataTable dataTableNecklaces;
public NecklaceBean(){
necklaces = super.listProductsByPoductType(ProductType.NECKLACE);
}
public List<Product> getNecklaces() {
return necklaces;
}
public void setNecklaces(List<Product> necklaces) {
this.necklaces = necklaces;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public DataTable getDataTableNecklaces() {
return dataTableNecklaces;
}
public void setDataTableNecklaces(DataTable dataTableNecklaces) {
this.dataTableNecklaces = dataTableNecklaces;
}
public String addNecklaceToShoppingCart(){
super.addProductToShoppingCart((Product)this.dataTableNecklaces.getRowData(), amount);
return null;
}
}
The problem is that you are binding a single bean to the components of each row in your table.
If you have multiple rows and in the first one you select 3 in the dropdown box and press "add to shopping cart", then if there is another row with 1 selected in the dropdown box, the bean will get updated to 1 (prcisely: firstly it will get updated according to the first row to 3, then according to the second row to 1, and so on).
I believe that this is the source of your problems.
One solution would be to create an object like:
class ProductPurchase{
Necklace necklace;
int amount;
}
change the List<Product> to List<ProductPurchase>, bind the drop down list value to necklace.amount and set the action of "add to cart" to action="#{necklaceBean.addToShoppingCart(necklace)".