Passing selected value of a select to form action - scala

I have a menu that I want to differ based on which account is currently selected in the system.
I have a page that allows a user to select an account from an html select. When the user submits the form from the account selection page I want to call the menu method on my controller passing in the selected value so my url looks correct.
Here is the existing template from the page that allows a user to select an account:
#helper.form(action = routes.Accounts.menu {
<table>
<tr>
<td><select id="accountNames">
#accountNames.map { name =>
<option value="#name">#name</option>
}
</select></td>
</tr>
<tr>
<td>
<p>
<input type="submit" value="Choose">
</p>
</td>
</tr>
</table>
}
From my routes file:
GET /account/:accountName/menu controllers.Accounts.menu(accountName: String)
How do I reference the selected value from my select (id="accountNames") and pass it into my form action?

Actually I think you're on the wrong side for doing that.
If the form's action has to change over the use of your 'select', it has to be done using JS.
So when the form is submitted (event submit) you have to update the url.
This can be done easily using javascriptRoutes.
So you have to do several things:
1/ create the javascriptRouter (assuming your add it in Application.scala)
def javascriptRoutes = Action {
Ok(
Routes.javascriptRouter("playRoutes")(
//accounts
controllers.routes.javascript.Accounts.menu
)
).as("text/javascript")
}
2/ define it in your routes file
# Javascript routing
GET /assets/javascripts/routes controllers.Application.javascriptRoutes
3/ add the related javascript file import in your views, let say in main.scala.html
<script type="text/javascript" src="#routes.Application.javascriptRoutes"></script>
4/ add a submit handler to your form that does that before executing the default behavior
$("form").submit(function () {
//this computes the correct URL giving a parameter which is the value of the selected option
var newURl = playRoutes.controllers.Accounts.menu($("#accountNames").val()).url
$(this).attr("action", newUrl);
})
Notice how we've used playRoutes both in the controller (1) and the JS call (4).

Related

Passing multiple data points to an action? VUEX

So I have a form that collects 3 data points that looks like this:
<form class="" >
<table>
<tr>
<td>Maximum Temperature</td>
<td><input class="setSettings" v-model="settings.maxTMP" type="number" max="30" min="5"></td>
</tr>
<tr>
<td>Minimum Humidity</td>
<td><input class="setSettings" v-model="settings.minHUM" type="number" max="95" min="20"></td>
</tr>
<tr>
<td>Maximum CO2</td>
<td><input class="setSettings" v-model="settings.maxCO2" type="number" min="200" max="5000" step="10"></td>
</tr>
</table>
<button type="button" v-on:click="whatSettings(settings)">Update Settings</button>
</form>
My data in the script tag is stored in the components local data, not the store, ike this:
data: function() {
return {
settings: {
maxTMP: "",
minHUM: "",
maxCO2: ""
}
}
}
There's no reason to put it through a mutation and commit it to the store as the purpose for the action is merely to send the data via post request to receiving api.
My methods for the component look like this:
methods: {
...mapActions({
setSettings: 'setSettings'
}),
whatSettings(settings){
let foo = settings.maxTMP;
let bar = settings.minHUM;
let uhm = settings.maxCO2;
console.log(foo);
console.log(bar);
console.log(uhm);
this.setSettings(foo,bar,uhm)
}
},
And that action from the store is write like this:
setSettings(foo,bar,uhm) {
console.log("Set these settings");
console.log(foo);
console.log(bar);
console.log(uhm);
},
Please forgive all the console.log()'s. I have it like this cause I was trying to test out different combinations of things to figure out where it goes wrong. Right now when I click the Update Settings button the console prints the whatSettings() correctly so I know that foo, bar, uhm are the correct value as they are passed into the setSettings() action. The problem is in the action's logs. "Set these settings" and foo are printed correctly followed by a single undefined, not two. So I'm not sure exactly what's happening with bar & uhm. When I rearrange the order it's always the first that gets printed.
Is it a problem with multiple arguments being passed to the action? Ideally I would just like it to look like this directly in the button tag for neatness but that didn't work so I tried trouble shooting like this:
v-on:click="this.setSettings(settings.maxTMP, settings.minHUM, settings.maxCO2)"
Thanks for reading and I appreciate the help!
Well, after a little more looking around I found this and it fixed my problem: Axios post request with multiple parameters in vuex action
correct button tag:
<button type="button"
v-on:click="setSettings({
foo: settings.maxTMP,
bar: settings.minHUM,
uhm: settings.maxCO2
})"
>Update Settings</button>
correct vuex store action:
setSettings({commit}, {foo, bar, uhm}) {
console.log("Set these settings");
console.log(foo);
console.log(bar);
console.log(uhm);
},
Not entirely sure why the {commit} needs to be present, but it does otherwise I just get 3 undefined results in the log. But it works now!

