Passing additional value to Controller method - Razor/MVC 5 - javascript

Hello I am having some trouble figuring out how to pass an additional value to my Controller's Delete method.
I have a form with a Delete button (auto-generated MVC).
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-sm btn-danger" />
<button onclick="location.href='#Url.Action("Index", "Admin")';return false;" class="btn btn-sm btn-primary" style="font-size:10px">Admin</button>
</div>
}
But I want to send along an additional value, this value would be the result of getCookie("username");
I have tried making another input and calling it.
<input type="text" name="userid" value="getCookie('username')" />
The problem is that this always shows "null" within my Controller method.
The method is
// GET: /Admin/Delete/5
public ActionResult Delete(int? id, string userid)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User user = db.Users.Find(id);
if (user == null)
{
return HttpNotFound();
}
return View(user);
}
and
// POST: /Admin/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id, string userid)
{
User user = db.Users.Find(id);
db.Users.Remove(user);
db.SaveChanges();
var time = new DateTime();
string text = time + ": User " + user.name + " was deleted.";
System.IO.File.AppendAllText(pathway, text + Environment.NewLine);
return RedirectToAction("Index");
}
All I want is to have the value of getCookie('username'); passed on to a method as userID.
Any help appreciated!

What you would want to do is have getcookie() set the value (using jQuery, or whatever) of the userId instead of returning it. You'd need to call this on page load. That would put the value in the DOM/form, so it posts to your controller action.
That said, can't you just access the cookies in your action from the Request object?

Related

Value of element created in JS required in Spring MVC controller

I created an input tag inside the javascript, and I also provide the attribute name to it,
var tdTotalEmployees = row.insertCell(k++);
tdTotalEmployees.innerHTML = rowData.totEmployees !== null ? '<h4>' + rowData.totEmployees + '</h4><input type="hidden" name="migrationRef" value=' + rowData.migrationReference + '>' : ' ------ ';
Now as usual, I need this variable value in my controller, I used #RequestParam("migrationRef")String migrationRef
it didn't work,
I used SOUT on request.getParameter("migrationRef"), it displays null. means no value supplied from, but when I inspect the element, I clearly see the value of this element
#RequestMapping(value = "/employee_details")
private ModelAndView getEmployeeList(HttpServletRequest request) {
ModelAndView mav = new ModelAndView("migrate_salary_hr/pre_migration_emp_list");
HttpSession session = request.getSession();
Userdetail loginUser = (Userdetail) session.getAttribute("loginUser");
System.out.println("migration ref no" +request.getParameter("migrationRef") );
try {
mav.addObject("yearMonth", request.getParameter("ym"));
mav.addObject("status", request.getParameter("s"));
mav.addObject("historyList", request.getParameter("h"));
if (loginUser.getEmployee().getRegion().getRegionId() != null && loginUser.getEmployee().getCircle() != null) {
mav.addObject("Region", loginUser.getEmployee().getRegion().getRegionId());
mav.addObject("circle", loginUser.getEmployee().getCircle().getCircleId());
} else {
mav.addObject("Region", loginUser.getEmployee().getRegion().getRegionId());
}
mav.addObject("orderBy", OrderByMap.PREMIGRATIONEMPLIST_ORDERBY);
} catch (Exception e) {
e.printStackTrace();
}
return mav;
}
kindly suggest me the best solution.
The value of the hidden input migrationRef is not sent to the server when one click on the link. That's why you don't see it server side.
I can see two ways to solve this :
Either add the parameter migrationRef into the href attribute of your link, and remove the useless <input type="hidden" ...
Or, if you really don't want to see the parameter migrationRef in the URL, you have to POST it using a form. In this scenario, the action attribute of the form should be of the like action="../emp_list_sm/employee_details?ym=...&s=...&h=...". Then in the Spring MVC controller you will have to use #ModelAttribute in place of #RequestParam on a Java Bean that has a migrationRef attribute.
I think workaround will be create form element and onclick of anchor trigger form submit. This will enable you to post all the information.
<form action="/{you-url}">
<a id="go" href="#" target="_blank"/>click here</a>
<input type="hidden" name= "ym" value = "+rowData.yyyymm+"/>
<input type="hidden" name="s" value="false"/>
<input type="hidden" name="h" value = "true"/>
<input type="hidden" name="migrationRef" value=' + rowData.migrationReference + '/>
<input type="submit"style="display:none"/>
<script>
document.querySelector("#go").onclick = function(){document.querySelector("input[type='submit']").click()};
</script>
</form>

