I have a SAPUI5 application and using following mechanism for showing errors in case fails in validation (documentation):
oMessage = new sap.ui.core.message.Message({
message: (typeof sText === "string" && sText.trim().length > 0) ? sText : ex.message,
type: MessageType.Error,
target: (oControlBinding.getContext() ? oControlBinding.getContext().getPath() + "/" : "") + oControlBinding.getPath(),
processor: oControlBinding.getModel()
});
this._aMessages[oControl.getId()] = oMessage;
sap.ui.getCore().getMessageManager().addMessages(oMessage);
This solution works for normal inputs:
What do I mean by normal elements???
Actually when it is an Input element that shows an expanded value it does not work and when it is not expanded it works.
For example when the element is:
<Input value="{ path: 'BusinessAddress/PostOfficeBox', type : 'sap.ui.model.type.String' , constraints:{search: '^[0-9]*$'}}">
Which shows an expanded value does not get the error message box.
But for the elements that have a path like value="{ path: 'MobilePhone', type: 'sap.ui.model.type.String', constraints: {search: '^[0-9]+$'}}" it shows the error message.
The difference between the two oMessage object that is generated by the snippet code is:
target: "/ContactSet('CO1')/BusinessAddress/PostOfficeBox" ==> for expanded ones
The BusinessAddress is a foreign key of the entity ContactSet which has been expanded.
And
target: "/ContactSet('CO1')/MobilePhone"
So clearly the problem is about the target of the sap.ui.core.message.Message instance.
Therefore my question is how can I target the error message for an expanded element?
It is needed to change the processor from the oDataModel to ControlMessageProcessor. It means instead of the path of the bound data in the model we can address the control itself for binding the error message to its correct place of showing. something like this:
var oMessageProcessor = new sap.ui.core.message.ControlMessageProcessor();
var oMessageManager = sap.ui.getCore().getMessageManager();
oMessageManager.registerMessageProcessor(oMessageProcessor);
var oInput = new sap.m.Input({
id: "myInputId",
value: { path: "/Products(1)/Price" , type: new sap.ui.model.type.Float() }
});
oMessageManager.addMessages(
new sap.ui.core.message.Message({
message: "ZIP codes must have at least 23 digits",
type: sap.ui.core.MessageType.Error,
target: "/myInputId/value",
processor: oMessageProcessor
})
);
By targeting the control itself it does not matter we bind an expanded property to the control.
Related
I'm getting same error as this question, but with XQuery:
SaxonApiException: The context item for axis step ./CLIENT is absent
When running from the command line, all is good. So I don't think there is a syntax problem with the XQuery itself. I won't post the input file unless needed.
The XQuery is displayed with a Console.WriteLine before the error appears:
----- Start: XQUERY:
(: FLWOR = For Let Where Order-by Return :)
<MyFlightLegs>
{
for $flightLeg in //FlightLeg
where $flightLeg/DepartureAirport = 'OKC' or $flightLeg/ArrivalAirport = 'OKC'
order by $flightLeg/ArrivalDate[1] descending
return $flightLeg
}
</MyFlightLegs>
----- End : XQUERY:
Error evaluating (<MyFlightLegs {for $flightLeg in root/descendant::FlightLeg[DepartureAirport = "OKC" or ArrivalAirport = "OKC"] ... return $flightLeg}/>) on line 4 column 20
XPDY0002: The context item for axis step root/descendant::FlightLeg is absent
I think that like the other question, maybe my input XML file is not properly specified.
I took the samples/cs/ExamplesHE.cs run method of the XQuerytoStream class.
Code there for easy reference is:
public class XQueryToStream : Example
{
public override string testName
{
get { return "XQueryToStream"; }
}
public override void run(Uri samplesDir)
{
Processor processor = new Processor();
XQueryCompiler compiler = processor.NewXQueryCompiler();
compiler.BaseUri = samplesDir.ToString();
compiler.DeclareNamespace("saxon", "http://saxon.sf.net/");
XQueryExecutable exp = compiler.Compile("<saxon:example>{static-base-uri()}</saxon:example>");
XQueryEvaluator eval = exp.Load();
Serializer qout = processor.NewSerializer();
qout.SetOutputProperty(Serializer.METHOD, "xml");
qout.SetOutputProperty(Serializer.INDENT, "yes");
qout.SetOutputStream(new FileStream("testoutput.xml", FileMode.Create, FileAccess.Write));
Console.WriteLine("Output written to testoutput.xml");
eval.Run(qout);
}
}
I changed to pass the Xquery file name, the xml file name, and the output file name, and tried to make a static method out of it. (Had success doing the same with the XSLT processor.)
static void DemoXQuery(string xmlInputFilename, string xqueryInputFilename, string outFilename)
{
// Create a Processor instance.
Processor processor = new Processor();
// Load the source document
DocumentBuilder loader = processor.NewDocumentBuilder();
loader.BaseUri = new Uri(xmlInputFilename);
XdmNode indoc = loader.Build(loader.BaseUri);
XQueryCompiler compiler = processor.NewXQueryCompiler();
//BaseUri is inconsistent with Transform= Processor?
//compiler.BaseUri = new Uri(xqueryInputFilename);
//compiler.DeclareNamespace("saxon", "http://saxon.sf.net/");
string xqueryFileContents = File.ReadAllText(xqueryInputFilename);
Console.WriteLine("----- Start: XQUERY:");
Console.WriteLine(xqueryFileContents);
Console.WriteLine("----- End : XQUERY:");
XQueryExecutable exp = compiler.Compile(xqueryFileContents);
XQueryEvaluator eval = exp.Load();
Serializer qout = processor.NewSerializer();
qout.SetOutputProperty(Serializer.METHOD, "xml");
qout.SetOutputProperty(Serializer.INDENT, "yes");
qout.SetOutputStream(new FileStream(outFilename,
FileMode.Create, FileAccess.Write));
eval.Run(qout);
}
Also two questions regarding "BaseURI".
1. Should it be a directory name, or can it be same as the Xquery file name?
2. I get this compile error: "Cannot implicity convert to "System.Uri" to "String".
compiler.BaseUri = new Uri(xqueryInputFilename);
It's exactly the same thing I did for XSLT which worked. But it looks like BaseUri is a string for XQuery, but a real Uri object for XSLT? Any reason for the difference?
You seem to be asking a whole series of separate questions, which are hard to disentangle.
Your C# code appears to be compiling the query
<saxon:example>{static-base-uri()}</saxon:example>
which bears no relationship to the XQuery code you supplied that involves MyFlightLegs.
The MyFlightLegs query uses //FlightLeg and is clearly designed to run against a source document containing a FlightLeg element, but your C# code makes no attempt to supply such a document. You need to add an eval.ContextItem = value statement.
Your second C# fragment creates an input document in the line
XdmNode indoc = loader.Build(loader.BaseUri);
but it doesn't supply it to the query evaluator.
A base URI can be either a directory or a file; resolving relative.xml against file:///my/dir/ gives exactly the same result as resolving it against file:///my/dir/query.xq. By convention, though, the static base URI of the query is the URI of the resource (eg file) containing the source query text.
Yes, there's a lot of inconsistency in the use of strings versus URI objects in the API design. (There's also inconsistency about the spelling of BaseURI versus BaseUri.) Sorry about that; you're just going to have to live with it.
Bottom line solution based on Michael Kay's response; I added this line of code after doing the exp.Load():
eval.ContextItem = indoc;
The indoc object created earlier is what relates to the XML input file to be processed by the XQuery.
In my Xtext project I want to use quickfix to insert a new line before the current line for the missing cross-reference.But it gives following exception.
!ENTRY org.eclipse.core.jobs 4 2 2015-06-02 17:22:05.616
!MESSAGE An internal error occurred during: "Select and reveal referenced object".
!STACK 0
java.lang.IllegalArgumentException: The feature 'content' is not a valid feature
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eStructuralFeature(BasicEObjectImpl.java:733)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eObjectForURIFragmentSegment(BasicEObjectImpl.java:551)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObject(ResourceImpl.java:766)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.getEObject(ResourceImpl.java:742)
at org.eclipse.xtext.resource.XtextResource.access$1(XtextResource.java:1)
at org.eclipse.xtext.resource.XtextResource$1.getEObject(XtextResource.java:115)
at org.eclipse.xtext.resource.DefaultFragmentProvider.getEObject(DefaultFragmentProvider.java:28)
at org.eclipse.xtext.resource.XtextResource.basicGetEObject(XtextResource.java:346)
at org.eclipse.xtext.resource.XtextResource.getEObject(XtextResource.java:332)
at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:235)
at org.eclipse.xtext.ui.editor.LanguageSpecificURIEditorOpener.findEObjectByURI(LanguageSpecificURIEditorOpener.java:159)
at org.eclipse.xtext.ui.editor.LanguageSpecificURIEditorOpener$2.process(LanguageSpecificURIEditorOpener.java:125)
at org.eclipse.xtext.ui.editor.LanguageSpecificURIEditorOpener$2.process(LanguageSpecificURIEditorOpener.java:1)
at org.eclipse.xtext.util.concurrent.IUnitOfWork$Void.exec(IUnitOfWork.java:37)
at org.eclipse.xtext.resource.OutdatedStateManager.exec(OutdatedStateManager.java:121)
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.internalReadOnly(XtextDocument.java:520)
at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.readOnly(XtextDocument.java:492)
at org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:133)
at org.eclipse.xtext.ui.editor.LanguageSpecificURIEditorOpener.selectAndReveal(LanguageSpecificURIEditorOpener.java:121)
at org.eclipse.xtext.ui.editor.LanguageSpecificURIEditorOpener$1.run(LanguageSpecificURIEditorOpener.java:88)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
My Code is very simple liking this:
acceptor.accept(issue, "Create label", "Create a new jump label", null) [ element, context |
if (element instanceof ContinueCommand) {
var lineNum = issue.lineNumber
var doc = context.xtextDocument
// If use doc.getLineOffset(lineNum). It works and inserts newline after current line.
var offset = doc.getLineOffset(lineNum-1)
var id = doc.get(issue.offset, issue.length)
var toInsert = "!" + id + " : comment\n"
doc.replace(offset, 0, toInsert)
}
]
I tried it in other quickfix methods (not for cross-references). It works good. I use xtext version 2.9.
Has anybody the same problem?
With TableSorter, when I export my table in a CSV file, the accented characters doesn't appear correctly.
How to solve that ?
In version 2.16.4, the output_encoding option was added to the output widget.
The demo now has a select dropdown in which you can choose "utf8 BOM" required to make the csv file work properly in Excel.
You can set this option to include a BOM by default as follows:
output_encoding : 'data:text/csv;charset=utf8,%EF%BB%BF'
With version 2.30.6, the solution proposed above didn't work for me.
I read an article saying the unicode character \uFEFF should be specified at the beginning of the CSV data.
So, my code below insert this character only once and I reset the boolean immediately to do it only once.
Dont pay attention about scroller_* widget options if you don't use the widget 'scroller' (same for 'columnSelector' and 'filter' widgets).
Here to show UTF8 data in Excel, use the callback function output_formatContent and see my code below.
var insertBOM = true;
var $tablesorterScroll = $(".tablesorter-scroll");
$tablesorterScroll.tablesorter({
sortInitialOrder: 'desc',
widthFixed : false,
showProcessing: true,
widgets: ['filter', 'columnSelector', 'scroller', 'output'],
widgetOptions: {
// Set the max-height property of the table for the scroller widget.
scroller_height : 412, // sized with table CompanyBoard statistics (fits like that without scrollbar and finishes at the end of the row)
// Delay in milliseconds before the filter widget starts searching; This option prevents searching for
// every character while typing and should make searching large tables faster.
filter_searchDelay : 200,
// target the column selector markup
columnSelector_container : $('#columnSelector'),
// column status, true = display, false = hide
// disable = do not display on list
columnSelector_columns : {
//0: 'disable' /* set to disabled; not allowed to unselect it */
},
// remember selected columns (requires $.tablesorter.storage)
columnSelector_saveColumns: true,
// container layout
columnSelector_layout : '<label><input type="checkbox">{name}</label>',
// data attribute containing column name to use in the selector container
columnSelector_name : 'data-selector-name',
/* Responsive Media Query settings */
// enable/disable mediaquery breakpoints
columnSelector_mediaquery: false,
// toggle checkbox name
columnSelector_mediaqueryName: 'Auto: ',
// breakpoints checkbox initial setting
columnSelector_mediaqueryState: false,
// hide columnSelector false columns while in auto mode
columnSelector_mediaqueryHidden: false,
// set the maximum and/or minimum number of visible columns; use null to disable
columnSelector_maxVisible: null,
columnSelector_minVisible: null,
// responsive table hides columns with priority 1-6 at these breakpoints
// see http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/#Applyingapresetbreakpoint
// *** set to false to disable ***
columnSelector_breakpoints : [ '20em', '30em', '40em', '50em', '60em', '70em' ],
// data attribute containing column priority
// duplicates how jQuery mobile uses priorities:
// http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/
columnSelector_priority : 'data-priority',
// class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
// applied icons; use this class name (input.checked) instead of input:checked
columnSelector_cssChecked : 'checked',
output_saveFileName : 'TableExport.csv',
output_separator: ';', // Excel recognize it and shows data in separated column without doing "Text to columns" Excel option.
output_replaceQuote: '\'',
output_delivery: 'd', // (p)opup, (d)ownload
output_saveRows: 'v', // (a)ll, (v)isible, (f)iltered, jQuery filter selector (string only) or filter function
output_encoding: "data:text/csv;charset=utf-8",
output_formatContent: function (config, widgetOptions, data) {
// data.isHeader (boolean) = true if processing a header cell
// data.$cell = jQuery object of the cell currently being processed
// data.content = processed cell content
// (spaces trimmed, quotes added/replaced, etc)
// **********
// use data.$cell.html() to get the original cell content
var BOM = "";
// Add BOM at file starting
if (insertBOM) {
BOM = "\uFEFF"; // set Excel enconding UTF-8
insertBOM = false;
}
return BOM + data.content.replace(/&/g, '&'); // data.content is HTML text converted so '&' has been converted to & which is the HTML reprensetation of the '&' character. Convert it back to show '&' in the CSV.
}
}
});
EDIT (15.10.2020)
My initial solution proposed above doesn't work when output_headerRows: true AND if the first header row has a rowspan. A colspan is ok.
To handle that situation, I found a way :
Before: The BOM was inserted by the function output_formatContentwhich is raised row after row (and a condition to apply the BOM only once)
Now: Use the output_callback function that is raised only once at the end of the data processed, so can insert the BOM.
IMPORTANT: You need tablesorter v2.25.1+ to be able to return data instead of true as before.
output_callback : function(config, data, url) {
BOM = "\uFEFF"; // The BOM character to force Excel opens CSV as UTF-8
return BOM + data;
}
I just looked at the kitchen sink demo and see that there is an option "Show token info" that shows up what type of text the mouse is over (variable, function etc.)
I want to create something similar that can get the current token string of the word at the current cursor position. Does anyone knows how to do that ?
Thanks!
In this way:
editor.on('mousemove', function(e) {
var position = e.getCursorPosition();
var token = editor.session.getTokenAt(position.row, position.column);
});
It will return an Object:
token = {
type: "paren.rparen",
value: "}",
index: 0,
start: 0
}
Let's consider the next function:
def generateUniqueIdent(String text, uniqueSuffix = {uid -> String.valueOf(uid)}) {
doSomething(text) + uniqueSuffix()
}
Now, when I try the next modification:
def generateUniqueIdent(String text, uniqueSuffix = { hash(text) }) {
doSomething(text) + uniqueSuffix()
}
..I got the next error:
| Error Fatal error during compilation
org.apache.tools.ant.BuildException: BUG! exception in phase 'class
generation' in source unit 'some path here' tried to get a variable
with the name text as stack variable, but a variable with this
name was not created (Use --stacktrace to see the full trace)
At the same time, if I try to use the name text as a parameter of the closure:
def generateUniqueIdent(String text, uniqueSuffix = {text -> hash(text) }) {
doSomething(text) + uniqueSuffix(text)
}
..then I got another error:
The current scope already contains a variable of the name text
The question is: can I somehow get access to other parameters from a closure, which is assigned as a default value to one of function parameters?
If no, then, why can't I use the same name as one of function parameters has inside the described closure?
You can use the default it parameter:
def generateUniqueIdent(String text, uniqueSuffix = { hash(it) }) {
doSomething(text) + uniqueSuffix(text)
}
(working example)
Or use a different name for the closure parameter instead of text:
def generateUniqueIdent(String text, uniqueSuffix = { x -> hash(x) }) {
doSomething(text) + uniqueSuffix(text)
}
(example)
Unfortunately, accessing the previous parameter from the closure is working for me in this case, so i don't know what the original problem is :S