getting a collection back from a form in grails - forms

I have an album view where a user can check which photos to delete. I am currently doing this:
<g:form action="delete">
<g:each in="${pictures}">
<div id="images2">
<img id="images2" src="${it.urlThumb}" alt="no Picture"/><br>
<g:checkBox name="myCheckbox"/>
</div>
</g:each>
<g:submitButton name="Submit"/>
</g:form>
The problem is this creates the form dynamically so each of the names are the same for the check boxes. I ideally want a collection returned to the controller that has each of the checked images.
Any ideas?

In the <g:checkBox> you need to specify a value. Each checkbox will be created with the same name but a different value. When the form is submitted with different checkboxes checked, you will get a list in the controller.
View:
<g:each in="${pictures}">
<div id="images2">
<img id="images2" src="${it.urlThumb}" alt="no Picture"/><br>
<g:checkBox name="myCheckbox" value="it.id"/>
</div>
</g:each>
Controller:
def checked = params.list('myCheckbox')

Related

TYPO3 merge list and edit

I've got a TYPO3 backend module which lists a lot of elements. Now, I want to include in my list the edit form, but that doesn't work well at the moment.
Rendering is good, but if I send the form, I get the error:
Required argument "note" is not set.
My code looks like this:
<f:for each="{notes}" as="note">
<f:form action="update" name="note" object="{note}">
<textarea class="form-control gettooltip" rows="1" placeholder="Kommentar" title="Kommentar zur Note">{note.kommentar}</textarea>
</f:form>
</f:for>
How can I merge these two views correctly?
Your code cannot work because your textarea doesn't have a property (or you don't use the <f:form.textarea ViewHelper).
If you property map $note in your controller, the property must be passed to Fluid with the prefixed extension name and plugin name. This is done automatically when using the "property" argument of the textarea ViewHelper. The name attribute will then be:
<textarea name="tx_myext_myplugin[note]"...
Thîs will map to $note in the controller.
So if you don't use the ViewHelper, you need to manually prefix the name attribute to create an output like printed just above.
If you're planning to update multiple objects of the of the same kind in one request, this won't because because there is an Extbase limitation.
You could do the following:
Use a submit button for each note and save/reload the changes through AJAX.
<f:for each="{notes}" as="note">
<f:form action="update" name="note" object="{note}">
<f:form.textarea class="form-control gettooltip" placeholder="Kommentar" property="kommentar">{note.kommentar}</f:form.textarea>
<f:form.submit value="Update" />
</f:form>
</f:for>
Then you intercept the submit click, submit the form through AJAX and set the new content to the textarea.
If you want to have one form for all objects, you will need to prefix the fields
<f:form action="update" name="note">
<f:for each="{notes}" as="note">
<f:form.textarea class="form-control gettooltip" placeholder="Kommentar" name="note[note{note.uid}][kommentar]">{note.kommentar}</f:form.textarea>
</f:for>
<f:form.submit value="Update" />
</f:form>
You will then have an array of values and need to iterate in your controller and manually persist the changes.
For your problem - as #lorenz answered you need to use viewhelpers for rendering fields OR at least use valid name attributes for your fields...
Anyway, I'm wondering why do you want to reinvent the wheel - especially while creating BE modules, the fastest, easiest and most elegant way is... using TYPO3 forms. They handle many things, relations, localization, validation, RTE etc, etc. What's more you can also add own type of field to TCA and process with your own PHP and JS - very rare situation, but may be used i.e. for adding GoogleMap field,
#see: user type in TCA
Finally all you need to open the record from your BE module is creating proper link - which can be easily copied from List module (right click on the yellow pencil next to your record and copy the code), sample:
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][1234]=edit'; return false;" title="Edit user">
<span title="" class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-open"> </span>
</a>
Where fe_users is table name and 1234 is record uid.
alt_doc.php?returnUrl='+T3_THIS_LOCATION part handles returning to the place from which edit was started, so it will be your module again including all GET params selected by admin before editing.
For creating new user
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][6789]=new'; return false;" title="New record">
<span class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-new"> </span>
</a>
In this case 6789 is a PID (uid of the page where the user should be created...
You can even set some default values when creating records from your own module using params in your new link:
&defVals[table_name][field_name]=value
sample
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][6789]=new&defVals[fe_users][tx_extbase_type]=Tx_MyExt_People&defVals[fe_users][usergroup]=1'; return false;" title="New record">
<span class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-new"> </span>
</a>

Questions about grails form

Assuming that i have the following data in my params
params:[input:[1, 2, 3]]
And i have the following form in my Grails app
<div class="block1">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input1" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block2">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input2" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block3">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input3" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
The form design above is correct, because in my form design, there will be several inputs of the same name (but each will be saved to the database under different primary keys) and it can be increases and decreases according to user selection.
Few questions using the above
How do i make it so that the value for input1 is params.input[0], input2 is params.input[1] and input3 is params.input[2] in the view? I can pass the model from controller without problem, but i couldn't distribute the value properly to each input on the form.
Is there any way to change the value ${input} dynamically? As in if i want to change the value to ${input[0]} or ${input[1]}
Can i automatically set the amount of block appended into the form using the g:each tag? Say like if from controller i want to set the rendering block amount to 3, so can i use the g:each tag to render the block 3 times in the form?
Thanks
The links are examples of how to use ajax/jquery to get values from a remote call and replace html element (divId) within a page - this divId could be the entire
<input type="text" name="input" value="newvalue"/>
upon triggering some form of call as above to get the new value.. in regards to
g:textField
yes it works like all other grails tags in the end they are transformed back to the correct HTML terminology...
The actual variable value is dynamic if you defined
<input name="existingvariable" value="${something}" ...
where something was a parameter from the given controller - and then you updated the call so
://YOURHOST:8080/yourapp/controller?existingvariable=newvalue
and refreshed or clicked this link which is what ajax would be doing for you doing a new call to either another controller to generate new values or same and passing new value to it and then grabbing data and pushing it back onto the divId ... (all in the background)
Groovy loading into divs
Grails - Select menu not rendering
I want my selects dropdowns to auto populate with Ajax in Grails website
The above are all related to using ajax to populate / update existing form elements
If you wish to update a live form with a new live value (non existant in DB) take a look at modaldynamix plugin. //github.com/vahidhedayati/modaldynamix

