I've seen various answers to similar questions, but not for this specific case:
I have a Grails gsp with several fields and a submit button. I want to enter a value in the first field, click submit, and have the controller return values into the remaining fields (including the original entry field). I want to do this with a simple page refresh (no AJAX) and it does not involve a database. I have it working fine with two gsp pages that are identical but have different names. I just call the first one, enter the value, and have the submit action point to the second. But I would like to be able to do it with a single gsp. A simplified version of my controller looks like this:
class CalculatorController {
def index = {
redirect(action: "input")
}
def input= {}
def calculateValues = {
def inputString = params.enterValue
def value2 = 'You entered something on the page'
[field1: inputString, field2: value2]
}
}
you need to have all of logic inside of the same closure if you want to use only one gsp. Test if the params are passed in and return the correct vals
Actually you don't need to have all of your logic in the same closure. Simply specify the view template to use in calculateValues...
def calculateValues = {
def inputString = params.enterValue
def value2 = 'You entered something on the page'
render(view: 'input', model: [field1: inputString, field2: value2])
}
By using the render method you can have multiple controller action reuse the same gsp view.
Related
I have a form with checkboxes that get passed as an array "list_person_ids" on form submit. My models are "Occurance" which has an n:m relationship with "ListPerson" through the Model "Person". "list_person_ids" are saved in Person with the Occurance id and the ListPerson id.
I want to append one or more values to the array before this gets saved. The reason I need to do this is because the user can also add a new value in ListPerson using a textbox with the name "person_name".
def create
#occurance = Occurance.new(occurance_params)
add_person_id(#occurance)
...
# save
end
def add_person_id(object)
if params[:person_check] == '1'
object.list_person_ids.push( ListPerson.find_or_create_by(person: params[:person_name]).id )
end
end
def occurance_params
params.require(:occurance).permit(:person_check, :person_name, dim_person_ids: [])
end
find_or_create_by is successful, but nothing gets pushed to the array "list_person_ids". There is also no error message. Do I have to give permission somewhere to append this array? Please let me know if some information is missing.
on your model you can do something like below:
....
before_create :create_lists
private
def create_lists
ListPerson.find_or_create_by(list_person_ids: person_name.id)
end
In a project, I implement checkbox filters via ajax. In my controller I have an action:
def casinos_filters
providers_from_categories = Provider.joins(:categories).where('categories.id = ?', params[:category_id])
providers = Casino.joins(:providers).where('providers.id = ?', params[:provider_id])
providers_from_categories.each do |provider|
#filtered_casinos = provider.casinos
end
casinos_list = []
casinos_list << #filtered_casinos if params[:category_id]
casinos_list << providers if params[:provider_id]
render json: { casinos: casinos_list.uniq }, status: 200
end
As a result, I want the array casinos_list include the casinos' objects. Clicking on a category checkbox, I get the json. But when I click the next category checkbox, the json doesn't have previous results. I think it's due to the initializing an empty array in the action. Is there any way to initialize the array only once, not on every ajax call? Thanks.
HTTP requests are stateless. You either need to store them in client side (as Javascript models/collections) or on the server side to be able to collect them together.
I want to exclude some fields in my inline based on my request user.
I know somehow I can handle this with methods like 'get_formsets', 'add_view', 'change_view', but I'm not sure what the syntax is.
Any suggestions?
I achieved what I needed with the next code in my inline class:
def get_formset(self, request, obj=None, **kwargs):
if request.user.groups.all().count() > 0:
if request.user.groups.all()[0].name == 'User Group Name':
kwargs['exclude'] = ['field_to_exclude',]
return super(MyInline, self).get_formset(request, obj, **kwargs)
The answer to this question gave me the hints: different fields for add and change pages in admin
There's also the get_exclude hook:
class FoodInline(TabularInline):
model = Food
def get_exclude(self, request, obj=None):
group = request.user.groups.first()
if group and group.name == 'User Group Name':
return ['field_to_exclude', ]
return self.exclude
I'm trying to do that:
User upload file in first controller,
In some conditions I show page to user for choose element from file and pass file data to another controller in params: data#new
In data#new:
#elm_file = Rails.cache.read(params[:cache_id])
#elm_id = params[:index]
#user_name = params[:name]
new_elm_id = Elm.create_from_file #elm_file, #elm_id, #user_name
if new_elm_id != 0
redirect_to :action => '', :id => new_elm_id
end
return
in Model:
new_elm = Elm.new
return new_elm.id
The problem is - nothing returned. How can I record new element to database?
Your new action of the controller data returns nothing, because you haven't defined anything behind the return argument.
The two other lines, which are supposed to be from your model, returns nothing, because the id field is only set for persisted records. You maybe want to persist it with create().
My controller:
def getMenuItemCount(String name){
def myCount = MenuItem.countByMenuItemCategory(name)
render myCount
}
What do i call in another gsp so that myCount appears. createLink doesnt seem to work
${createLink(action:'getMenuItemCount', params: [name:ci.name])}
A model has to be returned instead of rendering it in order to access it in a gsp.
def getMenuItemCount(String name){
[ myCount: MenuItem.countByMenuItemCategory(name) ]
}
Also, (not related to question really), try to avoid using action names as get* and set*. I have seen discrepancies with that nomenclature.