I am sending the employee object from the Project_level controller to the _add_members view and then from there I am sending the employee object to the Project_permission controller. while saving the id the following error is coming: No such property: id for class: java.lang.String in the line :proj_permission.setId_of_employee(emp.id)
class Project_levelController {
def auth_after_create_level(){
//creating a level under the above level
def res=Project_level.findByLevel_nameAndLevel_no(params.level_name,params.level_no)
// def res=null
if(res)
{
flash.message='level name has already been taken'
redirect(action:'_right')
}
else{
if(params.enter=="NEXT")
{
def proj_lev_right = new Project_level_right(params["project_level_right"])
proj_lev_right.save()
proj_lev_right.errors.allErrors.each { println it }
session.proj_lev_right = proj_lev_right
def proj_lev = new Project_level(params["project_level"])
proj_lev.setProj_lev_right_id("${proj_lev_right.id}")
proj_lev.id_of_project=session.id_of_project
proj_lev.mem_added = 0
proj_lev.save()
proj_lev.errors.allErrors.each { println it }
session.proj_lev = proj_lev
def emp = Employee.findAllByLevel(proj_lev.level_no)
render(view: "add_members", model: [proj_lev:proj_lev , proj_lev_right:proj_lev_right , employee:emp])
}
}
}
def _right(){
}
}
/*****************************************************************************/
class Project_permissionController {
def add_employee_to_project()
{
def emp = params.employee
def proj_permission=new Project_permission()
proj_permission.id_of_project=session.id_of_project
proj_permission.setId_of_employee(emp.id)
proj_permission.id_of_poject_level=session.proj_lev.id
/* def employee_proj_level= Project_level.get(proj_permission.id_of_project_level)//making a empty project_project and saving the project level field that belong to id_of_project_level
def employee_proj_level_right= new Project_level_right()//making a empty project_level_right
employee_proj_level_right= Project_level_right.get(employee_proj_level.proj_lev_right_id)//empty project_level_right is used to store the default right for that particular level that is given by "proj_lev_right_id"
proj_permission.setId_of_project_level_right("${employee_proj_level_right.id}")//saving employee project_level_right in id_of_proj_level_right
*/
proj_permission.id_of_project_level_right=session.proj_lev_right.id
render "Hari"
}
/**********************************************************/
<g:each var="emp" in="${employee}">
<g:link controller="project_permission" action="add_employee_to_project" params="[employee:emp]">
<button class="btn btn-block btn-info btn-sm">Add to Project</button>
</g:link></td>
</a>
</div>
</div>
</div>
</g:each>
</ul>
</div>
</div>
</div><!-- /.box-body -->
</div><!-- /.box -->
The problem is on this code:
def emp = params.employee
....
proj_permission.setId_of_employee(emp.id)
You get emp from params which is a string ( probably employee id) then you are trying to access id field from it, id field from string object? that is the problem.
Possible solution:
replace def emp = params.employee with def emp = Employee.get(params.employee)
Related
In my grails view the ordering applied on the domain class constraints are not picked when i use f:display with each individual property. I heard that domain class property comparator can be used to order the property display as per the constraints applied on the domain class.
Can some body help me on how to use DomainClassPropertyComparator to sort properties on my view?
You can install the scaffolding templates, edit _form.gsp and change the comparator it is using to DomainClassPropertyComparator e.g. my _form.gsp
<%=packageName%>
<% import grails.persistence.Event %>
<% import org.codehaus.groovy.grails.scaffolding.DomainClassPropertyComparator %>
<% excludedProps = Event.allEvents.toList() << 'version' << 'dateCreated' << 'lastUpdated'
persistentPropNames = domainClass.persistentProperties*.name
boolean hasHibernate = pluginManager?.hasGrailsPlugin('hibernate')
if (hasHibernate && org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder.getMapping(domainClass)?.identity?.generator == 'assigned') {
persistentPropNames << domainClass.identifier.name
}
DomainClassPropertyComparator mattsComparator = new DomainClassPropertyComparator(domainClass)
comparator = mattsComparator
props = domainClass.properties.findAll { persistentPropNames.contains(it.name) && !excludedProps.contains(it.name) }
Collections.sort(props, comparator)
for (p in props) {
if (p.embedded) {
def embeddedPropNames = p.component.persistentProperties*.name
def embeddedProps = p.component.properties.findAll { embeddedPropNames.contains(it.name) && !excludedProps.contains(it.name) }
Collections.sort(embeddedProps, comparator)
%><fieldset class="embedded"><legend><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}" /></legend><%
for (ep in p.component.properties) {
renderFieldForProperty(ep, p.component, "${p.name}.")
}
%></fieldset><%
} else {
renderFieldForProperty(p, domainClass)
}
}
private renderFieldForProperty(p, owningClass, prefix = "") {
boolean hasHibernate = pluginManager?.hasGrailsPlugin('hibernate')
boolean display = true
boolean required = false
if (hasHibernate) {
cp = owningClass.constrainedProperties[p.name]
display = (cp ? cp.display : true)
required = (cp ? !(cp.propertyType in [boolean, Boolean]) && !cp.nullable && (cp.propertyType != String || !cp.blank) : false)
}
if (display) { %>
<div class="fieldcontain \${hasErrors(bean: ${propertyName}, field: '${prefix}${p.name}', 'error')} ${required ? 'required' : ''}">
<label for="${prefix}${p.name}">
<g:message code="${domainClass.propertyName}.${prefix}${p.name}.label" default="${p.naturalName}" />
<% if (required) { %><span class="required-indicator">*</span><% } %>
</label>
${renderEditor(p)}
</div>
<% } } %>
I've just started coding in Rails 4, so I may need very specific instruction. I'm using AJAX to take user input from a text field, modify it (for simplicity's sake I'm just adding " yay!" on the end of it), and return the response as a string to the text field.
I believe I am sending my AJAX request correctly, but something in my controller or view isn't modifying or displaying the result.
Here is my code:
View (solve.html.erb):
<head>
<script>
function myFunction() {
var xmlhttp = new XMLHttpRequest();
var url = "solve";
var params = "field1=" + document.getElementById("field1").value;
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("field1").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET", url + "?" + params, true);
xmlhttp.send();
}
</script>
</head>
<h1>Solve!</h1>
<p>Type it in, type it in.</p>
<div class="col-lg-6">
<div class="input-group">
<input id="field1" type="text" class="form-control" placeholder="1+1">
<span class="input-group-btn">
<button class="btn btn-default" type="button" onclick="myFunction()">Solve</button>
</span>
</div>
</div>
Routes (routes.rb):
resources :equations
#rest of my routes code
get 'solve' => 'equations#solve'
Controller (equations_controller.rb):
class EquationsController < ApplicationController
def solve
if request.post?
new_var = params[:field1]
other_var = "#{new_var} yay!"
return other_var
end
end
end
If you have any questions, I'll get right back to you. Thank you so much for your help! Anything is greatly appreciated.
You're making a GET request but checking if the request is POST in your EquationsController#solve method. Update controller code as follows:
class EquationsController < ApplicationController
def solve
if request.get? # Change to `request.get?`
new_var = params[:field1]
other_var = "#{new_var} yay!"
return other_var
end
end
end
Then the second problem is, you should be writing the output instead of returning it from the controller. As you are expecting text/plain mime type, you should render text instead:
class EquationsController < ApplicationController
def solve
if request.get?
new_var = params[:field1]
other_var = "#{new_var} yay!"
render plain: other_var # Change to `render plain: other_var`
end
end
end
This however, is not the recommended way to handle AJAX requests/responses in Rails. Please refer to: Working with JavaScript in Rails. Also, please see The response object for details on the same.
Try this in myFunction()
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("field1").value = xmlhttp.responseText;
}
I think this works
ok, I think the controller's action is rendering the default 'solve.html.erb' view. so you should return just the value you wish like
class EquationsController < ApplicationController
def solve
if request.post?
new_var = params[:field1]
other_var = "#{new_var} yay!"
render html: other_var
end
end
end
and in js
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("field1").value = xmlhttp.responseText;
}
Image controller has a function
def scaled = {
log.debug("SCALED IMAGE " + params)
response.setContentType('image/jpeg')
response.setHeader('Cache-control', 'no-cache')
def userId = session.selectedUser.id
if(params.userId){
userId = params.userId
}
if(params?.id != null && !(params?.id.empty)){
params.maxWidth?: 20.00
params.maxHeight?: 20.00
response.outputStream << imageProxyService.loadImage(params.id, securityService.passwordEncoder(userId.toString()),params.maxWidth, params.maxHeight)
}
}
and profile photo's filename are stored in user table.
User has many status and i want to load user's profile photos depending on the statuses displayed. My status gsp looks like this:
<g:each in="${statusList}" status="i" var="status" status="i">
<tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
<tr><td><img id="profile_photo" src="${createLink(controller:'image', action:'profilePhoto', id:status.photo)}" alt="" title="" />
</td></tr>
</tr>
</g:each>
query I used in status controller:
def alllist = {
log.debug("BEGIN IWI PROFILE")
def statusList = []
def sql = new Sql(dataSource);
def statusQuery = """SELECT c.id, c.status_message, c.status_type as profile, se.id, se.photo FROM user_account se, status c
WHERE
c.user_account_id = se.id
GROUP BY se.id, c.id, c.status_message, c.status_type, se.photo"""
def result = sql.rows(statusQuery);
def userQuery = """not sure """
if (result){
log.debug("GOT SOME RESULTS IN PERSONAL user" + result)
result.each() { status ->
def userResult = sql.firstRow(userQuery, [status.id])
if (userResult){
status['userId'] = userResult.id
} else {
status['userId'] = ""
}
statusList += status
}
}
render(template: "alllist", model: [statusList: statusList])
Please Note: This way I am getting all the photos all right but photos display only for the session user.
<img id="profile_photo" src="/myApp/image/profilePhoto/9edd692580d148c791c6c2aa3510605a95ba6de6.jpg" alt="" title=""/>
I would create a TagLib. How you actually render the photo depends on what is stored in the UserAccount.photo field. I'll assume it's an absolute URL to an image.
class UserTagLib {
def photo = {attrs ->
UserAccount u = attrs.user
out << "<img src=${u.photo}/>"
}
}
You would use it in your GSP like:
<user:photo user="${status.userAccount}"/>
..assuming you are looping over a list of Status objects in a variable called status
You can use this one:
<img src="http://applicationUrl/images/${u.photo}" />
or
<img src="${createLink(dir:'images',file: u.photo}" />
they can be used but as create link is deprecated now, I recommend using:
Resource for the same
<img src="${resource(dir: 'images', file: 'file.jpg')}"/>
More information can be found at:
http://grails.org/doc/2.2.1/ref/Tags/resource.html
about the resources
Solved. I really don't know what I did, but it worked. One of those moments...
My domain object is "Actiune". I want to add a new entry with 4 preset fields from another entry that has the given id to "createNewEtapa" method. So I query that entry (with the id) and get it's values, preset them in the form and the hit save but it does not work. The save will not work.
What am I doing wrong ? I've been going around this for hours. Please help again stackOverflow :)
If you don't feel like checking all the code, please just let me know how is this done or link me a example :)
Thx!
These are the relevalt parts of my code
This is my GSP form:
<g:form action="save" enctype="multipart/form-data">
<fieldset class="form">
<g:applyLayout name="form">
<tmpl:/templates/form />
</g:applyLayout>
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save"
value="${message(code: 'default.button.adauga.label', default: 'Adauga')}" />
<g:actionSubmit name="create" class="save" action="savenew" value="Adauga2" />
</fieldset>
</g:form>
This is my controller:
def create(Long id){
def actiuneInstance = Actiune.findById(id)
def c = Actiune.createCriteria()
def instanceList = c {
eq("idActiune", actiuneInstance.idActiune)
order("termenPornire", "asc")
}
params.idActiune = actiuneInstance.idActiune
params.tema = actiuneInstance.tema
params.firma = actiuneInstance.firma
params.user = User.findById(springSecurityService.currentUser.id)
[instance: new Actiune(params)]
}
def save() {
def actiuneInstance = new Actiune(params)
actiuneInstance.user = User.findById(springSecurityService.currentUser.id)
actiuneInstance.termenPornire = new Date()
def actiuneBD = Actiune.findByIdActiune(params.idActiune)
actiuneInstance.idActiune = actiuneBD.idActiune
actiuneInstance.tema = actiuneBD.tema
actiuneInstance.firma = actiuneBD.firma
print "in params " + params
print "\\"
print "in save... " + actiuneInstance.properties
if (!actiuneInstance.save(flush: true)) {
render(view: "create", model: [firInstance: actiuneInstance])
return
}
flash.message = message(code: 'default.created.message', args: [message(code: 'actiune.label', default: 'Actiune'), actiuneInstance.idActiune])
redirect(action: "completeShow", id: actiuneInstance.id)
}
This is the output from the print statements in the save() method
*...*
in params [termenLimita_month:11, termenPornire_month:11, termenPornire_day:1, documentPath:, tema:Promotie A, termenLimita_day:1, _action_savenew:Adauga2, id:, observatii:uuu, termenLimita:date.struct, termenPornire_year:2012, etapa.id:1, etapa:[id:1], contact.id:1, contact:[id:1], termenPornire:date.struct, firma:Google, idActiune:zt8h, termenLimita_year:2012, action:save, controller:actiune]
\
....
in save... [user:Flavian, termenPornire:Thu Nov 01 22:57:45 EET 2012, contact:null, documentPath:null, temaId:1, etapaId:null, firmaId:3, firma:Google, contactId:null, termenLimita:null, idActiune:zt8h, observatii:null, userId:null, etapa:null, tema:Promotie A]
Call actiuneInstance.validate() and then look at the actiuneInstance.errors object to see the result of any validation errors on your object.
This is in the gsp
<g:if test="${hasError}">
<div class="errors">
<g:renderErrors bean="${eventInstance}" />
</div>
</g:if>
<g:else >
<div id="messageBox" class="message" style="display:none;">
<g:message code="legalevent.save.success" args="[entityName]" default="Event saved successfully" />
</div>
</g:else>
<g:formRemote name="eventForm" id="eventForm" url="[controller : 'search', action : 'saveLegalEvent']"
update="eventFormDiv" action="${createLink(controller: 'search', action: 'saveLegalEvent')}" method="POST"
onSuccess="jQuery('#messageBox').show()">
I am rendering a page for update with this :
def saveLegalEvent = {
def paramsView = params
def eventPattern = /(event\.).*/
def event = LegalEvent.findByLevId(params["levId"])
def corrTxt = params["corrTxt"] as CorrectionText
if(corrTxt.getCorrId()){
corrTxt = CorrectionText.findByCorrId(corrTxt.getCorrId())
}
event.setCorrTxt(corrTxt)
event.properties = params["event"]
def dataList = []
def hasError = false
def validated = event.validate()
validated &= event.validateHistoryParams()
if(validated)
event.save(flush:true)
else
hasError = true
def errorsView = event.errors
render(view:'leform', model:[attributeDataInstanceList:event.tags, lecInstance:event.leCode, eventInstance:event, hasError: hasError])
}
validateHistoryParams validate some more params that are usually not needed in the domain class.
def validateHistoryParams = { ->
if(!changeRef || !changeRef.trim()) {
this.errors.rejectValue('changeRef', 'event.changeRef.blank')
}
if(!corrTxt || !(corrTxt.corrTxt.trim() || corrTxt.corrId )) {
this.errors.rejectValue('corrTxt', 'event.corrTxt.null')
}
!(this.hasErrors())
}
The problem with all this is that the errors are not rendered in the gsp.
All other tags are rendered fine, when debugging I can see that the errors are actually in the error stack. But in the end, the tag isn't rendering them.
As you can see, there is no redirection, so I can't understand why the errors would somehow be erased between the response creation and the rendering ...
In your Groovy code, parameter returned is named hasError, and GSP checks for hasErrors. I'd recommend not to use extra variables, and just query the bean itself in GSP.
I also believe that you need to have that errors div inside the formRemote element in order to re-render after form submission.