GRAILS Placement of g:form affects params passed to controller - ajax

I have a HTML table that has a form field that can be updated for each row. In each row, I have created a form and when you change the editable field, a button will appear and you can save the change. This happens remotely using the GRAILS g:submitToRemote tag.
I have some hidden fields that also need to be passed.
When I do the following, none of the fields (the 3 hidden ones, nor the single visible ones) are passed the controller:
<g:form action="updatebaseprice" id="${obj.id}" name="form_${obj.id}">
<tr>
<td>${prod.product.name}</td>
<td class="text-center">${prod.product.type}</td>
<td class="text-center"><g:formatNumber number="${prod.product.unitCost}" type="currency" currencyCode="USD" /></td>
<td class="text-center">
<div class="row collapse">
<div class="small-3 columns">
<span class="prefix radius">$</span>
</div>
<div class="small-9 columns">
<g:field type="text" class="bemt_small_input_field" value="${prod.basePrice}" id="basePrice_${prod.id}" name="basePrice" onchange="Project.updateBasePrice(${prod.id});" maxlength="6"/>
</div>
</div>
</td>
<td class="text-center"><span id="display_recoveryPercent_${prod.id}"><g:formatNumber number="${prod.recoveryPercent}" type="number" minFractionDigits="2" maxFractionDigits="2"/></span>%</td>
<td class="text-center">
<g:hiddenField name="projectProduct" value="${prod.id}"></g:hiddenField>
<g:hiddenField name="unitCost" id="unitCost_${prod.id}" value="${prod.product.unitCost}"></g:hiddenField>
<g:hiddenField name="recoveryPercent" id="recoveryPercent_${prod.id}" value="${prod.recoveryPercent}"></g:hiddenField>
<g:submitToRemote id="save_button_${prod.id}" class="hidden button alert save_unitprice radius" id="save_button_${prod.id}" url="[action: 'updatebaseprice']" onSuccess="Project.saveBasePrice();" value="Save"/>
</td>
</tr></g:form>
Using a println params in the controller, nothing in printed.
When I do the following:
<tr>
<td>${prod.product.name}</td>
<td class="text-center">${prod.product.type}</td>
<td class="text-center"><g:formatNumber number="${prod.product.unitCost}" type="currency" currencyCode="USD" /></td>
<td class="text-center">
<div class="row collapse">
<div class="small-3 columns">
<span class="prefix radius">$</span>
</div>
<div class="small-9 columns">
<g:field type="text" class="bemt_small_input_field" value="${prod.basePrice}" id="basePrice_${prod.id}" name="basePrice" onchange="Project.updateBasePrice(${prod.id});" maxlength="6"/>
</div>
</div>
</td>
<td class="text-center"><span id="display_recoveryPercent_${prod.id}"><g:formatNumber number="${prod.recoveryPercent}" type="number" minFractionDigits="2" maxFractionDigits="2"/></span>%</td>
<td class="text-center">
<g:form action="updatebaseprice" id="${obj.id}" name="form_${obj.id}">
<g:hiddenField name="projectProduct" value="${prod.id}"></g:hiddenField>
<g:hiddenField name="unitCost" id="unitCost_${prod.id}" value="${prod.product.unitCost}"></g:hiddenField>
<g:hiddenField name="recoveryPercent" id="recoveryPercent_${prod.id}" value="${prod.recoveryPercent}"></g:hiddenField>
<g:submitToRemote id="save_button_${prod.id}" class="hidden button alert save_unitprice radius" id="save_button_${prod.id}" url="[action: 'updatebaseprice']" onSuccess="Project.saveBasePrice();" value="Save"/>
</g:form>
</td>
I get the three hidden params (as excepted), but not the input that is above the form (I don't expect that, given it is outside the form). The question I have is, why is the first way not returning anything, when I expect it to return the three hidden and one visible field values as params?
Thanks

The problem is that you're trying to nest a form inside the html table structure.
As you figured out, you can have a form inside a single table cell but trying to put a table row inside a form won't work.
See this question for some more info: Form inside a table

Related

laravel delete form is not working

#extends('layouts.app')
#section('content')
<div class="row">
<div style="float:left;" class="col-md-8">
<h3>Currency</h3>
</div>
<div style="float:right;" class="col-md-4">
<i class="fa fa-edit" style="color:white;"></i>Add New
<input type="text" id="search" name="search" placeholder="search" class="form-control-sm col-md-8 ml-1" style="float:right;"><br><br>
</div>
</div>
#if(count($currencies) > 0 )
<table class="table table-striped table-sm" >
<thead>
<tr><th scope="col">ID</th><th scope="col">Currency</th><th scope="col">Country</th><th scope="col" colspan="2" style="text-align:right">Actions</th></tr>
</thead>
#foreach($currencies as $currency)
<tr><td scope="row">{{$currency->id}}</td>
<td>{{$currency->title}}</td>
<td>{{$currency->country}}</td>
{!!Form::open(['action'=>['CurrencyController#destroy', $currency->id], 'method'=>'POST'])!!}
{{Form::hidden('_method','DELETE')}}
#csrf
<td><button type="submit" class="btn btn-danger btn-sm" style="float:right"><i class="fa fa-remove" style="color:white;"></i>Delete</button>
</i>Edit</td></tr>
{!!Form::close() !!}
#endforeach
</table>
{{$currencies->links()}}
#else
<p> No Data Available </p>
#endif
#endsection
Hi all, The delete form is not submitting in this code and I tried so many thing but I could not figure out the issue. Please help me with this.
It looks to me that your html is wrong, you open, close your form and place #csrf outside your td tag while submit button is inside it
Try to move your form definition inside td tag like:
<td>
{!!Form::open(['action'=>['CurrencyController#destroy', $currency->id], 'method'=>'POST'])!!}
{{Form::hidden('_method','DELETE')}}
#csrf
<button type="submit" class="btn btn-danger btn-sm" style="float:right"><i class="fa fa-remove" style="color:white;"></i>Delete</button>
</i>Edit
{!!Form::close() !!}
</td>
Try changing the method in the actual form tag to DELETE? By default if you are using something like route::resource in your routes, it will automatically assign the DELETE method to the route, not the POST.
I can see you're specifying the delete method in a hidden element anyway, but its worth a try.
{!!Form::open(['action'=>['CurrencyController#destroy', $currency->id], 'method'=>'POST'])!!}
If you're never quite sure, run php artisan route:list in your terminal inside your project root directory, and it will give you a full list of the routes and methods for your application.

Not working below angularjs code

<tr data-ng-repeat="myTrack in myTrackList">
<td class="project-status" data-ng-switch="myTrack.opened">
<span data-ng-switch-when="true" class="label label-primary">Active</span>
<span data-ng-switch-when="false" class="label label-default">Inactive</span>
</td>
<td class="project-title"><a
id="{{myTrack.trackId}},{{myTrack.file.fileId}}"
href="getDocumentByFileId?fileId={{myTrack.file.fileId}}&trackId={{myTrack.trackId}}">{{myTrack.trackName}}</a>
<br /><small>Description: {{myTrack.description}}</small>
<br /> <small>Created: {{myTrack.createdTime}}</small></td>
<td class="project-people" colspan="2">
<div class="project-people" ng-repeat="persons in myTrack.personTrack">
<a href=""><img alt="image" title="persons.firstName"
class="img-circle" src="persons.profilePictureUrl"></a>
</div>
</td>
<td class="project-actions"><a href="#"
class="btn btn-white btn-sm"><i class="fa fa-folder"></i>
View </a></td>
</tr>
I taken list of objects and in single object there is set of user with their profile picture. I used ng-repeat in ng-repeat for repeating users set from list of objects but my inner ng-repeat not working correctly. please help me.
As for the code bellow :
<div class="project-people" ng-repeat="persons in myTrack.personTrack">
<img alt="image" title="persons.firstName" class="img-circle" src="persons.profilePictureUrl">
</div>
The browser do not know that you are using angular js variable for title or src. So you will need.
<div class="project-people" ng-repeat="persons in myTrack.personTrack">
<img alt="image" ng-attr-title="{{persons.firstName}}" class="img-circle" ng-src="{{persons.profilePictureUrl}}">
</div>
So you will need to include the ng tags when you want to use the angular js for tags.

Improve page performance by reducing number of binding with AngularJS?

Context
I'm building a list a results where each result can be edited by users.
Approach
Currently I'm repeating the visible <span> tag that displays a result as well as the hidden <input> tag used to edit this same result. See the last <td> :
<tr ng-repeat="entry in paginateDict | orderBy:predicate:reverse" class="form-inline" role="form">
<!-- Edit buttons -->
<td>
<div class="radio">
<label ng-hide="editMode" title="edit">
<input class="sr-only" type="radio" name="edit"
data-ng-click="editMode=true">
<span tooltip="edit" class="fa fa-pencil fa-lg"></span>
</label>
<label ng-show="editMode" title="save">
<input class="sr-only" type="radio" name="edit"
ng-model="editMode" ng-click="submitEntry(true)">
<span tooltip="save" class="fa fa-save fa-lg text-primary"></span>
</label>
<label ng-show="editMode" title="cancel">
<input class="sr-only" type="radio" name="edit"
ng-model="editMode" ng-click="submitEntry(false)">
<span tooltip="undo" class="fa fa-times fa-lg text-danger"></span>
</label>
</div>
</td>
<!-- Content -->
<td ng-show="pyn" lang="cmn-py" data-id="{{entry.cid}}">
<span ng-hide="editMode">{{entry.pyn | pinyin }}</span>
<input type="text" placeholder="{{entry.pyn}}" ng-model="entry.pyn" ng-show="editMode" class="form-control">
</td>
</tr>
Each line as 5 editable columns and each column as two binding (on <span> and <input>).
Question
In order to improve page performance, by reducing the number of binding, is there an Angular way to dynamically create and attach the <input> to a row when the edit radio button is click ?
You can do that using ngIf directive instead of ng-show
The ngIf directive removes or recreates a portion of the DOM tree based on an {expression}.
<td ng-show="pyn" lang="cmn-py" data-id="{{entry.cid}}">
<span ng-hide="editMode">{{entry.pyn | pinyin }}</span>
<input type="text" placeholder="{{entry.pyn}}" ng-model="entry.pyn" ng-if="editMode" class="form-control">
</td>

Watir-Webdriver - Parsing through table and clicking start/stop toggle

Please be gentle. I'm very new to Ruby and Watir. In general also new to UI automation testing. I'm trying to parse through a table then click a toggle that start/stops an application. The applications that can be turned on and off are not set. They can range from 1 to 'infinite' number applications. I need something that will parse through each row and click the toggle. if the application is started, I need to turn it off and vice-versa. No matter how many rows exist. The row also contains an element in the first column that allows the application to be clicked and brought to another page that gives details about said application. The toggle exists in the last column of the table. Here is the HTML I'm looking at with two applications deployed. It may be something simple that I'm missing. I'm also normally an IT admin that just got thrown into this. Thanks for all the help
<table id="apps_data" class="table table-striped table-bordered table-hover ng-scope">
<thead>
<tr>
</thead>
<tbody>
<tr class="link ng-scope" ng-repeat="app in services.data | orderBy:services.sort">
<td class="ng-binding" ng-click="click_app(app.Id)">Zenoss</td>
<td class="ng-binding deploy-success" ng-class="app.deploymentClass">
<span class="glyphicon glyphicon-ok" ng-class="app.deploymentIcon"></span>
successful
</td>
<td class="ng-binding">default</td>
<td>
<div class="toggle btn-group" data-toggle="buttons">
<label class="ng-binding btn btn-success active" ng-click="clickRunning(app, 'start', servicesService)" ng-class="app.runningClass">
<input class="ng-pristine ng-valid" type="radio" value="1" ng-model="app.Running" name="running0">
started
</label>
<label class="ng-binding btn btn-default off" ng-click="clickRunning(app, 'stop', servicesService)" ng-class="app.notRunningClass">
<input class="ng-pristine ng-valid" type="radio" value="stopped" ng-model="app.Running" name="running0">
</label>
</div>
</td>
</tr>
<tr class="link ng-scope" ng-repeat="app in services.data | orderBy:services.sort">
<td class="ng-binding" ng-click="click_app(app.Id)">Zenoss</td>
<td class="ng-binding deploy-success" ng-class="app.deploymentClass">
<span class="glyphicon glyphicon-ok" ng-class="app.deploymentIcon"></span>
successful
</td>
<td class="ng-binding">default</td>
<td>
<div class="toggle btn-group" data-toggle="buttons">
<label class="ng-binding btn btn-success active" ng-click="clickRunning(app, 'start', servicesService)" ng-class="app.runningClass">
<input class="ng-pristine ng-valid" type="radio" value="1" ng-model="app.Running" name="running1">
started
</label>
<label class="ng-binding btn btn-default off" ng-click="clickRunning(app, 'stop', servicesService)" ng-class="app.notRunningClass">
<input class="ng-pristine ng-valid" type="radio" value="stopped" ng-model="app.Running" name="running1">
</label>
</div>
</td>
</tr>
</tbody>
</table>
I have this so far, but it's just going to the first line.
if ff.div(:class, 'toggle btn-group').label(:class, 'ng-binding btn btn-success active').exist?
ff.div(:class, 'toggle btn-group').label(:class, 'ng-binding btn btn-default off').click; sleep 1
ff.div(:class, 'toggle btn-group').label(:class, 'ng-binding btn btn-default off').exist?
ff.div(:class, 'toggle btn-group').label(:class, 'ng-binding btn btn-default off').click; sleep 1
end
This might do what you want:
apps = browser.table(:id => 'apps_data').tbody.trs
apps.each do |app|
set_radios = app.radios.find_all{ |radio| !radio.set? }
if set_radios.length == 2
# Neither radio button is set, so do nothing?
else
set_radios.first.set
end
end
What this does is:
Gets a collection of all tr elements in the table body. Each tr element is assumed to represent an "app".
Iterates through each row (app):
Counts the number of radio buttons that are not set.
If neither of the 2 radio buttons is set, it does nothing.
If only one unset radio button is found, it is set.
Note that since the 2 radio buttons of the app have the same name attribute value, setting the one radio button will automatically unset the other.

EditorFor .no need to show label

<td class="editor-label">
#Html.LabelFor(model => model.Gender)
</td>
<td class="editor-field">
#Html.EditorFor(model => model.Gender)
</td>
I have this in my view.
but at this time i am seeing
<td class="editor-label">
<label for="Deaseased_Gender">Gender</label>
</td>
<td class="editor-field">
<div class="fieldContainer">
<span class="fieldLabel">
Gender <text>:</text>
</span>
<div class="editorField">
<input id="Deaseased_Gender" name="Deaseased.Gender" type="text" value="" />
</div>
</div>
</td>
</tr>
At this time I am seeing Gender twice
what can i do to avoid the auto generated text 'Gender' ,but need to keep EditorFor with out change?
Here's my guess. This part:
<div class="fieldContainer">
<span class="fieldLabel">
Gender <text>:</text>
</span>
<div class="editorField">
<input id="Deaseased_Gender" name="Deaseased.Gender" type="text" value="" />
</div>
</div>
Makes me think that you've got custom editor for the Gender property of your model. Do you have an EditorTemplates folder, probably under Shared in your Views? That's a convenient place to stick reusable templates to use throughout your app.
If you do and you want to use that, then you'd want to remove either the span in that which has the "Gender :" or rework things to remove the
<td class="editor-label">
<label for="Deaseased_Gender">Gender</label>
</td>
part, but that might involve a little more work because you're mixing tables and divs then.
This is not the default behavior for EditorFor in MVC. But to overcome this problem, use "Editor Templates" for this datatype. Following are few examples.
http://xhalent.wordpress.com/2011/01/18/using-editortemplates-in-mvc-3/
http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/

Resources