ASP.NET Core 3.1
I have the following code in my View:
<span asp-validation-for="NewPassword" class="text-danger"></span>
If I type in a password, such as 'a', I get multiple errors back. I want to display them in that span ONE PER LINE.
In my Controller I have the following:
var descriptions = string.Empty;
foreach (var error in errors)
descriptions += error.Description + "<br />";
ModelState.AddModelError("NewPassword", descriptions);
But this does not translate the "br" tags and they get displayed as if they were part of one very long single error message.
Note: Adding them one at a time into the ModelState simply overwrites the previous, leaving only the last one displayed.
Instead of "br", i've tried HTMLString.NewLine and Environment.NewLine but none of these work. I could write a loop in my View, but is there a preferred way in ASP.NET Core?
So my question is: How can I put a new line between each description?
Instead of "br", i've tried HTMLString.NewLine and Environment.NewLine but none of these work.
That's because <br/> will be escaped by default. If you wish, you could use #Html.Raw() to generate the raw content without escaping the dangerous characters. But I don't think it's a good idea: there will be a high risk of XSS if you output a raw string directly.
By default, \r\n won't be displayed in browser. You need a CSS snippet to show a new line.
A much better way is to use the CSS to control the display style: add a style for the validation field in your *.css file:
span.field-validation-error{
white-space: pre-line;
}
And change the csharp code to use a \n as separator:
foreach (var error in errors)
descriptions += error.Description + "\n";
Demo :
Related
I'm trying to parse an html page:
url: https://dzone.com/articles/2-entity-framework-alternatives-or-give-me-data
html: read url
parse html [
to {<h1 class="article-title" itemprop="headline">}
thru {<h1 class="article-title" itemprop="headli
ne">}copy title to {</h1>}
]
probe title
Can't see why it doesn't work since I get error "title has no value"
I assume that you're using Rebol/view since the free versions don't do https though rebol3 does.
If you want to see if something is working you should look at the return value of the parse, and you'll see it's false which means that there's a problem with your parse rule. Anyway, this works for me though the quotes around the tags are not necessary as < and > are both string delimiters.
>> parse html [
thru <h1 class="article-title" itemprop="headline">
thru <h1 class="article-title" itemprop="headline">
copy title to </h1> to end
]
== true
>> trim/head/tail title
== "2 Entity Framework Alternatives (or Give Me Data!)"
It does not work most probably because the first to stops before the matched string, so that thru starts at the beginning of the first occurence of <h1 ...>, not at the second as you might have expected. You need to skip the first occurrence, before trying to search for the second one. You can achieve that using two thru rules as shown in another answer, or just repeat the rule twice to avoid duplicating it:
parse html [
2 thru <h1 class="article-title" itemprop="headline">
copy title to </h1> to end
]
Notice the final to end rule, which will make parse return true if your rules succeed in reaching the end. The to end rule is a placeholder rule, as you do not care about what is following </h1>, but want to reach the end of the input anyway.
EDIT: Testing the code you submitted works fine from here unchanged. The editing of your question has actually fixed the cause of the error. I can reproduce your issue with your original code.
I'm using docx4j to convert a Word template to several HTML files, one per chapter.
The Word template has several custom properties mapped by several fields (DOCPROPERTY ...) represented as both simple and complex fields. I populate those properties to obtain Freemarker code when the word document is converted to HTML (like ${...} or [#... /] directives).
In a later step I look for "heading 1" paragraphs to identify chapters and then split the document in several Word documents before conversion, then these documents are converted to HTML and written to temporary files.
Each document is successfully converted to HTML and fields are correctly replaced with my markers, but it behaves wrong when it writes header and footer parts: field codes are written before field values (eg. DOCPROPERTY "PROPERTY_NAME" \* MERGEFORMAT ${constants['PROPERTY_NAME']} ) instead of field values only (eg. ${constants['PROPERTY_NAME']} ).
If I write the updated document to a docx file instead, nothing seems wrong into the generated document.
If it's useful to solve the problem, this is what I do to split the document (per chapter):
clone the updated WordprocessingMLPackage (clone method)
delete every root element before the chapter's "heading 1" element
delete every root element from the "heading 1" element of the next chapter
convert the cloned and cleaned document
(actually I don't use the clone method every time, but I write the updated document to a ByteArrayOutputStream and then read it for every chapter, inspired by the source of the clone method).
I suspect it's for a docx4j bug, did anybody else try something similar?
Finally these are my platform details:
JDK 1.6
Docx4J v3.2.2
Thanks in advance for any help
EDIT
To produce freemarker markers in place of Word fields, I set document property values as follows:
traverse the document looking for simple or complex fields with new TraversalUtil(wordMLPackage.getMainDocumentPart().getContent(), visitor);, where visitor is my custom callback for looking for fields and set properties
traversing the document I look for
FldChar elements with type BEGIN and parse them using FieldsPreprocessor.canonicalise((P) ((R) fc.getParent()).getParent(), fields); (I don't use the return value of canonicalise) where fc is the found FldChar and fields is a empty ArrayList<FieldRef>; then I extract and parse field's instrText attribute
CTSimpleField elements and parse them using FldSimpleModel fldSimpleModel = new FldSimpleModel(); fldSimpleModel.build((CTSimpleField) o, null);; then I use fldSimpleModel.getFldArgument() to get the property name
I look for the freemarker code to show in place of the current field and set it as property value using wordMLPackage.getDocPropsCustomPart().setProperty(propertyName, finalValue);
finally I do the same from step 1 for headers and footers as follows:
List<Relationship> rels = wordMLPackage.getMainDocumentPart().getRelationshipsPart().getRelationships().getRelationship();
for (Relationship rel : rels) {
Part p = wordMLPackage.getMainDocumentPart().getRelationshipsPart().getPart(rel);
if (p == null) {
continue;
}
if (p instanceof ContentAccessor) {
new TraversalUtil(((ContentAccessor) p).getContent(), visitor);
}
}
Finally I update fields as follows
FieldUpdater updater = new FieldUpdater(wordMLPackage);
try {
updater.update(true);
} catch (Docx4JException ex) {
Logger.getLogger(WorkerDocx4J.class.getName()).log(Level.SEVERE, null, ex);
}
After filling all field properties, I clone the document as previously described and convert filtered cloned instances using
HTMLSettings settings = Docx4J.createHTMLSettings();
settings.setWmlPackage(wordDoc);
settings.setImageHandler(new InlineImageHandler(myDataModel));
Docx4jProperties.setProperty("docx4j.Convert.Out.HTML.OutputMethodXML", true);
ByteArrayOutputStream os = new ByteArrayOutputStream();
os.write("[#ftl]\r\n".getBytes("UTF-8"));
Docx4J.toHTML(settings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
String template = new String(os.toByteArray(), "UTF-8");
then I obtain in template variable the resulting freemarker template.
The following XML is the content of footer1.xml part of the document generated after updating the document properties as described: footer1.xml after field updates
The very strange thing (in my opinion) is that if some properties are not found, step 5 throws an Exception (ok), fields updating stops at the wrong field (ok) and all fields in header and footer are rendered right. In this case, this is the content for footer1.xml.
In the last case, fields are defined in a different way. I think the HTML converter handles well the last case and does something wrong in the first one.
Is there something I do wrong or I can do better?
I have a set of documents and each document has different heading. Example if document heading says "Psychological Evaluation" I want to tag the document as "Medicalrule".
I loaded the document and loaded ANNIE with defaults.
In Processing Resources > New > Jape Transducer
2.1 wrote the following code in the text document and saved it as .JAPE extension
CODE :
Phase: ConjunctionIdentifier
Input: Token Split
Rule: Medicalrule
(
({Token.string=="Psychological"})+({Token.string == " "})+ ({Token.string == "Evaluation"}):Meddoc({Token.kind=="word"})
)
-->
:Meddoc
{
gate.AnnotationSet matchedAnns= (gate.AnnotationSet) bindings.get("Meddoc"); gate.FeatureMap newFeatures= Factory.newFeatureMap();newFeatures.put("rule","Medicalrule");annotations.add(matchedAnns.firstNode(),matchedAnns.lastNode(),"CC", newFeatures);
}
Loaded the above created .JAPE file and reinitialized
After the application is run the Annotation Set does not show the tag !
Am I doing wrong somewhere ?It would be great if someone could help me on this.
Appreciate your time.
Thank you
I'm sure that there is no annotation like: Token.string == " ". Try to use a SpaceToken annotation instead.
Also, why not to try gazetteers instead of hardcoding of texts values in to JAPE code?
There are three issues I can see here.
First, as ashingel says, spaces are not represented as Token annotations - this is deliberate as in most cases you don't care about the spacing between words, only the words themselves.
Second, the trailing ({Token.kind=="word"}) means that the rule will only match when "Psychological Evaluation" is followed by another word before the end of the current sentence (because you've got Split in the Input line).
Third, you're only binding the Meddoc label to the "Evaluation" token, not to the whole match.
I would try and simplify the LHS of the rule:
Phase: ConjunctionIdentifier
Input: Token Split
Rule: Medicalrule
(
{Token.string=="Psychological"}
{Token.string == "Evaluation"}
):meddoc
and for the RHS (a) you don't need to do the explicit bindings.get because you've used a labelled block so you already have the bound annots available, (b) you should use outputAS instead of annotations, and (c) you should generally avoid the add method that takes nodes, as it isn't safe if the input and output annotation sets are different. If you're using a recent snapshot of GATE then the gate.Utils static methods can help you a lot here
:meddoc {
Utils.addAnn(outputAS, meddocAnnots,"CC",
Utils.featureMap("rule","Medicalrule"));
}
If you're using 7.1 or earlier then the addAnn method isn't available so it's slightly more convoluted:
:meddoc {
try {
outputAS.add(Utils.start(meddocAnnots), Utils.end(meddocAnnots),"CC",
Utils.featureMap("rule","Medicalrule"));
} catch(InvalidOffsetException e) { // can't happen, but won't compile without
throw new JapeException(e);
}
}
Finally, just to check, you did definitely add your new JAPE Transducer PR to the end of the pipeline?
I'm using Rails 3.2, Rspec 2 and capybara 2.
I am truncating a string of body text in my webpage and would like to test this in my feature spec.
Can someone advise how to do this because I can't seem to call truncate in my test because it keeps saying it's an undefined method and I don't really want to have a long string of truncated text in my test suite; just applying the truncate function is good enough.
I've tried using helper.truncate(), view.truncate() but to no avail.
I've used the Faker gem in other parts of my tests if there's a way to generate a lorem ipsum string and truncate it to compare against somehow.
View code:
<dd><%= truncate(project.details, :length => 100) %></dd>`
Test code
it { should have_selector('dd', #project.details) }
This test test worked fine when I was showing the full details text but because I've decided to only show the first 100 characters in this view I'm not sure how to test for this without having to set the details as a fixed string and then check for a truncated version of it somehow.
Thanks
Col
truncate is a Rails extension to the String class and, as such, is not available in Ruby or RSpec. There may be way to "include" it in some fashion, but I'm familiar with how to do that. It turns out that the definition is self-contained, however, so defining it yourself is straightforward. Here is the source taken from http://apidock.com/rails/String/truncate. It's defined to an instance method, so if you want to use it with a string that's passed in, you'd need to include a text parameter in lieu of referencing self as is currently done in the first line of the body.
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 38
def truncate(length, options = {})
text = self.dup
options[:omission] ||= "..."
length_with_room_for_omission = length - options[:omission].mb_chars.length
chars = text.mb_chars
stop = options[:separator] ?
(chars.rindex(options[:separator].mb_chars, length_with_room_for_omission) || length_with_room_for_omission) : length_with_room_for_omission
(chars.length > length ? chars[0...stop] + options[:omission] : text).to_s
end
This works for me :)
require 'active_support/core_ext/string/filters'
it { should have_selector('dd', #project.details.truncate(100)) }
In the end I decided that if the page was being viewed on a larger screen then the wider column would allow more of the details to be shown and reduce the need for truncating the text so I decided to trim the details using css instead to reduce what was shown onscreen using the following:
.text-trim {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
I have a dojo editor on a jsp page. The dojo editor is one of the required fields and i have a validation in place for it. There is a scenario in which some tags are getting appended. I cannot find a particular pattern when it gets appended but most of the times it occurs after one selects and copies all the content and pastes on the editor. So the editor content in this case was
<div id="dijitEditorBody">content which user entered</div>
Issue: When the user deletes all content which was entered the tags are still there and get submitted. In this case atleast visually editor has no content but the field holds the following value:
<div id="dijitEditorBody"></div>
or
<div id="dijitEditorBody"><br /></div>
So it skips validation and displays an empty editor when data is retrieved from DB?
I am confused about why these tags are getting appended?
In RichText.js, this snippet :
if(dojo.isIE || dojo.isWebKit || (!this.height && !dojo.isMoz)){
// In auto-expand mode, need a wrapper div for AlwaysShowToolbar plugin to correctly
// expand/contract the editor as the content changes.
html = "<div id='dijitEditorBody'></div>";
setBodyId = false;
}else if(dojo.isMoz){
// workaround bug where can't select then delete text (until user types something
// into the editor)... and/or issue where typing doesn't erase selected text
this._cursorToStart = true;
html = " ";
}
Explains the reason why that tag is added...
Although you see it in your alertbox, I believe it's not present in the posted contents... right ?
The editor should take care of removing the extra-tags => not tested but pretty sure...