Dynamic Editor Type In Dialog - serenity-platform

I want to change the editor from StringEditor to Boolean, Integer or Decimal editor depending on the AnswerType field.
Any ideas?
My Answer field contains a JSON string with a "value" property.
I tried this but this doesnt change the string editor. This just adds a s-BooleanEditor class to input element.
switch (this.form.AnswerType.value) {
case 'boolean': {
debugger;
var val = JSON.parse(this.form.Answer.value).value;
var edt = new _Ext.BooleanSwitchEditor(this.byId("Answer"), {});
edt.value = val;
}
default:
""
}

Related

How to check if a text contains an element of an ArrayList

I have a text and an array list. I would like to check if my text contains any element in the ArrayList, and if he does find it, to replace the space between two words with "%".
Here's my code :
public static boolean stringContainsItemFromList(String text, ArrayList<String> list)
{
for (String i: list)
{
if (text.contains(list[i]))
{
text.replaceAll(" ", "%");
System.out.println("done");
return true;
}
}
return false;
}
It gives me this error: string cannot be converted to int for the line if (text.contains(list[i])). Any idea how else can I proceed?
i is a String. In that case list[i] does not make sense, since i inside of list[i] should be an index, which is an integer (e.g. list[0], list[1], but can not be list["hello"]).
So if you want to check that your text contains a String from list, you can use
if(text.contains(i))
Also, be aware that your result of
text.replaceAll(" ", "%");
is being ignored. If you want to keep the altered text, you can do that by storing the result of the replace into a new, separate variable.
Your error is because i is a string and you're using it as a int
public static boolean stringContainsItemFromList(String text, ArrayList<String> list)
{
for (String i: list) // HERE: i is an element of the list, not the index!
{
if(text.contains(list[i])) // HERE: list[string] -> error!
{
text.replaceAll(" ", "%");
System.out.println("done");
return true;
}
}
return false;
}
replace text.contains(list[i]) for text.contains(i) and try to use more descriptive var names :)
Something makes me believe, you actually need this !
public static boolean stringContainsItemFromList(String text, ArrayList<String> list)
{
boolean flag = false;
for (String i: list) {
if(text.contains(i)) {
text = text.replaceAll(i, "%");
flag = true;
}
}
System.out.println(text);
System.out.println("done");
return flag;
}
ArrayList<String> list is not an array, it is a list. So you can get the elements of list by calling get() method.
e.g.
list.get(0) // returns the first element of the list
Also
for (String i: list) {
// ...
}
is a foreach loop, a different version of
for(int x=0; x<list.size(); x++) {
// ...
}
i corresponds to list.get(x)
You should change text.contains(list[i]) to text.contains(i) because i stands for list.get(x)
Q: How to check if a text contains an element of an ArrayList
After fixing the error you'll see that the variable text has not changed. Because in Java strings are immutable and replaceAll() method returns a new string. So you should assign the new value to the text variable:
text = text.replaceAll("\\s", "%");
Here is the corrected version of the stringContainsItemFromList() method:
public static boolean stringContainsItemFromList(String text, List<String> list)
{
for (String i: list) {
if(text.contains(i)) {
text = text.replaceAll("\\s", "%");
System.out.println("done");
System.out.println(text);
return true;
}
}
return false;
}

what is "Dojo Name Text Box" onremove event?

