Jpa 在运行时从数据库生成基于Primefaces extensions DynaForm的动态表单,并允许表单';数据存储
我想创建一个动态表单,在这个表单中,我在运行时从数据库生成表单,但也使用运行时提供的字段(使用JPA)在数据库服务器上创建数据存储表。我已经尽力了,现在我需要帮助。我将尽可能描述我的问题所在,以及我想要实现的目标。Jpa 在运行时从数据库生成基于Primefaces extensions DynaForm的动态表单,并允许表单';数据存储,jpa,dynamic,jsf-2,primefaces,primefaces-extensions,Jpa,Dynamic,Jsf 2,Primefaces,Primefaces Extensions,我想创建一个动态表单,在这个表单中,我在运行时从数据库生成表单,但也使用运行时提供的字段(使用JPA)在数据库服务器上创建数据存储表。我已经尽力了,现在我需要帮助。我将尽可能描述我的问题所在,以及我想要实现的目标。 当我在这里搜索StackOverflow时,我发现要在primefaces中创建动态表单,必须使用primefaces扩展动态表单。我从primefaces extensions showcase中的示例中借用了一片叶子,并成功地实现了它,如下所示。 DynaFormCont
当我在这里搜索StackOverflow时,我发现要在primefaces中创建动态表单,必须使用primefaces扩展动态表单。我从primefaces extensions showcase中的示例中借用了一片叶子,并成功地实现了它,如下所示。
DynaFormController
下面是我在上述控制器中使用的TblPerson实体类
下面是我在控制器中使用的DynaFormAttribute实体类
这就是我需要帮助的地方:读完所有这些,你可能会问你自己我到底想问什么。这就是我真正需要帮助的地方:
一,。数据存储:我在运行时生成所有表单字段,但我的数据存储表是静态创建的。在其他情况下,即使我在运行时创建表单字段,也可以只创建数据存储表中的字段。我如何在运行时动态创建数据存储表,而不危及数据完整性和约束,从而使数据库表包含在运行时定义的字段?实际上,我希望在第一次部署应用程序时,例如,我将创建一个表单定义并将其存储在数据库中,从数据库生成一个动态表单,但也创建一个数据库表以在运行时存储字段的数据。这应该在第一次安装应用程序时完成。(这个问题的一部分可以归结为,如何在运行时创建一个实体并在db服务器上运行它以在运行时创建一个实际的表?)
2.此实现仅允许我从用户捕获新数据并按给定方式存储。如果我想在将字段值提交到数据库之前对其执行一些逻辑,我该怎么办?此外,有时,在某些情况下,可能需要在加载表单时自动提供表单的某些值。e、 g您可能希望生成一个员工编号,并在捕获新记录时将其显示为只读字段。通过我的实施,我将如何实现这一点
这是一个很长的问题,但首先感谢您的善意和深思熟虑的贡献。我保证你的贡献将大有帮助 您可以将数据以XML格式存储在一个大的文本字段中。您需要代码将XML转换为实体并返回。这与数据库无关,并且与字段定义方案配合良好。不过,索引和关系很难实现
如果您不介意特定于数据库,那么可以编写存储过程并触发函数,以便在数据定义表中创建记录时创建动态表。大约十年前,我开发了这样一个设备文档系统,以允许动态设备类型 我有一个类似的问题,需要创建“响应”表单。因此,不是生成的DynaForm,而是生成
@PostConstruct
protected void initialize() {
model = new DynaFormModel();
// add rows, labels and editable controls
// set relationship between label and editable controls to support outputLabel with "for" attribute
// 1. row
DynaFormRow row = model.createRegularRow();
DynaFormLabel label11 = row.addLabel("Author");
DynaFormControl control12 = row.addControl(new BookProperty("OurAuthor", true), "input");
label11.setForControl(control12);
DynaFormLabel label13 = row.addLabel("ISBN");
DynaFormControl control14 = row.addControl(new BookProperty("ISBN", true), "input");
label13.setForControl(control14);
// 2. row
row = model.createRegularRow();
DynaFormLabel label21 = row.addLabel("Title");
DynaFormControl control22 = row.addControl(new BookProperty("Title", false), "input", 3, 1);
label21.setForControl(control22);
// 3. row
row = model.createRegularRow();
DynaFormLabel label31 = row.addLabel("Publisher");
DynaFormControl control32 = row.addControl(new BookProperty("Publisher", false), "input");
label31.setForControl(control32);
DynaFormLabel label33 = row.addLabel("Published on");
DynaFormControl control34 = row.addControl(new BookProperty("Published on", false), "calendar");
label33.setForControl(control34);
// 4. row
row = model.createRegularRow();
DynaFormLabel label41 = row.addLabel("Language");
DynaFormControl control42 = row.addControl(new BookProperty("Language", false), "select");
label41.setForControl(control42);
DynaFormLabel label43 = row.addLabel("Description", 1, 2);
DynaFormControl control44 = row.addControl(new BookProperty("Description", false), "textarea", 1, 2);
label43.setForControl(control44);
// 5. row
row = model.createRegularRow();
DynaFormLabel label51 = row.addLabel("Rating");
DynaFormControl control52 = row.addControl(new BookProperty("Rating", 3, true), "rating");
label51.setForControl(control52);
}
public DynaFormModel getModel() {
return model;
}
public List<BookProperty> getBookProperties() {
if (model == null) {
return null;
}
List<BookProperty> bookProperties = new ArrayList<BookProperty>();
for (DynaFormControl dynaFormControl : model.getControls()) {
bookProperties.add((BookProperty) dynaFormControl.getData());
}
return bookProperties;
}
public String submitForm() {
FacesMessage.Severity sev = FacesContext.getCurrentInstance().getMaximumSeverity();
boolean hasErrors = (sev != null && (FacesMessage.SEVERITY_ERROR.compareTo(sev) >= 0));
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.addCallbackParam("isValid", !hasErrors);
return null;
}
<h:form id="mainForm">
<h:panelGroup id="dynaFormGroup">
<p:messages id="messages" showSummary="true"/>
<pe:dynaForm id="dynaForm" value="#{dynaFormController.model}" var="data">
<pe:dynaFormControl type="input" for="txt">
<p:inputText id="txt" value="#{data.value}" required="#{data.required}" />
</pe:dynaFormControl>
<pe:dynaFormControl type="calendar" for="cal" styleClass="calendar">
<p:calendar id="cal" value="#{data.value}" required="#{data.required}" showOn="button"/>
</pe:dynaFormControl>
<pe:dynaFormControl type="select" for="sel" styleClass="select">
<p:selectOneMenu id="sel" value="#{data.value}" required="#{data.required}">
<f:selectItems value="#{dynaFormController.languages}"/>
</p:selectOneMenu>
</pe:dynaFormControl>
<pe:dynaFormControl type="textarea" for="tarea">
<p:inputTextarea id="tarea" value="#{data.value}" required="#{data.required}" autoResize="false"/>
</pe:dynaFormControl>
<pe:dynaFormControl type="rating" for="rat">
<p:rating id="rat" value="#{data.value}" required="#{data.required}"/>
</pe:dynaFormControl>
<f:facet name="buttonBar">
<p:commandButton value="Submit" action="#{dynaFormController.submitForm}"
process="dynaForm" update=":mainForm:dynaFormGroup :mainForm:inputValues"
oncomplete="handleComplete(xhr, status, args)"/>
<p:commandButton type="reset" value="Reset" style="margin-left: 5px;"/>
</f:facet>
</pe:dynaForm>
</h:panelGroup>
<p:dialog header="Input values" widgetVar="inputValuesWidget">
<p:dataList id="inputValues" value="#{dynaFormController.bookProperties}" var="bookProperty"
style="margin:10px;">
<h:outputText value="#{bookProperty.name}: #{bookProperty.formattedValue}"
style="margin-right: 10px;"/>
</p:dataList>
</p:dialog>
<h:outputScript id="dynaFormScript" target="body">
/* <![CDATA[ */
function handleComplete(xhr, status, args) {
if(args && args.isValid) {
PF('inputValuesWidget').show();
} else {
PF('inputValuesWidget').hide();
}
}
/* ]]> */
</h:outputScript>
<h:outputStylesheet id="dynaFormCSS">
/* note: trick with colspan is needed for IE8 */
.pe-dynaform-cell input,
.pe-dynaform-cell textarea,
.pe-dynaform-cell[colspan="1"] input,
.pe-dynaform-cell[colspan="1"] textarea {
width: 150px;
}
/* note: trick with colspan is needed for IE8 */
.pe-dynaform-cell.calendar input,
.pe-dynaform-cell[colspan="1"].calendar input {
width: 120px;
}
.pe-dynaform-cell.select .ui-selectonemenu {
width: 157px !important;
}
.pe-dynaform-cell.select .ui-selectonemenu .ui-selectonemenu-label {
width: 130px !important;
}
</h:outputStylesheet>
</h:form>
@ManagedBean
@ViewScoped
public class DynaFormBacking implements Serializable{
private @Inject
DynaFormAttributeFacade dynaFormAttributeFacade;
private List<DynaFormAttribute> dynaFormAttributeList;
private DynaFormModel model;
private @Inject TblPersonFacade personFacade;
/**
* Creates a new instance of DynaFormBacking
*/
@PostConstruct
public void init(){
model = new DynaFormModel();
DynaFormRow row;
DynaFormLabel label;
DynaFormControl control;
int i = 0; //loop incrementer
//Number of form attributes.
int listSize = getDynaFormAttributeList().size();
for (; i < listSize;) {
//Get form attributes that belong to the same row
List<DynaFormAttribute> rowDynaFormList = dynaFormAttributeFacade.getEntityRowsGivenColumnValue(new DynaFormAttribute(), "rowNumber", getDynaFormAttributeList().get(i).getRowNumber());
//create a new row
row = model.createRegularRow();
//place labels and controls on the newly created row. If we have multiple fields on the same row, this loop will place them
for (int r = 0; r < rowDynaFormList.size(); r++) {
//place label and control on the row (This is for a single form attribute)
label = row.addLabel(rowDynaFormList.get(r).getLabelName(), rowDynaFormList.get(r).getLabelColspan(), rowDynaFormList.get(r).getLabelRowspan());
control = row.addControl(new Person(false), rowDynaFormList.get(r).getControlName(), rowDynaFormList.get(r).getControlColspan(), rowDynaFormList.get(r).getControlRowspan());
label.setForControl(control);
//increment to keep track of the number of form attributes
i++;
}
}
}
public DynaFormBacking() {
}
public DynaFormModel getModel() {
return model;
}
//This list picks the form fields and their definitions from the database
public List<DynaFormAttribute> getDynaFormAttributeList() {
dynaFormAttributeList = dynaFormAttributeFacade.findAll();
return dynaFormAttributeList;
}
public String submitForm() {
FacesMessage.Severity sev = FacesContext.getCurrentInstance().getMaximumSeverity();
boolean hasErrors = (sev != null && (FacesMessage.SEVERITY_ERROR.compareTo(sev) >= 0));
RequestContext requestContext = RequestContext.getCurrentInstance();
requestContext.addCallbackParam("isValid", !hasErrors);
TblPerson person = new TblPerson();
person.setFirstName((String) getPersonList().get(0).getFormattedValue());
person.setSecondName((String) getPersonList().get(1).getFormattedValue());
person.setSex((String) getPersonList().get(2).getFormattedValue());
person.setDateOfBirth( (Date) getPersonList().get(3).getFormattedValue());
person.setPhone((String) getPersonList().get(4).getFormattedValue());
personFacade.create(person);
return null;
}
public List<Person> getPersonList() {
if (model == null) {
return null;
}
List<Person> personList = new ArrayList<Person>();
for (DynaFormControl dynaFormControl : model.getControls()) {
personList.add((Person) dynaFormControl.getData());
}
return personList;
}
}
/**
* This method returns Entity rows of data specific to the given column
* value - return rows when given a column name and the column value
*/
public List<T> getEntityRowsGivenColumnValue(T entity, String columnName, Object columnValue) {
List<T> resultList;
javax.persistence.criteria.CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(rt).where(cb.equal(rt.get(columnName), columnValue));
javax.persistence.TypedQuery<T> q = getEntityManager().createQuery(cq);
try {
resultList = q.getResultList();
} catch (NoResultException ex) {
resultList = null;
}
return resultList;
}
@ManagedBean
@RequestScoped //Must be request scoped. otherwise, it won't work
public class Person implements Serializable{
private static final long serialVersionUID = 20120521L;
private Object value;
private boolean required;
/**
* Creates a new instance of Person
*/
public Person() {
}
public Person(boolean required) {
this.required = required;
}
public Person(Object value, boolean required) {
this.value = value;
this.required = required;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public Object getFormattedValue() {
if (value instanceof Date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
return simpleDateFormat.format(value);
}
return value;
}
}
public class TblPerson implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Size(max = 45)
@Column(name = "firstName")
private String firstName;
@Size(max = 45)
@Column(name = "secondName")
private String secondName;
@Size(max = 10)
@Column(name = "sex")
private String sex;
@Column(name = "dateOfBirth")
@Temporal(TemporalType.DATE)
private Date dateOfBirth;
// @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$", message="Invalid phone/fax format, should be as xxx-xxx-xxxx")//if the field contains phone or fax number consider using this annotation to enforce field validation
@Size(max = 45)
@Column(name = "phone")
private String phone;
public TblPerson() {
}
public TblPerson(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof TblPerson)) {
return false;
}
TblPerson other = (TblPerson) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "ijmis.model.TblPerson[ id=" + id + " ]";
}
}
public class DynaFormAttribute implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Size(max = 45)
@Column(name = "labelName")
private String labelName;
@Column(name = "labelColspan")
private Integer labelColspan;
@Column(name = "labelRowspan")
private Integer labelRowspan;
@Size(max = 45)
@Column(name = "controlName")
private String controlName;
@Column(name = "controlColspan")
private Integer controlColspan;
@Column(name = "controlRowspan")
private Integer controlRowspan;
@Column(name = "rowNumber")
private Integer rowNumber;
public DynaFormAttribute() {
}
public DynaFormAttribute(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public Integer getLabelColspan() {
return labelColspan;
}
public void setLabelColspan(Integer labelColspan) {
this.labelColspan = labelColspan;
}
public Integer getLabelRowspan() {
return labelRowspan;
}
public void setLabelRowspan(Integer labelRowspan) {
this.labelRowspan = labelRowspan;
}
public String getControlName() {
return controlName;
}
public void setControlName(String controlName) {
this.controlName = controlName;
}
public Integer getControlColspan() {
return controlColspan;
}
public void setControlColspan(Integer controlColspan) {
this.controlColspan = controlColspan;
}
public Integer getControlRowspan() {
return controlRowspan;
}
public void setControlRowspan(Integer controlRowspan) {
this.controlRowspan = controlRowspan;
}
public Integer getRowNumber() {
return rowNumber;
}
public void setRowNumber(Integer rowNumber) {
this.rowNumber = rowNumber;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof DynaFormAttribute)) {
return false;
}
DynaFormAttribute other = (DynaFormAttribute) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "ijmis.model.DynaFormAttribute[ id=" + id + " ]";
}
}