How do I check the Html.ValidationSummary for errors? - html

I am writing an mvc web app and I'm trying to check to see if there are any errors in the Html.ValidationSummary to determine if I need to display the div that handles the messages.
#if(Html.ValidationSummary() != null)
{
<div class="registration-val-summary">
<label class="registration-val-label">
Please correct the following issues with your registration:
</label>
#Html.ValidationSummary()
</div>
}
This is the error that I receive:
Unexpected "if" keyword after "#" character. Once inside code, you do
not need to prefix constructs like "if" with "#".
From what I read in this post: Unexpected "foreach" keyword after "#" character It is due to the "Html" that I have inside my code. I understand the error but I do not know how to get around it. I want to avoid displaying the div that wraps the ValidationSummary unless there are actually errors to display otherwise the message about correcting your error shows up and displaces my form.
How do I hide this if ValidationSummary has no messages to display?

You are recieving that error because you are rendering the partial view rasor code from Html.ValidationSummary() into your if statement. The compiler then sees any # symbols the validationSummary renders and fails.
A simple check to see if there are validation errors is to do #if(!ViewData.ModelState.IsValid)
#if(!ViewData.ModelState.IsValid)
{
<div class="registration-val-summary">
<label class="registration-val-label">
Please correct the following issues with your registration:
</label>
#Html.ValidationSummary()
</div>
}

Html.ValidationSummary() is displayed IF and ONLY IF there validation errors on the page.
What you are trying to do is already achieved by the Html.ValidationSummary() helper and it returns an HTML div element that contains an unordered list of all validation error messages from the model-state dictionary [Source]
Html.ValidationSummary() renders a partial view, but you can customize/extend the view by following this answer
In your case, you might want to put the following code inside the customized view that you will create
<div class="registration-val-summary">
<label class="registration-val-label">
Please correct the following issues with your registration:
</label>
</div>

Related

With use PathVariable CSS not loading and how to fill form to update in thymeleaf

