A related problem that is specific to single field has been solved here. But how to customize a collection field's conversion error message?
Here is an example:
On a jsp page, I have a field in Collection type:
...
<s:iterator value="items" status="m">
<s:hidden name="selitmems[%{#m.index}].id" value="%{id}"/>
<s:textfield name="selitmems[%{#m.index}].quant" size="10"/>
</s:iterator>
The items' type is: List<Item>; the selitems' type is List<SelItem>.
I want selitmems[].quant property to be an integer type. If a string like "abc" is filled in for the first item by an end user, the default error message is:
Invalid field value for field "selitmems[0].quant".
The above message is not what i want. In my case, I would prefer to generalize the error message as follows regardless of the specific selected item:
Please input integers for the items.
Of course it would be great if the error message can vary according to the specific item:
Please input an integer for the first item.
I have tried to add some keys like "selitmems[0].quant" or "selitmems" in the properties file, but can't get the result. Is there way to customize the error message for a collection field in struts2 when I can still reuse the built-in type conversion functions?
Try using the "label" attribute. You can play some... interesting games with this, such as (untested, but close):
label="%{getText('selitem.quantity', { #m.index })}"
The property file would contain:
selitem.quantity=Item #{0}
You can change the conversion error message as described here, although this may not be precisely what you want to do.
(I've been known to remove the conversion interceptor altogether and let either the default converters or custom converters handle conversion errors when a bad conversion also fails the field's "real" validation.)
Mm hmm... you can play some crazy games with OGNL and substituion.
Put something like this in your properties file.
invalid.fieldvalue.selitmems.quant = Please input integers for the items.
Then selitmems[0].quant, selitmems[1].quant, selitmems[2].quant conversion errors all return the same message.
Related
I have a numeric field in a Notes form connected to a combobox in the xpage. the values from the combobox is a list of decimal values, 1,02, 1,03 etc but they are stored as text in the keyword documents
The combobox is of type "string" (no converters) but it doesn't seem to matter if I change it to a "decimal" using converters.
comma is a decimal separator in Sweden
I fetch the keyword values using a #dbLookup
something like this.
#DbLookup(db,"vwLookupCat","BONUS","KeyWord")
When I save the document the values from the keyword document is saved as a numric value as it should. but the combobox is no longer showing the correct selected value (in edit mode) and displayes a validation error when I change it because the value is now numeric and not text as in the combobox keyword values.
or because the field was initially a text field, but when saved it is a numeric field.
<xp:comboBox id="comboBox7" value="#{doc.bonus}">
<xp:this.converter>
<xp:convertNumber type="number"></xp:convertNumber>
</xp:this.converter>
<xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="tbl"></xp:eventHandler>
<xp:selectItem itemLabel="Välj Bonus" itemValue="0"></xp:selectItem>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:#DbLookup(db,"vwLookupCat","BONUS","KeyWord")}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox>
Note that I am not using any validators on the combobox
I can't change the keyword field type to numeric as this is used on many other places
if doesn't help to use #Text (#Text(#DbLookup(db,"vwLookupCat","BONUS","KeyWord")))
How should I tackle this problem?
thanks in advance
Thomas
Seem to be a similar question here without solution
I can think of 2 ways you can go about it, both of which require you to make use of beans, hopefully you should already be familiar with the concept.
The conceptually righteous
The converter stays where it is. After all you want to deal with a number, you are saving a number. The converter instructs the framework to convert the returning string value from the POST into a number, and that is what you want, since also the destination field bound with the component is saved as a number.
The problem is matching such value with the list of values used to populated the options. Why? Those values are not numbers.
The solution is custom building the options rather than letting the framework doing the autoboxing from the array of string values returned from dblookup.
It pains me to write ssjs+formula but the call should be something like this:
<xp:selectItems
value="${javascript:myBeanName.getSelectItems(#DbLookup(db,"vwLookupCat","BONUS","KeyWord"))}">
</xp:selectItems>
The bean method:
public List<SelectItem> getSelectItems(String[] values) {
List<SelectItem> options = new ArrayList<SelectItem>();
for (String value : values) {
options.add(new SelectItem(Double.valueOf(value), value));
}
return options;
}
By doing this you are creating options with comparable values.
The only problem remaining is the utterly counterintuitive converter provided by IBM. Because you don't know what choosing 'number' does internally, whether it will be a Integer, a Double, a BigDecimal etc... you're stuck with more uncertainties than certainties. I have my own number converter but since I know how the IBM one works I think you can get away with the problem by specifying an additional param to the converter.
<xp:this.converter>
<xp:convertNumber type="number" integerOnly="true" />
</xp:this.converter>
I know, I know, integerOnly makes you think it will convert the value to Integer. It doesn't, it converts to Double. Lucky you! Imagine you needed an Integer!
The conceptually crappy
The other approach is to bind the combobox to a view scoped variable.
You would initialize the variable with the string converted doc value at page load and then work with that. At save time you would read the view scoped variable, convert it back to number and push the number to the doc field before saving it.
We have "Date/Time" property type in Bitrix. But there is no "Time" type.
I tried to google it but I get a bunch of code without comments and there is no explanations where I need to put it.
I also tried to search in Bitrix Market place but without success too.
Please help me to understand how to implement "Time" type for infoblock properties.
If you need just time - fastest workaround is to save time as usual string property.
In Bitrix best solution for this is not making custom property types and use types, that you alredy have.
If you need store "timestamp" (1472356615 - like this), make property with type "integer" and CODE like "TIME_OF_EVENT" (letters in code field must be capitalised).
If you need save string like this "23:45:59", better use "string" type.
If you want automated data validation, you can use Bitrix Event Handlers to check specific fields before updating elements in Infoblock.
There is something I don't understand how to do with Gtkmm 3.
I have a custom business type that I have declared like this:
enum class Eurocents : int {};
I would like to render this type into a Gtk::TreeView which has a Gtk::ListStore as model. So I declare a Gtk::TreeModelColumn<Eurocents>, and add it to the model. I then append_column this model column to the Gtk::TreeView with an appropriate title.
I then append_row to the model and set the value corresponding to the column to (Eurocents)100.
The result I get is that the cell is displayed empty. Understandably so, because I would not expect Gtkmm to know how to render my arbitrary type.
I would like to instruct Gtkmm on how to render my type.
I already know how to display Glib types like Glib::ustring and formatting to Glib::ustring for display is possible, but it is not the subject of the question.
Is it possible to code columns that can display arbitrary types like this? And if so, how? What is required for sorting to work?
The most common, and easiest way, is to use a cell_data_func callback. For instance, you can create your own instance of a Gtk::TreeView::Column (the view column), pack a cell renderer (or more) into your Gtk::TreeView::Column, append your Gtk::TreeView::Column to the TreeView with Gtk::TreeView::append_column(), and call set_cell_data_func() on your Gtk::TreeView::Column():
https://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeViewColumn.html#a3469e1adf42e5932ea123ec33e4ce4e1
You callback would then get the value(s) from the model and set the appropriate values of the properties of the renderer(s).
Here is an example that shows the use of set_cell_data_func(), as well as showing other stuff:
https://developer.gnome.org/gtkmm-tutorial/stable/sec-treeview-examples.html.en#sec-editable-cells-example
This link should also be useful:
https://developer.gnome.org/gtkmm-tutorial/stable/sec-treeview.html.en#treeview-cellrenderer-details
If you like, Gtk::TreeView::insert_column_with_data_func() makes this a little more concise: https://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeView.html#a595dcc0b503a7c1004c296b82c51ac54
As for the sorting, you should be able to just call set_sort_func() to specify how the column is sorted: https://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeSortable.html#a3a6454bd0a285324c71edb73e403cb1c
Then this regular sorting advice should apply: https://developer.gnome.org/gtkmm-tutorial/stable/sec-treeview-sort.html.en
Good evening all,
Writing an application in IronPython that will act as a message spoofer for a system that has not been developed far enough to test for our system. Part of the application is a set of tables that show values for messages and commands. In the case of commands there are some fields of our commands that have enum values. The command table is to have a drop-down box with those enum options in it.
My approach is to create a DataSet for each of our messages. The DataSet has a DataTable that had the message fields in it and the message values. It also has a table for each enum type in the message. So, the following code is what I use to figure out if the field is a normal field or an enum field.
msg = mpas.M120()
msg_fields = msg.DESCRIPTOR.fields
for field in msg_fields:
fieldEnumType = msg.DESCRIPTOR.fields_by_name[field.name].enum_type
print("{} --> EnumType: {}".format(field.name, fieldEnumType.name if fieldEnumType != None else 'None'))
I have also found that this works for me as well:
msg = mpas.M120()
msg_fields = msg.DESCRIPTOR.fields
for k,v in msg.DESCRIPTOR.fields_by_name.items():
print ("{} --> {}".format(k, ((v.enum_type).name if v.enum_type != None else 'None')))
What I will get from this is the name of the enum for each of the enum fields. I now want to be able to get a list of all of the values for each of the enum fields found. Here is the trick, enums that are used by a certain message and only that message are defined at the message level (i.e. mpas.M120().. Enums that are used by other messages are defined at the top level (i.e. mpas..
So, how would I go about finding the values for these enums so I can populate my drop-down boxes? I have been working on this for the better part of a day now and I cannot figure it out.
Thanks in advance...
You've already found v.enum_type, which is the EnumDescriptor corresponding to the field's enum type. You are getting name from here, but this object also contains a list of values. See the documentation here:
https://developers.google.com/protocol-buffers/docs/reference/python/google.protobuf.descriptor.EnumDescriptor-class
Using EMF Validation to validate model I get error messages such as
The feature 'blah' of 'blah' with 0 values must have at least 1 values
This message might be confusing to user, is there anyway I can override this error message for particular element/attribute with custom message? In a schema perhaps?
We have done this by adding a new fragment for org.eclipse.emf.ecore with our new message texts in the file plugin_en.properties. These will take precedence over the texts in plugin.properties...