I have a Dojo Name Text Box "xe:djextNameTextBox" on my form. By clicking [x] it removes a name from the list. How do I check what exact name was removed or clicked without parsing all values in getComponent("myNameBox").getValue()?
In my opinion the only way to handle this issue is to parse all values to get the information which name exactly was removed. I had to deal with the same problem in a previous project.
XPage
Set viewScope var "viewFiltersAsString":
<xp:this.beforeRenderResponse><![CDATA[#{javascript:log('beforerenderresponse (start rendering)');
requestScope.start = new Date().getTime();
viewScope.put('viewFiltersAsString', viewController.getViewFiltersAsString());
viewController.actionSetPage();}]]></xp:this.beforeRenderResponse>
Extension Library Dojo Name List Text Box control:
<xe:djextListTextBox id="djFilters" multipleSeparator=","
value="#{viewScope.viewFiltersAsString}" displayLabel="true"
title="Hier klicken um Filter zu löschen">
<xe:this.dataProvider>
<xe:simpleValuePicker caseInsensitive="false"
labelSeparator="~" valueListSeparator=","
valueList="#{viewController.viewFiltersLabelsAsString}">
</xe:simpleValuePicker>
</xe:this.dataProvider>
<xp:eventHandler event="onChange" submit="true" refreshMode="partial"
refreshId="${javascript:compositeData.refreshId}" execMode="partial"
action="#{javascript:viewController.setViewFiltersAsString(#Trim(viewScope.get('viewFiltersAsString')).toString())}">
</xp:eventHandler>
</xe:djextListTextBox>
Managed Bean "viewController"
/**
* Converts all filters to a useable format for dojo List Textbox
* #return string of filters
*/
public String getViewFiltersAsString() {
String filtersAsString = "";
for (ViewFilter filter : viewFilters) {
if (filtersAsString == "") filtersAsString = filter.getKey();
else filtersAsString += "," + filter.getKey();
}
return filtersAsString;
}
public void setViewFiltersAsString(String viewFiltersAsString) {
if (viewFiltersAsString != null && !viewFiltersAsString.equals("")) {
List<String> currentfilters = Converter.toList(",", viewFiltersAsString);
for (ViewFilter filter : viewFilters) {
boolean remove = true;
for (String currentFilter : currentfilters) {
if (filter.getKey().equals(currentFilter)) {
remove = false;
break;
}
}
if (remove) {
// user can click only one filter at one time
setActionViewFilter(viewFilters.removeFilter(filter));
break;
}
}
} else {
setActionViewFilter(viewFilters.removeFilter(viewFilters.get(0)));
}
}
Hint: viewFilters is a java.util.List of ViewFilter objects and a ViewFilter is a simple java class holding information about a filter (in your case a name)

QML ListModel and custom function property

I want to write tuned version of TableView (TableView.qml in Qt package).
I have ColumnDescriptor.qml with column definition:
Item {
property string title
property var formatDelegate: null
.... (other property definition)
function format(val) {
if (formatDelegate != null)
return formatDelegate(val);
else
return val;
}
}
The above code defines set of properties and fuction format(val), that calls for format value if formatDelefate was set.
In the main table I use list to store predefined columns definition (temporaly) and ListModel to store final columns definition ( the latter is more useful than list in remaining implementation)
list example:
property list<ColumnDescriptor> colDefines: [
ColumnDescriptor {
title: qsTr("col1")
},
ColumnDescriptor {
title: qsTr("col2")
formatDelegate: function(val) { return "!" + val}
}
]
Filling ListModel (id: columnModel):
Component.onCompleted: {
for(var i = 0; i < colDefines.length; ++i)
{
var col = colDefines[i];
...(some calculation)
columnModel.append(col);
}
}
All looks fine, but when I try to call format from model item, Qt sends me the following error
Property 'format' of object QQmlDMListAccessorData(0x8e3bf78) is not a function
Example of calling format:
Repeater {
model: columnModel
Text {
text: model.format([SOME USEFUL DATA])
}
}
On the other hand, if I call format directly from list it works well.
So my question here is how to fill model in a way that the format or other function will work correctly when being called from model?
For QtQuick2 this should work
formatDelegate = [function(val) { return "!" + val}]
formatDelegate[0]("some text")
but you could also use an overriding technique:
Item {
function formatDelegate(val) {
return val;
}
function format(val) {
return formatDelegate(val);
}
}
ColumnDescriptor {
function formatDelegate(val) {
return "!" + val
}
}
This way Item.format() should call "return val" as default and "!"+val for ColumnDescriptor given that ColumnDescriptor is derived from Item.
Try this
Repeater {
model: columnModel
Text {
text: columnModel[index].format([SOME USEFUL DATA])
}
}

How to remove a line with a particular content in docx4j

