I need to disable button when property 'Flag' is true. This is my model and controller.
public class User {
public string Name { get; set; }
public bool Flag{ get; set; }
}
controller
public ViewResult Index() {
var userFlag = context.Users.Where(u => u.Flag = true).FirstOrDefault();
if (userFlag != false)
{
// disable button
}
else
{
// enable button
}
return View();
}
You disable the button in the view, not in the controller. First, the controller needs to send some information to the view. Ideally this is in the form of a view model, but for now let's just put a simple value into the ViewBag. Something like this:
ViewBag.UserFlag = userFlag;
return View();
Then in the view you can use that value. For example:
#if(ViewBag.UserFlag == true)
{
<button type="button" disabled>Click here</button>
}
else
{
<button type="button">Click here</button>
}
Or however your button is "enabled" vs. "disabled" in your HTML. You could even compress this into a single line using the ternary conditional operator if you want, it's a matter of personal preference.
But the point is that the controller simply provides the view with the data it needs to render the UI. It's then the view's responsibility to respond to that data and render the UI.
You have to pass that flag (boolean value) to the view and conditionally render the button with disabled attribute
You can pass the boolean value in multiple ways.
If you have a view model, set it's corresponding property. Let's say you have a view model called YourViewModel for your view and it has a IsEnabled property of boolean type ,set that in your action method and send the view model to the view.
So in your action method
var vm = new YourViewModel();
var user = context.Users.Where(u => u.Flag == true).FirstOrDefault();
vm.IsEnabled= user != null && user.Flag;
// Pointless because you are getting the one with True;
// So the value will be always true if user is not null
return View(vm);
and the view, check the IsEnabled property of your model,
#model YourViewModel
#if (Model.IsEnabled)
{
<input type="submit" value="Save" />
}
else
{
<input type="submit" value="Save" disabled="disabled" />
}
Or if you do not have a view model/your view is not strongly typed to any class, you can pass the boolean value as the model of the page
var user = context.Users.Where(u => u.Flag = true).FirstOrDefault();
var flag= user != null && user.Flag;
// Pointless because you are getting the one with True;
// So the value will be always true if user is not null
return View("Index",flag);
and in the view
#model bool
#if (Model)
{
<input type="submit" value="Save" />
}
else
{
<input type="submit" value="Save" disabled="disabled"/>
}
Another option is to use ViewBag to transfer this boolean flag from action method to view.
var user = context.Users.Where(u => u.Flag == true).FirstOrDefault();
ViewBag.IsEnabled = user != null && user.Flag;
// Pointless because you are getting the one with True;
// So the value will be always true if user is not null
return View();
and in the view
#if (ViewBag.IsEnabled !=null && ViewBag.IsEnabled)
{
<input type="submit" value="Save" />
}
else
{
<input type="submit" value="Save" disabled="disabled" />
}
Here i am rendering the enabled button only if the Flag value of your record is true. Adjust the code to negate it as needed ( in your question, it is the other way)
You cas use ViewBag to pass flag value from controller to view as
public ViewResult Index() {
var userFlag = context.Users.Where(u => u.Flag = true).FirstOrDefault();
ViewBag.UserFlag = userFlag == null ? true : false;
return View();
}
You can disable button in view as
<input type="button" value="Save" #{ if (ViewBag.UserFlag == true){ #: disabled="disabled"} } />
Related
I have a simple view with a checkbox at the bottom:
#model Application.Areas.Cms.Models.ProduktBeispielViewModel
#{
ViewBag.PopupHeadline = "Produktbeispiele";
ViewBag.PopupSubHeadline = Model.Item != null ? Model.Item.NameInCurrentLang : "";
ViewBag.HideLanguageComparison = true;
}
#section TabMenu
{
<ul>
<li>Einstellungen</li>
<li>Bild</li>
</ul>
}
<form action="#Url.Action("SaveIndex")" method="POST" id="idForm">
#Html.HiddenFor(m => m.AutoCloseWindow)
#Html.HiddenFor(m => m.Item.Id)
<checkbox/>
</form>
I have this Index:
public ActionResult Index(int id = 0, int categoryId = 0, bool autoclosewindow=false,bool refreshOpener=false)
{
var model = LoadModel(id, categoryId);
model.AutoCloseWindow = autoclosewindow;
model.RefreshSequenceInOverview = refreshOpener;
foreach (var lang in new LanguageManager().GetItems())
{
...
}
return View(model);
}
And ofc I have my model containing the data properties.
I can already display values bound inside my model in my view but I cannot seem to go the way back, meaning if the user checks the checkbox, how do I retrieve that is has been checked?
(Same would go for an editor or entry field)
How can I access the data from my checkbox?
EDIT:
I already have a form of which the checkbox is a child:
<form action="#Url.Action("SaveIndex")" method="POST" id="idForm">
#Html.HiddenFor(m => m.AutoCloseWindow)
#Html.HiddenFor(m => m.Item.Id)
#Html.CheckBoxFor(m => m.Test2)
But when I set a stoppoint at the corresponding function:
public ActionResult SaveIndex(Product item, List<GeneralLanguageEntry> languages, bool autoclosewindow = false)
{
...
return RedirectToAction("Index", new { autoclosewindow = autoclosewindow, refreshOpener = true, id = productFromDb.Id });
}
The model is not returned here... So i cannot see my altered checkbox
You need to use a rendered control from the html helper rather than just putting a checkbox on the page. This will bind the control to the property in your model.
#Html.CheckBoxFor(m => m.YourBoolValue)
Make sure you have a method that will accept your post data when the form is submitted:
[HttpPost]
public ActionResult SaveIndex(Product item)
...
I have created a dropdownlist using html helper.
It's able to get the value and bind to dropdown.
How can i pass the selected dropdown value to controller?
My View:
#Html.DropDownList("Language", new SelectList(ViewBag.LangList, "Text", "Value"))
<input type="button" class="btn" title="Filter By Language"
value="Filter By Language" onclick="location.href='#Url.Action("SURV_Answer_Result", "SURV_Answer",
new { Survey_ID = Model[0].Survey_ID, Language = ViewBag.LangList })'" />
My Controller to get Language and bind into dropdown:
public ActionResult SURV_GetLanguage(int Survey_ID)
{
var getlanguagelist = from r in db.SURV_Question_Ext_Model
join s in db.SURV_Question_Model on r.Qext_Question_ID equals s.Question_ID
where s.Question_Survey_ID == Survey_ID
group new { r, s } by r.Qext_Language into grp
select grp.FirstOrDefault();
foreach (var item in getlanguagelist.ToList())
{
List<SelectListItem> langResult = new List<SelectListItem>();
foreach (var item2 in getlanguagelist)
{
SelectListItem temp = new SelectListItem();
temp.Text = item2.r.Qext_Language;
temp.Value = item2.r.Qext_Language;
langResult.Add(temp);
}
ViewBag.LangList = langResult;
}
return View(ViewBag.Langlist) ;
}
And i want pass the Language to the controller below:
public ActionResult SURV_Answer_Result(int Survey_ID, string Language)
{
List<AnswerQuestionViewModel> viewmodel = new List<AnswerQuestionViewModel>();
SURV_GetLanguage(Survey_ID);
// do whatever i want...
}
Your button in the view istype="button" and you have attached a onclick event which will just redirect to the SURV_Answer_Result passing the original ViewBag property back to the method (which will not bind to string Language because its List<SelectListItem>.
You need a form with FormMethod.Get
#using (Html.BeginForm("SURV_GetLanguage", "ControllerName", new { Survey_ID = Model[0].Survey_ID }, FormMethod.Get))
{
#Html.DropDownList("Language", (Enumerable<SelectListItem>)ViewBag.LangList)
<input type="submit" ... />
}
Notes:
The Survey_ID has been added to the form as a route value
ViewBag.LangList is Enumerable<SelectListItem> which is all that
is required by the DropDownList() helper so there is no point in
the extra overhead of creating another SelectList from it
(SelectList IS Enumerable<SelectListItem>)
The code you have used would work if you change the method signature on the controller to public ActionResult SURV_GetLanguage(int Survey_ID, string Language = null). You could then test for nulls and process as necessary.
However it would be better to wrap the dropdownlist inside a form, and use a POST request. Something like:
#using (Html.BeginForm("SURV_GetLanguage","ControllerName",FormMethod.Post))
{
#Html.DropDownList("Language", new SelectList(ViewBag.LangList, "Text", "Value"))
<input type="submit" class="btn" />
}
Then in the controller you could have a new method:
[HttpPost]
public ActionResult SURV_GetLanguage(string Language)
{
//Do whatever you want with language.
}
There are two ways,
1) You can put your dropdown and submit button into a form containing action parameter. On button press, your form will be submitted to its action. Your action must contain a parameter with name 'Languages'. It will give you selected value.
All the parameters of action, if matching to 'name' property of controls, will contain their values on form submit.
2) You can get selected value from dropdown by using jquery and then use either window.location or build url for form's action and call submit.
I get the feeling I am violating MVC best practise here, but I don't see how.
I have a form with two buttons with different names so when it gets posted to the action, I can do different things based on which button is pressed.
#using (Html.BeginForm("Display", "PlayBoard")
// form properties
<button class="btn btn-primary" type="submit" name="Display">Filter PlayBoard</button>
<button class="btn btn-primary" type="submit" name="Report">Report View</button>
then in the controller:
[HttpPost, FlexAuthorize]
public ActionResult Display(FormInput filter )
{
if (Request["Report"] != null)
{
var model = queryRepository.Load<FormInput , ReportViewPlayBoardView>(filter);
return View(model);
}
if (Request["Display"] != null)
{
var model = queryRepository.Load<FormInput , DisplayPlayBoardView>(filter);
return View(model);
}
When I click the report button, it runs through the query ok but then comes back with the exception: "The model item passed into the dictionary is of type '...ReportViewPlayBoardView', but this dictionary requires a model item of type '...DisplayPlayBoardView'."
I don't really follow why this has to be a DisplayBoardView model that gets returned.
edit: fixed it, I just had to change the view command on the report branch to: return View("ReportView", model);
fixed it, I just had to change the view command on the report branch to:
return View("ReportView", model);
Is it possible to use Model binding to get value of a button in the POST action method when its clicked on. I have a complex type and I wanted to have the user click on a button and retrieve the value of that button so I can use it to update the value of the complex type in the DB.
Note that at this point I have already saved the entity into the database and all that is left is to get a way to update properties of the complex type.
If there is a recommended way to do that am willing to adopt that.
Thanks in advance.
You can use multiple submit buttons with different values to specify the way of update model.
#using (Html.BeginForm("MultipleCommand", "Home", FormMethod.Post, new { id = "submitForm" }))
{
.
.
.
<button type="submit" id="btnSave" name="Command" value="create">Save</button>
<button type="submit" id="btnSubmit" name="Command" value="update">Submit</button>
}
public ActionResult(ComplexModel model, string Command)
{
if(Command == "create")
{
}
else if(Command == "update")
{
}
else
{
// Default action
}
}
For more info read Handling multiple submit buttons on the same form - MVC Razor.
Do something like this
public ActionResult Index(string submit)
////Your action while clicking the button and in the view button name should be submit
{
//// The string submit will have the value of the button
}
I have created a C# ASP.NET MVC application. In the Index view, i have added 3 buttons, when each button is clicked i want to execute 3 different functions from the Index controller.
Index View that resides in the Home folder
#using (Html.BeginForm()) {
<input type="submit" value="b1" />
<input type="submit" value="b2" />
<input type="submit" value="b3" />
}
Home Controller
public ActionResult Button1Click()
{
return View();
}
public ActionResult Button3Click()
{
return View();
}
public ActionResult Button2Click()
{
return View();
}
When each button is clicked how can i write code to execute the correct controller method ?
If you are posting then you can put each button in a separate form:
#using (Html.BeginForm("Button1Click","Index")) {
<input type="submit" value="b1" />
}
#using (Html.BeginForm("Button2Click","Index")) {
<input type="submit" value="b2" />
}
#using (Html.BeginForm("Button3Click","Index")) {
<input type="submit" value="b3" />
}
If there is no data to post, as shown in your method, and you still want to have all buttons in the same form then you can do an ajax post (this does not make sense though but hey I'm basing it on the code you gave in your question), with this though you may want to change your buttons from a submit into a button (input type="button").
$("#b1").click(function(){
$.post('/index/button1click', function() {
});
});
$("#b2").click(function(){
$.post('/index/button2click', function() {
});
});
$("#b3").click(function(){
$.post('/index/button3click', function() {
});
});
If you want to do a GET instead of a post then just replace .post with .get.
In MVC you need to remove the (Asp.Net) idea of linking button clicks to actions. ASP.Net is event driven MVC uses the classic HTTP REST approach.
So the buttons aren't actions, the buttons submit actions. The action that is submitted is controlled by your form. So your form POSTs data to the controller, using a HTTP post.
Now it's not clear what your trying to achieve here. You appear to be returning different views from each action. So using the REST idea, you should be a GETing not a POSTing (your getting HTML). So the simplest idea is to turn your input(submit) into Anchor tag, i.e. a HTTP GET:
#Html.ActionLink("Button1Click")
etc.
MVC doesn't work like Webforms where you have a ButtonClick event.
Do you want to post any values to the controller?
If not, you can use a link that you can style like a button. Use the buildin Html extensions.
//For links
#Html.ActionLink("Button1Text","Button1Click")
#Html.ActionLink("Button2Text","Button2Click")
#Html.ActionLink("Button3Text","Button3Click")
//If you need more styling options
Button1
Button2
Button3
That way you don't need any javascript or multiple forms in your view. You'll have to add some styling in your CSS files.
One easy way to execute different actions on different button within the same form is to distinguish button click by their name:
Example code is:
View:
#using (Html.BeginForm("MyMethod","Controller"))
{
<input type="submit" value="b1" name="b1" />
<input type="submit" value="b2" name="b2" />
<input type="submit" value="b3" name="b3" />
}
Controller:
[HttpPost]
public ActionResult MyMethod(string b1, string b2, string b3)
{
if (b1 != null)
{
return Button1Click();
}
else if (b2 != null)
{
return Button2Click();
}
else
{
return Button3Click();
}
}
public ActionResult Button1Click()
{
return RedirectToAction("Index");
}
public ActionResult Button3Click()
{
return RedirectToAction("Index");
}
public ActionResult Button2Click()
{
return RedirectToAction("Index");
}