How to call script based on value of Model - asp.net-mvc

I have the following code that is used when logging in and it works. However, if the login successful, I need to close the form. I have a button that does that which the user can click, but I don't know how to wire that up so I can call it programmatically. The Model has a property called IsAuthenticated. So if that is true, then I need to call the cancelLogin() function which will close the window.
#using (Ajax.BeginForm("Login", "Account", new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "loginSection", }))
{
#Html.Partial("_LoginInfoPartial", Model)
<input} type="submit" value="Log in" />
<button type="button" id="close_button" onclick="cancelLogin()" >Cancel</button>
<script>
function cancelLogin()
{
var window = $("#loginWindow").data("kendoWindow");
window.close();
}
</script>
}

From within your controller on a successful login, you could return a call to that function. For example:
public ActionResult Login() {
// login logic here
if(loginSuccess)
return Content("<script>cancelLogin();</script>");
else
return View();
}
So when the form loads from the backend, it will replace your div with this Javascript which should execute and close the window.

Related

View is not displaying after Post Request

I'm making a post request from on view so that I don't see the parameters on the URL and I can tell it is passing the appropriate parameters to controller for the request but it does not display the appropriate view from that controller.
Calling view
#Ajax.ActionLink("Work1", "NewIndex", "WorkItems",
new
{
eventCommand = "createforrig",
//eventArgument1 = #item.Id,
eventArgument2 = #item.Id
},
new AjaxOptions
{
HttpMethod = "POST"
})
WorkItems Controller method
[HttpPost]
public ActionResult NewIndex(NewWorkItemViewModel vm)
{
vm.IsValid = ModelState.IsValid;
vm.HandleRequest();
if (vm.IsValid)
{
// NOTE: Must clear the model state in order to bind
// the #Html helpers to the new model values
ModelState.Clear();
}
else
{
foreach (KeyValuePair<string, string> item in vm.ValidationErrors)
{
ModelState.AddModelError(item.Key, item.Value);
}
}
return View(vm);
}
Putting a breakpoint on the last Return View(vm) confirms it is being called but the browsers does not update to display the workItems view.
Suggestions on why the browser is not being updated to display the appropriate view.
You're making an ajax post, the newly rendered view is being returned by the server if you were to look in the network console in your browser. Add a success callback. Either assign a callback to handle the response or use the
UpdateTargetId property in your AjaxOptions
#Ajax.ActionLink("Work1", "NewIndex", "WorkItems",
new
{
eventCommand = "createforrig",
//eventArgument1 = #item.Id,
eventArgument2 = #item.Id
},
new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "AjaxSuccess", //handle with callback
UpdateTargetId = "MyElementID" //update html element
})
if you choose to use OnSuccess then in javascript
function AjaxSuccess(data){
//handle response
}
AjaxOptions properties and usage can be found here
EDIT
You could use javascript to submit a form when a link is clicked, put a form somewhere in your code and hide it.
#using (Html.BeginForm("NewIndex", "WorkItems", FormMethod.Post,
new { class = "hidden", id = "postForm" } ))
{
<input type="hidden" name="eventCommand" value="createforrig" />
<input type="hidden" name="eventArgument2" value="#item.Id" />
<input type="submit" value="link text" id="submitForm"/>
}
then change your #Ajax.ActionLink... to
#Html.ActionLink("Work1", "NewIndex", "WorkItems", new { id = "postLink"})
and if you're using jQuery
<script>
$(function(){
$('#postLink').click(function(e)
{
e.preventDefault();
$('#postForm').submit();
});
});
</script>
and don't forget to hide the form in css
.hidden { display:none;}

Wrong Function Being Called From MVC View

