thymeleaf Property or field cannot be found on null - thymeleaf

if ${object} is null, then its items visited by *{item} would cause:
org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'item' cannot be found on null
So how to solve this and I want to have the div structure remained, like in the following example, when currentUser is null, div containing city and name remains.
<div class="form" th:object="${currentUser}">
<div class="form-group form-group-sm">
<label>city:</label>
<span id="details_city" th:text="*{address == null ? '' : address.city}">Hongkong</span>
</div>
<div class="form-group form-group-sm">
<label>name:</label>
<span id="details_username" th:text="*{name}">Jane</span>
</div>
</div>

I've seen such a situation in a project (but not a spring project). The approach was that all users, even anonymous (not authenticated), were represented by a User (e.g. or CurrentUser) instance. This instance was mostly empty for anonymous users. The idea was to get rid of null checks. There was a dedicated method in the User class that answered if the represented user is authenticated or not. IMO the approach worked decently in the context of the technology stack that was used.
If feasible in for your project you may also try the idea. You may create an empty currentUser instance for anonymous users. Then currentUser will never be null. But if you use spring security + thymeleaf security dialect you may use thymeleaf to determine if the user is anonymous if this is necessary. E.g. a sample logout link visible for logged in users only may be rendered like this:
<li sec:authorize="isAuthenticated()">
<a href="#" class="log-out-link">
<i class="fa fa-sign-out"></i> Log out
</a>
</li>
A #ControllerAdvice and #ModelAttribute may push the user representation in all relevant views. Alternatively you may provide a separate, empty user in the view and use something like th:object="${#objects.nullSafe(currentUser,emptyUser)}"
If this is too much then do not use the th:object and add some extra checks.

In my opinion, you've got two options:
Pass an object instance anyway (with null values for the fields) or
Duplicate your div structure, one with th:if="${object != null}" and one with th:if="${object == null}

Related

adding tooltip to zendesk home_page.hbs

