add class for selected radio button in thymeleaf - thymeleaf

I am new to Thymeleaf. I am trying to add a class based on the selected radio button in a for loop.
<div class="btn-group" data-toggle="buttons">
<div th:remove="tag" th:each="obj : ${T(com.sab2i.esabplugin.model.NatureEnum).values()}" >
<label class="btn btn-primary" th:classappend ="...?'active'">
<input type="radio" autocomplete="off" th:field="*{nature}" th:value="${obj}" />
<span th:text="#{${obj.value}}">Radio</span>
</label>
</div>
</div>
what test should I be making to compare the value of "nature" against the value of loop variable "obj", in order to add the "active" class in th:classappend?
Thank you.

did you try th:classappend="(${obj} eq *{nature})? 'active'"
if *{nature} is a String try th:classappend="(${obj.name()} eq *{nature})? 'active'"

Related

bootstrap5 way of right aligning two buttons

I am using Bootstrap5 and wondering how to align two buttons to the right in the same column as the "Delete" button. Another problem is no matter which "breakpoint" (md, sm) I use it's not possible to right align these two buttons properly. I am wondering what is the bootstrap way of doing it.
Snippet
<form>
<div class="hx-form-group position-relative">
<label for="el62ba8cb87eb84be2bebc9c2970de0552" class="form-label">Goal #1</label><span class="input-group"><input id="el62ba8cb87eb84be2bebc9c2970de0552" type="text" class="form-control" placeholder="Enter goal #1 text here." _bl_6="">
<button type="button" class="hx-button btn btn-danger" _bl_7="">
Delete
</button>
</span>
<div class="form-text">Hint: enter short, precise description what you want to do today</div>
</div>
<div class="hx-form-group position-relative">
<label for="el28a7e89fc62249dd80048d65487a2354" class="form-label">Goal #2</label><span class="input-group"><input id="el28a7e89fc62249dd80048d65487a2354" type="text" class="form-control" placeholder="Enter goal #2 text here." _bl_8="">
<button type="button" class="hx-button btn btn-danger" _bl_9="">
Delete
</button>
</span>
<div class="form-text">Hint: enter short, precise description what you want to do today</div>
</div>
<div class="hx-form-group position-relative">
<label for="ele59dd34cf9ed4db2a92de894f47b5946" class="form-label">Goal #3</label><span class="input-group"><input id="ele59dd34cf9ed4db2a92de894f47b5946" type="text" class="form-control" placeholder="Enter goal #3 text here." _bl_10="">
<button type="button" class="hx-button btn btn-danger" _bl_11="">
Delete
</button>
</span>
<div class="form-text">Hint: enter short, precise description what you want to do today</div>
</div>
<div class="container text-center">
<div class="row justify-content-end">
<div class="col-4">
<button type="button" class="hx-button btn btn-secondary" _bl_4="" disabled="">
New Goal
</button>
</div>
<div class="col-4">
<button type="submit" class="hx-button btn btn-primary">
Save
</button>
</div>
</div>
</div>
</form>
First of all, you don't need to use row and col as a wrapper of buttons as row cols have different purposes so you can do it like this
[https://codepen.io/kukrati/pen/YzaYEXy]
and make sure you have removed its parent .container class
if you don't want to change your existing layout due to some limitations then you just need to replace .col-lg-4 with .col-auto and then remove the parent .container class

click event inside ngFor does Not work Angular 7

I am having the following Piece of Code:
<div class="custom-control custom-checkbox" *ngFor="let airline of airlines">
<input type="checkbox" (click)="airLineFilter($event)" value="{{airline}}" name="{{airline}}" class="custom-control-input">
<label class="custom-control-label" for="{{airline}}">{{airline}}</label>
</div>
When this was without *ngFor (click) event was working fine like this:
<div class="custom-control custom-checkbox">
<input type="checkbox" id="americanAir" (click)="airLineFilter($event)" value="American Airlines" name="airlines" class="custom-control-input">
<label class="custom-control-label" for="americanAir">American Airlines</label>
</div>
But after using *ngFor click event is not getting triggered. Is there something I can do to fix this.?
After going through many options I finally found the solution.
It is due to Id attribute of checkbox and for attribute of label.
When I changed my code to something like this it worked:
<div class="custom-control custom-checkbox" *ngFor="let airline of airlines;let i = $index;">
<input type="checkbox" id="airline{{i}}" (click)="airLineFilter($event)" value="{{airline}}" name="{{airline}}" class="custom-control-input">
<label class="custom-control-label" for="airline{{i}}">{{airline}}</label>
</div>

Accessing Map values in gsp page Grails using variables as key

I am trying to create multiple divs on the fly using a template which is called for a number of times and each time i create a new div ... which seems to be working fine below is the code. I am passing a map tempMap from the controller to the gsp page which is of the below format
tempMap = [key_1:v1,key_2:v2,key_3:v3] //from the controller
//this is the gsp part
<g:set var="counter" value="${1}" />
<g:while test="${counter <= tempMap.counter}">
<g:render template="travelDetailsToShow" />
<g:set var="counter" value="${counter + 1}" />
</g:while>
I need to set the ids of the elements based on the counter which also is working ... But i am unable to set the values of the fields.
<div class="col-sm-6" id="key_${counter}"> // This sets the id to key_1, key_2 depending on the counter value
<div class="form-group">
<label>Departure Date</label>
<span class="input-icon-right input-group">
<g:set var="temp" value="kep_${counter}" />
**<input type="text" name="key_${counter}" class="form-control" value="${tempMap?.key_${counter}}" readonly></input> // this does not work**
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</span>
</div>
</div>
I searched a lot but with no luck ... can anyone tell me where am i going wrong with this .. Any help is appreciated ... Thanks in advance people
The render tag has a model attribute. It works like the model passed from controller to view. You can use it to pass data into the template.
view
<g:each in="${1..tempMap.counter}" var="counter">
<g:set var="key" value="key_${counter}">
<g:render template="travelDetailsToShow" model="${[id: key, value: tempMap[key]]}"/>
</g:each>
template
<div class="col-sm-6" id="${id}">
<div class="form-group">
<label>Departure Date</label>
<span class="input-icon-right input-group">
<input type="text" name="${id}" class="form-control" value="${value}" readonly></input>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</span>
</div>
</div>
Thanks Emmanuel for your answer ... but i think i wasnt clear enough and misled you to think that the "key" would be static ... As your logic would expect the static value "key" ..... The proper structure of the map is below ...
tempMap = [key_1:v1,anotherkey_1:v2,yetanotherkey_1:v3,key_2:v4,anotherkey_2:v5,yetanotherkey_2:v6]
I havent tried out the solution posted by you but got another solution to work.... code for which is below ...
<div class="col-sm-6" id="key_${counter}">
<div class="form-group">
<label>Departure Date</label>
<span class="input-icon-right input-group">
<input type="text" name="key_${counter}" class="form-control" value='${tempMap?."${'key_' + counter}"}' readonly></input>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</span>
</div>
</div>
<div class="col-sm-6" id="anotherkey_${counter}">
<div class="form-group">
<label>Return Date</label>
<span class="input-icon-right input-group">
<input type="text" name="anotherkey_${counter}" class="form-control" value='${tempMap?."${'another_' + counter}"}' readonly></input>
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</span>
</div>
</div>
</div>
The problem was that i was not referencing the value in the Map properly... The code that fails is stated below.
<div class="col-sm-6" id="departureDate_${counter}">
<div class="form-group">
<label>Departure Date</label>
<span class="input-icon-right input-group">
**<input type="text" name="departureDate_${counter}" class="form-control" value="${tempMap?.${departureDate_counter}"} readonly></input>** // THIS CODE DOES NOT WORK. This will look for a key ${departureDate_counter} and will through a gsp error that tags have not been closed
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
</span>
</div>
</div>
Although i have found a solution to my problem it would be nice if we posted more solutions as i feel that not a lot of solutions are present on the net for grails and gsp ...