I am trying to do same small service and sometimes I am sending requests to my Rest Api.
I am getting two problems:
How to fill field in form in html using thymeleaf? I have form like this and would like to fill fields with current values (th:value="${}" - not working for me):
<form th:action="#{/offences/edit}" method="post" th:object="${createOffenceForm}"> <input th:field="*{name}" th:value="${currentOffence.name}"/> <input th:field="*{penaltyPoints}" th:value="${currentOffence.penaltyPoints}"/> <input th:field="*{amountOfFine}" th:value="${currentOffence.amountOfFine}"/> <button type="submit">UPDATE</button> </form>
The problem is with loading css styles to html when I redirect to the site with path variable. For example i created html with two buttons. First one is hardcoded:
<a th:href="#{/offences/test}" class="link" style="text-decoration: none"><button class="buttonOK" type="submit">EDIT</button></a>
after redirect my site looks like this (everything works, it should be like that):
`
and here is after second button - redirect with path variable:
<a th:href="#{'/offences/edit/' + ${offence.id}}" class="link" style="text-decoration: none"><button class="buttonOK" type="submit">EDIT</button></a>
and view after load:
For the issue with your form data not being filled, this is because th:field and th:value are not meant to be used at the same time. So th:field ends up overwriting you value.
In your case I would suggest either manualy setting name (and id) or replacing th:object with the a filled version of the bean you want to return and only using th:field
As for the second issue it looks like a faulty fragment return on a post call to me but need to atleast have the controller functions and more complete html to say anything about that. And in general it's advisable to have 1 question per problem and not bundle things.
Ok so i found soultion.
To fill fields in form I only had to add to ModelMap form with fields.
Something like this and thymeleaf autofilled fields in html.
modelMap.addAttribute("createOffenceForm", new CreateOffenceForm(offenceDTO.getName(), offenceDTO.getPenaltyPoints(), offenceDTO.getAmountOfFine()));
Second solution is simple too. When changed mapping in Controller from #GetMapping("/path/{id}") to #GetMapping("/path-{id}") - everything works. There is no other problems with styles...

unable to find multiple existing element with selenium

here is the html code of the Links i am trying to click on (i dont know why selenium cant locate the link. My guess is, that there are X amounts of the link. The only difference is the string in the brackets of onclick.) Underneath i'll show you 2 examples of the html code. I'd like to click on all of them (in this case on both)!
Button or Link:
<td class="text-right">
Ansehen</td>
Button or Link:
<td class="text-right">
Ansehen</td>
here are my Attempts to click on the button:
driver.find_element_by_link_text("doRetrievePnr('DUA75J')").click()
driver.find_element_by_xpath("//a[#onclick='doRetrievePnr('DUA75J')']").click()
Here are the Errors i get:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"link text","selector":"doRetrievePnr('DUA75J')"}
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression //a[#onclick='doRetrievePnr('DUA75J')'] because of the following error: SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//a[#onclick='doRetrievePnr('DUA75J')']' is not a valid XPath expression.
am I missing out on something?
EDIT
Heres a picture of the BUTTONS, the HTML CODE and my PYTHON CODE (lines 34 & 35)
As mentioned in the comments - getting all the items of a specific identifier can be done with find_elements_by_... (note find elements - it's plural)
That returns an array you can iterate through to interact with each element.
It looks like all your links have the same ID.
Something like this might work:
links = driver.find_elements_by_id('viewPnr')
for link in links:
link.click()
time.sleep(10) #replace this with what you want to do
Obviously if you're clicking links and the page changes this might not work after the first iteration. However, this is the concept on how you can get all objects and iterate through them.

In an Angular page containing custom components, how should I make sure all IDs are unique to get rid of the warnings?

I have a custom component for text input and each of them has an internal field ID'ed as data. It causes the warning below to appear.
[DOM] Found 13 elements with non-unique id #data
I'm clear on why it happens and I understand that's a warning not an actual error. I also recognize the appropriateness of an ID being unique (in its scope).
I'm not entirely sure regarding the implications in my particular case. In my opinion, warnings are tolerable but not acceptable.
Is there a best-practice approach to get rid of the error? By the very concept of a GP component, some parts will be alike in each instance. Or is there a trick to unique'fy the IDs? Or perhaps a directive or such to let Angular know we're cool with the state as is?
The component uses #ViewChild("data") to refer the input control in the template below.
<div id="outer">
...
<label for="data">{{label}}</label>
<input #data id="data" ... >
<div *ngFor="let error of errors" class="row"> ... </div>
</div>
As far as I understand the purpose of using ids is querying it inside of Angular. You could use a directive or another attribute to query without any warnings. Also you could make a kind of wrapper which would apply common ID to input and its label and just concat UUID and ID you want to use. But if it's only about querying just choose another attribute. For example data-id or data-qa whatever gives you an ability to query and have no errors at the same time. Just in case #ViewChild("data") refers to #data and not id="data" whilst you may wrap input with label tag.

How to make Symfony/Bootstrap checkbox errors display outside of the form_widget?

I'm not sure how I explain this... :)
I am using symfony, twig and bootstrap to make a basic registration form on my website.
I have a checkbox at the end which the user must tick to accept the terms and conditions. the label for this checkbox includes HTML (the tag) which Bootstrap (or Twig) escapes, so I have to use a custom label next to the checkbox:
<div class="row align-items-center"> <!-- this is a workaround, may not be best practise -->
{{ form_errors(form.acceptTerms) }}
{{ form_widget(form.acceptTerms, { 'attr': {'form.acceptTerms.errors': ' '} }) }}
<label class="form-check-label" for="acceptTerms">I have read and accepted the Terms and Conditions</label>
</div>
Bootstrap renders the label as part of the form_widget twig element rather than the form_label , and the form_error is also rendered within the form_widget when there is an error. So, before, my label would just be displayed in plaintext, i.e. the html <a> tags would be visible to the user. But of course, since I am showing a custom label as well as the widget which includes the label, I have to set the widget label to ' ' (empty string) so now only one label is shown.
This work perfectly, UNTIL there is an error (i.e. the user doesn't tick the box and thus cannot register).
Then the error displays within the form_widget which is next to my custom label (they are in a bootstrap row div) and it ends up pushing my label to the right, when I want the error to be above the label. I tried adding {{form_errors(form.acceptTerms) }} above it as you can see, but that just displays the error BOTH above and next to the label. This is what it looks like with the above code in place:
ERROR you must accept the terms and conditions!
[ ] ERROR you must accept the terms and conditions!I Accept the **Terms and Conditions**
then this is what I WANT it to look like:
ERROR you must accept the terms and conditions!
[ ] I accept the **Terms and Conditions**
This seems like it should be a really easy thing to do, I don't know why its this difficult.
I need to somehow stop bootstrap from rendering the form_error and form_label within the form_widget .
Thanks
In Symfony 4.1 the bootstrap form theme was updated to be compliant with the WCAG 2.0 standard. As a result, the error for a field is no longer displayed with form_errors but within your form_label. If you separate your widget and label you will notice.
More information about this change can be found here.
In order to fix your problem just get rid of form_error (you don't need it any more) and only use form_label and form_widget. If that doesn't satisfy your needs or if you do not like the new behaviour for bootstrap 4 forms in symfony 4.1, you can always use an older form theme, or create your own.
If you decide to create your own form theme make sure to update the file twig.yaml file to something like this:
twig:
form_themes:
- form/custom_form_theme.html.twig
In this case, your custom form theme is strored in templates/form/custom_form_theme.html.twig

how put a html args in a message of grails?

I wish to insert into message a line like "view.mail.warning". It contains a html code, but using encodeAs="html", the message shows a href ... too and does not show a link. What is the correct way for do these things?. I don't want to insert the message in parts :(.
In a gsp:
<"p style='color:#ddd; font-size:12px; text-align:center;'> <"g:message code="view.mail.warning" encodeAs="html>
In message.properties:
<"view.mail.warning= textPart1 <"a href=['http://page.com']> <"g:message code="view.pageName"/> textPart2 <"a href='mailto:support#page.com'">'support#page.com' textPart3
The correct way /is/ to insert it in parts. However, if you /must/ include html in your properties file you can. What you can not include there however, is GSP/taglibs. Your call to g:message will never be parsed/executed. Messages from the resources are just strings. The following are perfectly valid:
messages.proprties
view.mail.warning=<p>I {0} do html in here!</p><em>But I {1} shouldn't.</em>
GSP
<g:message code="view.mail.warning" args="['can', 'really']" />
Output
<p>I can do html in here!</p><em>But I really shouldn't.</em>
A few things to note about this. As you can see you can pass arguments to your message codes. They are ordinal, and start a zero. This way you can tokenize your message and even pass values from your GSP to your messages.
This is the correct way to use message resource bundles in Grails.
For example:
message.properties
view.mail.warning= >p>I can do html in here!>/p> >p>But I really shouldn't.>/p>
GSP
Output
I can do html in here!>/p> >p>But I really shouldn't.
i want insert into message properties, message with strings+html