I want to delete a particular line in the docx if it has a particular word, say "killer".
How i can write a program using docx4j?
If i replace it with empty data, the line will be still there. I want to remove the whole line.
I tried something like this,
private void replacePlaceholders(WordprocessingMLPackage targetDocument,
String nameOfTheInvitedGuest) throws JAXBException {
List<Object> texts = targetDocument.getMainDocumentPart()
.getJAXBNodesViaXPath(XPATH_TO_SELECT_TEXT_NODES, true);
System.out.println(texts.size());
Iterator<Object> itr = texts.iterator();
while (itr.hasNext()) {
Object obj = itr.next();
Text text = (Text) ((JAXBElement) obj).getValue();
// System.out.println(text.getValue());
if (text.getValue().contains("Hulk Hogan")) {
itr.remove();
}
else {
String textValue = replacePlaceholderOfInvitedGuestWithGivenName(
nameOfTheInvitedGuest, text.getValue());
for (Object key : templateProperties.keySet()) {
textValue = textValue.replaceAll("\\$\\{" + key + "\\}",
(String) templateProperties.get(key));
}
text.setValue(textValue);
}
}
System.out.println(texts.size());
}
But its still showing in the docx file.
A Text element in a docx file has parent elements. The text will reside within a Run which in turn will sit within a block element like a paragraph (P node) or a table cell. If you're looking to remove a particular block element based on its textual content, once you've located the relevant text elements, you need to move up the parent elements, and remove them too -- for example, if the ultimate parent is a paragraph node, remove that.
If say, a paragraph displays as 3 lines in Word and you are trying to remove the 2nd line in that paragraph, then you have a different and more challenging problem.
maybe this will help futur people :
if(((org.docx4j.wml.Text) o2).getValue().contains("WhatYouWant")) {
// if your text contains "WhatYouWant" then...
Object o4 =((org.docx4j.wml.Text)o2).getParent();
//gets R
Object o5 = ((org.docx4j.wml.R) o4).getParent();
// gets P
Object o6 = ((org.docx4j.wml.P) o5).getParent();
// gets SdtElement
((List<List<Object>>) o6).remove(o5);
// now you remove your P (paragraph)
}
I had a content control (SdtElement) but I needed to put it in List < List < Object > > don't really know why but.... You might have something else so check in your document.xml before copy/pasting this.
This is for others who have a hard time, like I did to understand docx4j
You could use Apache POI to remove Text from docx file as shown below.
public static void removeTextFromDocx(FileInputStream inpudocxfile, String stringToBeReplaced,
String stringToBeReplacedWith, FileOutputStream outputdocxfile) {
XWPFDocument document = null;
try {
//loading docx file
document = new XWPFDocument(inpudocxfile);
for (XWPFParagraph paragraph : document.getParagraphs()) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
//reading an entire paragraph. So size of list is 1 and index of first element is 0
String text = run.getText(0);
if (text != null) {
if (text.contains(stringToBeReplaced)) {
text = text.replace(stringToBeReplaced, stringToBeReplacedWith);
text = text.trim();
run.setText(text, 0);
}
}
}
}
for (XWPFTable table : document.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
for (XWPFRun run : paragraph.getRuns()) {
String text = run.getText(0);
if (text != null) {
if (text.contains(stringToBeReplaced)) {
text = text.replace(stringToBeReplaced, stringToBeReplacedWith);
text = text.trim();
run.setText(text, 0);
}
}
}
}
}
}
}
document.write(outputdocxfile);
} catch (IOException e) {
LOGGER.error("Could not create outputdocxFile --> IOEXception" + e);
}
}

Telerik Mail Merge - Friendly Names (using RadRichTextBox)

