We use a lot of tables in our website ( Vaadin Table ), but our customer just told us that they want to be able to edit inside the table. Now, I know that is possible in Table ( I already got that to work ), but I sort of like the edit mechanism for Grid better. Is there an easy way to convert Vaadin Table to Vaadin Grid? Since Grid is not a drop in replacement, I know it will take some conversion work. Just wondering how hard people have found it, and if there is any documentation out there on doing such a conversion.
Here is our normal table usage:
public final class ReplenishmentOrderMgmtView extends VerticalLayout implements View {
private final Table table;
private static final String[] DEFAULT_COLLAPSIBLE = {
"contactFirstName",
"contactLastName",
"supplierName",
"carrier", "carrierService", "trackingNumber"
};
private static final Object[] VISIBLE_COLUMNS = {
"barcode",
"contactUserId",
"contactFirstName",
"contactLastName",
"PO",
"orderId",
"cellId",
"cellName",
"wmsItem",
"description",
"supplierId",
"supplierName",
"statusDesc",
"resizedBinQty",
"expectedOnDockDate",
"shipQuantity",
"receivedQty",
"lastReceiptDate",
"carrier",
"carrierService",
"trackingNumber",
"creationDate"
};
private static final String[] COLUMN_NAMES = {
"Barcode",
"Contact User",
"First Name",
"Last Name",
"PO Number",
"Replenishment Order Id",
"Cell Id",
"Cell Name",
"Part",
"Description",
"Supplier Id",
"Supplier Name",
"Status",
"Resized Bin Qty",
"Expected On Dock Date",
"Ship Quantity",
"Received Qty",
"Last Receipt Date",
"Carrier",
"Carrier Service",
"Tracking Number",
"Creation Date"
};
private Table buildTable() {
final Table table = new Table();
table.setSizeFull();
table.addStyleName(ValoTheme.TABLE_BORDERLESS);
table.addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES);
table.addStyleName(ValoTheme.TABLE_COMPACT);
table.setSelectable(true);
table.setColumnCollapsingAllowed(true);
table.setColumnReorderingAllowed(true);
updateList( table );
table.setSortContainerPropertyId("creationDate");
table.setSortAscending(true);
table.setColumnHeaders( COLUMN_NAMES );
// Allow dragging items to the reports menu
// table.setDragMode(TableDragMode.MULTIROW);
table.setMultiSelect(false);
table.addActionHandler(new ReplenishmentOrdersActionHandler());
table.addValueChangeListener(event -> this.selectItemFromTable());
table.setImmediate(true);
return table;
}
}
There is also some binding involved in there - my data source is a java bean. Obviously, I am only includine code that will impact the table itself. Any advice or opinions would be much appreciated.
Is there an easy way to convert Vaadin Table to Vaadin Grid?
No. You have to declare and apply properties of Grid and no direct way to have conversion between Grid and Table. Both are different elements and can not be switched with so called minimal changes in terms of UI.
Because switching involves lot of things to be considered like,
Data source of table can works fine with Grid or not.
Style applied to table will not work for Grid (i.e. Valo theme styles, responsive style)
Events of table are not same as Grid. Table has value change event while Grid has item click listener.
and so on...
However, you can have same container for both the elements. Container data source can be common between both the elements. Note that Grid has some limitations like it does not support component in row while table supports that. On the other hand Grid is fast, optimized with some extra features like freeze column, support component in header etc. Same way table is descendant of Grid and will not have some features which are supported by Grid.
Related
so I am using JavFX to create a form that stores all the answers in a csv file. I need to create a dropdown menu that allows the users to select an option, which is then recorded in the csv file. I have tried a lot of different options, however I think comboBox is the best option.
I have no problem creating the ComboBox, I only run into problems when it comes to the method to get the value of the box.
Can someone help me find a solution, or suggest what another JavaFX menu I can use?
This is the code I have right now:
public VBox setFamiliar(){
Button button = new Button();
button.setOnAction(e -> toString());
familiarComboBox = new ComboBox<>();
familiarVBox = new VBox();
familiarComboBox.getItems().addAll("Irmão", "Irmã", "Avó", "Avô", "Tio", "Tia", "Pai", "Mãe");
familiarVBox.getChildren().add(familiarComboBox);
familiarVBox.getChildren().add(button);
return familiarVBox;
}
Here I set the ComboBox, this part doesnt seem to have a problem because it appears and I can select an item. I created a separate void toString() method that sets the value of a variable to the current selected item
public void toString(ActionEvent e){
familiar = familiarComboBox.getSelectionModel().getSelectedItem().toString();
}
The problem is then in the get method to get the value that was selected.
public String getIrmao(){
if(familiar.equals("Irmão")){
return "2";
}
return "0";
I also tried to do familiarComboBox.getSelectionModel().getSelectedItem().equals(), and other variations of this combination.
If I understand your requirement -- that when a user makes a choice from the "Familiar" combo box, a value should be written immediately to a CSV file -- you don't need the getIrmao() method. You simply write the value out in the action which you are calling toString(...) (not a good choice of names), but which we will rename to handleFamiliarChange(...).
Now the method becomes
public void handleFamiliarChange(ActionEvent e){
final String familiar =
familiarComboBox.getSelectionModel().getSelectedItem().toString();
FileUtils.writeToCsvFile(familiar.equals("Irmão") ? 2 : 0);
}
where FileUtils.writeToCsvFile(...) is a method that does the file writing. Note that FileUtils is a class you have created to separate out file handling concerns -- your JavaFX view class should only concern itself with views.
I'm attempting to follow the logic describe here: https://msdn.microsoft.com/en-us/library/gg309282.aspx for creating associated entities using the RelatedEntities Property. Problem is, no Associated Entities are getting created. I'm attempting to perform this action from within a Pre=Operation plugin... Is it not supported within a PreOperation Plugin? What am I doing wrong if it?
Here is the code:
var collection = new EntityCollection();
collection.Entities.AddRange(incentives.Select(e => e.ToSdkEntity()));
target.RelatedEntities.Add(new Relationship(new_LeadProduct.Fields.new_lead_new_leadproduct_LeadId), collection);
Since a pre-create plugin executes before the target entity has been created in the database you will not be able to create related entities referencing the target. You should execute related entity logic in a post-create plugin.
Edit:
This answer applies if you are trying to create related records associated with the Target in a plugin operation. Your question did not specify otherwise but based on the code in your answer it looks like this is not what you are trying to do.
Here is the code from the MSDN Example:
//Define the account for which we will add letters
Account accountToCreate = new Account
{
Name = "Example Account"
};
//Define the IDs of the related letters we will create
_letterIds = new[] { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
//This acts as a container for each letter we create. Note that we haven't
//define the relationship between the letter and account yet.
EntityCollection relatedLettersToCreate = new EntityCollection
{
EntityName = Letter.EntityLogicalName,
Entities =
{
new Letter{Subject = "Letter 1", ActivityId = _letterIds[0]},
new Letter{Subject = "Letter 2", ActivityId = _letterIds[1]},
new Letter{Subject = "Letter 3", ActivityId = _letterIds[2]}
}
};
//Creates the reference between which relationship between Letter and
//Account we would like to use.
Relationship letterRelationship = new Relationship("Account_Letters");
//Adds the letters to the account under the specified relationship
accountToCreate.RelatedEntities.Add(letterRelationship, relatedLettersToCreate);
//Passes the Account (which contains the letters)
_accountId = _service.Create(accountToCreate);
After some additional testing, the Related Entities Collection must be populated before the PreOperation stage. So registering this to run on PreValidation works as expected.
I am creating a pdf where the title of each pdf page would be customized based on the current page number. For example, in the 1st page the title is "First Page", and in the 2nd page the title is "Second Page", and so on...
What we do now is we add the title to a PdfPTable, then we add a lot of other stuff to the PdfPTable as well, so this PdfPTable contains several pages of data. Finally we add this large PdfPTable object to document. Now we want to use the onStartPage() method in PdfPageEventHelper to get the current page number so that we can customize the title for each page.
The problem is onStartPage() does not trigger until we add that large PdfPTable object to the document, which means we cannot make the resource bundle to load different key values before the PdfPTable object is added to the document, right? Any suggestion to realize this?
--------------------we have codes like below-------------------------------------
Phrase title = new Phrase();
title.add(new Chunk(bundle.getString(pdfNewPageEventHandler.getKey()), headerFont));
PdfPCell cell = new PdfPCell(new Paragraph(
new Phrase(title)));
.........
PdfPTable table = new PdfPTable(tableSize);
table.addCell(cell);
.........
document.add(table);
private class PdfNewPageEventHandler extends PdfPageEventHelper {
private int currentPageNum = 0;
private String key;
#Override
public void onStartPage(PdfWriter writer, Document document) {
currentPageNum = currentPageNum + 1;
if (currentPageNum == 1) {
key = "firstPage";
}
else if (currentPageNum == 2) {
key = "secondPage";
}
}
public String getKey() {
return key;
}
}
I have more than one answer. I don't know which one applies to your specific situation:
Don't ever add content in the onStartPage() method. As documented, all content should be added in the onEndPage() method.
It's not always wise to create one large table (it builds up in memory) and then add the table to the document (only at this moment, memory can be freed). Maybe you want to try out some of the large table strategies from the documentation.
In some cases, building a table in memory and then adding it to the document is the only strategy you can use. iText will then distribute the content of the table over different pages, triggering page events. However: if you want to trigger events that are specific to the table, you can also define events at the level of the table. There's a PdfPTableEventSplit and a PdfPTableEventAfterSplit class for this exact purpose.
The code sample you provided, didn't really illustrate the problem. Can you please rephrase the problem, as I'm not sure if any of my answers go to the core of the problem.
I am working on the Event Handler for saving a component.
My objective is to perform some validations when the user creates and component based on a schema.
I have a schema with the name "Employee".
Employee has an embedded schema with the name "Experience" and it is multivalued.
Experience has 3 fields.
Role : Drop down with the values Manager, Lead.
Company: Text field
Years: Text field
When the user enters some data in these fields, I want to do some validations before save.
The high level design would look like this.
Load the instance of the Component
Navigate to embedded field "Experience"
For every "Experience". I need to get the value of the "Role", and check that appropriate value is entered in other two fields(By writing Component Save event)
For( all the repeated "Experience")
{
If (Role=="Manager")
check the values in the other two fields and do some validation
If (Role=="Lead")
check the values in the other two fields and do some validation
}
I am stuck at extracting the value and Names of subfields at the embeddded field.
I have tried:
Tridion.ContentManager.Session mySession = sourcecomp.Session;
Schema schema= sourcecomp.Schema;
if(schema.Title.Equals("Employee"))
{
var compFields = new ItemFields(sourcecomp.Content, sourcecomp.Schema);
var embeddefield = (EmbeddedSchemaField)compFields["Experience"];
var embeddedfields = (IList<EmbeddedSchemaField>)embeddefield.Values;
foreach(var a in embeddedfields)
{
if(a.Name.Equals("Role"))
{
string value=a.Value.ToString();
}
}
}
Actually I am stuck how to retrieve the values in the other fields at the same time.
Can any one explain how it can be done?
What you need to understand on a EmbeddedSchemaField class is that it represents both a schema and a field (as the name implies...)
I always find it helpful to look at the source XML of the component when writing code that targets its fields, you get a good visual representation of what your classes must do. If you look at a component XML like this:
<Content>
<Title>Some Title</Title>
<Body>
<ParagraphTitle>Title 1</ParagraphTitle>
<ParagraphContent>Some Content</ParagraphContent>
</Body>
<Body>
<ParagraphTitle>Title 2</ParagraphTitle>
<ParagraphContent>Some more Content</ParagraphContent>
</Body>
</Content>
Body is your embedded Schema field, which is multivalued, and contains 2 single-valued fields within it.
Addressing these fields in TOM.NET then:
// The Component
Component c = (Component)engine.GetObject(package.GetByName(Package.ComponentName));
// The collection of fields in this component
ItemFields content = new ItemFields(c.Content, c.Schema);
// The Title field:
TextField contentTitle = (TextField)content["Title"];
// contentTitle.Value = "Some Title"
// Get the Embedded Schema Field "Body"
EmbeddedSchemaField body = (EmbeddedSchemaField)content["Body"];
// body.Value is NOT a field, it's a collection of fields.
// Since this happens to be a multi-valued field, we'll use body.Values
foreach(ItemFields bodyFields in body.Values)
{
SingleLineTextField bodyParagraphTitle = (SingleLineTextField)bodyFields["ParagraphTitle"];
XhtmlField bodyParagraphContent = (XhtmlField) bodyFields["ParagraphContent"];
}
Hope this gets you started.
Trying to create a select list with a first option text set to an empty string. As a data source I have a List of a GenericKeyValue class with properties "Key" & "Value". My current code is as follows.
<%= this.Select(x => x.State).Options(ViewData[Constants.StateCountry.STATES] as IList<GenericKeyValue>, "Value", "Key").Selected(Model.State) %>
This gets fills the select list with states, however I am unsure at this point of an elegant way to get a first option text of empty string.
"Trying to create a select list with a first option text set to an empty string." The standard way isn't fluent but feels like less work:
ViewData[Constants.StateCountry.STATES] = SelectList(myList, "Key", "Value");
in the controller and in the view:
<%= Html.DropDownList(Constants.StateCountry.STATES, "")%>
Sure you can, but you add it to your list that you bind to the dropdown...
List<State> list = _coreSqlRep.GetStateCollection().OrderBy(x => x.StateName).ToList();
list.Insert(0, new State { Code = "Select", Id = 0 });
ViewData["States"] = new SelectList(list, "Id", "StateName", index);
Or this...
Your view;
<%=Html.DropDownList("selectedState", Model.States)%>
Your controller;
public class MyFormViewModel
{
public SelectList States;
}
public ActionResult Index()
{
MyFormViewModel fvm = new MyFormViewModel();
fvm.States = new SelectList(Enumerations.EnumToList<Enumerations.AustralianStates>(), "Value", "Key", "vic");
return(fvm);
}
Without extending anything - you can't.
Here's what author says:
One final point. The goal of MvcFluentHtml was to leave the opinions to you. We did this by allowing you to define your own behaviors. However, it is not without opinions regarding practices. For example the Select object does not have any “first option” functionality. That’s because in my opinion adding options to selects is not a view concern.
Edit:
On the other hand - there is 'FirstOption' method for Select in newest source code.
Download MvcContrib via svn, build and use.