How can I do: required="false" in grails g:select? - grails

required="false" does not work in "g:select" tag
Example:
<g:select from="${}" name="select" required="false" />
and
<g:select from="${}" name="select" required="true" />
produces a html tag required (in html5)
How can I make the "g:select" produces the required or not, dynamically?

Just remove required, for eg:
<g:select id="select" from="${}" name="select"/>
You can use jquery to change the g:select to be required or not required. For example, lets say you have another
<g:select id="yesNo" from="[yes, no]">
In the gsp, use javascript:
$( "#yesNo" ).change(function() {
if($(this)[0].value == "yes") {
$( "#select" ).attr('required', 'required')
}
else {
$( "#select" ).removeProp( "required" )
}
});
Another approach is if you pass a variable required to gsp, you can use <g:if>:
In controller:
[required: "true"] //If dont want required, simply don't return required at all
In gsp:
<g:if test="${required}">
<g:select from="${}" name="select" required/>
</g:if>
<g:else>
<g:select from="${}" name="select"/>
</g:else>

<g:select from="${}" name="select" required="${false/true}" />
should work !

Related

Problems with form gsp

I'm trying to send parameters from my form (gsp) to my controller grails, but doesn't work.
<g:form url="[action:'searchByFilter', controller:'invoice']" method="GET">
<p>Filtro de busca</p>
<g:textField name="search" value="${invoice?.search}" params="search : search"/>
<g:submitButton name="search" class="input-search" value="${message(code: 'default.button.search.filter')}" />
</g:form>
I need to send input's value to do a result's filter. But, input's value isn't sending.
My domain class code:
static namedQueries = {
getInvoicesByStatus {
eq 'deleted', false
}
getInvoicesByFilter {
eq 'description', Invoice.get(params.search)
}
}
What's my mistake? I need to use namedQuery :)

Tag "Select" in gsp

How to correctly use tag select in gsp while passing to it ArrayList<String> ? I know how to use it this my own composed objects, for example:
<g:select name="tablePlacesAvailable" from="${tableInfo}" optionValue="${{it.placesInTableAmount}}" optionKey="placesInTableAmount" value=""/>
But how to use it with built in objects, like String?
If you want to use a g:select with a list of String
<g:select name="selection" from="${values}" />
Where values is a collection of Strings. My controller code is
class DemoController {
def index() {
[values: ["This", "is", "a", "test"]]
}
}
Here are some tests and its results:
Controller:
Controller:
def index() {
def myList=['hello','world']
def myMap=['h':'hello','w':'world']
render view: 'index', model: [myList:myList,myMap:myMap]
}
gsp:
<g:form name="test" >
<g:select name="s1" from="${['lastUpdated', 'id']}" value="${sortby}" />
<g:select name="s2" from="${['lastUpdated', 'id']}"
optionKey="value" optionValue="value" value="${sortby}" />
<g:select name="g" from="${['90%':'90%','100%': '100%']}"
optionKey="key" optionValue="value" value="${params.g}" />
<g:select name="g2" from="${myList}" />
<g:select name="g3" from="${myMap}" />
<g:select name="g4" from="${myMap}" optionKey="key" optionValue="value"/>
<g:select name="g5" from="${myMap}" optionKey="key" optionValue="key"/>
<g:select name="g6" from="${myMap}" optionKey="value" optionValue="value"/>
<g:submitButton name="go" value="post"/>
</g:form>
Results:
[g:100%, s2:lastUpdated, s1:id, g2:world, g6:world, g5:w, g4:w,
go:post, g3:w=world, action:index, format:null, controller:test]
As you can see a Arraylist with no optionKey optionValue works by default, in s2 I have also physically defined key value to be value and it still works

Getting a value from g:select in Grails

I'm trying to create my own 'edit' form in my grails application.
My g:select is currently populated with stuff from my database and looks like this:
<g:select name="nameList" from="${Card.list()}" value="${name} " />
And then the value :
<g:field name="amount" type="number" value="" required=""/>
My domain has only two variables - name and amount. I want to select the item from the dropdown box, type in the amount and just click 'update', my update method is a default one generated by grails so it requires ID and Version, how would I go about passing it through?
My update button ;
<g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" />
My domain code:
package cardstorage
class Card {
String name;
int amount;
static constraints = {
name(blank:false);
amount(blank:false);
}
String toString(){
return name;
}
}
Thank you
I have fixed it but I'm sure it is not a proper way to do so.
<g:form method="post" >
<g:select name="card" from="${Card.list()}" optionValue ="name" optionKey="id" />
<g:field name="amount" type="number" value="" required=""/>
<fieldset class="buttons">
<g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" />
</fieldset>
</g:form>
thats my code for the g:select. In my Controller method, passing the value of 'card' to the 'Long id' would result in 'id' being 49 (null + 1 = 49?)
def update(Long id, Long version) {
id = params.card;
id = id- 48;
...
}
Now I'm able to update my records, however I'm curious how should I have done this more properly.

