grails : how to pass params in remoteFunction - grails

I want to a param using remoteFunction of grails.
HTML
<table class="table table-hover table-bordered" id="profittable">
<thead>
<tr>
<th>Date</th>
<th>Profit</th>
<th>Delete?</th>
</tr>
</thead>
<tbody>
<g:each in="${dailyProfit}" var="dp">
<tr onclick="<g:remoteFunction action='edit' params="[date:${dp.date}]"></g:remoteFunction>" >
<td><g:formatDate format="yyyy-MM-dd" date="${dp.date}"/></td>
<td>
<g:formatNumber number="${dp.profit}" type="currency" currencyCode="PHP" format="###.##" />
</td>
<td>
<g:form controller="dailyProfit" action="delete" >
<g:hiddenField name="date" value="${dp.date.format("yyyy-MM-dd")}" />
<g:actionSubmit class="delete" value="Delete" >
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</g:actionSubmit>
</g:form>
</td>
</tr>
</g:each>
</tbody>
</table>
ERROR MESSAGE
URI /SampleGrailsApp/dailyProfit/index Class
org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException
Message Attribute value quote wasn't closed (action='edit'
params="[date:${dp.date}]").
ACTIONS FOR EDIT
The remoteFunction tag is inside every tr of my table. The plan is, if the row is clicked, the edit page will appear
def edit() {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date date = format.parse(params.date);
def dailyProfit = DailyProfit.findByDate(date)
render view:"edit" , model:[dailyProfit : dailyProfit]
}
def update() {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date date = format.parse(params.date);
def dailyProfit = DailyProfit.findByDate(date)
if(dailyProfit){
dailyProfit.properties = params
dailyProfit.save(flush:true)
}
list()
}
What is the proper way of passing parameters using remoteFunction tag of grails?

You can do like this .
<tr onclick = "${remoteFunction(
controller: 'xyz',
action: 'edit',update:'divId',
params: [date: dp.date])}" >

This is also a valid syntax:
<tr onClick="<g:remoteFunction action='edit' params="${[param1: 'value', param2: 0]}"></g:remoteFunction>">.....</tr>
Note that the code will translate into an Ajax call with the parameters you indicate. Being an Ajax call, you wont see the page change.
If you want to send the user to the edit page when the row is clicked one option is the following:
<tr onclick='document.location = "<g:createLink action='edit' params="${[date: dp.date]}"/>" '> ... </tr>

Related

Thymeleaf: How to get selected item on click