I have an MVC view, which is launched by a function in the controller. That view has a button that I want to use to submit data to a different function in that same controller, but it always go back to the function that launched it instead.
The controller is called, the ViewForPrepare view is launched from PrepareList, I hit the button on ViewForPrepare, and it submits to PrepareList again instead of RunList.
In the controller I have:
public ActionResult PrepareList(int Key)
{
return "ViewForPrepare";
}
public ActionResult RunList(int Key)
{
return "OtherView";
}
Then in the View:
<input type="button" value="Submit Report" id="submit">
<script type="text/javascript">
$(document).ready(function () {
$('#submit').click(function () { window.location ='#Url.RouteUrl("RunList", new { Key = #Model.caseNumber })' });
});
</script>
So I press the button to go to RunList, but it keeps going to PrepareList. I've checked the routing and it looks OK. What do I need to do to get the button to submit to RunList?
You're code right now basically says "When I click the submit button. Change the window's location to something else." If that is what you want, try using
#Url.Action("RunList", new { Key = Model.caseNumber })
instead of
#Url.RouteUrl("RunList", new { Key = #Model.caseNumber })
and try using a <button> element instead of an <input> element.
If what you want is to post the data from the form, you should wrap your button in a form tag (make sure to replace "ControllerName" below with your actual controller.)
#Html.BeginForm("RunList","ControllerName", new { Key = Model.caseNumber })
{
<input type="submit" value="Submit Report" id="submit">
}
and get rid of the javascript altogether as it isn't necessary in this case. Also you will have to mark your RunList action as HttpPost for this to work.
[HttpPost]
public ActionResult RunList(int Key)
{
return "OtherView";
}
Why dont you just use a RouteLink instead of the Input?
#Html.RouteLink("Submit Report", "RunList", new { Key = Model.caseNumber }, new {#class="btn" })
not sure if you're using bootstrap or jquery ui but there are css classes to make links look like buttons.
ActionLink works the same way.
#Html.ActionLink("Submit Report", "RunList", "ViewForPrepare ", new { Key = Model.caseNumber }, new { #class = "btn" })
Using VS2015 Pro I created a project using the MVC template.
HomeController.cs added:
public ActionResult PrepareList(int Key)
{
return View();
}
public ActionResult RunList(int Key)
{
return View(); ;
}
Index.cshtml added:
#Html.ActionLink("Submit Report", "RunList", new { Key = 4 }, new { #class = "btn" })
Put a break point in "RunList" and it worked!
Using
<input type="button" value="Submit Report" id="submit">
#section script{
<script type="text/javascript">
$(document).ready(function () {
$('#submit').click(function () { window.location ='#Url.RouteUrl("RunList", new { Key = 4 })' });
});
</script>
}
I got the meessage
A route named 'RunList' could not be found in the route collection.
when you need to send data, you must add the attribute HttpPost to this action:
[HttpPost]
public ActionResult RunList(int Key)
{
return "OtherView";
}

Controller code gets called twice

