call javascript method from mvc3 controller? - asp.net-mvc-3

i have a button on the cshtml view..its clicked every-time an item is scanned.
The user has to do it one by one and once all the items have been scanned..i want to opem/pop up a new window plus redirect him to another page.. The condition whether it was the last item..is being checked in the controller method.
How can i call a javascript to open the new window from the controller..right before my 'redirecttoaction' ?
is there a better way to do it?

Here's a sample pattern:
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// TODO Process the scanned code model.Code
if (IsLastItem())
{
model.IsLast = true;
}
return View(model);
}
and inside the view:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(x => x.Code)
<input type="submit" value="OK" />
}
<script type="text/javascript">
#if (Model.IsLast)
{
<text>
window.open('#Url.Action("foo")', 'foo');
window.location.href = '#Url.Action("bar")';
</text>
}
</script>

Its not clean to call JavaScript from controller. Instead, move the logic of checking if its a last item to the client side and call appropriate controller action as appropriate.

Related

MVC Preserving Model When Jumping Between Controller and Forms

so I recently started project in .net MVC and have been having issues preserving data. I read somewhere that in order to do so, you have to pass the model back and forth. I tried doing this, but it still runs into issues. In my project, I have two buttons right now, getData and getData2. My view prints their true/false values. When I press one, it turns true, but if I press the other, it turns true but the other one goes to false. I want them both to stay true if I press them both.
Controller:
[HttpPost]
public ActionResult GetData(TestSite.Models.FarModels theFars)
{
theFars.HasData = true;
return RedirectToAction("FarCalc",theFars);
}
[HttpPost]
public ActionResult GetData2(TestSite.Models.FarModels theFars)
{
theFars.HasData2 = true;
return RedirectToAction("FarCalc", theFars);
}
[HttpGet]
public ActionResult FarCalc(TestSite.Models.FarModels theFars)
{
return View(theFars);
}
View:
#using (Html.BeginForm("GetData", "Home", FormMethod.Post))
{
//#Html.TextBoxFor(model => model.FarValue)
<input type="submit" value="GetData" />
}
#using (Html.BeginForm("GetData2", "Home", FormMethod.Post))
{
//#Html.TextBoxFor(model => model.FarValue)
<input type="submit" value="GetData2" />
}
#Model.HasData
#Model.HasData2
Thanks
You would need to make use of TempData object because the use of RedirectToAction returns a status code of 302, and the model binding does not exist. A good example is below.
https://www.codeproject.com/Tips/842080/How-to-Persist-Data-with-TempData-in-MVC

Using two button in a form calling different actions

I have a form on my page:
#using(Html.BeginForm("DoReservation","Reservation"))
{
...some inputs
<button id="recalculate">Recalculate price</button>
<button id="submit">Submit</button>
}
When I click the "Recalculate price" button I want the following action to be invoked:
public ActionResult Recalculate(FormCollection form)
{
var price = RecalculatePrice(form);
... do some price recalculation based on the inputs
return PartialView("PriceRecalculation",price);
}
When I click the "Submit" button I want the "DoReservation" action to be invoked (I want the form to be submitted).
How can I achieve something like that?
What I can suggest is , adding a new property to your view model and call it ActionType.
public string ActionType { get; set; }
and then change your cshtml file like below
#using (Html.BeginForm())
{
<div id="mytargetid">
...some inputs*#
</div>
<button type="submit" name="actionType" value="Recalculate" >Recalculate price</button>
<button type="submit" name="actionType" value="DoReservation" >Submit</button>
}
in post action method based on ActionType value you can decide what to do !
I noticed that in your comments you mentioned you need to return partial and replace if with returning partial , no problem , you can use
#using (Ajax.BeginForm("DoProcess", new AjaxOptions { UpdateTargetId = "mytargetid", InsertionMode = InsertionMode.Replace }))
and in controller change your action to return partial view or java script code to redirect page
public ActionResult DoProcess(FormModel model)
{
if (model.ActionType == "Recalculate")
{
return PartialView("Test");
}
else if (model.ActionType == "DoReservation")
{
return JavaScript(string.Format("document.location.href='{0}';",Url.Action("OtherAction")));
}
return null;
}

ASP.NET MVC 3 - Posting a Form Back to the Controller