I think i'm missing something obvious...
I'm using the Telerik Rad controls for WPF but i assume that the Rich text box uses some similar implementation for the mail merge functionality.
I want to have some friendly names on my mail merge fields. (namely spaces in the field names)
So i have a class for instance
Public Class someclass
{
<DisplayName("This is the complex description of the field")>
Public property thisfieldnamehasacomplexdescription as string
Public property anothercomplexfield as string
}
This is the only way i know to get "Friendly" names in the dropdown that is the mail merge.
So the two fields turn up okay as :
"This is the complex description of the field"
"anothercomplexfield"
but only anothercomplexfield actually populates with data when you do the merge.
Am i going to have to template the raddropdownbutton that holds the mail merge fields?
Is there an example of this somewhere?
Also a sub question. How do i add a scroll bar on these things?
(also i know this board is not a TELERIK specific board (duh!) but this might be useful to someone in the future. So i'll copy the answer i get from Telerik into here!
http://www.telerik.com/community/forums/wpf/richtextbox/558428-radrichtextbox-mailmerge---using-displayname-to-create-a-friendly-name-with-spaces.aspx )
This is what telerik gave me:
With the default MergeFields, it is not possible to change the display name fragment of the field in order to achieve a more friendly look. This should be possible if you implement a custom MergeField by deriving from the MergeField class. Here is a sample implementation that shows how this can be done:
public class CustomMergeField : MergeField
{
private const string CustomFieldName = "CustomField";
static CustomMergeField()
{
CodeBasedFieldFactory.RegisterFieldType(CustomMergeField.CustomFieldName, () => { return new CustomMergeField(); });
}
public override string FieldTypeName
{
get
{
return CustomMergeField.CustomFieldName;
}
}
public override Field CreateInstance()
{
return new CustomMergeField();
}
protected override DocumentFragment GetDisplayNameFragment()
{
return base.CreateFragmentFromText(string.Format(Field.DisplayNameFragmentFormat, this.GetFriendlyFieldName(this.PropertyPath)));
}
private string GetFriendlyFieldName(string fieldName)
{
int lettersInEnglishAlphabet = 26;
List<char> separators = new List<char>(lettersInEnglishAlphabet);
for (int i = 0; i < lettersInEnglishAlphabet; i++)
{
separators.Add((char)('A' + i));
}
StringBuilder newFieldName = new StringBuilder();
int previousIndex = 0;
for (int i = 1; i < fieldName.Length; i++)
{
if (separators.Contains(fieldName[i]))
{
if (previousIndex > 0)
{
newFieldName.Append(" ");
}
newFieldName.Append(fieldName.Substring(previousIndex, i - previousIndex));
previousIndex = i;
}
}
newFieldName.Append(" " + fieldName.Substring(previousIndex));
return newFieldName.ToString();
}
}
Note that the fragment that is shown when the DisplayMode is Code cannot be changed.
As for your other question, you can change the content of the dropdown button to show the friendly name of the fields and to include a scrollbar in the following way:
1. First, remove the binding of the button to the InsertMergeFieldEmptyCommand from XAML and give it a name (e.g. insertMergeField).
2. Next, add the following code in code-behind:
AddMergeFieldsInDropDownContent(this.insertMergeFieldButton);
private void AddMergeFieldsInDropDownContent(RadRibbonDropDownButton radRibbonDropDownButton)
{
Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(100, GridUnitType.Pixel) });
ScrollViewer scrollViewer = new ScrollViewer();
scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
StackPanel stackPanel = new StackPanel();
foreach (string fieldName in this.editor.Document.MailMergeDataSource.GetColumnNames())
{
RadRibbonButton fieldButton = new RadRibbonButton()
{
Text = this.GetFriendlyFieldName(fieldName),
Size = ButtonSize.Medium,
HorizontalAlignment = HorizontalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Left
};
fieldButton.Command = this.editor.Commands.InsertFieldCommand;
fieldButton.CommandParameter = new MergeField() { PropertyPath = fieldName };
//or
//fieldButton.CommandParameter = new CustomMergeField() { PropertyPath = fieldName };
stackPanel.Children.Add(fieldButton);
}
stackPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
scrollViewer.Content = stackPanel;
grid.Children.Add(scrollViewer);
radRibbonDropDownButton.DropDownContent = grid;
}
You can, of course optimize the code of the GetFriendlyName method and add it in a way that will be available by both classes.