handling multi-select with no selection - grails

I used grails generate-all on my application. The Author view has a multi-select which allows for a number of Book instances:
<g:select multiple="true" ... />
However, if I edit an existing Author who owns 5 out of total 15 books (the multi-select shows 15 books, 5 selected), unselect all books and click save, the Author still keeps their 5 books. From what I can tell, no book input from the form - books property of Author don't get changed.
Now, I can test for this in my controller (something like this):
if (params?.books.size() < 1) {
authorInstance.books = []
}
Is this the way to do it, or is there a better way?

Most examples I've seen use:
authorInstance.books.clear()

I had the same problem, that a multi select list can not be emptied by default data binding, as the params map does not contain fields with a value of NULL.
To circumvent this, you can do this in your .gsp:
<g:hiddenField name="books" value="" />
<g:select multiple="true" name="books" />
When you post this form elements, the multi select will override the hidden field. If the multi select is empty, you will fallback to the empty string.
Not pretty, but get the job done, when you can not alter the controller action.

Related

Select dropdown with f:field (fields plugin) in Grails 3

I'm trying to generate a select drop down with an option preselected (based on params) using the fields plugin. The code below generates a select box with the proper elements and everything works except it doesn't add "selected" to the option tag. It seems to be ignoring my widget- attributes.
From what I understand the fields plugin will pick g:select in this case by default if not overridden, and you can use widget- to pass arguments to it.
What am I doing wrong?
<f:field bean="specialUser" property="user" label="user.label" widget-optionKey="id" widget-value="${params.user?.id?:value?.id}"/>
Link to the fields documentation:http://grails3-plugins.github.io/fields/snapshot/guide/single.html#
This seems to have done what I wanted, computed specialUserList from the controller. Though it would've been nice to utilize the "widget-" to do this form me.
<f:field bean="specialUser" property="user" label="user.label">
<g:select id="user" name="user.id" optionKey="id" class="span-8 margin-bottom-none" from="${specialUserList}" noSelection="${['null': message(code: 'common.list.select')]}" value="${params.user?.id}"/>
</f:field>

g:select tag in grails does not store key of list element in target field

I have the following codeline in my grails view
<g:select id="partner" name="partner.id" from="${org.strotmann.partner.Partner.partners}" optionKey="id" value="${auftragInstance?.kundenNr}" class="many-to-one" noSelection="['null': '']"/>
I expect it to show me the list specified in the from clause as a select box (that works fine)
After selecting an Item from the box I expect that it stores the id of that Item in the field specified in the value clause ( that does not work, always null)
I'm somewhat confused, because the followin codeLine does exactly what I expect:
<g:select id="partner" name="partner.id" from="${org.strotmann.partner.Partner.partners}" optionKey="id" value="${arbeitsgangInstance?.kundenNr}" class="many-to-one" noSelection="['null': '']"/>
Can anybody tell me where I can find a difference or how to recode my ?
peter
let me reformulate my question:
I have a list
org.strotmann.partner.Partner.partners
It contains partners with just the attribute name and of course the id.
I want the names in a selectList and want the id of a partner stored in
auftragInstance.kundenNr
feel free to code a working g:select
peter
The value attribute is used to provide the initial selection. The name attribute will contain the selected value when the form is submitted. In a controller you can get it like this:
def partner = params.partner
See:
select tag in grails documentation
thanks to comment from masc I found that there was just missing the following code snippet in save and update method of AuftragController:
if (params.partner.id == 'null')
salesOrderInstance.kundenNr = 0
else
salesOrderInstance.kundenNr = params.partner.id.toLong()
That code block was allready contained in ArbeitsgangController, and therefore the second html-line in my question was working fine.
the following select (with id and value clauses omitted) will also do:
<g:select name="partner.id" from="${org.strotmann.partner.Partner.partners}" optionKey="id" class="many-to-one" noSelection="['null': '']"/>
sorry the value entry
value="${auftragInstance?.kundenNr}"
must not be removed, it is important for update.

How do I get Grails g:select with multiple-selection with all selections when returning from the controller