Indexed properties are getting duplicated struts2 on form submission

I need to add/edit/delete the table of objects in struts2. When I submit the form, I am getting objects duplicated.
Let me know where I made a mistake.
This is my code:
<s:form action="addPromotionLineItems" id="promotionLineItemsAddFormId">
<display:table id="data"
name="lstPromotionLineItems" sort="external" uid="row" htmlId="rowid"
class="tborder" excludedParams="*" style="width:100%" export="false">
<display:column titleKey="table.title.material" style="width:100px">
<s:property value="%{#attr.row.materialCode}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).promotionLineItemId"
value="%{#attr.row.promotionLineItemId}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).materialCode"
value="%{#attr.row.materialCode}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).material.description"
value="%{#attr.row.material.description}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).programId"
value="%{#attr.row.programId}" />
</display:column>
<display:column property="material.description"
titleKey="table.title.materialdesc" />
</s:form>
function refreshTableRecords(url,formNameId,resultId)
$.ajax({
type:'POST',
url: url,
data:$('#'+formNameId).serialize(),
success : function(response) {
$('#'+resultId).html(response);
},
error:function(data)
{
alert(data);
}
});
}
I have this content in jQuery ui modal popup.
I think when mapping to collection data in struts the syntax is not:
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).promotionLineItemId"
rather:
name="lstPromotionLineItems[%{#attr.row_rowNum-1}].promotionLineItemId"
There is a slight difference in the bracketing around the row_num attribute in the input name.

How to direct to submit button to another action

how can I jump to another action in controller?
I have form and several submit buttons. Every submmit button has name.
<g:form action="save" method="post">
<g:input name="title" value="${letter.title}" />
<g:input name="comments[0].text" value="${letter.comments[0].text}" />
<g:submitButton name="save" value="save" />
<g:submitButton name="addComment" value="add" />
</g:form>
def save = {
if (params.addComment){
letter.addToComents( new Comment() )
render(view:'form', model:["letter": letter])
return
}
...
if ( letter.save() )
...
}
def addComment = {
...
}
It works, but it is not good. I want move code from block "addComment" to action addComment:
def save = {
if (params.addComment){
// it donĀ“t work
redirect ( action:"addComment" )
}
...
if ( letter.save() )
...
}
def addComment = {
letter.addToComents( new Comment() )
render(view:'form', model:["letter": letter])
return
}
Or it exists better solution?
It would be nice:
<g:submitButton name="save" value="save" action="save" />
<g:submitButton name="addComment" value="add" action="addComment" />
Thanks a lot
Tom
Use the g:actionSubmit tag instead.
<g:form method="post">
<g:input name="title" value="${letter.title}" />
<g:input name="comments[0].text" value="${letter.comments[0].text}" />
<g:actionSubmit action="save" value="Save" />
<g:actionSubmit action="addComment" value="Add Comment" />
</g:form>
For those who are using Twitter Bootstrap plugin (or need something besides text in your button) and want to add a glyphicon to the button, you will need to use the button tag. So you need to do something like
SNIPPET 1.
<g:form role="form" method="post">
...your inputs
<button type="submit" name="_action_save">
<span class="glyphicon glyphicon-ok"></span>
Save
</button>
<button type="submit" name="_action_saveAndNew">
<span class="glyphicon glyphicon-ok"></span>
Save and New
</button>
</g:form>
where in your button you will need to specify the name of your action with the prefix
_action_
to get something like this
name="_action_yourActionName"
just a little reminder, since I am using twitter Bottstrap plugin 3.0 this is how you add a glyphicon
<span class="glyphicon glyphicon-ok"></span>
SNIPPET 1. has a similar behaviour to:
<g:form role="form" method="post">
...your inputs
<g:actionSubmit action="save" value="Save" />
<g:actionSubmit action="saveAndNew" value="Save and New" />
</g:form>
In the end this example help you have a similar behaviour to actionSubmit in cases where you don't want or can't use it. This is only an alternative and it'd be better to use actionSubmit whenever possible.

Resources