rails parameterize form data - html

I have a rails application that allows searching of posts when a get request in the form of /posts/search/:searchstring is recieved. I have no problems with the functionality when I put the search string in using my browser's url bar, but I am stuck trying to create a search form.
How can I make an html form in rails that allows me to send a get request using the above syntax? Am I going to be stuck using a controller method to redirect? I really want this functionality because I am a firm believer that the URL is a part of the UX and I hate ugly URLs like this:
http://example.com/search?utf8=%E2%9C%93&q=searchstring&commit=Search

A form's gonna do what a form's gonna do, and if you have a form using GET, it's gonna serialize those parameters into the query string.
But since you are using get, you also don't truly need to submit the form. Rather you can just send the browser to the URL.
So for example, somewhere in your JS:
function doSearch(form) {
// This assumes that the first input of your form is the search
// box. YMMV.
var query = encodeURIComponent(form.elements[0].value);
// just send the browser to the constructed URL
window.location = form.action + "/" + query;
// and return false to prevent the actual submit
return false;
}
Then in your html:
<form action = "/posts/search" onsubmit="return doSearch(this)">
<input type="text" name="searchstring" />
<input type="submit" />
</form>

How about adding the form this way:
<form method="get" action="<%= search_posts_url_path %>">#text input here with name "searchstring"</form>

Related

How to get clicked img src and pass it to the next view function