Calling jQuery code in razor block of code

I have a problem where I need to call jQuery code to fetch a value from an HTML element like following:
#using (Html.BeginForm("Login", "Home",new { Checked = $('#checkbox5').checked }, FormMethod.Post,new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
}
Note that besides passing the entire model into my Login action I'm trying to pass an optional parameter named "Checked". This parameter basically states whether the "remember me" checkbox has been checked on the form or not.
The checkbox itself is not the one that .NET uses by default like:
#Html.CheckboxFor(somepropertyhere);
But instead a regular checkbox like this:
<input id="checkbox5" type="checkbox">
<label for="checkbox5">
Remember me?
</label>
How can I fetch this checkbox's value when passing it as an extra parameter besides my model?
So that my method in the end would look like:
Public ActionResult Login(bool Checked, LoginViewModel model)
{
// To have the checked value here now...
}
P.S. And I can't use Html.CheckboxFor for some reasons, but I don't wanna get too much into details since the question wouldn't make sense then (maybe it doensn't even now I'm not sure if this is doable what I'm trying to achieve).
Can someone help me out?
You can get checkbox value in Controller using Checkbox Field name like this :
bool isRememberMe=Request.Form["CheckBoxName"];
if you want to send any variable, you should set name for field, and on serverside you can call it with name
<input id="checkbox5" type="checkbox" **name="checkbox_name"** value="true">
<label for="checkbox5">
Remember me?
</label>
on server side
Public ActionResult Login(bool checkbox_name = false, LoginViewModel model){
// To have the checked value here now...
}
You can't use JavaScript within a Razor block, because they run at entirely different times. The Razor code runs server-side, long before the response is ever sent to the client. JavaScript runs client-side, only after the server has sent its response to the client, and Razor has already done its work.
On first load, the value of your checkbox will always be the default, which in your case is false. That's why none of the other answers help you. The user would have to interact with the checkbox and submit the form first, and then the checkbox would have that user-set value within the post action that handles the form. If you returned to the form, because of an error, then you could utilize the checkbox value.
To actually alter the form action without posting first, you'd have to handle the click event of the checkbox and manually change it via JavaScript. However, that's extremely brittle. If you want the value of the checkbox on post, then just bind it to something your action accepts. For example:
#Html.CheckBox("checked", Request["checked"] as bool? ?? false)
Then:
[HttpPost]
public ActionResult MyPostAction(MyClass model, bool checked)
I really don't understand why you don't want to use a new property model for the RememberMe value, but I think this might work for you:
Assuming your View looks like this:
#using (Html.BeginForm("Login", "Home", FormMethod.Post, new { #class = "form-horizontal", role = "form", id = "login-form" }))
{
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(x => x.Username, new { #class = "form-control" })
#Html.TextBoxFor(x => x.Username, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(x => x.Password, new { #class = "form-control" })
#Html.PasswordFor(x => x.Password, new { #class = "form-control" })
</div>
<div class="form-group">
<input id="checkbox5" type="checkbox">
<label for="checkbox5">Remember me?</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Login</button>
</div>
}
And assuming your Controller looks like this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, bool rememberMe)
{
// Do something with 'rememberMe'
// Do something with 'model'
return RedirectToAction("Index");
}
Then you must need a Javascript like this in your login view to replace the form action before the submit event was completed:
$(function () {
var form = $("#login-form");
var checkbox5 = $("#checkbox5");
form.submit(function () {
var checked = checkbox5.is(":checked") ? "true" : "false";
var action = updateQueryStringParameter(form.action || '', "rememberme", checked);
form.attr('action', action);
});
// stolen from http://stackoverflow.com/a/6021027/1605778
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
}
else {
return uri + separator + key + "=" + value;
}
}
});
Let me know if this works for you.
Just to give more context: when you have a parameter of a primitive type (like bool or int) in your action, MVC expects this parameter in the Url; but the values of the Complex Types (like LoginViewModel) should pass as a Request Body in the HTTP POST. So if you want to pass both (complex and primitive) you need to be careful to pass all primitive types in the url and the values of complex types in the request body.
The POST of the Login Form could looks like:
POST /Home/Login?rememberMe=false
username=admin&password=secret

