I have a thymeleaf application that should do the following.
Persist some data to the database when the user clicks the submit button. That same submit button must fetch some data from another server that has its own database; different from mine. Here is my code (obviously, I am doing something wrong ergo my question here.)
<form method="POST" th:action="#{/index}" th:object="${notification}" class="contact-form">
<div id="asset-search" class="row">
<div class="col span-12-of-12">
<!-- <div class="alert alert-info" th:if="${notificationSent}">Your feedback is greatly appreciated.-->
<!-- </div>-->
</div>
<div class="col span-1-of-1">
<label class="search-lbl">Tell us what you are searching for and we will try to find it. Please
include email if you wish us to contact you.</label>
</div>
<div class="col span-2-of-2">
<input type="text" name="keyword" id="keyword" placeholder="Search" th:field="*{search}">
<input type="text" name="email" id="email" placeholder="Email (Optional)" th:field="*{email}">
<button type="submit"
th:data-url
="#{http://auction.mainauctionservices.com/cgi-bin/mmcal.cgi?mainauction/keyword/{search}(search=${search}))}"
onclick="window.open(this.getAttribute('data-url'))">Go
</button>
<!--<button type="submit" onclick="equipmentSearchFn()">Search</button>-->
</div>
</div>
</form>
My controller is working fine. It persists data. No need to worry about the back end. Maybe the controller could be rewritten, but its persisting.
HOWEVER, I need to fetch data from the back end of ANOTHER server. The server that I need to get data from has the following format
"http://auction.mainauctionservices.com/cgi-bin/mmcal.cgi?mainauction/keyword/oven" <--- the word oven comes from this input ... you can click the link you will see it will work; you can replace oven for table or sink and it will work.. that is the back end I am fetching from.
However the words oven or sink or table that the user types in the input search bar below are coming from this th:field="*{search}
<input type="text" name="keyword" id="keyword" placeholder="Search" th:field="*{search}">
It does not come from my database, it doesn't have to; it comes from what the user types in the search bar.
I tried to use the
th:data-url
="#{http://auction.mainauctionservices.com/cgi-bin/mmcal.cgi?mainauction/keyword/{search}(search=${search}))}"
onclick="window.open(this.getAttribute('data-url'))">Go
</button>
That you see up there but I don't know how to grab the search the user enters from the
<input type="text" name="keyword" id="keyword" placeholder="Search" th:field="*{search}">
My controller is this
public class IndexController {
#GetMapping({"", "index", "home"})
public String index(Model model) {
model.addAttribute("notification", new Notification());
return "index";
}
#PostMapping(value = "/index")
public void searchNotification(#Valid #ModelAttribute("notification") Notification notification,
#RequestParam("search") String search,
#RequestParam("email") String email,
Model model, BindingResult result,
HttpServletRequest request) {
if (result.hasErrors()) {
return "index";
}
notification.setSearch(search);
notification.setEmail(email);
model.addAttribute("notification", notification);
notificationService.save(notification);
String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
SimpleMailMessage simpleMailMessage = mailConstructor.sendSearchNotification(appUrl, request.getLocale(), notification);
javaMailSender.send(simpleMailMessage);
model.addAttribute("notificationSent", "true");
model.addAttribute("appUrl", appUrl);
return appUrl;
}
}
I also tried using javascript which was my original thought but the javascript and the controller with return "index" were interfering with each other.
So, I tried to do it with what you see above
here is my javascript
function equipmentSearchFn() {
let keyword;
let url;
keyword = document.getElementById("keyword").value;
url = "http://auction.mainauctionservices.com/cgi-bin/mmcal.cgi?mainauction/keyword/" + keyword;
window.location = url;
}
ideally the javascript would be the fastest and best route but the problem is when its persisting the data via the controller im running into problems with a http POST trying to open a new page with the results..
i don't know if i am overworking this but its definitely got me overworked
thanks
If I understand your question correctly, then you want to have the browser redirect to an external URL after the POST to your controller. To do that, just return a String from your searchNotification method:
#PostMapping(value = "/index")
public void searchNotification(...) {
...
String url = "http://auction.mainauctionservices.com/cgi-bin/mmcal.cgi?mainauction/keyword/" + search;
return "redirect:" + url;
}
Related
I have a simple Window Forms application that opens up a webpage with set parameters.
The link send the user to a page with 2 text box fields and a submit button.
I am trying to automate this process so it grabs the parameter values and puts it into the text box then clicks submit .
This is my current code for my windows form:
using System;
using System.Windows.Forms;
using System.Diagnostics;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
libLink.Links.Remove(libLink.Links[0]);
libLink.Links.Add(0, libLink.Text.Length,
"http://www.example.com/?UserName=value1&FirstName=value2");
}
private void libLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) {
ProcessStartInfo sInfo = new ProcessStartInfo(e.Link.LinkData.ToString());
Process.Start(sInfo);
}
}
}
How can I create a script that that takes those parameters in the URL to populate two text box fields and then submit the form?
This is my HTML Page:
<form action="/send" method="post" novalidate="novalidate">
<input class="form-control" data-val="true" data-val-UserName="Wrong username" data-val-required="Enter a valid Username" id="Username" name="Username" placeholder="Username" type="text" value="">
<input class="form-control" id="FirstName" name="FirstName" placeholder="First Name" type="text" value="">
<button type="submit">Sign In</button>
</form>
Fairly new to coding so I tried to keep my code as simple as possible.
I looked at possible methods such as QueryStrings, JavaScript and Jquery, but I am not sure how to approach this problem.
There's a few ways of doing it really but i'll give you a basic walk through of how i would do it in javascript with a bit of JQuery.
we have variable with the URL we start by:
var url = "http://www.example.com/?UserName=value1&FirstName=value2"
var params_string = url.split("?")[1] //UserName=value1&FirstName=value2
so first we split the string into a list like above which returns a list of the items which are separated by the "?" character, but we only need the second item(at index 1) so we add the [1] to the end to only store that bit.
We then split this again to get the individual parameters.
var params_string_list = params_string.split("&")
["UserName=value1","FirstName=value2"]
which returns a list as above, again need to break that down i would make it into an object like so :
var params = {}
for(var i =0;i < params_string_list.length;i++ ){
var temp = params_string_list[i].split("=") // looks like ["UserName","value1"]
params[temp[0]]= temp[1]
} //params now looks like {"UserName":"value1","FirstName":"value2"}
as this makes it easy to access and use.
we can then do the following to set the values in the form:
if(params.UserName){
$('#Username').val( param.UserName );
}
if(params.FirstName){
$('#FirstName').val( param.FirstName );
}
if statments are there to check that the value exists in the object so we don't sent the value to "undefined" by accident.
Hope this helps.
I am working on an app with NodeJS and have been able to use handlebars and partials without much trouble. I am getting to the point where I have view and edit forms for a car.
For example, after the user submits an application I have "View" and "Edit" links that go to localhost:3000/cars/:id/view and localhost:3000/cars/:id/edit, respectively.
The only difference between these two links is that the "View" page has the form with readonly="readonly" and the "Edit" does not have the readonly attribute.
What I would like to do
cars/view
{{ >car_form readonly=true }}
cars/edit
{{ >car_form readonly=false }}
<button type="submit">Submit</button>
Is this possible with handlebars templates? Or is there something similar I can do to get the result I want?
Thank you!
You're passing in the readonly option correctly, now all you need to do is use it when rendering your form.
To do that I've used a helper to render the form via JavaScript, where we can do anything we like using the Hash Arguments funtionality Handlebars supports.
// Let's pretend this is the user input you're holding in Node.js
// and want to render in your view and edit forms.
var userInput = {
"name": "Bob",
"tagline": "Yep, I'm Bob!"
};
Handlebars.registerHelper('userForm', function(options) {
var formOpening = options.hash.readonly ? "<form readonly=\"readonly\">" : "<form>";
// Notice that I feed in `userInput` as the context here.
// You may need to do this differently, depending on your setup.
var formContents = options.fn(userInput);
return formOpening + formContents + "</form>";
});
var userFormTemplate = Handlebars.compile(document.getElementById("userForm-template").innerHTML);
var pageTemplate = Handlebars.compile(document.getElementById("page-template").innerHTML);
Handlebars.registerPartial('userForm', userFormTemplate);
document.getElementById("wrap").innerHTML = pageTemplate();
<div id="wrap"></div>
<script id="page-template" type="text/x-handlebars-template">
<h2>View</h2>
{{> userForm readonly=true}}
<h2>Edit</h2>
{{> userForm readonly=false}}
</script>
<script id="userForm-template" type="text/x-handlebars-template">
{{#userForm readonly=readonly}}
<input type="text" name="name" value="{{name}}" />
<input type="text" name="tagline" value="{{tagline}}" />
<button type="submit">Submit</button>
{{/userForm}}
</script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v4.0.5.js"></script>
In the above snippet, the readonly="readonly" attribute is being added to the form beneath the "View" heading.
Note that on my browser, this does not actually make the form read-only - I'm not sure if you've got another library or something to handle that?
On my shopify website I have a product page with a request button, that when clicked should redirect the user to another page which has a form on it.
Clicking the button on the product page should pass the product title from that page to the other page and place that string variable into the form for the user to see and so that they can fill out the rest of the form with their information.
This is my link:
REQUEST ITEM
What needs to be passed:
{{ product.title }}
Where it needs to be placed ( #form_text ):
<form id="request-form" method="post">
<input id="first_name" name="firstName" placeholder="First Name*" type="text" value="" />
<input id="last_name" name="lastName" placeholder="Last Name*" type="text" value="" />
<textarea id="form_text" name="content" placeholder="What item do you want?"></textarea>
<input id="requestFormSubmit" type="submit" value="SUBMIT" />
</form>
How would I go about writing a url query string to pass this liquid variable?
Edit:
Thank you to #TylerSebastion, I was able to get it to work.
The link:
REQUEST ITEM
Here is the code I used on the form page:
$(function() {
var product = getParameterByName('product');
$("#form_text").text(product);
function getParameterByName(product) {
url = window.location.href;
product = product.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + product + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
});
You can pass it in via a query parameter.
REQUEST ITEM
As for getting it into the form, use the method from this post and
$(function() {
$("form #form_text").val(getParameterByName("product"));
});
I would also suggest, if at all possible in the templating engine you're using, to url encode the product name before appending it to the url.
If looks like there is a request object, though, in the Shopify/Liquid templating engine - I would try something like
<textarea id="form_text" name="content" placeholder="What item do you want?">{{ request.params.product }}</textarea>
and ditch the JS altogether (for this example)
I am using Angular-Payments that intercepts the form data and submits it to Stripe. This works well, however, I'm not sure how to access form data after its sent to stripe. For example, my form has quantity field which I would like to get access to but I don't know how to...
Here is what I'm doing HTML
<form stripe-form="handleStripe" role="form" ng-if="authenticated" name="takeMoneyForm" ng-submit="takeMoney(takeMoneyForm, model)">
<input type="text" name="card_number" ng-model="number" payments-validate="card" payments-format="card" payments-type-model="type" ng-class="takeMoneyForm.number.$card.type">
<input type="text" name="card_cvc" ng-model="cvc" payments-validate="cvc" payments-format="cvc" payments-type-model="type">
<input type="text" nam="card_expiry" ng-model="expiry" payments-validate="expiry" payments-format="expiry">
<input type="text" ng-model="quantity"/>
<button class='form-control submit-button btn btn-majoo' type='submit'>Pay ยป</button>
</form>
JS
$scope.takeMoney = function(formData, model){
$scope.handleStripe = function(status, response){
if(response.error) {
// there was an error. Fix it.
alert("Error happened")
} else {
var dataModel = {
email: model.email,
profile: {
stripe_token: response.id,
stripe_id: model.profile.stripe_id
//here I would like to get access to the quantity from the form
}
}
djangoAuth.takeMoney(dataModel)
$scope.complete = true;
}
}
}
I feel like this should be simple but I'm very new to Angular and can't seem to figure this out.
since youre using ng-model the values of those fields should be on that form's scope(as in scope.number)
If they are not accessible it could be one of two things:
1) Angular Payments clears the ng-model following submit
2) you are trying to access it from a different scope.
I have the following code that needs to be duplicated:
<form method="post">
<div id="field-row-container">
<div id="field-row-1" class="field-row">
<div class="field-element">
<label for="Name[1]">Name</label>
<input type="text" id="Name[1]" name="Name[]" />
</div>
<div class="field-element">
<label for="Email[1]">Email</label>
<input type="text" id="Email[1]" name="Email[]" />
</div>
<hr/>
</div>
</div>
<div class="form-element">
<input type="button" class="confirm add-field-row" value="Add" />
<input type="button" class="danger delete-field-row" value="Delete" />
<input type="submit" />
</div>
The duplicated / dynamically added elements will have the same names of Name[] and Email[] but their ID's will be incremented.
The JavaScript is below, based from Josiah Ruddell's form duplication script.
var template = $('#field-row-container #field-row-1').clone();
window.addForm = function () {
var parent = $(this).closest('.dynamic-rows').attr('id');
var fieldRowCount = countRows(parent) + 1;
var newFieldRow = template.clone().find(':input').each(function () {
var newId = this.id.substring(0, this.id.length - 3) + "[" + fieldRowCount + "]";
$(this).prev().attr('for', newId); // update label for
this.id = newId; // update id and name (assume the same)
$(this).closest('.field-row').addClass('new-row');
}).end()
.attr('id', 'field-row-' + fieldRowCount)
.appendTo('#field-row-container');
}
$('.add-field-row').click(addForm);
Whenever I submit the form to CodeIgniter and if there is a validation error, once the controller reloads the multi-part form, the dynamically added elements disappear as well as the values in the initial fields.
How do I go around this problem? I'm at a loss on how to solve this...
Other notes that might help:
This is a component multi-part form with only one form controller
I have multiple instances of this - Addresses, Education Degrees and such
I use CodeIgniter's form_validation library to check server-side each array of posts
When the page with the form on reloads after the controllers redirects back to it after failing validation, it will only reload the original page, with no DOM manipulations applied.
I would perform the POST request which submits the form via ajax, so you can handle the response without leaving the page. Something like this:
$.post('/locationOfController.php', $('#yourForm').serialize(), function(response){
if(response.valid){
window.location.href = '/somewhereAfterFormPosted.php';
} else {
$('#yourForm').append("<p>"+response.error+"</p>");
}
}, 'json');
and change the controller to return a JSON object based on whether validation passed or not. To match up with my example above, you would return something like below when an error occurs:
{valid: false, error: 'Please fill out the whole form'}
Try something like that as a basic example. You could do much more, such as returning several errors if multiple fields are invalid.