I have an MVC view which will have menu and detail sections. As items are clicked on the menu, I would like the detail section to get updated. The menu and detail would be PartialViews.
My main view is layed out like this (so far):
#model WorkflowData.ProjectWorkflow
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="form-horizontal">
<h4>Project Workflow</h4>
<hr />
<div>
#{Html.RenderPartial(
"_WorkflowSteps",
Model.ProjectWorkflowSteps.ToList());
}
</div>
<div id="StepDetail"></div>
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section scripts{
#Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")
<script>
$(function () {
$('.workflow-step').on('click', function (e) {
$.get($(this).prop('href'), function (response) {
$('#StepDetail').html(response)
});
});
});
</script>
}
The '_WorkflowSteps' partial view renders links using this:
#Html.ActionLink(
item.StepName,
"Step",
new { id = item.ProjectworkflowPages.FirstOrDefault().ProjectWorkflowPageId },
new { #class = "workflow-step" });
My controller action for Step is:
public ActionResult Step(int id)
{
if (id == null)
return RedirectToAction("Index");
using (var _db = new MarkTestDbEntities())
{
var stepPage = (from s in _db.ProjectworkflowPages
where s.ProjectWorkflowPageId == id
select s).FirstOrDefault();
var projectModel = new Project
{
ProjectWorkflowId = stepPage.ProjectWorkflowStep.ProjectWorkflowId
};
return PartialView(string.Format("../{0}/{1}",stepPage.Controller, stepPage.CreateAction)
, projectModel);
}
return View();
}
What is happening now is I see the div get populated with the partial view, then the page refreshes with just the partial view from Step. Debugging I see that the Step action is actually called twice, but when I look at the rendered source, I don't see why. Any thoughts?
Your elements with class="workflow-step" are links which make a GET call to your Step() method. You are handling the .click() event of those elements and making a ajax call, but your not cancelling the default redirect so its doing both, the $.get() followed by the redirect. You need to cancel the default action by including return false; in the script
$('.workflow-step').on('click', function (e) {
$.get($(this).prop('href'), function (response) {
$('#StepDetail').html(response)
});
return false; // add this
});

Can I forward to a HttpPost method without a BeginForm?

I'm new to MVC and still haven't found a way to do this.
In the view I have this Clone button:
<a href="#Url.Action("Clone", "Game", new { pModelId = Model.Id })" class="btn btn-default btn-xs">
<i class="fa fa-plus"></i>Clone Game</a>
And in my Controller this:
[HttpPost]
public ActionResult Clone(int pGameId)
{
int lClonedGameId = mGameRepository.CloneGame(pGameId);
return RedirectToAction("Show", new { id = lClonedGameId, message = "Your game was cloned succesfully" });
}
I'm getting a 404 due to the [HttpPost] but I don't want to make it [HttpGet] since it writes to the DB. Is there a way to make that button go to the HttpPost method without a BeginForm or something like that?
If this is only a matter of having link instead of button to submit the form I suggest you adding a form and using javascript to submit a form when the link is pressed (below code assumes you are using jQuery):
#using (Html.BeginForm("Clone", "Game", FormMethod.Post, new {id = "form1"}))
{
//Your other elements go here
CloneGame
}
And hook the script:
$(function() {
$("a.cloneGameSubmit").click(function () {
$("#form1").submit();
});
});

Invoking an action using jquery ajax

I am using ASP.NET MVC 2. I have a modal dialog (done through jquery UI) that contains two text boxes and a button. All the controls are inside a form.
I would like to invoke, when the user click the button, a controller action that do some operations on the passed data contained in the two text boxes and then return an integer value and a string message to the user.
Could anybody provide an example for doing this with jquery?
Thanks so much!
suppose you have the following form :
<form id="ajax-form">
<fieldset>
<input type="text" id="firstname" name="firstname" />
<input type="text" id="lastname" name="lastname" />
<input type="submit" value="send" />
</fieldset>
</form>
using jQuery
$(document).ready(function(){
$("#ajax-form").submit(function(){
$.ajax({
type: "POST",
url: "Person/Add",
data: $("#ajax-form").serialize(),
success: function (response) {
// whatever you want to happen on success
},
error: function (response) {
alert('There was an error.');
}
});
});
});
Accessing Your Data in the Action Method.
public ActionResult Add(FormCollection form)
{
string firstname = form["firstname"];
string firstname = form["lastname"];
// do whatever you want here
// then return something to the view
return Json(/*some object*/);
}
another way is to use Microsoft Ajax
<% using (Ajax.BeginForm("Add", "Person",
new AjaxOptions() {
UpdateTargetId = "formDiv",
InsertionMode = InsertionMode.Replace,
HttpMethod = "Post" })) {%>
<fieldset>
// Form Elements Here.
</fieldset>
<% } %>
UpdateTargetId is the id of the html element to be targeted.
The InsertionMode option has three values Replace, InsertAfter, InsertBefore
Hope that was helpful
Update : you don't have to return a Json result in your action method you can simply return a partial view or any HTML code as the response object and then insert it using jQuery.
You may take a look at the documentation about how you could implement a dialog that contains form fields. And when the confirm button is clicked you could simply send an AJAX request.
buttons: {
Confirm: function() {
// read the value in the textbox
var name = $('#name').val();
// send an AJAX request to an action that will return JSON:
$.getJSON('/home/foo', { name: name }, function(result) {
// read the returned value
alert(result.Value);
});
},
Cancel: function() {
$(this).dialog('close');
}
}
And your controller action:
public ActionResult Foo(string name)
{
return Json(new { Value = '123' }, JsonRequestBehavior.AllowGet);
}

Resources