I'm trying to map a button action to the controller function.
When I tried with :
#RequestMapping(method = RequestMethod.POST)
public void processValidateGenerate
....
and
<input type="button" id="continue" name="continue"...>
that works just fine, but now i want to add another button, so to differentiate betweent them I added so for the first action :
#RequestMapping(method = RequestMethod.POST, params="continue")
public void processValidateGenerate
....
but the function is not called anymore when the button is pressed, I think that works only for a submit input.
Are there any solution to do this with a non submit input ?
Thank you
You can use javascript/jquery to do an ajax call and hit the required controller method.
function doSomething(){
$.ajax({ //This is a jquery ajax call. You need to inlude jquery js files to do
type: "POST", // this operation
url: //URL,
data: //JSON data
}).done(function( msg ) {
alert( "Operation done: " + msg );
window.location.href=contextPath+"/newURL"; //If you want to go to a new page
});
}
now add the new button (It doesn't matter even it isn't a button, a div would suffice). Use the onclick function and give the javscript function name.
<input type="button" id="newcontinuebutton" name="continue" onclick=doSomething()...>
You can check the jquery ajax details here
I think this would help you.
Related
I'm trying to add a search form in the navbar on every page in my spring mvc web app, just like the one here on stackoverflow, and I'm having issues. Right now I have a working search functions on a couple of my pages, using the typical mvc forms. I take the inputted string and store a variable called "searchString" in an object I created called "searchForm.java". Then I try to query that inputted string in the database using spring data's findbycontaing method, and then put that result on the model, and then represent that on the view, using thymeleaf. However I think that the navbar should be done using ajax, since it's on every page and pages with other forms.
So I think I'm sending the string that was submitted to the search form in the navbar to the controller where I queried it in the repository to bring back search results, then I tried to put the search results on the model, but I get nothing, all it does is redirect me to the search page. I may not be making very much sense, but I'll show my code, and if anyone could let me know if I'm going about my problem in the right way or not, and if you guys see any errors in my code. Thanks in advance.
So here's my ajax and jquery to submit the form.
<script th:inline="javascript">
/*<![CDATA[*/
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
$(document).ready(function(){
$("#searchButton").on("click", function(ev) {
$.ajax({
url : "navSearch",
type : "post",
data : {
"newSearch" : $("#newSearch").val()
},
success : function(data) {
console.log(data);
},
error : function() {
console.log("There was an error");
}
});
});
});
/*]]>*/
</script>
There may be an issue here, because in the console in the chrome developer tools, before it redirects, a message pops up very quickly that says uncaught TypeError: Cannot read property 'toLowerCase' of undefined, and it's coming from jquery.min.js:5 so that could be my issue, but I have no idea how to go about fixing this, and I've searched for answers so far with no luck.
Here's my html form, I think this shouldn't be a problem, but who knows, so I'll put it up anyways. And I'm using thymeleaf for this view.
<form action = "setSearch" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" id="newSearch"></input>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
</div>
<button type="submit" class="btn btn-default" id="searchButton">Search</button>
</form>
Here's my searchForm.java class, where I temporarily store the string to be queried in the database.
public class SearchForm {
private String searchString;
public String getSearchString()
{
return searchString;
}
public void setSearchString(String searchString)
{
this.searchString = searchString;
}
}
And Here's my controller, where I'm trying to handle the ajax submission and return it as search results on the setSearch.html page. What I'm thinking here is that the string "newSearch" from the form could be matched using the Spring Data query methods, and then be able to return it and add it to the model, but it's not working, it's just redirecting me to the /searchSet page with no data, because that's where the form action goes and that's what I tell it to return. So honestly I'm no sure if any data is even getting to this point.
#RequestMapping(value="setSearch/navSearch", method=RequestMethod.POST)
public #ResponseBody String navSearch (#RequestParam String newSearch, ModelMap model)
{
List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(newSearch);
model.put("searchResult", questionAnswerSetByQuestion);
return "setSearch";
}
And here's an example of a working search method that I have in my controller that I use on a regular form, with no ajax, on the /searchSet page.
#RequestMapping(value="/setSearch", method=RequestMethod.GET)
public String searchGet(ModelMap model) {
SearchForm searchForm = new SearchForm();
model.put("searchForm", searchForm);
return "setSearch";
}
#RequestMapping(value="/setSearch", method=RequestMethod.POST)
public String searchPost(#ModelAttribute SearchForm searchForm, ModelMap model) {
List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(searchForm.getSearchString());
model.put("searchResult", questionAnswerSetByQuestion);
return "setSearch";
}
UPDATE
I've changed my code in the form from <button type="submit" class="btn btn-default" id="searchButton">Search</button> to <button type="button" class="btn btn-default" id="searchButton">Search</button> and now I get the Uncaught TypeError: Cannot read property 'toLowerCase' of undefined from earlier and nothing happens with the page.
UPDATE
I can now submit the ajax form without a problem, I was missing meta tags in the header, so the csrf wasn't submitting correctly, so now I get this error in the chrome developer tools console XHR Loaded (navSearch - 405 Method Not Allowed - 7.265999971423298ms - 634B)
UPDATE
Now everything works on the Ajax side, I needed to adjust my url to match the url I had in the request mapping on the controller and it runs through all the code fine. However the overall search function still doesn't work, here's my updated controller.
I know my issue here is that I'm returning a string and not an object, but I'm not sure how to return the object and then redirect the url to the /setSearch page. It's running through the code and returning a string "setSearch" in the console, because I told it to at the end of the controller.
#RequestMapping(value="/setSearch/search", method=RequestMethod.POST)
public #ResponseBody String search (#RequestParam String newSearch, ModelMap model)
{
List<QuestionAnswerSet> questionAnswerSetByQuestion = (List<QuestionAnswerSet>) questionAnswerSetRepo.findByQuestionContaining(newSearch);
model.put("searchResult", questionAnswerSetByQuestion);
return "setSearch";
}
Here's my working ajax
<script th:inline="javascript">
/*<![CDATA[*/
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
$(document).ready(function(){
$("#searchButton").on("click", function(ev) {
$.ajax({
url : "/setSearch/search",
type : "post",
data : {
"newSearch" : $("#newSearch").val()
},
success : function(data) {
console.log(data);
},
error : function() {
console.log("There was an error");
}
});
});
});
/*]]>*/
</script>
but it's not working, it's just redirecting me to the /searchSet page
with no data, because that's where the form action goes and that's
what I tell it to return
You are right, it is because you are submitting the form and in the action you specify it to submit to setSearch, that is why the page is getting redirected to the same page. Just replace button type="submit" with button type="button" so that the form will not be submitted when searchButton is clicked.
enter code here
*MainView.cshtml*: #RadioButtonFor(m=>m.registeras,Individual) #RadioButtonFor(m=>m.registeras,BusinessEntity) <div id="loadpartial"> </div>
I have a register form in which User can register as Individual or Business entity. I kept two radio buttons.
If user selects Individual Radio Button, then that partial view should be loaded. if user selects Business entity radio Button then second partial view should be loaded on the same div.
I am new to asp.net mvc4 razor. Can someone please give the sample code.
You will have to use jQuery in order to make ajax calls.
First reference jQuery at the bottom of your page.
in your controller, define and implement a method which returns a partial view.
[HttpGet]
public ActionResult GetRegisterForm(int registeras)
{
if(registeras == Individual)
{
return PartialView("IndividualPartialViewName");
}
else
{
return PartialView("BusinessPartialViewName");
}
}
Now in your view, you can call the above action using ajax.
<script type="text/javascript">
$(function(){
$("[name=registeras]").on('change', function(){
var $radio = $(this);
$.ajax({
url:'#Url.Action("GetRegisterForm", "ControllerName")',
data: { registeras = $radio.val() }
type: 'GET',
success: function(data){
$("#loadpartial").html(data);
}
});
});
</script>
I have already read this and this to get some help but there is something wrong in my code. Well I want to insert a form to database via Ajax and this is what i did:
The Ajax function :
<script type="text/javascript">
function doAjaxPost() {
var form = $('#ajf');
frm.submit(function () {
$.ajax({
type: "POST",
url: "${pageContext.request.contextPath}/ajouter_user",
data: form.serialize(),
success: function(response){
// we have the response
$('#info').html(response);
},
error: function(e){
alert('Error: ' + e);
}
});
});
}
</script>
'#info' is the ID of the DIV where i want to show the success message returned by the controller.
this is my controller :
#RequestMapping(value="/ajouter_user",method=RequestMethod.POST)
public #ResponseBody String addUser(#ModelAttribute User us,BindingResult result,ModelMap model){
String returnText;
if(!result.hasErrors()){
model.addAttribute("us", new User());
userservice.AddUser(us);
model.addAttribute("usersystem", userservice.getAllUsers());
return returnText = "User has been added to the list." ;
}else{
return returnText = "Sorry, an error has occur. User has not been added to list.";
}
}
HTML :
<form:form id="ajf" method="POST" commandName="user">
Here are my fields ...
<input type="submit" value="Créer" onclick="doAjaxPost()"/>
</form:form>
What is wrong is : I don't get the String that the controller return , I get an alert error (object [] object ), the data is inserted to database and the page reload after submitting without giving any error
Can someone give me a toturial how to use Ajax with spring (inserting to database )
please help me
If you are using jQuery (it looks like you are), then you need to include the event in the function and do an event.preventDefault() to prevent the form from submitting. Otherwise the event will propagate up and the form will submit, and you will get the ajax post and the form post.
I am developing an ASP.Net MVC 3 Web Application. One of my Razor Views contains a few Textboxes and a Drop Down List. When the User selects an option from the Drop Down List, I need a Partial View, or something like this, to appear below the Drop Down List preferable without a post back.
The thing is, it isn't as easy as a simply JQuery Hide and Show for the Partial View, when the User selects an option from the Drop Down List, I need their option to be sent to a method in the Controller, perform some logic based on this option, and then return some data to the Partial View.
I haven't really got much experience with AJAX, but I get the feeling this is the technology I need to use in order to fulfil my problem.
Has anyone ever had to code anything similar to what I have described above? And if so, is AJAX what I need to use?
Also, if anyone knows of any tutorials or code snipets I could look at to help, that would be greatly appreciated.
Thanks.
UPDATE
I have followed Ryan's answer, but unfortunately I am still having some problems. I have created the following JavaScript file which is then referenced in my View
$(document).ready(function () {
$("#myDDL").change(ChangeEventOfDDL);
function ChangeEventOfDDL(){
var dropDownValue = $('#myDDL').val();
//alert(dropDownValue);
$.ajax({ type: "GET",
url: '#Url.Action("SomePartialView","testAjax")',
data: {
id: dropDownValue
},
success: function(data) {
$('#someDivToLoadContentTo').html(data);
}
});
}
});
View
<select id="myDDL">
<option></option>
<option value="1">F1</option>
<option value="2">F2</option>
<option value="3">ST1</option>
<option value="4">ST2</option>
</select>
<div id="someDivToLoadContentTo">
</div>
My Controller then looks like this
public class testAjaxController : Controller
{
//
// GET: /testAjax/
LocumEntities context = new LocumEntities();
public ActionResult SomePartialView(int id)
{
var test = "Hello World";
return View(test);
}
}
However, my method 'SomePartialView' never gets hit. Does anyone know why?
Thanks.
Yes Ajax would be the easiest thing to use here. There are plenty of good Ajax tutorials around, just remember that what Ajax does is effectively a background POST, so you can do everything you would normally do with MVC, except within an existing page.
The way I would get this to work would be to have your code something like this:
public class SomeController{
public ActionResult SomePartialView(){
// Do some logic
return View("SomePartial");
}
}
Your Ajax would be something like:
function ChangeEventOfDDL(){
$.ajax({
url: '#Url.Action("SomePartialView","Some")',
success: function(data) {
$('#someDivToLoadContentTo').html(data);
}
});
}
I hope that helps at least a little bit.
Crucially with Ajax, you can add a data object to the function, which is passed as a querystring. This means you can send values from your page quite easily with ajax. Working with the above example, the Javascript would be:
function ChangeEventOfDDL(){
var dropDownValue = $('#ddl').val();
$.ajax({
url: '#Url.Action("SomePartialView","Some")',
data: {
id: dropDownValue
}
success: function(data) {
$('#someDivToLoadContentTo').html(data);
}
});
}
The Id value is linked with the parameters of the method in your MVC class:
public class SomeController{
public ActionResult SomePartialView(int id){
// Do some logic
var model = MakeModelWithSupplierId(id);
return View("SomePartial",model);
}
}
And there you have an interactive partial view that has been populated with the value from your drop down.
Since a controller can also return a partial view, you can do the following:
$('#idofyourdropdown').change(function () {
var theValue = $(this).val();
$.post('#Url.Action("Action","Controller")', {nameOfParameter: theValue, function(data) {
$('#divWhereYouWantToAttachData').html(data);
});
});
On the change event of your dropdown, send the selected value to your desired controller action, which will pass it to the partial view and return the rendered html. The html is received in the data var and can be attached to the dom, wherever you want it (see jQuery documentation for this).
This is a common use case.
What you need to do is
create a controller method that can take the parameters you need (read about MVC model binding before you do so)
write javascript that will harvest the data you want from your form and make a call to your new controller method and render the results below
In jQuery it goes something like this:
$("#yourDIV").load('/area/controller/method', { property1: 'asasd', property2: 'asdasdadfa'})
The second parameter of this call should be prepared based on the data you harvest from your form. (if you don't know how, then learn javascript)
I have an input
<input type="button" id="test" value="test" />
My action on the 'Home' controller:
public ActionResult DataUsage(DateTime startDate, DateTime endDate, string userName)
{
var data = FetchDataFromDB(startDate, endDate, uName);
return PartialView("DataUsageChartViewPartial", data);
}
The div I want to load the result form DataUsage in
<div id="myChart"></div>
jQuery code
$(function() {
$("#test").click(function () {
$.ajax({
url: '/Home/DataUsage',
type: 'POST',
data: { startDate: $('#startDate').val(), endDate: $('#endDate').val(), userName: $('#userName').val() },
success: function (result) {
alert("success " +result);
},
error: function (err) {
alert("error "+err);
}
});
return false;
});
}
);
When I click the button I want the div(myChart) to be populated with the result from the action in the controller.
I'm not sure if my jQuery is correct as I keep getting an error and the breakpoint in my controller/action is never hit.
Can someone please tell me what I'm doing wrong and how to correct it
Make sure that the format of the date you entered in the textbox is correct and matches your server side culture settings. For example depending on the culture your application is configured to, 12/15/2012 and 15/12/2012 might indicate the same date to the user depending on where he comes from and yet the default model binder will use the current culture settings.
Also to debug those kind of problems please use a javascript debugging tools such as FireBug and inspect the AJAX request. If you had done that you would have seen the exact error message sent from the server which in your case should be something long the lines of: 15/12/2012 is not a valid DateTime.
Dude the issue in your code for the starters is that you have specified Post method for the Ajax to call the controller , whereas as per your code which you have put shows that the method is available in get method .
Simplest way out is put [HttpPost] annotation on the controller action method.
i.e the method in your controller looks like :
[HttpPost]
public ActionResult DataUsage(DateTime startDate, DateTime endDate, string userName)
{
var data = FetchDataFromDB(startDate, endDate, uName);
return PartialView("DataUsageChartViewPartial", data);
}
So this will solve the problem of the breakpoint not getting called.
Other thing suggested is always user Url.Action(...) Method when you want to give urls to be called from ajax or wherever . Else it may create problems when deployed etc.
Maurice,
I think it could well be a very simple case of not having the correct url being called. You should try using the helpers in mvc:
url: '#Url.Action("DataUsage", "Home")'
Also, you might want to decorate your action with HttpPost to ensure that it's in step with your ajax type, i.e:
[HttpPost]
public ActionResult DataUsage(...)
this should take you one step closer, if not solve the issue completely.
The final step is to ensure that you have a div called 'myChart' inside your 'calling' view, then populate it as thus:
<div id='myChart'></div>
success: function (result) {
$('#myChart').html(result);
}
hope this helps