I am using flask to deploy my model for image similarity search. To run it, I will have two pages:
1) first page (say, query.html) that shows a randomly generated image from my dataset; users can continue to refresh this page till they see an item that they like. In html, it would be something like <img src="{{ random_path }}" alt="">. When the user is satisfied, the image needs to be clicked to direct to the next page;
2) second page (say, results.html) that takes the img src from the first page, and run the model at backend and return the similar images.
I am now confused how I should link step 1) to step 2) - how to get the img src on click and pass that information on to the next step?
You can use a form with hidden input tags and make a post request (More on flask's post request here) to pass on the data from one page to the other. In code it would look something like this:
HTML:
<html>
<body>
<form action = "/imagematch" method = "post">
<p><input type = "hidden" name = "imagesrc" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
Python Backend:
#app.route('/imagematch',methods = ['GET', 'POST'])
def login():
if request.method == 'POST':
user = request.form.get('imagesrc')
Alternatively you can use JavaScript localstorage/sessionStorage. More on localstorage here:
Write a <form> and place the <input type="hidden"> (with base64 format of the image as value) or <input type="hidden"> (with the server file path as value) whichever comfortable and upon submitting the form the image path/base64 format of the image as value will be sent to server.
Or
Using Javascript or JQuery upon user selects the image, send the image to the server via a AJAX request and do whatever you want at the server-side and return the status to the user accordingly.
Option 1 is simple and straight forward and you need to deal with base64 conversion.
Option 2 is a little complex and needs good JQuery expertise.

Html data attribute in Coldfusion form submission

I understand how to pull out the data attribute in JQuery from an HTML form, but can it be done from within a .cfc controller to which a form is passed?
Page.cfm
<cfform action="controller.cfc" method="getData">
<cfinput name="uploadMyData" type="submit" data-primaryID="123">
</cfform>
Controller.cfc
function getData(rc){
writeDump(rc.uploadMyData.?????(primaryId)????);
}
Not sure if the data attribute is stored in any way in the struct.
I tried a getMetaData on the rc.uploadMyData but just got a list of java functions.
Update
Adrian J. Moreno
Data attributes are just markup that impact the internal data object of the element. They are not part of a form request. You wouldn't submit a form to a CFC file either. Using Ajax, you can read the value from the data attribute and pass it to the server as part of the request's data packet.
So in Page.cfm
<script type="text/javascript">
var otherData = $("#myForm").serialize();
function sendForm(){
var primaryID = $("#submitData").data("primaryID");
jQuery.post("urlpath/controller/",'{"id":'+''+primaryID+'}', function(dataReturn, status){
//I want to get my form and submit the other data as well to the controller
}
}
</script>
<form id="myForm" action="sendForm()">
<input name="uploadMyData" id="submitData" type="submit" data-primaryID="123">
<input name="importantThing" value="#importantVariable#" type="text">
</form>
pass it to the server as part of the request's data packet.
how would I pass them together?
I want this form submission to redirect to another page so I don't see how I couldn't use the controller? The form data should go the newPage.cfc to process it and get it ready for output on newPage.cfm. I'm using framework one but that doesn't change much.
Thanks for the help, what do you think?
Update 2
Ok, now I ask myself why I would want to submit a form with both ajax and coldfusion form submission together? I realize that's not what should be done. I can either
Submit the form via JQuery/Ajax with no page reload, and include the data attribute in the post url and include the serialized form data
Page.cfm
<script type="text/javascript">
var otherData = $("#myForm").serialize();
function sendForm(){
var primaryID = $("#submitData").data("primaryID");
jQuery.post("controller/method/?primaryId="+primaryID+"",otherData, function(dataReturn, status){
//do stuff with dataReturn or do a javascript redirect
}
}
</script>
Controller.cfc
function method(requestContext){
//do stuff with that otherData, all stored in request context. includes the primaryID value i appended to the url
//send it back to the Page.cfm
fw.renderData("rawjson",jsonString,200,"");
}
and if that made it back ok, I could run a function back in my original view with that information. Like display it on the page.
Submit the form traditionally which would result in a page reload. Include a hidden input type with the value that I want to pass.
Page.cfm
<cfform action="controller.method" method="getData">
<cfinput name="uploadMyData" type="submit" value="Submit Form Button">
<cfinput name="primaryID" type="hidden" value="123">
</cfform>
Controller.cfc
function method(requestContext){
//do stuff with requestContext.primaryID
//go to the view method.cfm or do a fw.redirect("new page or back to the page i came from");
}
Why would we want to submit the form twice? just do one or the other.
Matt, I think you're confused about a number of things that are quite basic to HTML, JavaScript and jQuery and have nothing to do with ColdFusion.
Let's start with an HTML Form.
<form id="{{unique_dom_value}}" action="{{uri}}" method="{{http_verb}}">
unique_dom_value: Some string unique to the document. Allows you to reference the entire form object using JavaScript.
uri: The URI to which you submit the form for processing.
http_verb: Defaults to GET, but you should most often use POST.
The URI you're trying to post to in just controller.cfc, but that won't do anything but redirect you to the ColdFusion CFC inspector.
In the context of most MVC frameworks, index.cfm?event=handler.action uses the underlying framework to call a function named action within a CFC named handler. Without a framework, you have to do that manually. So if you have a CFC named controller.cfc and want to send your form data to a function named myFunction, you need to say action="controller.cfc?method=myFunction.
But that's not right either. When you submit a form, the browser expects to load the URI that's found in the action attribute. But your CFC function doesn't respond with HTML, it responds with something else. Maybe a query object, maybe JSON. This is why you would use jQuery.Ajax() to send the form data (including the data attribute values) to the CFC's function, which should return data in JSON. Once you get a response, you can continue processing on the same page or redirect to another page.
However, since you're using Framework One, I would look into the documentation on using renderData() within one of your handler functions.

How to send a more complex POST form?

I have the following table where a user can choose some quanitity for a corresponding item.
What is the simplest way to send this data to the server without using JavaScript?
Right now I am creating a data-name with item's name on each quantity input field. Then grabbing all those input fields, followed by the $.post request (not shown here).
var items = [];
var $quantities = $('.quantity');
$.each($quantities, function(index, input) {
items.push({
name: $(input).data('name'),
quantity: $(input).val()
});
});
I am curious to know if there is a more elegant approach to do this with just using the HTML form element.
Edit: I am free to choose whatever model I see fit. No constraints there since this is a fresh from the start personal project.
You could create a traditional HTML form.
<form method="post" action="/url/to/submit/to.php" id="orderform">
<table>
... all your order table code ...
<input type="text" name="cucumber" value="0">
... and all your input code ....
... etc ...
</table>
</form>
Then have the action URL be a server-side script that processes the form data and returns an appropriate webpage. Note: this will require the webpage to reload.
The nice thing about JavaScript is you can submit the form data and not have to reload the webpage.
Also note, you can get your HTML form data using jQuery very easily. In my above example:
var formData = $('#orderform').serializeArray();
Now use can use formData in your $.post() script.
If you put the item names into hidden input fields in the form, you can use:
$('#formID').serialize()
to get all the inputs in one step, and pass this as the data argument to $.post().
In this way you can send form data using ajax
$.ajax({
url:'TarfetPage.jsp',
type:'POST',
datatype:'text',
data:$('#formID').serialize(),
success:function(data)
{
$("#divId").html($.trim(data));
}
});

How to remove trailing question mark from a GET form with no fields?

Example:
<form>
<input type='submit'>
</form>
When submitted results in:
http://example.com/?
How to make it:
http://example.com/
?
[This is a very simple example of the problem, the actual form has many fields, but some are disabled at times. When all are disabled, the trailing ? appears]
In my case I'm using window.location, not sure it's the best alternative, but it's the only one I could make it work:
$('#myform').submit(function()
{
... if all parameters are empty
window.location = this.action;
return false;
});
My real use was to convert GET parameter to real url paths, so here is the full code:
$('#myform').submit(function()
{
var form = $(this),
paths = [];
// get paths
form.find('select').each(function()
{
var self = $(this),
value = self.val();
if (value)
paths[paths.length] = value;
// always disable to prevent edge cases
self.prop('disabled', true);
});
if (paths.length)
this.action += paths.join('/')+'/';
window.location = this.action;
return false;
});
Without using Javascript, I'm not sure there is one. One way to alleviate the problem may be to create a hidden input that just holds some junk value that you can ignore on the other side like this:
<input type="hidden" name="foo" value="bar" />
That way you will never have an empty GET request.
This is an old post, but hey.. here ya go
if you are using something like PHP you could submit the form to a "proxy" page that redirects the header to a specific location + the query.
For example:
HTML:
<form action="proxy.php" method="get">
<input type="text" name="txtquery" />
<input type="button" id="btnSubmit" />
</form>
PHP (proxy.php)
<?php
if(isset($_GET['txtquery']))
$query = $_GET['txtquery'];
header("Location /yourpage/{$query}");
?>
I am assuming this it what you are trying to do
I was looking for similar answer. What I ended up doing was creating a button that redirects to a certain page when clicked.
Example:
<button type="button" value="Play as guest!" title="Play as guest!" onclick="location.href='/play'">Play as guest!</button>
This is not an "answer" to your question but might be a good work around. I hope this helps.
Another option would be to check the FormData with javascript before submitting.
var myNeatForm = document.getElementById("id_of_form");
var formData = new FormData(myNeatForm); // Very nice browser support: https://developer.mozilla.org/en-US/docs/Web/API/FormData
console.log(Array.from(formData.entries())); // Should show you an array of the data the form would be submitting.
// Put the following inside an event listener for your form's submit button.
if (Array.from(formData.entries()).length > 0) {
dealTypesForm.submit(); // We've got parameters - submit them!
} else {
window.location = myNeatForm.action; // No parameters here - just go to the page normally.
}
I know this is a super old question, but I came across the same issue today. I would approach this from a different angle and my thinking is that in this day and age you should probably be using POST rather than GET in your forms, because passing around values in a querystring isn't great for security and GDPR. We have ended with a lot of issues where various tracking scripts have been picking up the querystring (with PII in the parameters), breaking whatever terms of services they have.
By posting, you will always get the "clean url", and you won't need to make any modifications to the form submit script. You might however need to change whatever is receiving the form input if it is expecting a GET.
You will get a trailing question mark when submitting an empty form, if your server adding trailing slash to URL and your action URL of form - is directory (and not file) and:
Trailing slash in the action attribute URL (action="/path/").
With dot (with or without trailing slash after it) instead specific URL (action="." or action="./").
With empty action (action="").
Form without action attribute.
Try to specify an action-URL without trailing slash:
action="path"
or
action="./path/sub"
and
action="/path"
or
action="/path/sub"

How to append querystrings to a URL on submit of a form?

Ok, so I have 2 forms on a clients website (website is built in wordpress).
The client is using Mail Chimp for his email marketing and has 2 forms set up in Mail Chimp to capture users data and subscribe them to two different lists.
I have 2 sections on the website with mini versions of these forms - The forms he has done in mail chimp are much bigger and require allot more details the ones I have on the site only have name, phone, email.
I have read an article on mail chimps blog that talks about how you can auto fill certain fields on the form on page load by adding the relevant query to the end of the url e.g. http:/FORMADRESS&MERGE1=Jack - this would pre-fill the "First Name" box on the form with the name Jack.
((http://blog.mailchimp.com/how-to-pre-fill-items-on-your-mailchimp-hosted-form/))
How can I add these query strings to the end of the URL in order to prefil the 3 fields from the mini form on the site on the large mail chimp form?
Any alternative solutions anyone is aware of would also be greatly appreciated.
Kind Regards,
A form should do the trick, if I understand you correctly:
<form action="http://echo.iambroken.com/" method="get">
<input name="one">
<input name="two">
<input type="submit">
</form>
Note that if there’s already a query string on the action URL, this will replace it — so if there are other parameters on the URL already, include them instead in the form as hidden inputs like this one:
<input type="hidden" name="q" value="123">
You can append a hidden variable to form using simply append query
Here you can do as following in your javacript.
Var hiddenVar="<input type="hidden" name="q" value="123">"
$('form').append(hiddenVar)
and you can get this value request parameter on your action.
Using JQuery you can modify the action attribute when the form loads. In the example below I am filtering out just the QueryString parameters I need submitted with the form and applying them to the action.
$(function(){
var urlParams = new URLSearchParams(location.search);
var id = urlParams.get('id');
var codeid = urlParams.get('codeid');
var params = "?id=" + id + "&codeid=" + codeid;
$("form").attr("action", location.pathname + params);
});
You get mini form three fields and push them to other form as hidden fields. Then when used submit them, hidden field also part of the form and will be added to URL.