I have embed a controller in a template:
{% render "AcmeUserBundle:User:showUsersList"} %}
<a onClick="changeStatus({{user.getUserId()}})"
The aim is simple:
The user clicks on the link which updates the status via ajax (this works fine)
Reload the embedded controller only, not the entire page!
At the moment, I managed to do this, by reloading the entire page using document.location.reload(true); This has no point so far...
Here is the ajax part:
//...
function changeStatus(userId){
$.ajax({
type: "POST",
url: ajaxControllerPath,
data: "userId="+userId,
success: function(){
document.location.reload(true);
}
});
}
How would you reload the embedded controller only?
This is working so far:
Embed the controller within a div:
<div id="block1">
<a onClick="changeStatus({{user.getUserId()}})"
</div>
And reload the controller using javascript at the end of the ajax call
$('#block1').load("{{ path('show_users_list') }}");
Does anyone have a better suggestion?
When you call the ajax controller, this controller could render the showUsersList template and return the generated html as a json object:
$answer['html'] = $this->forward('AcmeUserBundle:User:showUsersList')->getContent();
$response = new Response();
$response->headers->set('Content-type', 'application/json; charset=utf-8');
$response->setContent(json_encode($answer));
return $response
Then in your javascript use this generated html to replace the content of the controller part of the page (use a div or similar to identify it)
<div id="changethis">{% render "AcmeUserBundle:User:showUsersList"} %}</div>
function changeStatus(userId){
$.ajax({
type: "POST",
url: ajaxControllerPath,
data: "userId="+userId,
success: function(returnData){
$('#changethis').html(returnData['html']);
}
});
}
Related
I've got a controller that is generating some markup. In the markup there is a link that dynamically adds some content to the page using jQuery ajax.
The content that's added to the page comes from another controller. In that content there's a Drupal form. It renders correctly on the page, but it doesn't submit properly (although it works well if I call it directly - it only fails to submit if it's inserted through AJAX).
So, in summary, controller A renders some markup like this:
<a id="ajax-link">Click here to display the form</a>
<div id="form"></div> <!-- form will be displayed here through AJAX -->
In the javascript, I've got:
$("#ajax-link").on("click", function() {
$.ajax({
url: "/controller-B/get-form",
type: "POST",
dataType: "JSON",
success: function(data) {
$("#form").html(data.output);
}
});
Controller B renders the form like this:
public function get_form() {
$form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\MyForm');
$output = \Drupal::service('renderer')->render($form);
$data = new \StdClass();
$data->output = $output;
return new JsonResponse($data);
}
So I click on the link, it calls the script, which calls controller B, which generates the form, and the script adds the markup for the form on the page.
It works well, but the form doesn't submit properly.
Looking at the markup that's generated after the form is inserted on the page, it looks like it's the action attribute that's incorrect. It generates something like this:
<form action="form_action_p_pvdeGsVG5zNF_XLGPTvYSKCf43t8qZYSwcfZl2uzM" method="post" id="comment-form" accept-charset="UTF-8" class="comment-form" data-drupal-selector="comment-form">
Any tip would be greatly appreciated!
Are all button control has to be post method? or we can set it to get method, for example, I want to see an employee details by giving employeeId and click submit button
There is no difference between GET and POST method. They both provide url and parameters. POST method only have some advantages and some restrictions.
If your button is on form (as in classic asp.net), and there is no javascript handler for this button - only POST method can be here.
If you create jquery code (or pure javascript), that overrides default behaviour of the button, you can select what method use: POST or GET
<script>
$('#button').click(function() {
$.ajax({
url: '....',
data: { ....},
type: 'GET', //or 'POST'
success: function(res) {
//all fine
},
error: function() {
//invalid url or server error
}
};
return false; //to avoid default submit
});
</script>
In my layout page I've got this html:
<div id="ajax-loading" class="global-loading-image" runat="server">
<img src="/content/travelbill/img/small-loading-image.gif"/>
</div>
Which is a loading-symbol. I want it to show when my code is doing its business.
I've read on other threads here on Stackoverflow that if you use runat="server", you are supposed to be able to access the div in the controller. Like so:
ajax-loading.Visible = true;
EditTravelBillViewModel model = this.travelBillService.GetTravelBill(travelBillId);
model.StageOfProcess = (int)TravelBillStageOfProcessEnum.APPROVED;
this.travelBillService.Update(model, true);
ajax-loading.Visible = false;
return RedirectToAction("GetTravelBillsPerCompany");
But I get the error that the loading and the ajax do not exist in the current context. What am I doing wrong?
That was in the old ASP.NET pages. In ASP MVC you don't have a ViewState, isPostBack or runat="server" you can pass variables from the controller to the view using ViewBag and ViewData like:
Controller:
ViewBag.Name = "My Name";
ViewData["Name"] = "My Name";
View:
#ViewBag.Name
#ViewData["Name"]
I don't think you need to do that. You can have a action that do the task that you need to get done and with JavaScript request that action via AJAX. You can then with JavaScript show and hide the loading as you wish:
function LoadAjax(containerId, url, params){
//Set loading in container
$(containerId).html('<img src="loading.gif" alt="loading"/>');
//Do the request
$.ajax({
type: 'POST',
dataType: "html",
url: url,
data: params,
success: function(data){
// show response inside container (removes loading)
$(containerId).html(data);
},
error: function( jqXHR, textStatus, errorThrown){
// show error inside container (removes loading)
$(containerId).html(textStatus);
}
});
}
While the page is loading it will display the loading image. You will need Jquery to use my code. Hope it helps.
In my view i have 10 link every link associated with some unique value. Now i want that associated value at my controller action and from that action i want to redirect the flow to some other action based on that value.
But the condition is i dont want to display it on url.
How can i acheive this?
I tried ajax.post/#Ajax.ActionLink but doing this will not facilitate redirect to another action.
Is there anything with route i need to do?
View
<ul>#foreach (var item in Model)
{<li>
#Ajax.ActionLink(item.pk_name, "Index","Candidate", new { para1= item.para1 }
, new AjaxOptions { HttpMethod = "POST" })</li>
}</ul>
Action
[HttPost]
public ActionResult(int para1)
{
return RedirectToAction(para1,"anotherController");
}
I am getting value at para1 with ajax post(that is what i primarily needed) but here also want to redirect my application flow base on para1 value which is action name.
Confision : here i am not sure is this is the right way to do this thing. So i am asking you guys should i go for route map of working with ajax post will solve my objective.
If you only need to redirect the user based on what he clicks on without showing him the link, I believe the best way to achieve this is by client-side coding.
In my opinion there is no need to take any request through the server in order to change the page for such a low-complexity redirect.
View
// HTML
// Might be broken, been awhile since I worked with MVC
// Can't really remember if that's how you put variables in HTML
<ul id="button-list">
#foreach(var item in Model)
{
<li class="buttonish" data-para1="#item.para1">#item.pk_name</li>
}
</ul>
// JS
// I wouldn't do any server related work
$('#button-list li.buttonish').click(function(){
// Your controller and action just seem to redirect to another controller and send in the parameter
window.location.href = "/controller/method/" + $(this).data('para1');
});
I think you should make one jQuery function that is call when clicked and pass unique parameter.In that function you can use AJAX and post it on appropriate controller method.
Example:
<input type="button" id="#item.pk_name" onclick="getbuttonvalue(#item.para1);" />
In script
<script type="text/javascript">
$(document).ready(function () {
function getbuttonvalue(para1) {
$.ajax({
cache: false,
type: "POST",
dataType: 'json',
url: "/controller/method/" + para1,
success: function (data) {
}
});
}
});
</script>
i have a form which includes list of records. When user clicks edit image on table modal div will show to him. i get this modal div with ajax. Now after changing some fields i am posting it via ajax. I watched to firebug. it sends parameter. But when i debug code in VS method calls but no parameter has been send. i have done it before in other pages. but now i can not. What problem can be here in my code?
C# Code here
[HttpPost]
//[Authorize(Roles = "Operator")]
public ActionResult EditRow(string Name, string SecondName)
{
//code goes here
return Content("Saved");
}
jquery ajax code is here
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: 'EditRow',
data: { Name: "php", SecondName: "MVC" },
dataType: 'html',
success: function (response) {
//some code goes here
}
});
Have you tried to simplify your Ajax call to:
$.ajax({
type: 'POST',
url: 'EditRow',
data: { Name: "php", SecondName: "MVC" },
success: function (response) {
//some code goes here
}
});
If this doesn't work there must be something else in your code that makes your code invalid. Maybe some base controller action filters you forgot to put there or some custom model binders or some other global registration.
Sending complex JSON to server
If you'd like to send complex JSON using the same technique, you can read my blog post and use the simple plugin that will make it possible to send complex JSON objects to Asp.net MVC controller action.