My object is Consumer:
Here is a Consumer object has a following fields and want to create a record. But the null pointer exception is reported.
Visualforce page:
<apex:page controller="signup1" >
<apex:form >
<h1>User SignUp</h1>
<apex:panelGrid columns="2" style="margin-top:2em;">
<p><b>Name :</b><br />
<apex:inputField id="name" value="{!con.Name}"/>
</p>
<p><b>Address :</b><br />
<apex:inputField id="address" value="{!con.address__c}"/>
</p>
<p><b>Email Id :</b><br />
<apex:inputField required="true" id="emailid" value="{!con.email_id__c}"/>
</p>
<p><b>Password :</b><br />
<apex:inputSecret id="password" value="{!con.password__c}"/>
</p>
<p><b>Confirm Password :</b><br />
<apex:inputSecret id="confirmpassword" value="{!con.Confirm_Password__c}"/>
</p>
<p><b>Security Question :</b><br />
<apex:inputField required="true" id="securityquestion" value="{!con.Security_Question__c}"/>
</p>
<p><b>Answer :</b><br />
<apex:inputField required="true" id="answer" value="{!con.Answer__c}" />
</p>
<p><b>Ph No :</b><br />
<apex:inputField required="true" id="phno" value="{!con.phone__c}"/>
</p>
<p><b>Pan Card No :</b><br />
<apex:inputField required="true" id="pancardno" value="{!con.Pan_Card_No__c}"/>
</p>
<p> <apex:commandButton action="{!registerUser}" value="SignUp" id="SignUp"/></p>
</apex:panelGrid>
</apex:form>
</apex:page>
controller :
public class signup1
{
Consumer__c con = new Consumer__c();
public void signup1()
{
con = [SELECT Name, address__c, email_id__c, password__c, Confirm_Password__c, Security_Question__c, Answer__c, phone__c from Consumer__c where Name =: ApexPages.currentPage().getParameters().get('Name')];
}
public Consumer__c getcon()
{
return con;
}
public PageReference registerUser()
{
try
{
insert Con;
}
catch(System.DMLException e)
{
ApexPages.addMessages(e);
return null;
}
PageReference pageRef = new PageReference(ApexPages.currentPage().getUrl());
pageRef.setRedirect(true);
return pageRef;
}
}
I cannot insert data into the Consumer object due to the null exception.
This coding the entirely wrong.
1. What is the purpose of the fetching the fields Name, address__c, email_id__c, password__c, Confirm_Password__c, Security_Question__c, Answer__c and phone__c from customer object, as those input fields only.
2. why don't you have Standard Controller on Customer object.
3. If you are fetching values based on name, you need to put search button next to name field and fetch values.
regards,
PK
Consumer is not accessible in your Visual Force page as there is no getter or setter method for it.
public class signup1
{
public Consumer__c con {get; set;}
public signup1()
{
try
{
// Make sure 'ApexPages.currentPage().getParameters().get('Name')' is indeed not null.
con = [SELECT Name, address__c, email_id__c, password__c, Confirm_Password__c, Security_Question__c, Answer__c, phone__c from Consumer__c where Name =: ApexPages.currentPage().getParameters().get('Name')];
}
catch(Exception ex)
{
system.debug(ex.getMessage());
}
}
..............
}
You are not setting the values retrieved from the VF page into any parameter in the controller. First set them. Then create a object of type Consumer and then assign these values from VF page into the fields from the object. Only then you will be able to insert con.
Related
If I had a Java class called for instance Buffet and one of its fields was something like:
#ManyToOne
private Chef chef
and I had to create a new Buffet object in an html form using Thymeleaf, how would I be able to refer to this chef field? At the moment my html looks like this:
<form th:action="#{/newBuffet}" method="POST" th:object="${buffet}">
<div>
<div>
<span><input type="text" th:field="*{name}" placeholder="name"/></span>
</div>
<div>
<span><input type="text" th:field="*{chef}" placeholder="chef"/></span>
</div>
<div>
<span><button type="submit">Invio<i class="material-icons">done</i></button></span>
</div>
</div>
</form>
and my controller like this:
#RequestMapping(value = "/newBuffet", method = RequestMethod.GET)
public String formBuffet (Model model) {
model.addAttribute("buffet", new Buffet());
return "newBuffet.html";
}
#RequestMapping(value = "/newBuffet", method = RequestMethod.POST)
public String addBuffet (#ModelAttribute("buffet") Buffet b, Model model) {
this.buffetService.save(b);
model.addAttribute("buffets", this.buffetService.listBuffets());
return "buffets.html";
}
the error it gives is, of course, because of the way Thymeleaf's input takes only strings whilst my input is an instance of my class Chef.
I am trying to pass an array of ints from my HTML back to my controller.
My flow is as follows:
I am retrieving data from an API and converting it to an Entity. All works fine.
However, I pass this to my HTML (Thymeleaf) and display some of the values to the User.
They then select one of the options and this is passed back to my Controller.
It is at this stage I lose the data I need.
In my Entity, I get the following data which I pass to the View (Example Below):
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "MOVIE_ID")
private long movieId;
#JsonProperty("title")
#Column(name = "TITLE")
private String title;
#JsonProperty("overview")
#Column(name = "OVERVIEW", length = 2000)
private String overview;
#JsonProperty("popularity")
#Column(name = "POPULARITY")
private float popularity;
#JsonProperty("release_date")
#Column(name = "RELEASE_DATE")
private String releaseDate;
#JsonProperty("genre_ids")
private int[] genreIds;
Then in my view, I display some values and hide the ids I dont need to display so that I can pass them back to my controller:
<form action = "#" th:action="#{/saveMovie}" method="post" th:object="${movie}">
<tr>
<td th:text="${movie.title}"></td>
<td th:text="${movie.releaseDate}"></td>
<td th:text="${movie.overview}"></td>
<input type="hidden" id="title" name="title" th:value="*{title}"/>
<input type="hidden" id="overview" name="overview" th:value="*{overview}"/>
<input type="hidden" id="popularity" name="popularity" th:value="*{popularity}"/>
<input type="hidden" id="releaseDate" name="releaseDate" th:value="*{releaseDate}"/>
<input type="hidden" id="genreIds" name="genreIds" th:value="*{genreIds}"/>
<td>
<div class="col-auto">
<button class="btn btn-primary" type="submit">Add</button>
</div>
</td>
</tr>
</form>
Controller to handle the call:
#PostMapping("/saveMovie") public String saveMovie(#ModelAttribute(value = "movie") Movie movie)
UPDATE***
Adding the GET/POST controllers that currently interact with this page:
#GetMapping("/searchMovie")
public String searchMovie(final Model model){
List<Movie> returnedMovies = new ArrayList<>();
model.addAttribute("movies", returnedMovies);
return "Search";
}
#PostMapping("/searchMovie")
public String searchMovieInTMDB(#RequestParam(value = "movieName", required = true) String movieName,
Model model){
List<Movie> returnedMovies = service.searchMovies(movieName);
model.addAttribute("movies", returnedMovies);
return "Search";
}
#PostMapping("/saveMovie")
public String saveMovie(#ModelAttribute(value = "movie") Movie movie){
service.storeMovie(movie);
return "WORK_IN_PROGRESS";
}
However, when I pass the values back to the controller I get the conversion error:
[Failed to convert property value of type 'java.lang.String' to required type 'int[]' for property 'genreIds']
I have changed it to String[] to test this works and error goes away but then I am presented with another problem in that it is converted to :
String Value Image
The only way I have found to pass the object back is by using the input tag and hiding them.
It converts the float fine, but can't handle the array of ints.
Is there a better way to pass objects back and forth between the controller using Thymeleaf or is there another attribute I can use to pass the array back and forth?
Thanks in advance
Conor
<form action="#" th:action="#{/saveMovie}" method="post"
th:object="${movie}">
<tr>
<td th:text="${movie.title}"></td>
<td th:text="${movie.releaseDate}"></td>
<td th:text="${movie.overview}"></td>
<input type="hidden" id="title" name="title" th:value="*{title}" />
<input type="hidden" id="overview" name="overview"
th:value="*{overview}" />
<input type="hidden" id="popularity" name="popularity"
th:value="*{popularity}" />
<input type="hidden" id="releaseDate" name="releaseDate"
th:value="*{releaseDate}" />
<input type="hidden" name="genreIds" th:field="*{genreIds}" />
<td>
<div class="col-auto">
<button class="btn btn-primary" type="submit">Add</button>
</div>
</td>
</tr>
</form>
#PostMapping("/saveMovie")
public String saveMovie(#ModelAttribute Movie movie) {
System.err.println(movie);
return "redirect:/movies";
}
#GetMapping("/movies")
public String getBooks(Model model) {
Movie movie = new Movie();
movie.setGenreIds(new int[] {4,5,6,7,8});
model.addAttribute("movie", movie);
return "movie";
}
Maybe You should send numbers as List to the controller.
#PostMapping("/saveMovie")
public String saveMovie(#RequestBody List<Movie> movies){
movieService.function_name(movies);
return "movies";
}
Another way to do this is using AJAX call to the controller. Just need to collect numbers as list in javascript and through ajax you should send array as json to controller. In controller you will parse them
This question already has answers here:
Creating master-detail pages for entities, how to link them and which bean scope to choose
(2 answers)
Closed 4 years ago.
I am developing a website using JSF 2.2 and Primefaces 6.1 where I have, initially, 2 pages: A "list" page, where I can show the data to the user, and a "create" page, where I can create new data or edit existing ones.
NOTE: "Cargo" means occupation.
list.xhtml:
...
<h:form>
<p:commandButton value="Cadastrar" styleClass="ui-button-sucesso" action="create.xhtml?faces-redirect=true"/>
</h:form>
...
<h:form>
<p:dataTable value="#{cargoListMB.listaCargo}" var="cargo" rowKey="#{cargo.codigo}" emptyMessage="Nenhum cargo encontrado" filteredValue="#{cargoListMB.listaCargoFiltro}">
<f:facet name="header">Tabela de Cargos</f:facet>
<p:column headerText="Código" sortBy="#{cargo.codigo}" filterBy="#{cargo.codigo}" filterPosition="top">
<h:outputText value="#{cargo.codigo}"/>
</p:column>
<p:column headerText="Nome" sortBy="#{cargo.nome}" filterBy="#{cargo.nome}" filterPosition="top" filterMatchMode="contains">
<h:outputText value="#{cargo.nome}"/>
</p:column>
<p:column headerText="Funcionários" sortBy="#{cargo.funcionariosNesteCargo}"filterBy="#{cargo.funcionariosNesteCargo}" filterPosition="top">
<h:outputText value="#{cargo.funcionariosNesteCargo}"/>
</p:column>
<p:column headerText="Editar">
<p:commandButton icon="fa fa-pencil" title="Editar" styleClass="ui-button-icone-apenas" action="create.xhtml?faces-redirect=true">
<f:param name="objcargo" value="#{cargo.codigo}"/>
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
CargoListMB.java:
#ManagedBean(name = "cargoListMB")
#ViewScoped
public class CargoListMB implements Serializable {
private List<Cargo> listaCargo;
private List<Cargo> listaCargoFiltro;
public List<Cargo> getListaCargo() {
if (listaCargo == null) {
listaCargo = CargoDAO.listarTodos(); //load data from database
}
return listaCargo;
}
public void setListaCargo(List<Cargo> listaCargo) {
this.listaCargo = listaCargo;
}
...
}
create.xhtml:
<h:form>
<f:metadata>
<f:viewParam name="objcargo" value="#{cargoCreateMB.cargo}" converter="cargoConverter"/>
<f:viewAction action="#{cargoCreateMB.inicializar()}"/>
</f:metadata>
<div class="ui-grid ui-grid-responsive">
<div class="ui-grid-row">
<div class="ui-grid-col-6">
<h1 class="if-page-title"><h:outputText value="#{cargoCreateMB.cargo.codigo == 0? 'Cadastro de Cargos' : 'Edição de cargo'}"/></h1>
</div>
<div class="ui-grid-col-6"></div>
</div>
<br/>
<div class="ui-grid-row">
<div class="ui-grid-col-12">
<div class="ui-grid-row">
<div class="ui-grid-col-1">
<p:outputLabel for="nome" value="Nome:"/>
</div>
<div class="ui-grid-col-3">
<p:inputText id="nome" placeholder="nome" value="#{cargoCreateMB.cargo.nome}" required="true""/>
</div>
<div class="ui-grid-col-8">
<p:message for="nome"/>
</div>
</div>
<br/>
<div class="ui-grid-row">
<div class="ui-grid-col-3">
<p:commandButton value="Salvar" actionListener="#{cargoCreateMB.salvar}" update="form" styleClass="ui-button-salvar"/>
</div>
<div class="ui-grid-col-9"></div>
</div>
</div>
</div>
</div>
</h:form>
CargoCreateMB.java
#ManagedBean(name = "cargoCreateMB")
#ViewScoped
public class CargoCreateMB implements Serializable {
private Cargo cargo;
public void salvar() {
try {
ControleCargo.insereCargo(cargo); //saves the 'occupation' on the database
MensagensUtil.mensagemInfo("Atenção", "Cargo inserido com sucesso");
} catch (RuntimeException e) {
MensagensUtil.mensagemInfo("Erro", "Erro ao inserir cargo");
System.out.println("Erro: " + e);
}
}
public void inicializar() {
//QUESTION!! : Due to a JSF page's life cycle, could I put this code on the constructor??
if (this.cargo == null) {
this.limpar();
}
}
private void limpar() {
cargo = new Cargo();
}
public Cargo getCargo() {
return cargo;
}
public void setCargo(Cargo cargo) {
this.cargo = cargo;
}
}
As you can see, I am trying to pass the selected 'occupation' from page list.xhtml to crate.xhtml using <f:param> and <f:viewParam> tags. When I click on button 'Cadastrar' (means 'register'), everything works fine (the "cargo" object is initially null, as expected), but when I click on the edit button, the "cargo.codigo" (occupation's ID) value, sent by the <f:param> tag, does not "arrive" to the "cargo" object. The converter ('cargoConverter') should be working fine, BUT, when I checked the String value that the method getAsObject was receiving, it was ALWAYS "0", no matter which occupation I choose on my list.
I also tried to send the "raw" data: Instead of using a converter, I sent the "cargo.codigo" value directly to a String field, but it was ALWAYS null.
Could someone help me discover what was my mistake? Also, if it is possible, is there another way to send data to other Managed Beans? Thanks in advance.
Edit: Based on Kukeltje's comments, I formatted my code (which can be seen above) and removed all the nested <h:form> elements BUT the problem still persists. Therefore, the answers on question How to use <h:form> in JSF page? didn't help at all and this question is not a duplicate.
Based on Kukeltje's comments and tips and the answers on this question, I managed to find my mistake: my <f:metadata> was indeed inside a <h:form>
tag. I removed it from there and it worked perfectly.
How to return List of Objects to Backend Service? For E.g. there are list of customer getting displayed in UI, out of which only those customers which users selects (checks in checkbox) should be returned to the backend (Controller class). But i am not able to returned the selected object back.
My code:
public class CustomerType {
private String customerName;
private String customerMsg;
private Boolean selected;
// setter
// getter
}
public class Customers {
private ArrayList<CustomerType> customerType;
// setter
// getter
}
#GetMapping(value = "/")
public String index(ModelMap modelMap) {
ArrayList<CustomerType> customerType = new ArrayList<>();
customerType.add(new CustomerType("1", "c1", null));
customerType.add(new CustomerType("2", "c2", null));
customerType.add(new CustomerType("3", "c3", null));
Customers customers = new Customers();
customers.setCustomerTypes(customerType);
modelMap.put("customers", customers);
return "index";
}
#PostMapping(value = "/save")
public String save(#ModelAttribute Customers customers, BindingResult errors, Model model) {
...
...
return "hello";
}
========== index.html ==========
...
<form id = "form" class="col-xs-12 col-sm-4" role="form"
th:action="#{/save}" method="post" th:object="${customers}">
<div class="checkbox" th:each="customerType : ${customers.customerType}" >
<input type="checkbox" id="custType" name="custType"
th:text="${customerType.customerName}" th:value="${customerType.customerMsg}" th:checked="${customerType.selected}"></input>
</div>
<div>
<p>
<button type="submit" class="btn btn-default">Submit</button>
</p>
</div>
</form>
I am able to display lists of Customers on UI e.g there are three customer c1, c2, c3 out of which if user selects c1 and c3 so after clicking on submit button those should get mapped to #ModelAttribute Customers Object in save method and that object should contain list of two Objects c1 and c3, but instead of getting 2 Objects I am receiving Null.
I am not able to get where i am going wrong.
While sending your form back to controller, be sure that transmited data reflect desired object structure. You have to provide checkboxes that correspond the checked field of the CustomerType objects and additional hidden inputs which correspond others fields of mentioned class.
Please update your form to looks like:
<form id = "form" class="col-xs-12 col-sm-4" role="form" th:action="#{/save}" method="post" th:object="${customers}">
<div class="checkbox" th:each="customerType, iterator : ${customers.customerType}" >
<input type="hidden" th:field=*{customerType[__${iterator.index}__].customerName} />
<input type="hidden" th:field=*{customerType[__${iterator.index}__].customerMsg} />
<input type="checkbox" th:field="*{customerType[__${iterator.index}__].selected}" th:text="${customerType.customerName}" ></input>
</div>
<div>
<p>
<button type="submit" class="btn btn-default">Submit</button>
</p>
</div>
</form>
With this you'll receive the Customers object containing list of all passed CustomerType objects, with selected fields evaluated to true for checked records.
The name of the input fields in the form should match the property name in the CustomerType class i.e they should be customerName and customerMsg for the Spring to be able to create and populate the corresponding CustomerType object.
I'm doing a page where i display some labels and input text field so the user can introduce some data and send it back to the server. But sometimes the server send back more than 50 rows of information. In this case the user need to scoll multiple times in order to see all the fields. I want to create 2/3 divs and each contains maybe ~20 fields so that all fields can be displayed without scrolling. Any idea?
Here is my code
<div class="container">
<div class="row">
<f:view>
<h:form>
<h:dataTable value="#{Message.bits}" var="bit">
<h:column>
<div class="col-lg-4">
<h:outputText value="#{bit.id} #{bit.name}" />
<div class="input-group">
<h:inputText styleClass="form-control" size="100"
maxlength="100" value="#{bit.value}" />
</div>
</p>
</div>
</h:column>
</h:dataTable>
</h:form>
</f:view>
</div>
</div>
Class Message -> A container of bits. It is a bean manager
#ManagedBean
#ViewScoped
public class Message implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2712306195992874273L;
private List<Bit> bits = null;
public List<Bit> getBits() {
return bits;
}
//Do more things
Bit class
public class Bit implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6341896264030346040L;
private String name = null;
private String value = null;
private int id = 0;
//Business logic
I can use html, css, any js framework, jsp,java.
Thanks for your time.
If I got your question right, you want to display your data like this:
1 4 7
2 5 8
3 6 9
Instead of this:
1
2
3
4
5
..
I don't know if this is the best solution but it works for me.
You can try the code below.
<div class="row">
<ui:repeat var="bit" value="#{message.bits}" varStatus="bitstatus">
<h:outputText escape="false" value="<div class='col-lg-4'>" rendered="#{(bitstatus.index + 1) % 20 eq 1}" />
<h:outputText value="#{bit.id} #{bit.name}" />
<div class="input-group">
<h:inputText styleClass="form-control" size="100" maxlength="100" value="#{bit.value}" />
</div>
<h:outputText escape="false" value="</div>" rendered="#{(productstatus.index + 1) % 5 eq 0}" />
</ui:repeat>
</div>