angularjs: trigger form validate programmatically (inside a controller)

I have this situation in which I show 1 form in two steps. So to proceed to the second part of the form you have to click on a button. But before moving on I would like to perform form validation (all required fields need to be filled in). But because this is a normal button, the whole submit magic is not triggered and the validation does not happen. So the question I'm interested in is how can I trigger form validation in my controller ? It would even be better to trigger validation for specific fields. Just to give an idea, the form looks like
<form name="form" submit="save()">
<section id="step1">
<label for="username" required>Username</label>
<input type="text" name="username" ng-model="user.username" required />
.....
<button ng-click="proceed()">Proceed</button>
</section>
<section id="step2">
<label ...></label>
<input...>
....
<button type="submit">Save</button>
</section>
</form>
Also, I don't want to opt for disabling the button until all required fields are valid.
Take a look at the ng-form directive. It allows nesting forms (actually not HTML <form>s, but Angular NgFormControllers). So you can split your one form, used for posting to the server, into two logical forms, used for independent validation:
<form submit="save()">
<div ng-form="form1">
...controls...
<button ng-click="proceed()"
ng-disabled="form1.$invalid">Proceed</button>
</div>
<div ng-form="form2">
...controls...
<button type="submit"
ng-disabled="form2.$invalid || form1.$invalid">Submit</button>
</div>
</form>
You can access the $valid property from your controller. Something like this could work.
$scope.proceed = function(){
if($scope.form.username.$valid){
//username is valid we may proceed to the next step
}
};
<button ng-click="proceed()">Proceed</button>
Replace To :
<button ng-click="proceed()" ng-disabled="form.$invalid">Proceed</button>
Button will not visible button until all required fields are valid.
DEMO

Is it possible to implement dynamic form input rows (adding new row by clicking on Add) with Handlebars and Meteor?

I'm getting my hands dirty with Meteor, and I wanted to port this AngularJS app (http://simplydo.com/projector/) over as an exercise.
I'm having difficulty implementing adding dynamic input form rows to sections using Handlebars, and I've found no documentation anywhere that documents if this possible. It's a snap in Angular using ng-repeat, but I want to confirm if this is something that is possible in Handlebars or whether I need to use Jquery in order to achieve this.
Thanks in advance.
It's just as easy in Meteor
all you have to do is repeat the rows with {{#each rowData}} and have a button that adds a document to the collection. Here is an example:
In this template the rows for a page are shown. In order to add a row, the user has to click on the add image. The template is :
<template name="page">
{{#with page}}
<h3>{{title}}</h3>
{{#each rows}}
<div class="row-fluid page-row {{#if isSelected this}}selected-row{{/if}}">
... page content here
</div>
{{/each}}
{{/with}}
<div class="btn-toolbar">
<div class="pull-right">
<a id="add-row" href="#" data-toggle="tooltip" title="{{lbl 'add-page'}}">
<img src="/images/add.png" class="asset-icon"/>
</a>
<img src="/images/separator.png" class="asset-icon"/>
<a id="delete-row" href="#" data-toggle="tooltip" title="{{lbl 'delete-page'}}">
<img src="/images/delete.png" class="asset-icon"/>
</a>
</div>
</div>
</template>
the helpers for this template are:
Template.page.page = function () {
return Session.get("selected-page");
}
in order to add a page the click event for the add button is implemented:
"click #add-row": function (evt, template) {
var page = Session.get("selected-page");
Pages.update({_id: page._id}, ... add a new row here ...)
}
because the whole thing is reactive, the list of rows will redraw after the update on the Pages collection.

MVC Multiple submit buttons on a array of objects

I've got a list of objects in an MVC view, each with a set of submit buttons - Move up, Move down and Remove.
Using the answer from this question, I can get the button clicked - but I need to know which item it would be operating on.
The problem comes from the fact the input's value attribute is passed back, I need more information than that - i.e. an id.
Below is a snippet of the contents of a for loop, rendering each item.
<ul>
<li><input type="submit" name="SubmitButton" value="Move-Up" class="linked-content-position-modifier" /></li>
<li><input type="submit" name="SubmitButton" value="Move-Down" class="linked-content-position-modifier" /></li>
<li><input type="submit" name="SubmitButton" value="Remove" class="linked-content-modifier" /></li>
<li><%= Model.Contents[i] %></li>
</ul>
When the form is posted back, I can see that the SubmitButton has a value of either Move-Up, Move-Down or Remove - but no idea which item in the array it's referring too.
Without changing the value to something really ugly, how would I tell which item it's referring to?
Just a quick idea, but maybe you could try adding hiddenfield to each row and see which one gets submitted?
Why are you using a button?
Could a link work instead?
Move Up
I use similar code to update items in a table, but I do it with javascript and update the table accordingly...
<script type="text/javascript">
$('img.action').click(function(){
var itemId = this.attr('id'); // Do some parsing of the id here, i use a format of bi-##
$.ajax({ uri: 'controller/MoveUp/' + itemId });
});
</script>