I'm new to ASP.NET MVC. I'm currently using ASP.NET MVC 3. I'm trying to create a basic form with an image button that posts data back to the controller. My form looks like the following:
MyView.cshtml
#using (Html.BeginForm())
{
#Html.TextBox("queryTextBox", string.Empty, new { style = "width:150px;" })
<input type="image" alt="Search" src="/img/search.png" value="Search" name="ExecuteQuery" />
}
MyController.cs
public class MyController: Controller
{
public ActionResult Index()
{
ViewData["CurrentDate"] = DateTime.UtcNow;
return View();
}
[HttpPost]
public ActionResult ExecuteQuery()
{
if (ModelState.IsValid)
{
return View();
}
}
}
I have verified that I'm accessing my controller code. The way I've been able to do this is by successfully printing out the "CurrentDate" associated with the ViewData. However, when I click my image button, I was assuming that my break point in the ExecuteQuery method would fire. It does not. What am I doing wrong? How do I do a simple POST in MVC?
Your form is pointing to the wrong action.
Calling Html.BeginForm() creates a <form> that POSTs to the current action (Index).
You need to pass the action name to BeginForm.
Try this one
#using (Html.BeginForm("ExecuteQuery", "MyController", FormMethod.Post))
{
#Html.TextBox("queryTextBox", string.Empty, new { style = "width:150px;" })
<input type="submit" value="Search" />
}
In your controller
public class MyController: Controller
{
public ActionResult Index()
{
ViewData["CurrentDate"] = DateTime.UtcNow;
return View();
}
[HttpPost]
public ActionResult ExecuteQuery(string queryTextBox)
{
if (ModelState.IsValid)
{
// DO SOMETHING WITH queryTextBox
return View();
}
}
}
If the image submit button is very important for you, you can still change the button background image using CSS.

jQuery Mobile 1.0 anchor tag not loading page for same URL

I've noticed that with jQuery Mobile, if an anchor tag's href is the same as the current URL, the page does not refresh, as it does normally. I'm using a Stepped Wizard through a series of pages, and the final page has a link to repeat the process; this works fine except in jQuery Mobile. I'm new to the Mobile framework, so I'm not sure what events are firing that I need to hook into. Any help would be appreciated.
Here's a glimpse of the controller/ view code:
Controller:
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
if (ModelState.IsValid)
{
switch (model.SubmitButton)
{
case Buttons.Review:
return Review(model);
case Buttons.Confirm:
return Confirm(model);
}
}
return View(model);
}
public ActionResult Review(MyViewModel model)
{
return View("Review", model);
}
public ActionResult Confirm(MyViewModel model)
{
if (ModelState.IsValid)
{
return View("Confirm", model);
}
return View("Index", model);
}
View:
<div>
#* display stuff *#
#Html.ActionLink("Do it again!", "Index", "MyController", new { area = "MyArea" }, new { data_role = "button" })
#* display more stuff *#
</div>
Hmm, the code you posted is not javascript and for sure not using JQM..... Is that your aspx code-behind?
Either way, you'll probably want to disable JQM's ajaxEnabled loading if you want to reload the whole page in the current browser window.
See documentation

MVC3 Razor: how to make a partial view conditionally loaded?

I am beginner in MVC3 and still learning. I try to write an application (MVC3 with Razor) which allows user to select files and upload/save. During upload/save process I want to simply show "wait" text as partial view. I have problem since the partial view is loaded as soon as the web application is started and I got error from HomeController - [HTtpPost] Wait method, since it can't trace the list Files in object job. OF course, the list of Files will be filled after upload. I don't know how to solve this and need your help. Thank you in advance.
My HomeController.cs :
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult UploadFile(IEnumerable<HttpPostedFileBase> attachments)
{
foreach ( var file in attachments )
{
// do something
}
return RedirectToAction("Wait");
}
public ActionResult Wait()
{
// do something
ViewBag.Message = "Wait...";
return View();
}
[HttpPost]
public ActionResult Wait(FormCollection formCollection)
{
Work job = MvcApplication.GetWork();
if ( job.Files.Any() )
{
return RedirectToAction("SubmitWork");
}
else
{
return View();
}
}
The view Index.cshtml :
#{
ViewBag.Title = "FirstTry";
}
<p>
<div id="AddFiles">
#Html.Partial("_AddFiles")
</div>
</p>
<div id ="Wait">
#Html.Partial("_Wait")
</div>
The partial view _Wait.cshtml :
#{
ViewBag.Title = "Wait...";
}
#ViewBag.Message
#using ( Html.BeginForm("Wait", "Home", FormMethod.Post, new
{
id = "waitform"
}) )
{
}
<script type="text/javascript">
window.setTimeout("document.getElementById('waitform').submit()", 1000);
</script>
The partial view _AddFiles.cshtml :
#using ( Html.BeginForm("UploadFile", "Home", FormMethod.Post, new{id = "uploadForm", enctype = "multipart/form-data"}) )
{
#(Html.Telerik().Upload().Name("attachments").Multiple(true)
.Async(async => async.AutoUpload(true) )
)
<input type="submit" value="Send" class="t-button" />
<input type="reset" value="Reset" class="t-button" />
}
MVC does not work like WebForms, client side events will not propagate to server controls (there aren't really even controls, I think Telerik blurs this line a bit and complicates the MVC experience).
You can invoke additional actions in your controller to download HTML or JSON or something, but the only way on the client side to swap HTML without having your page change (since an upload is in progress) would be to use javascript.
I'm not familiar with this Telerik control, but I think you will have to do something on the client side, not on the server side, to indicate loading progress or show a spinner.
Their API shows there is an onupload event you can listen for and possible swap to the loading div:
http://www.telerik.com/help/aspnet-mvc/telerik-ui-components-upload-client-api-and-events.html
They probably have a sample somewhere. I will see if I can dig something up, but really I think just listening for this event is your best bet and do this on the client side, not the server side.

Resources