I am trying to generate a html select element with one option preselected. I am unable to think of a way to do this with stringtemplate.
If user.choice is set to "B" then I want to print an html select element with option B preselected.
user.choice = "B";
StringTemplate myPage = group.getInstanceOf(....);
myPage.setAttribute("user", user);
on printing the template should generate:
<select>
<option value="A" >A Selected</option>
<option value="B" SELECTED >B Selected</option>
<option value="C" >C Selected</option>
<option value="D" >D Selected</option>
</select>
Can someone tell me how to write the template for doing this. The number of choices (A,B...) is fixed (known at time of writing template).
This is a pretty common requirement when generating html pages for websites. But nothing like a comparison operation for passed values seems to be available in stringtemplate. Am I missing something obvious?
I am using stringtemplate group (.stg) files so solutions that have templates referencing other templates are fine. Using stringtemplate 3.2.1 in java. Using "$" delimiter instead of the now default "<>" to make html generation easier.
StringTemplate enforces a very strict separation between your view and model. It doesn't support doing conditional operations on anything other than boolean values. I think the engine really wants you to have done the computation before you pass the data off to be rendered.
I'd suggest storing the value with the actual list items themselves. Say you already have a "value" and a "text" property on the "list" object (which are stored in your collection), you could add a selected boolean property to the list item as well. You could then use it as follows:
<select>
$list:{ l |
<option value=$l.value$ $if(l.selected)$selected="selected"$endif$>$l.text$</option>
}$
</select>
Related
I'm using Spring boot + thymeleaf and I'm trying to set the default value of a select element in order to show the selected object that is stored in database (edit form).
To do that, from the controller, I insert into the model the entity with its values, but, when I try to set the default value of the select, it always gets the first option.
This is the code:
<select class="selectpicker"
id="alarmPeriod" name="alarmPeriod"
th:selected="${alarm.alarmPeriod}"
th:value="${alarm.alarmPeriod}">
<option th:each="period:${periods}"
th:value="${period}" th:text="${period}">
</option></select>
I have tried with th:field="*{alarm.alarmPeriod}" but the thymeleaf processor crash.
How could I set the default value of the select with my stored entity value?
PD: alarm is my entity and alarmPeriod is an attribute of alarm.
selected is an attribute for the option tag. Since you're trying to mark one of the options as selected, you must add the th:selected attribute to your options, with an expression that will evaluate to true or false depending on your alarmPeriod.
The selected option should be put as an option like you would do with with an htnl select tag, the following piece of code should work
<select class="selectpicker"
id="alarmPeriod" name="alarmPeriod">
<option value="${alarm.alarmPeriod}" selected="selected">
${alarm.alarmPeriod}
</option>
<option th:each="period:${periods}"
th:value="${period}" th:text="${period}">
</option></select>
For legacy code support reasons, I need to create a select tag in struts 2 and also need the label attribute in the resulting option list to match the value. An example probably will explain it better.
The generated code should look something like this:
<select>
<option label="Darth Vader">Darth Vader</option>
<option label="Luke Skywalker">Luke Skywalker</option>
<!-- etc -->
</select>
My struts markup is as follows:
<s:select headerKey="-1" headerValue="" list="users" size="4" multiple="true"
tabindex="2" listKey="key" listValue="value"/>
The "users" collection is of type Map. Essentially, I want the value of each entry of the map to also be the label attribute for the option elements that struts creates. I've tried using the listLabelKey and label attributes provided by Strut's select tag with no luck. Is there an easy way to accomplish this that I'm just missing?
EDIT
I have some legacy javascript code that dynamically selects/unselects dropdown elements and relies on the label attribute on option being explicitly filled in. Using the listKey and listValue attributes simply generates the following HTML.
<select>
<option>Darth Vader</option>
<option>Luke Skywalker</option>
</select>
I have disabled=true textboxes and combox boxes in my jsp.
When I try to map those value back to action, they disappear.
I don't want to call to DB again.
How can I set those disabled=true textboxes and combo boxes's data value into hidden values?
Thanks ahead.
The property of disabled elements' value not being submitted with the form is not an issue with struts2, but an HTML behavior. To handle this behavior, use the following implementations:
Use readonly="readonly" attribute to prevent modification rather than using disabled. (This won't be available for few elements)
Use onfocus="return false" to prevent any focus on html elements. This will prevent the modification of their value. You can use CSS to make these elements look like readonly or disabled.
Before you disable an element, create a hidden element and attach the value of the element you are about to disable. This will make sure that the item gets submitted.
See the following implementation for select element. You may make use of the id attribute of s:select to set the html id of select element.
<select id="demoSelect" class="readonly">
<option value="0">A</option>
<option value="1">B</option>
<option value="2" selected="selected">C</option>
<option value="3">D</option>
<option value="4">E</option>
<option value="5">F</option>
</select>
<input type="hidden" value="2" name="demoSelectDefault"/>
jQuery:
$(document).ready(
function() {
$("select.readonly").live('change', function() { //live() makes sure that this is executed if you apply the class to the element even after the initial load. So, if you set the readonly class to a select element, you are done.
var selectElement = this;
$("input[type=hidden][name=" + this.id + "Default]").each( //This is implemented in case of multiple select support. You will need to select nothing at first and then make this select each of this element
function() {
selectElement.value = this.value;
}
);
});
}
);
Here, when you implement this using struts, populate the s:select, then use an s:hidden element to generate a corresponding default value.
How to pass a value from one dropdown to a second dropdown.
Example:
Template
#{select 'pl'}
#{list platforms, as: 'platform'}
#{option}${platform.description} #{/option}
#{/list}
#{/select}
#{select 'pl'}
#{list cdrs, as:'cdr'}
#{option}${cdr.description} #{/option}
#{/lisst}
#{/select}
If you mean using Javascript to "chain" two selects like Country/City, what I did was moving the code for the second select to its own view (e.g. Cities/selectCities.html)
#{select 'city', items: cities, valueProperty: 'id', labelProperty: 'name' /}
and use an include in the view where I'll have both chained selects
<select name="country" id="select-country">
<option value="ES">Spain</option>
<option value="US">United States</option>
</select>
<span id="select-city">
#{include 'Cities/selectCities.html' /}
</span>
now some javascript in that same view to reaload second select in case first select changes
$('#select-country').change(function() {
var selectAction = #{jsAction #reloadCities(':country') /};
$('#select-cities').load(selectAction({country: $(this).val()}));
});
and in the controller we have our reaload cities method rendering only the second select again
public static void reloadCities(String country) {
List<City> cities = City.find("byCountryCode", country).fetch();
render("#selectCities", cities);
}
and that's about it, for me it's working using play 1.2.5
Your question is not really clear but if I understand it right, you want to change a select depending on the value of the selected item in the first select. That is impossible as it is a runtime animation.
You will have to take a look at Ajax/Javascript in order to do things like that.
If you mean once is rendered in the browser, you must use Javascript.
Otherwise, use the value keyword as explained in the documentation (here)
This is a continuation of an issue I was having yesterday so if it looks familiar, thats why :) It IS a different question tho!
So I have another dijit.form.Select initially created on the page like so;
<c:set var="clazzId" value="${verification.clazz.id}" />
<div id="clazzOptions">
<select id="clazz" name="clazz" style="width:22em" dojoType="dijit.form.Select" maxHeight="140">
<option value="-1" label=" " />
<c:forEach items="${requestScope.clazzes}" var="clazzItem">
<c:choose>
<c:when test="${clazzId eq clazzItem.id}">
<option value="${clazzItem.id}" selected = "true">${clazzItem.name}</option>
</c:when>
<c:otherwise>
<option value="${clazzItem.id}">${clazzItem.name}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
</div>
I then have some javascript that I'm trying to use to swap the contents of the div "clazzOptions" depending on the value chosen from a different drop down (not seen here). If its a certain value, replace the div with a text message, if its any other value, re-show the original dijit.form.Select;
<script type="text/javascript">
var classDropDown;
var classPhDMessage = "PhD's do not require a Class or Grade";
dojo.addOnLoad(function() {
classDropDown = dojo.byId('clazzOptions').innerHTML;
});
function checkForPHD() {
var awardOption = dijit.byId('qualification').attr('displayedValue');
if(awardOption == "PhD"){
dojo.byId('clazzOptions').innerHTML = classPhDMessage;
} else {
dojo.byId('clazzOptions').innerHTML = classDropDown;
}
}
</script>
As you can see I'm trying to capture the innerHTMLof the div as it is when the page loads and then depending on the value chosen in the other drop down (not seen) change between a predefine message and the captured div contents.
The issue is that after the original div contents have been replaced with the message and then the selection changes again away from "PhD" and the original div innerHTML is placed back into the div, the dijit.form.Select re-appears but is completely empty and in fact doesn't appear usable at all? If I remove the dijit.form.Select dojoType and just leave it as a normal select this whole operation works perfectly but I kinda need it to be a dijit.form.Select.
Why won't dijit.form.Select work in this case whereas a normal select does?
You shouldn't use innerHTML to add/remove dijits, especially if you're trying to re-use them.
A dijit is a combination of HTML and Javascript and can be thought of as 'more complex' than simply the contents of a specific node.
You have a number of options:
Disable your dijit.form.Select and add a small note under it (or set it's value) explaining why it's disabled (this is generally a better UI paradigm than removing controls). Depending on your UI this is what I'd try and do
Create a <span> as a sibling of your dijit.form.Select and use CSS to show/hide one of them at a time.
Obviously you'll still get the value of the dijit.form.Select when you submit your form, but because you do server side validation as well as client side validation (I hope :) this won't be a problem
Use the dojo.data API to create a datastore from your "${requestScope.clazzes}" iterator. Use this store when you (programatically) create the dijit.form.Select. Keep track of the current value of said Select somewhere. When you don't need it, call yourSelect.destroy() to properly destroy it, then when you need it again create a new one and set it's value to the saved value from before.
This seems unnecessarily expensive to me tho.