ng-model not working for certain attributes in angularJS

Hi I encountered a problem with ng-model. I want to create an edit page for admin user to edit the rest of the user's permission level.
So, I listed out all the user's attributes in the edit page, and these attributes should display the current values.
I can update all the attributes correctly, however, the problem is that when visiting the edit page, only certain attributes are displayed while some are not. I think it is the problem with ng-model.
code snippets from my _form.html.erb
<div class="col-md-12 space-1" ng-class="{ 'has-error' : form['email'].$invalid }">
<label class="control-label">Email</label>
<div class="input-icon right">
<i ng-show="form['email'].$invalid" class="fa fa-warning tooltips" data-original-title="{{errors['email']}}" data-container="body"></i>
<input ng-model= "user.email" name="email" type="text" class="form-control">
</div>
</div>
<br>
<div class="col-md-12 space-1" ng-class="{ 'has-error' : form['events'].$invalid }">
<label class="control-label">Event Permission Level : {{user.activities.events}}</label>
<div class="input-icon right">
<i ng-show="form['events'].$invalid" class="fa fa-warning tooltips" data-original-title="{{errors['events']}}" data-container="body"></i>
<input ng-model= "user.activities.events" name="activities.events" type="range" max="2" min="0" class="form-control">
</div>
</div>
<br>
<div class="col-md-12 space-1" ng-class="{ 'has-error' : form['admin_events'].$invalid }">
<label class="control-label">Admin Event Permission Level : {{user.activities.admin_events}}</label>
<div class="input-icon right">
<i ng-show="form['admin_events'].$invalid" class="fa fa-warning tooltips" data-original-title="{{errors['admin_events']}}" data-container="body"></i>
<input ng-model= "user.activities.admin_events" name="activities.admin_events" type="range" max="2" min="0" class="form-control">
</div>
</div>
<br>
The code above shows 3 different ng-models, 1.user.email, 2.user.activities.events 3.user.activities.admin_events
The way I process them is the same, but when visiting the edit page, only email and events attributes displayed the current value, but not admin_events. I can update their values alright, but I cannot get admin_events to display its current value when visiting the edit page. This is weird isn't it. I mean if I can see the value of events, why can't I see the value of admin_event since they all belong to the user variable.
Can anyone explain why is it like this? It is very confusing for me. Thank you very much.
As it solved the problem, I quote myself from the comments :
If only user.activities.admin_events is not working, it may be related to the _ notation. Try camel case user.activities.adminEvents or user.activities['admin_events'].