I want to add tooltips for some "Categories" box in Zendesk, so when the user hang over one box then I can show a tooltip with more information about the "Category".
Problem is that I'm trying to use IF statement like this:
{{#if href == '/hc/en-us/categories/360001117812-Cow-Traffic' }}
{{#each categories}}
{{#if ../has_multiple_categories}}
<li class="blocks-item">
<a href='{{url}}' class="blocks-item-link">
{{#if href == 'url_to_compare' }}
<a class="tooltiptext">tooltip_text</a>
{{/if}}
<span class="blocks-item-title">{{name}}</span>
<span class="blocks-item-description">{{excerpt description}}</span>
As this IF is inside of a {{#if}} of the categories I want to select in this example only one link using the href to see if the mouse is over or not the box.
I already tried to add a helper in the script.js file but looks like it's not working, I remember that there was a way to use this IF and IS to be able to solve it.
Thanks!
I get a lot of help on this, at the end I found that the better way to solve this is using a {{#is}} statement, So it's possible to use {{#is name "Category Name"}} {{/is}}
And this option will do a comparation between the name of the Category and the name you are looking for, if the value it's equal then you can do something inside, if not then you can use an {{else}} between and do another thing over there.
{{#is name "Category Name"}}
<div class="tooltip1">{{name}}<span class="tooltiptext">{{excerpt description}}</span></div>
{{else}}
<span class="blocks-item-title">{{name}}</span>
{{/is}}
I used the "Excerpt description" to add the value of the tooltip inside Zendesk, and no need to add it manually in the home_page.hbs code.
I added 3 different tooltips and working fine now. Thank you all!

Tempdata becomes null after redirect to another page

When the user successfully login, i'm storing the username in tempdata so i can use it in my _Layout:
TempData["username"] = model.Email.Split('#')[0];
TempData.Keep("username");
on my _Layout:
<li class="nav-item">
<h5 style="color:white"> Welcome, #TempData["username"]</h5>
</li>
this actually works on the first load, but if I go to another page, the tempdata turns to null and no username is displaying. How can i keep the username on my _layout?
Username displaying
Username not display
Tempdata keep method work only for next request. If you want to store data in over all pages. Use MVC identity principal methodology to persist data overall page. Iprincipal
If you've recently changed your authentication to azure Ad and your application is load balanced. Please make sure, you've updated the load balancer to use sticky session. Without a sticky session, the response can come from any server which can result in null temp data.
TempData is designed to have a life span only in between the current and the next request. You'd have to re-store it on every request (or call .Keep()) to make it available on the subsequent request.
You would be better of using a Session object or retrieving it from your user identity.
However you can "keep" your TempData object, if you call .Keep() after calling it (displaying counts towards calling).
<li class="nav-item">
<h5 style="color:white"> Welcome, #TempData["username"]</h5>
#TempData.Keep("username")
</li>
Yet another way to circumvent this, is to use .Peek():
<li class="nav-item">
<h5 style="color:white"> Welcome, #TempData.Peek("username").ToString()</h5>
</li>

Is ASP.NET MVC's Checkbox Implementation Accessible / Screen Reader-Friendly?

If you've ever looked at what ASP.NET MVC actually renders when you use #Html.CheckBoxFor, then you've seen that each checkbox you request to be rendered actually results in the emission of not one but two input tags. One is the "true" value checkbox, and the other is for "false." The latter input is of type "hidden".
Generally this doesn't cause problems if you're using ASP.NET MVC correctly. You wouldn't notice the input doubling unless you tried to, for example, do something directly with Request.Form(e.g. Why does ASP.NET MVC Html.CheckBox output two INPUTs with the same name?)
My question, though, is how screen readers deal with this. For example, can they be relied upon to correctly report only the visible checkbox to the site user?
Screen readers will ignore hidden inputs.
Given the example you cite in your comment, it returns this code:
<div class="col pure-u-xl-1-3 pure-u-lg-1-3 pure-u-md-1 pure-u-sm-1 pure-u-xs-1">
<label>Home Club Newsletter</label>
<input checked="checked" … id="newsletter" name="JoinHomeClub" type="checkbox" value="true">
<input name="JoinHomeClub" type="hidden" value="false">
<span class="checkbox-label">Yes, please sign me Up!</span>
</div>
Right off the bat there is a problem here because the <label> is not associated with the control, and the visible text that is next to the checkbox is not associated with the field.
When I access the field in NVDA, all it says is "checkbox checked". There is no accessible name at all.
But to your question…
Your question was related to the <input type="hidden">. As #SLaks said, screen readers ignore <input type="hidden">. The fact that they have the same name value is no problem. If they had the same id value, then you would have a problem (how it would manifest in a screen reader depends on things and stuff).

Adobe DTM: Event based rule to track form submission

I am trying to track form submission for a form using event based rule in DTM. I know that the ideal way to do it is to do via direct call rule but need to track the form fields as well through a data element and then into an eVar.
The form code looks something like this on the page:
<div style='display:none'>
<div id="popupform">
<div class="form_container">
<img src="/images/New-Offer-Pop-Up-Without-form_18-Jan-16.jpg" style="width: 100%;">
<form class="offerform" accept-charset="UTF-8" action="/site/sendtohs">
<div class="formrow"><input type="text" name="popup_fullname" class="new-input1 required" placeholder="Name" /></div>
<div class="formrow"><input type="email" name="popup_email" class="new-input1 required" placeholder="Email" /></div>
<div class="formrow"><input type="number" name="popup_phone" class="new-input1 required" placeholder="Mobile"
minlength="10" maxlength="15" /></div>
<input type="hidden" name="popup_url" value="/" /></br>
<p align="right"><input class="tbn newtbn" type="submit" name="submit" value="Submit" /></p>
</form>
</div>
<div class="offerform_success" style="display: none">
<img src="/images/Thank-you-pop-up-new-xyz.jpg" style="height: 440px; width: 100%; position: absolute;width: 99%;">
</div>
</div>
</div>
The even based rule in DTM is :
DTM Rule
The event fires when I click on the Submit button but the rule does not validates if the form fields have been filled or not. Any hints how can I add validation to the form submit event within DTM.
Targeting the form
Firstly, based on your screenshot vs. posted code, your event will not trigger because the form tag does not have an id attribute of "popupform" (or any id attribute at all) (You do have that as an id in a parent div, but that's not what you are targeting). So, you will need to remove that.
If you only want to target the form if it's within a div, then you will need to add it as a Rule Condition. Under Rule Conditions > Criteria, choose "Data > Custom", and click Add Criteria.
In the code box, add the following:
if ($(this).parents('#popupform').length)
return true;
return false;
Note: I'm using jQuery syntax here for brevity and easy cross-browser compatibility. The overall goal is this references the targeted form, and you want to check that it is within an html element with the popupform id. The jQuery above traverses up the form's ancestor chain to look for it. If it finds it, we return true. Otherwise we return false. Ultimately, custom rule conditions should return true if you want it to pass, or false if not. Also note that if you have multiple rule conditions (which you will; see below), all conditions must return true in order for the rule to trigger. If your site does not use jQuery or you do not want to use jQuery for this, then you will need to write your own code following the above concept.
Validating the form fields
Before I get into this, one thing I should note is in general you should not rely on client-side form validation for your forms. It is super easy to disable/get around it. You should be doing form validation with server-side code when the form is submitted, and then pop whatever you need to pop (form complete tracking or w/e) after it has been server-side validated.
Maybe you already have server-side validation in place but for whatever reason you can't control popping a dtm rule after validation, and this is your next best thing. Well hopefully the only thing you are doing is popping tracking and not using the dtm rule for actual site functionality, but even then, just want you to be aware that this is a "lesser evil" solution, not a "good" solution.
Having said that, you can again turn to a custom condition to make sure all the form fields are filled out. Here is a quick and dirty custom rule condition to demonstrate. Again, under Rule Conditions > Criteria, choose "Data > Custom", and click Add Criteria (so you will now have another custom code box). Add the following:
var isFieldsFilled=true;
$.each($(this).serializeArray(),function(i,v) {
if (!v.value||v.value=='')
isFieldsFilled=false;
});
return isFieldsFilled;
This code again uses jQuery to grab the form fields of the targeted form and loops through them and sets a flag to false if one is found not to have a value. Again, this is kind of quick and dirty and will work based on your current form example, but you may need to expand upon it in practice.

Use Bootstrap Navbar choice in controller?

All, I'm trying to use the Bootstrap Navbar user choice to control the filtering of posts shown to the user.
The model includes an 'expired' field which is a date-time type.
Three choices are: All (no filtering), Open (show only open issues) and Closed (show closed).
Is there a way to do this without defining three different index.html.erb variants (DRY problem). The filter should show only closed issues if #post.expired < Time.now .. etc.
Stated alternately - can controller 'know' what the user chose, although Navbar, as i am using it, is simply a fancy navigation toolbar?
Thanks for any advice.
Typically this is done by including a parameter in the request, and looking for that parameter in the controller. The bootstrap navbar uses regular anchor links so you should be able to add parameters easily to them (modified example from the doc):
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="/some_url">List</a>
<ul class="nav">
<li>All</li>
<li>Open</li>
<li>Closed</li>
</ul>
</div>
</div>
You can read the filter parameter in the controller by accessing the value of params[:filter].

Resources