How to delete objects on a Thymeleaf th:each iteration passing an ID to the controller?

My controller:
#GetMapping("/deletesocio/{id}")
public String delSocios(#PathVariable Long id){
socioSer.borrar(socioService.buscarPorId(id));
return "redirect:/webapp/socios";
}
My HTML
<tr th:each="soc : ${list}">
<td th:text="${soc.idSocio}">#</td>
<td th:text="${soc.nombreSocio}">Nombre</td>
<td class="button778"><button type="button"
th:href="#{/webapp/delsocio/${soc.idSocio}}"></button></td>
</tr>
I want to delete the object by clicking this button who pass de id to the controller (well, thats the idea), could any one help me please?? thank you very much
There are 2 parts to this...
1) The url expressions you should use is: #{/webapp/delsocio/{id}(id=${soc.idSocio})}
2) You can either make it a form with a submit button or style a regular link as a button as described here. Whichever solution you decide on will determine if you use th:action="#{/webapp/delsocio/{id}(id=${soc.idSocio})}" or th:href="#{/webapp/delsocio/{id}(id=${soc.idSocio})}".

fine-uploader resubmit parameters but not file

I'm using fine-uploader to take multiple (large) files and pass the filename along with an additional user-input parameter. I do that by creating a text input box (called 'allele_freq') next to each file and I pass the filename and the allele_freq parameter to my cgi script.
What happens next (or what will happen next) is that I analyse the data in the file, using the allele_freq parameter and then some images are returned to the page for the user to look at.
If the user wants to re-analyse the data with a new allele_freq, all I want to do is to pass the filename along with the new allele_freq, i.e. I don't want to have to upload the file again.
I've pasted my working code below (it uploads multiple files along with user input for each file) and then the code that I can't get to work (it produces a 'resubmit' button, but doesn't appear to do anything), along with some comments/musings within the code.
Any information on how I would do this will be gratefully received. I'm very new to both fine-uploader and Javascript (as you can probably tell), so please feel free to criticise (constructively of course!) any of my code.
Many thanks,
Graham
<link href="fineuploader/fineuploader-3.6.4.css" rel="stylesheet">
<script src="fineuploader/jquery-2.0.1.js"></script>
<script src="fineuploader/jquery.fineuploader-3.6.4.js"></script>
<div id="multiFineUploader"></div>
<div id="triggeredUpload" class="btn btn-primary" style="margin-top: 10px;">
<i class="icon-upload icon-white"></i> Upload now
</div>
<script>
$('#multiFineUploader').fineUploader({
request: {
endpoint: 'src/lib/upload.cgi'
},
autoUpload: false,
text: {
uploadButton: '<i class="icon-plus icon-white"></i> Select Files'
}
})
.on('submitted', function(event, id, name) {
var fileItemContainer = $(this).fineUploader('getItemByFileId', id);
$(fileItemContainer)
.append('<input type="text" name="allele_freq">');
})
.on('upload', function(event, id, name) {
var fileItemContainer = $(this).fineUploader('getItemByFileId', id),
enteredAlleleFreq = $(fileItemContainer).find('INPUT[name="allele_freq"]').val();
$(this).fineUploader('setParams', {allele_freq: enteredAlleleFreq}, id);
});
$('#triggeredUpload').click(function() {
$('#multiFineUploader').fineUploader('uploadStoredFiles');
});
</script>
above code works fine
code below doesn't
<div id="resubmitFreqs"></div>
<div id="retry" class="btn btn-success" style="margin-top: 10px;">
<i class="icon-upload icon-white"></i> Resubmit
</div>
<script>
$('#resubmitFreqs').fineUploader({
request: {
//use a different script as shouldn't need to handle all the upload stuff
endpoint: 'src/lib/resubmit.cgi'
}
)}
//get the information from the allele_freq box. Should it still be in scope?? If not, how do I get at it?
.on('upload', function(event, id, name) {
var fileItemContainer = $(this).fineUploader('getItemByFileId', id),
enteredAlleleFreq = $(fileItemContainer).find('INPUT[name="allele_freq"]').val();
$(this).fineUploader('setParams', {allele_freq: enteredAlleleFreq}, id);
});
$('#retry').click(function() {
//I presumably don't want to use 'uploadStoredFiles', but I'm not sure how to post my new parameters into the resubmit.cgi server-side script
$('#resubmitFreqs').fineUploader('uploadStoredFiles');
});
</script>
It seems like you are trying to bend Fine Uploader into something that it is not. Fine Uploader should probably not be involved with this step of your process, as its job is to upload files to your server. It is not meant to be an all-in-one web application. If you want to send additional data to your server at some point in time after the file has been sent, simply send a POST request with that data via XHR.

Uploading file using Google Apps Script using HtmlService

How can I upload files to google drive?
I want to create a web app using google app script - htmlservice.
I don't know how to point form in html to existing google app script.
I am having hard time to find a right example in google documentation.
I found hundreds of examples using UI but according to https://developers.google.com/apps-script/sunset it will be deprecated soon.
Thank you in advance!
Janusz
<html>
<body>
<form>
<input type="file"/>
<input type="button">
</form>
</body>
</html>
Script
function doGet() {
return HtmlService.createHtmlOutputFromFile('myPage');
}
function fileUploadTest()
{
var fileBlob = e.parameter.upload;
var adoc = DocsList.createFile(fileBlob);
return adoc.getUrl();
}
Have the button run the server side function using google.script.run, passing in the entire form as the only parameter. (Inside the button's onClick, 'this' is the button, so 'this.parentNode' is the form.) Make sure to give the file input a name.
<html>
<body>
<form>
<input type="file" name="theFile">
<input type="hidden" name="anExample">
<input type="button" onclick="google.script.run.serverFunc(this.parentNode)">
</form>
</body>
</html>
On the server, have your form handling function take one parameter - the form itself. The HTML form from the client code will be transformed into an equivalent JavaScript object where all named fields are string properties, except for files which will be blobs.
function doGet() {
return HtmlService.createHtmlOutputFromFile('myPage');
}
function serverFunc(theForm) {
var anExampleText = theForm.anExample; // This is a string
var fileBlob = theForm.theFile; // This is a Blob.
var adoc = DocsList.createFile(fileBlob);
return adoc.getUrl();
}
If you actually want to use that URL you are generating and returning, be sure to add a success handler to the google.script call. You can modify it like this:
// Defined somewhere before the form
function handler(url) {
// Do something with the url.
}
<input type="button" onclick=
"google.script.run.withSuccessHandler(handler).serverFunc(this.parentNode)">
try: return HtmlService.createTemplateFromFile('myPage').evaluate();
More: html service reference
I found an answer for my question.
Submit a Form using Google App Script's HtmlService
The code in the Google App Script link below is:
function doGet(e) {
var template = HtmlService.createTemplateFromFile('Form.html');
template.action = ScriptApp.getService().getUrl();
return template.evaluate();
}
function doPost(e) {
var template = HtmlService.createTemplateFromFile('Thanks.html');
template.name = e.parameter.name;
template.comment = e.parameter.comment;
template.screenshot = e.parameter.screenshot;
return template.evaluate();
}
https://script.google.com/d/1i65oG_ymE1lreHtB6WBGaPHi3oLD_-wPd5Ter1nsN7maFAWgUA9DbE4C/edit
Thanks!

Fake HTML URL address when mouse is over a form

let's say that I have the following form:
<form method="post" action="" autocomplete="off"><input name="checking2" type="submit" value="Name" class="ssd"></form>
When a user submits the form this PHP code takes place:
if(isset($_POST['checking2'])){
$xmla = new SimpleXMLElement('passwords/' . views . '.xml', 0, true);
$plus = $xmla->goodx;
$result = $plus + 1;
$xmla->goodx = $result;
$xmla->asXML('passwords/' . views . '.xml');
header( 'Location: http://google.com' ) ;
}
And the following CSS to design the form: code:
.ssd {
border: none;
background-color: transparent;
padding: 0;
cursor: pointer;
font-size:89%;
display:inline;
text-decoration: underline;
color: #00c;
}
Now, every time that the user clicks on the form he is being redirected in return to google. The PHP code is supposed to add +1 to a xml file's value(It works) every time that someone submits the form. My problem is, that whenever someone places his mouse over the form's value, the URL that he sees is the URL address of the current page he is currently on, Not the URL he will be actually redirected to - Google. I am trying to fake the URL address, so instead of seeing the current page URL address(which is action=""), he will see the URL address of google. And no, do not suggest to just place the URL address of google in "action=", because then the PHP data does not being updated properly for some reason whenever I do that. Any help will be appreciated.
In case I got you right, you want to change the forms action property, don't you?
If so, use this little javascript code:
<script>
function fake_action(){
document.forms["myform"].action="http://example.com";
document.forms["myform"].submit();
}
</script>
<form id="myform" action="http://google.com">
<input type="text" placeholder="placehold.it"/>
<input type="button" value="send" onclick="fake_action();"/>
</form>
Just a quick explenation: I have replaced the submit button with a standard button and specified the fake_action(); function as onclick event handler for it. The fake_action function just change the form's action and submit it afterwards. So you can do your stuff without any problem.
(You should just check for GET / POST Parameters at the page load and eventually send them on to the second page after you received them on the first one ;) )