Bootstrap button group and form_for

In my Rails app I'd like to use a Bootstrap button group. There is a single field, and each button represents a different state .. ie like radio buttons.
Even better if I can do it with simple_form but can't find a solution by Googling.
<%= simple_form_for #user_word, url: user_words_path, remote: true, wrapper: :inline_form, html: { class: 'form-inline' } do |f| %>
<div class="row">
<div class="col-sm-12">
<div id="selector" class="btn-group btn-group-sm" >
<button class="btn level-unknown" id='unknown' type="button">Unknown</button>
<button class="btn level-low" id='low' type="button">Low</button>
<button class="btn level-medium active" id='medium' type="button">Medium</button>
<button class="btn level-high" id='high' type="button">High</button>
<button class="btn level-known" id='known' type="button">Known</button>
</div>
</div>
</div>
<% end %>
Not sure exactly what you're asking. If your issue is that the active class is not switching to your clicked button, it's because you need javascript to do so.
$('#selector button').on('click',
function(e){
var $obj=$(e.target);
$('#selector .active').removeClass('active'); //remove active class from buttons
$obj.addClass('active'); //add active class to clicked button
});
See a working example here https://jsfiddle.net/DTcHh/14519/
Edit:
I just learned that this functionality is built in to the bootstrap javascript library. Your markup just needs to be modified to match this syntax
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked> Radio 1 (preselected)
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2" autocomplete="off"> Radio 2
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3" autocomplete="off"> Radio 3
</label>
</div>
See example at http://getbootstrap.com/javascript/#buttons-checkbox-radio

Resources