Confirm Box not stopping controller action

Giving the user the option to see the rows returned from the search or not. If I hit Cancel, it still runs the controller code.
HTML:
<td><input type="submit" name="SubmitSearch" id="search" value="Search" class="form-control alert-success" onclick="return rowcount()" /></td>
Javascript:
<script type="text/javascript">
function rowcount() {
confirm("There are rows");
}
Controller:
[HttpPost]
public ActionResult OracleVerification(string company, string location, string product, string department)
{
List<OracleStringViewModel> oracleStringList = OracleStringRepository.GetOracleStrings(company, location, product, department);
return View(oracleStringList.ToList());
}
The construct confirm() returns true or false. You need to make use of it. You forgot to use the return keyword:
function rowcount() {
return confirm("There are rows");
}
The problem here is, the confirm actually returns the boolean value from the user, but it goes nowhere. You need to return it back to the calling place, which is the input's onclick event.

Calling an Action Method based on the value of DropDownList and the model

I have a dropdownlist in my View. I need to enable the user to select a value from the dropdownlist and click a button/ActionLink to call another action method in the same controller. The values that needs to be passed to the new ActionMethod are the ID of the selected Value from the dropdownlist and also the ID of the model which is being passed into the View. The model and the Dropdownlist are not linked together by any means.
I have tried onchnage = document.location.href to set the path of the action method and pass a single value to the action method. But the issue with document.location.href is that it appends the url to the existing url which is not appreciated; i.e, the final url turns out be localhost:port/controller1/action1/controller1/action2 which should have been simply localhost:port/controller1/action2
I am looking for a way where it could be done without using javascript as I have already tried it.
Code in the View
#using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
<p>
#Html.DropDownList("OptionValueID", null, "Select")
<input type="submit" value="Copy" />
//This is the preferable method though
#*#Html.ActionLink("Copy", "Copy", "SetValues", new { #OptionValueID = #ViewBag.id,#CopyID = CopyDDL.SelectedValue},null)*#
</p>
}
The copy function is going to take two arguments: Id of the selected item and ID that is being passed through ViewBag.id
The View that is being returned by View would a different View
JavaScript that I have tried
<script language="javascript" type="text/javascript">
function copy(_OptionValueID)
{
var url = "/SetValues/Copy";
$.ajax({
url: url,
data: { copyid: _OptionValueID},
type: "POST",
success: function (data) { }
});
response();
}
</script>
It doesn't evaluate at all.
Action Method that calls this View
public ActionResult Index(int id)
{
var ov = db.OptionValue.Include(x => x.Option).FirstOrDefault(x => x.OptionValueID == id);
var opid = ov.OptionID;
var op = db.Option.Include(x => x.TechnicalCharacteristic).FirstOrDefault(x => x.OptionID == opid);
var tcid = op.TechnicalCharacteristicID;
var tc = db.TechnicalCharacteristic.Include(x => x.TcSets).FirstOrDefault(x => x.TechnicalCharacteristicID == tcid);
var tcset = tc.TcSets;
var opv = db.OptionValue.FirstOrDefault(x => x.OptionValueID == id);
ViewBag.OptionValue = opv.OptionVal;
ViewBag.Option = opv.Option.OptionName;
ViewBag.Lsystem = opv.Option.Lsystem.LsystemName;
ViewBag.FamilyName = opv.Option.Lsystem.LsystemFamily.FamilyName;
ViewBag.OptionValID = id;
ViewBag.OptionID = opv.OptionID;
var setValue = db.SetValue.Where(x=>x.OptionValueID==id).OrderBy(x=>x.TcSet.SetName);
ViewBag.OptionValueID = new SelectList(db.OptionValue.Where(x=>x.OptionID==opid), "OptionValueID", "OptionVal");
return View(setValue.ToList());
}
I ahve checked most question relating to this, but none had the overhead of passing two parameters without using a model.
UPDATE: making it more clear
public ActionResult copy(int OptionValueID,int CopyID)
{
//do Something
return View("Error");
}
Above is the Copy Method
OptionValueID = ViewBag.OptionValID //Got from the Action Method Index of SetValues
CopyID = Value from the DropDownlist
Edit Based on Answer
#using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
<p>
#Html.DropDownList("CopyID", null, "Select")
<button type="submit" id="Copy" data-id="#ViewBag.OptionValID"> Copy </button>
</p>
}
now the page is being redirected but the no parameters are being passed. Should I be adding routevalues?
You cannot do it without javascript. Your ActionLink() method is parsed on the server before its sent to the client, so any route values are the initial values in the controller, not any edited values the user makes in the view. In order to respond to client side events you need javascript.
You can use ajax to post the values to the server method.
Include a button and handle its click event
<button type="button" id="Copy" data-id="#ViewBag.id">Copy</button>
Script
var url = '#Url.Action("Copy", "SetValues")';
$('#Copy").click(function() {
var optionID = $(this).data('id');
var copyID = $('#OptionValueID').val();
$.get(url, { OptionValueID: optionID, copyID : CopyID }, function(response) {
// do something with the response
});
});
or alternatively if you wanting to redirect, then replace the $.get() with
location.href = url + '?OptionValueID=' + optionID + '&CopyID=' + copyID;
Edit
Based on revised question and comments, if you wanting to post and redirect, there is no need for any javascript or the link. The dropdownlist needs to be #Html.DropDownList("CopyID", null, "Select") so that its selected value is bound to method parameter int CopyID and since the OptionValueID is not edited, then either add its value as a route parameter in the form
#using (Html.BeginForm("Copy", "SetValues", new { OptionValueID = ViewBag.OptionID }, FormMethod.Post))
or add a hidden input for the value
<input type="hidden" name="OptionValueID" value="#ViewBag.OptionID" />