I want to call a method with the clicked object as a param.
Problem: on every reload or button press the method is called for every element.
<form action="#" th:action="#{/}" th:object="${chessBoard}" method="post">
<table>
<tr th:each="i, iter1: *{board}">
<td th:each="item, iter2: ${i}">
<button th:onclick="${chessBoard.selected(item)}" th:text="${item.text}"></button>
</td>
<tr>
</table>
</form>
You don't need the onclick method in your form to submit a parameter.
You can simply pass a parameter to the controller with a RequestedParam annotation in your controller.
It will be something like:
<form th:action="#{/}" method="post">
<table>
<tr th:each="i: ${board}">
<td th:each="item: ${i}">
<button name="item" th:value="${item.id}" th:text="${item.text}"/>
</td>
<tr>
</table>
</form>
and in your controller:
#PostMapping (path = "/")
public String test(Model model, #RequestParam(name = "item") int id) {
System.out.println(id);
}
A second option is to use an attribute that you add to your model and you get back in your controller with something like:
#PostMapping("/")
public String greetingSubmit(#ModelAttribute ChessBoard chessBoard, Model model) {...}
Html will be something like
<form th:action="#{/}" th:object="${chessBoard}" method="post">
<table>
<tr th:each="i: ${board}">
<td th:each="item: ${i}">
<button th:field="*{id}" th:value="${item.id}" th:text="${item.text}"/>
</td>
<tr>
</table>
</form>

How to pass data from one view to other

I Have a table, there i have a details hyperlink on click of which i m showing a new table on same page in other div. The details Hyperlink has 3 input parameters based on which a service method gets triggered and I get data in the data. Now i have this task to show the 2nd grid on a new page. I m not sure how to do it.
Please help.
<table class="table table-bordered table-condensed table-hover ">
<thead>
<tr style="white-space: nowrap;">
<th>Date</th>
<th>Organization No</th>
<th>Contract No</th>
<th>Company Name</th>
<th>Plan No</th>
<th>Status</th>
<th>View Detail</th>
</tr>
</thead>
<tr ng-repeat="mas in vm | startFrom:currentPage*pageSize | limitTo:pageSize" data-ng-class="{active1:$index==selectedRow}" data-ng-click="rowHighilited($index)">
<td>{{mas.startDate | amDateFormat:'YYYY-MM-DD'}} </td>
<td>{{mas.organizationNumber}}</td>
<td>{{mas.contractNumber}} </td>
<td>{{mas.name}}</td>
<td>{{mas.planNumber}} </td>
<td>{{mas.description}} </td>
<td><span>Details</span></td>
</tr>
</table>
//getErrorDetailBySearch(mas.productAccountOid,mas.planNumber,mas.migrationRunID)it calls the function to bring data an binds it to the below div.//
<div ng-show="IsVisible">
<div ng-show="vm1.length > 0 && !loading">
<h2>Error Detail</h2>
<br />
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 table-responsive">
<table class="table table-bordered table-condensed table-hover table-striped">
<thead>
<tr style="white-space: nowrap;">
<th>Contract Number</th>
<th>Plan Number</th>
<th>Business Error Message</th>
<th>System Error Details</th>
</tr>
</thead>
<tr ng-repeat="mas in vm1">
<td>{{mas.contractNumber}} </td>
<td>{{mas.planNumber}} </td>
<td>{{mas.businessErrorMsg }} </td>
<td>{{mas.systemErrorMsg}} </td>
</tr>
</table>
</div>
</div>
I am able to call a new page Called as ErrorDeatils but i dont know how to pass data b/w the pages.
This is controller written for 1st page
$scope.getErrorDetailBySearch = function (productAccountOid, planNr, migrationrunid) {
var path = "/Utilities/Error";
$location.path(path.replace(/\s+/g, ""));
};
var onSuccess = function (response) {
$scope.vm1 = response;
if ($scope.vm1 < 1) {
messageService.noDataFound();
}
}
$scope.getErrorDetailBySearch = function (productAccountOid, planNr,migrationrunid, skipFormValidate) {
if (skipFormValidate || b360FormsService.validateForm($scope.ViewErrorDetail)) {
errorService.globalproductAccountOid = productAccountOid;
errorService.globalplanNr = planNr;
errorService.globalmigrationrunid = migrationrunid;
$scope.loading = true;
repositoryService.getErrorDetailBySearch(productAccountOid, planNr, migrationrunid).$promise.then(onSuccess, onError).finally(function () {
$scope.loading = false;
});
}
}
Hi you can pass data both as query parameters or route params
Query Parameters
Lets say you have path "/errorDetails" and you want to pass "param" with value "10", then you can use $location.path() as follows:
$location.path("/errorDetails").search({param: 10});
and you can access value of "param" on resultant page's controller as:
$location.search().param;
Route Parameters
For using route params you will need to change your route configurations and you path will be like:
$routeProvider
.when('/errorDetails/:param', {
title: 'Error Details',
templateUrl: 'path/to/errorDetails.html'
});
Now you can send param using $location.path as follow:
$location.path("/errorDetails/"+param);
And you can access route parameter on resultant page's controller as follows:
$routeParams.param

Paginate in GSP with an array List

How can I use the <g:paginate\> tag to paginate an array list in a table?
I have this in my controller
def selectevents(){
def events = DomainEvents.findAllByMonth('June')
[events:events, count:events.size()]
}
And I have this in My GSP:
<table id="results-table" class="table table-bordered table-striped" style="width:100%">
<thead>
<tr style="background: #d3d3d3;">
<th style="width: 3%;text-align: center;"></th>
<th style="width: 10%;text-align: center;">Name</th>
</tr>
</thead>
<g:each in="${events}" status="i" var="eventsInstance">
<tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
<td>-</td>
<td>${eventsInstance?.Name}</td>
</tr>
</g:each>
and then this:
<g:paginate next="Forward" prev="Back" maxsteps="5" controller="Controller" action="selectevents" total="${count}" />
But the pagination tag doesn't appear. I want to make a pagination to get 5 rows per page, some one?
Your code is calling DomainEvents.findAllByMonth('June') which is returning all of the events for the month of June. You only want to retrieve a subset of 5 of them and then use pagination to navigate around those subsets.
You probably want something like this in your controller:
def showEvents() {
params.max = 5
def count = DomainEvents.countByMonth('June')
def events = DomainEvents.findAllByMonth('June', params)
[domainEventsInstanceCount: DomainEvents.count(), domainEventsInstanceList: events]
}
And then something like this in your GSP:
<div class="pagination">
<g:paginate total="${domainEventsInstanceCount ?: 0}" />
</div>
I hope that helps.

Grails passing params in controllers to selectBox

Hey. I have this controller:
def participated_favourite = {
def user = User.get(1)
def conferenceUser
def original = ConferenceUser.findAllByUser(user)
def temp = ConferenceUser.findAllByUserAndIsFavourite(user, 1) // all conferenceUser filtered by User
def priz = [:]
def subm = [:]
...
...
[temp: temp, priz: priz, subm: subm, orig: original]
}
I want now to be able to select in a selectBox, the list of conferences passed by 'original' (in the participated_favourite.gsp).
How can i do that?
<g:select name="" from="${orig.list()}" optionKey="id" value="" />
This is giving me an empty select box which shouldnt. because there is one record in my database. What am i doing wrong?
Thanks in advances,
EDIT______________
I have in same gsp the folowing:
<g:each var="it" in="${orig}">
<table cellspacing="2">
<tbody><tr>
<th>Name</th>
</tr>
<tr>
<td class="color1">${it.conference}
</td>
</tr>
</tbody>
</table>
</g:each>
And it is p+rinting the values. So i dont know what is the problem in the select..
Try giving the name attribute a value.
---EDIT -----
Try the following to troubleshoot:
Does this work?
<g:select from="${ConferenceUser.list()}" />
If so, how about this?
<g:select from="${ConferenceUser.list()}" optionKey="id" />
use
<g:select name="" from="${orig}" optionKey="id" value="" />

Passing data from GSP to a controller in Grails

I create a GSP page with controls depending on the rows in a database.
This depends on the value returned by the <g:each in="${Vehicles}" var="vehicle">
So, if there are 3 vehicles, 3 rows with text boxes will be generated. (The maximum can be 200)
<g:form action="update" >
<label for="SearchTerm">${term}</label>
<g:each in="${Vehicles}" var="vehicle">
<tr>
<td> <label for="Name">${vehicle.name}</label> </td>
<td><g:textField name="${vehicle.id}.ModelNo" /> </td>
<td><g:textField name="${vehicle.id}.Year" /> </td>
</tr>
</g:each>
<td> <g:submitButton name="update" value="Update"/></td>
</g:form>
How can I basically pass this value to my controller so that I can then save/update the data to the database. or Is there any easy way to achieve this scenario?
You need some code like this in the GSP
<g:form action="update" >
<label for="SearchTerm">${term}</label>
<g:each in="${Vehicles}" var="vehicle" status="i">
<tr>
<td> <label for="Name">${vehicle.name}</label> </td>
<td><g:hiddenField name="vehicle[${i}].id" value="${vehicle.id}"/>
<g:textField name="vehicle[${i}].ModelNo" value="${vehicle.ModelNo}"/> </td>
<td><g:textField name="vehicle[${i}].Year" value="${vehicle.Year}"/> </td>
</tr>
</g:each>
<td> <g:submitButton name="update" value="Update"/></td>
</g:form>
The Controller needs to either have a Domain with a List Property or a Command Object with a List Property ie
SearchCommand {
List<Vehicle> vehicle = new Arraylist<Vehicle>(3);
}
Then in the controller (if using the command object)
def save = {SearchCommand searchCmd->
searchCmd.vehicle.each {vehicle ->
/* Process Vehicle */
}
}
Hope that Helps
You need to use the request object from your controller. If you can generate the names of the controls you need to access do something like the following
idList.each {
theYear=request.getParameter(it+Year)
}
If you want a list of all your generated form fields use something like
java.util.Enumeration theFields=request.getParameterNames()
theFields.each {
//look at your field name and take appropriate action
}
For more info on the request object see this

Resources