I have a page that is a report from a database and I'm working on modifying how the filtering works. The intention is to allow the user to select possible values form a list that will be used to filter the resulting report. There are too many values to do this with checkboxes. I'm defining a multiple selection list box with this:
<g:select name="country" from="${countryDataList.KOUNTRY}" value="${params.country}" multiple="true" />
countryDataList is a List<> of objects with a name and a value which I create in the controller. I'm able to get the selected counties and process them without an issue.
But when the page returns from the controller with the filtered report, only the first selection in the list is selected. It doesn't re-select all of the items that the user selected. I am passing the params.country object back from the controller as
country:params.country
I saw some posts about this not working, but they are all from several years ago. Am I missing a vital step?
Ahh sorry, I was reading it on the phone initially and missed the point.
So what you want is a way of sending a multiple select box to a confirmation page. If I understand correctly?
Anyways how many objects in the select are we talking massive or a dozen couple of dozen or so ?
What I did was use check boxes and did a confirmation which shows the selection ticked in check boxes.. So this is the confirmation page that loads in https://github.com/vahidhedayati/mailinglist/blob/master/grails-app/views/mailingListEmail/confirmcontact.gsp
this page which is where multiple attachments selected from the schedule re-appear...
https://github.com/vahidhedayati/mailinglist/blob/master/grails-app/views/mailingListAttachments/_mailerAttachmentsDisplay.gsp.
Please note advice below is all conceptual stuff and there may be easier ways than this
Other than that You could create a taglib call on the confirmation page https://github.com/vahidhedayati/ajaxdependancyselection/blob/master/grails-app/taglib/ajaxdependancyselection/AutoCompleteTagLib.groovy#L55 which takes in your arrayList you could probably convert it to JSON pass it into the javascript that you load in within the taglib (on mine further down it loads this page in)
https://github.com/vahidhedayati/ajaxdependancyselection/blob/master/grails-app/views/autoComplete/_selectJs1.gsp#L23
and look to reselect them using javascript... as I say I haven't tested the last bit, the first bit i.e. checkbox works it is/has been in use.
Years later from you I just had the same problem. What I figured out is: it happens when params.country is an array instead of a Collection (i.e. an ArrayList).
A workaround for this if you want to stick to the array type is at the value attribute of the tag doing this: params.country?.findAll().

JQuery Mobile, find a specific input form on a given page

Here is the answer from another question: jQuery find $.find('selector') versus $('selector') difference
The reason this does not work is because find() lets you filter on a set of elements based on a selection you've already made.For example if you wanted to select all of the inputs within a particular form, you could write:
$('#aParticularForm').find('input')
It cannot be called on its own.
How can I expand this statement to find specific inputs on a page? (Specifically listviews)
Working example: http://jsfiddle.net/Gajotres/93VFG/
Wanted element must have a unique identification, like id or class.
HTML :
<form id="aParticularForm">
<input type="text" value="One" id="input1"/>
<input type="text" value="Two" id="input2"/>
</form>
Javascript :
var input = $('#aParticularForm').find('#input1');
alert(input.val());
You can even go further, because you are working with a jQuery Mobile you can have several pages loaded into the DOM and they can all have identical input fields, so to find elements only in a current active page you would use:
$.mobile.activePage.find('#input1');

Dropdowns with 10 thousand possible values and sequence-important dropdowns vs. graceful degredation

Background
I have this form that uses javascript exclusively to search through ~5k entries (suppliers) and populate a select dropdown from them (factories, ~10k entries). Right now, it's a javascript-required form. I'd like to make it so that javascript errors no longer render the form unusable, but the number of entries and the sequential nature of the entries leave me without a idiomatic way to provide just a basic html version.
The Issues
Sequential/hierarchical dropdowns
An example dropdown where sequence is important:
http://www.javascriptkit.com/javatutors/selectcontent2.shtml
So that shows "filtering" of sequential/hierarchical dropdown content, where the selections in the second City dropdown get filtered based on the selections in the first Country dropdown. But take away the javascript, and it could instantly become a mess. Madrid in the USA? Berlin in France? The sequence becomes corrupted.
Dropdowns that have huge numbers of options
If you have a select dropdown with 10k possible options, it's pretty easy to filter/search through them with javascript. Dealing with those options without javacript, on the other hand, is much more difficult.
How do you provide your users with all of the possibilities when just loading all the options them all would blow up their browser?
Possible Solutions
Sequential/Hierarchical Select boxes:
Server-side 2-part forms.
?Select option groups?
???
Selects with huge numbers of options:
Server-side 2-part search forms.
Server-side text search matching of entry names.
???
Simple links to resourceful solutions welcome.
The only solution that I can think of is to use a form submit each time you need to narrow down your results. You start off by showing a page to select a supplier's country. That submits, and returns a page that shows the selected country as text and now has a drop-down to select the next field, like cities. That way, the server can do the filtering at each level.
Here's a JSP example:
<c:choose>
<c:when test="${empty country}">
Country:
<form>
<select>
<option value="USA">America</option>
<option value="DEU">Germany</option>
<%-- ... --%>
</select>
</form>
</c:when>
<c:otherwise>
Country: ${country}
<c:choose>
<c:when test="${empty city}">
<input type="submit" value="Change" /> <%-- Button to change the previous value --%>
<%-- your form for choosing a supplier's city --%>
</c:when>
<c:otherwise>
<%-- continue filtering until you have all of the data --%>
</c:otherwise>
</c:choose>
</c:otherwise>
<c:choose>
When you select a country, the form submits. Your server processes the country, returns the same page with the country field value and a list of possible cities for your next drop-down. Doing it like this allows you to rely only on form submits (rather than JavaScript) to filter data sequentially. Your server would be responsible for keeping track of how far along the user is. The obvious downfall of this solution is that your JSP would be pretty messy, with all of the nested <c:choose> blocks.
You might also try a hybrid solution: when the page loads, find out if your JavaScript has loaded. If so, replace your submission forms with plain HTML that has AJAX behind it to populate the next set of options. That way, your page doesn't have to refresh a bunch of times when the JavaScript does load, but will still be functional if the JavaScript doesn't load. Just a thought.

Resources