How to update div tag in Javascript with data from model for onsubmit form asp.net mvc

In my page I have a form tag which submits to server, gets data and redirects to same page.
The problem is the the div tag which has the data from server is not getting updated. How to do that in Javascript?
<% using (Html.BeginForm("Addfile", "uploadfile", FormMethod.Post, new
{
id = "uploadform",
enctype = "multipart/form-data"
}))
{ %>
<input type="file" id="addedFile" name="addedFile" /><br />
<input type="submit" id="addfile" value="Addfile" />
<div id="MyGrid">
//data from the model(server side) filelist is not updating</div>
What will be the form onsubmit Javascript function to update the div tag with the data from the model.
My uploadfile controller get post methods are as:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Upload()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddFile(HttpPostedFileBase addedFile)
{
static List<string> fileList = new List<string>();
string filename = Path.GetFileName(addedFile.FileName);
file.SaveAs(#"D:\Upload\" + filename);
fileList.Add(filename);
return("Upload",fileList);
}
In your post action method you are instantiating new list (fileList) every time a file is uploaded and no matter how many files you upload this list will contain only one entry in the current setup. i would suggest saving file list to database and retrieve it from there when you want to show the list on view. it could be like
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Upload()
{
List<string> fileList = //retreive from db;
return View(fileList);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddFile(HttpPostedFileBase addedFile)
{
string filename = Path.GetFileName(addedFile.FileName);
file.SaveAs(#"D:\Upload\" + filename);
//add file name in database
return redirectToAction("Upload");
}
you should ideally always redirect from your post action method instead of returning a view if there are no model errors. In Get Action method you can retrieve the values from db and display it on the view. you can also put some parameter like id in both of your methods to save and retrieve values in database

Categories

Resources