In my project I need to add functionality, that show infobox in right top corner of page, when client save something. Everything works fine when save operation do redirect to another page in my solution.
Client run save action:
[SaveAction] //my own action filter to show info box
public ActionResult Details(int id, FormCollection form)
{
var pojazd = PojazdRepo.GetById(id);;
if (UpdateAndSave(pojazd, form))
{
return RedirectToAction("Index");
}
else
{
return View(GetDetailsViewModel(id, true));
}
}
Now my action filter test that ModelState.IsValid is true then add something to TempData:
public class SaveActionAttribute : ActionFilterAttribute
{
private bool test;
private bool isAjax;
public override void OnActionExecuted(ActionExecutedContext ctx)
{
test = ctx.Controller.ViewData.ModelState.IsValid;
isAjax = ctx.HttpContext.Request.IsAjaxRequest();
base.OnActionExecuted(ctx);
}
public override void OnResultExecuting(ResultExecutingContext ctx)
{
if (test)
{
if (isAjax) ctx.Controller.TempData["ActionPopUp"] = "";
else ctx.Controller.TempData["ActionPopUp"] = "save";
}
base.OnResultExecuting(ctx);
}
}
And my Site.Master run script if TempData["ActionPopUp"] = "save":
<script type="text/javascript">
$(document).ready(function () {
var test = '<%: TempData["ActionPopUp"] %>';
if (test != '') SaveSuccessPopUp(test);
});
</script>
As mentioned, this solution works fine, when controller make Redirect and Site.Master is loaded again, my problem is, how to inject SaveSuccessPopUp() function to action result, when Action was called by AJAX and return something, what don't reload page and don't run Site.Master $(document).ready code block.
Nice question.
You need to probably work with partial view here. I mean if your request is an ajax request, append the TempData again and the TempData will be outputted inside the partial view.
How will you send that partial view output as chunk of html?
I have a blog post about how you can send the partial view as string. The topic is different but you will get the idea:
http://www.tugberkugurlu.com/archive/working-with-jquery-ajax-api-on-asp-net-mvc-3-0-power-of-json-jquery-and-asp-net-mvc-partial-views
Here is an example:
[HttpPost]
public ActionResult toogleIsDone(int itemId) {
//Getting the item according to itemId param
var model = _entities.ToDoTBs.FirstOrDefault(x => x.ToDoItemID == itemId);
//toggling the IsDone property
model.IsDone = !model.IsDone;
//Making the change on the db and saving
ObjectStateEntry osmEntry = _entities.ObjectStateManager.GetObjectStateEntry(model);
osmEntry.ChangeState(EntityState.Modified);
_entities.SaveChanges();
var updatedModel = _entities.ToDoTBs;
//returning the new template as json result
return Json(new { data = this.RenderPartialViewToString("_ToDoDBListPartial", updatedModel) });
}
RenderPartialViewToString is a controller extension. you can find the the complete code for that from below link:
https://bitbucket.org/tugberk/tugberkug.mvc/src/6cc3d3d64721/TugberkUg.MVC/Helpers/ControllerExtensions.cs
After you have your html back on the client side code, append it you DOM and work on it. Animate it, show/hide it, do whatever you need with it
Related
I have a webgrid am using and the grid has rows. I want to be able to delete
any row I want. I have a garbage icon on every row for deletion. If I click on
it, the javascript function DeleteTaskFromDb is called below
function DeleteTaskFromDb(processCompleteData) {
var url = "#Url.Action("RemoveTaskFromList", "Home")";
$.get(url, { 'objdata': processCompleteData }, function (data) {
//jQuery.removeData(data);
//$('#mainListContent').html(data);
});
}
In this method, I want to be able to redirect to EmployeeHoursDetail in same controller.
This is working. I hardcoded the uniqueId just for testing.
public ActionResult RemoveTaskFromList(string objdata)
{
Employeehourstaskinfo getAllTaskSaved = null;
try
{
var stripOffObjectName = JObject.Parse(objdata)["EmployeeTask"];
var cleanedData = JsonConvert.DeserializeObject<Employeetaskdto>(stripOffObjectName.ToString());
getAllTaskSaved = _dtcDataService.RemoveTaskRecordFromDb(cleanedData);
}
catch (Exception ex)
{
logger.Error(ex);
}
return RedirectToAction("EmployeeHoursDetail", "Home", new { uniqueId = 51207 });
}
This method returns the correct data i need i.e after deleting a record from above.
public ActionResult EmployeeHoursDetail(Int64 uniqueId = 0)
{
...//code here
...
getEmhourdetails = _dtcDataService.GetEmployeeHoursDetails(uniqueId);
return View(getEmhourdetails);
}
Problem : If I have 4 records on the webgrid and I delete 1, by the time my page reloads I can still see
the 4 records. It should only show 3 since i deleted one. I think my html page is not refreshing.
I suspect its my $.get call that is not refreshing the page.
How can I resolve this?
In the View I have a linked button and there is java scripts to collect information from view and then post to the corresponding action 'GroupDeny'
#Html.ActionLink("Deny Selected", "GroupDeny", null, new { #class = "denySelectedLink" })
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(document).on('click', '.denySelectedLink', function (e) {
//Cancel original submission
e.preventDefault();
var identifiers = new Array();
//build the identifiers . . .
var jsonArg = JSON.stringify(identifiers);
$.post('/LicenseAssignment/GroupDeny?licensePermissionIdentifiers=' + encodeURIComponent(jsonArg));
});
</script>
Then in the controller, the GroupDeny will update the DB and then
call RedirecToAction in order to refresh the view
public class LicenseAssignmentController : Controller
{
[HttpPost]
public ActionResult GroupDeny(string licensePermissionIdentifiers)
{
// changes the DB
return RedirectToAction("Index");
}
// GET:
public async Task<ActionResult> Index()
{
var model = get data from DB
return View(model);
}
Everything seems work as expected, The Index will be called after the RedirectToAction("Index") is executed, and the model is update to date their when I watch it during debugging, the only problem is that the page is not refreshed at all, that is to say the view still keep unchanged, but after I refresh the page manually (press F5), the data will be updated with the values from DB
We use AJAX when we don't want to navigate away from the page. Your $.post() is an AJAX request.
Since you want navigation add a form to your page
#using(Html.BeginForm("GroupDeny", "LicenseAssignment", FormMethod.Post))
{
<input type="hidden" value=""
name="licensePermissionIdentifiers"
id="licensePermissionIdentifiers" />
}
Now submitting this form will navigate
$(document).on('click', '.denySelectedLink', function (e) {
e.preventDefault(); // prevent link navigation
var identifiers = new Array();
//build the identifiers . .
// populate the form values
$("#licensePermissionIdentifiers").val(identifiers);
$("form").submit();
});
The RedirectToAction() returns to the browser a 302 Redirect to LicenseAssignment/Index then you hit the Index action.
Since you are using Ajax you will have to redirect on the return of your $.post call and change your GroupDeny to a JsonResult.
Something like this maybe:
JS
$.post('/LicenseAssignment/GroupDeny?licensePermissionIdentifiers=' + encodeURIComponent(jsonArg), function(data){
if(data.Success){
//redirect
window.location.reload();
}else{
//handle error
}
});
Controller Action
[HttpPost]
public JsonResult GroupDeny(string licensePermissionIdentifiers)
{
// changes the DB
return Json(new { Success = true });
}
I have the following action in ASP.NET MVC4
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
// ?? Need some code here
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
I have the following code that calls this:
$('#article').on('submit', '#loginForm, #registerForm', function (e) {
e.preventDefault();
var $form = $(this);
var href= $form.attr('data-href');
$form.validate();
if (!$form.valid()) {
return false;
}
var data = $form.serializeArray();
$.ajax(
{
data: data,
type: 'POST',
url: href
})
.done(submitDone)
.fail(submitFail);
function submitDone(content) {
$('#article').html(content)
}
function submitFail() {
alert("Failed");
}
return false;
});
If the registration works I would like to force the whole web page to refresh. Is there
a way that I can send back a message from the actionmethod to the javascript to
tell it that the registration works and the javascript should refresh the whole
web page?
I did try return RedirectToLocal("/"); but this definitely does not work. What
this does is to return a new page and then have it populated in the #article DIV.
There is nothing that will automatically refresh the browser from the server.
To refresh the browser from the server you'll need to send something from the server to the client indicating that you want to refresh the page. You'll need to write the javascript to look for the indication to refresh the browser.
Client Code
function submitDone(content) {
var json = $.parseJson(content);
if(json.isSuccess) {
//Do something here
}
$('#article').html(json.content)
}
Server code
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
// ?? Need some code here
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return Json(new {isSuccess = true, content = model});
}
I am unsure of what you are trying to accomplish by refreshing the page, if it's to clear out the form fields. The same could be achieved by using JavaScript. By using javascript instead of a page refresh you won't lose page state, such as error messages.
well i can think of a quick javascript trick to refresh a page on success like this
function submitDone(content) {
window.location.reload();
}
this will reload the page on the success.
I am using javascript to load up an Action and finding that when the action method is called one of the parameters "returnUrl" is always null. I have confirmed that returnUrl is populated in the javascript correctly using firebug, but somewhere between executing the .load function and the action method the value for returnUrl is lost and set to null. I have found that if I remove the "id" parameter and just have the "returnUrl" parameter that returnUrl has the correct value. I have spent many hours trying to figure out what is going on here and am completely stumped, I would apprectiate some help.
My Javascript:
<!-- Review Dialog Popup -->
<script type="text/javascript">
function showWriteReviewDialog(gameId, returnUrl) {
if( $("#Review").length == 0)
{
var url = "#Url.Action("WriteUserReview", "UGDBUser", new { id = "PLACEHOLDER", returnUrl = Request.Url.ToString() })";
// ajax load
$('#writereview').load(url.replace('PLACEHOLDER', gameId));
} else {
// clear summary & reviewtext fields
$('#summary,#reviewtext').val('');
//reopen the write review dialog which was previously rendered
$("#Review").dialog({
modal: true,
autoOpen: true,
resizeable: false
});
}
};
</script>
My Dumbed Down Action Method:
[Authorize]
public ActionResult WriteUserReview(Guid id, string returnUrl)
{
return Redirect(returnUrl);
}
There must be something wrong with the URL generated. Also make sure the id is a guid. Here is an example.
Option 1
function showWriteReviewDialog(gameId, returnUrl) {
var url = '#Url.Action("TestParams", "Home")?id=' + gameId + '&returnUrl=' + returnUrl;
$("#writereview").load(url);
//rest of your operations
};
Option 2
function showWriteReviewDialog(gameId, returnUrl) {
var url = '#Url.Action("TestParams", "Home", new { id = "guid_replace", returnUrl = "url_replace"})';
url = url.replace('guid_replace', gameId);
url = url.replace('url_replace', returnUrl);
$("#writereview").load(url);
//rest of your operations
};
Screen shot on hitting the action; it returns both the values (have a look at the watch window)
I tried to Use the Telerik component Upload in asp mvc .
#(Html.Telerik().Upload()
.Name("attachement")
.Multiple(true)
.Async(async => async
.Save("Save", "Image")
.Remove("Remove", "Image")
.AutoUpload(true)
).ClientEvents(events => events.OnSuccess("onSuccess")))
In My Controller I have:
public ActionResult Save(HttpPostedFileBase attachement)
{
var fileName = attachement.FileName;
Guid id = SaveImage(attachement);
return Json(
new
{
Succces = true,
Content=id,
}
);
}
In my View I need to display the content of the Json Result ,
I have a event on the uploader called OnSucces
function onSuccess(e) {
}
How Can I get the JsonContent in this method javascript and display the content .
Or all this logic is wrong .
Thanks in advance
Check the sending and receiving metadata help article.