I have a view that uses the next Model
#model Merak.Models.Product.Options.NumberOfObjectsProductOptionModel
And 2 radiobuttons
#Html.RadioButton(Constants.HtmlControlValues.OptionNumberObjectSelect, #Model.OptionOnePrice, true) <br/>
#Html.RadioButton(Constants.HtmlControlValues.OptionNumberObjectSelect, #Model.OptionTwoPrice)
Inside constants.HtmlControlValues.OptionNumberObjectSelect is a string with "groupname" inside.
I would think that the Html control would generate something like:
<input id="groupname" name="groupname" type="radio" value="50,00">
But instead it generates something like:
<input id="NumberOfObjectsProductOptionModel_groupname" name="NumberOfObjectsProductOptionModel.groupname" type="radio" value="50,00">
Any idea why this behaviour is happening and what I can do to get the short name/id version?
You can assign the constants.HtmlControlValues.OptionNumberObjectSelect to a variable a then get the value:
#model Merak.Models.Product.Options.NumberOfObjectsProductOptionModel
#{
string myControl = constants.HtmlControlValues.OptionNumberObjectSelect
}
And then use it in your control:
#Html.RadioButton(#myControl, #Model.OptionOnePrice, true)
Could you use #Html.RadioButtonFor(model => Model.OptionOnePrice) and see if that works better. That way it's bound to your model.
Related
Here i have used two checkbox
<label asp-for="SendReport" class="checkbox-inline"><input type="checkbox" asp-for="SendReport" />Send Report</label><br>
<label asp-for="SendInvoice" class="checkbox-inline"><input type="checkbox" asp-for="SendInvoice" />Send Invoice</label><br>
and data type for both checboc i.e asp-for="SendReport" and asp-for="SendInvoice" is bit.
Now the problem is that when ever i try to load the page its throws error as below
Unexpected 'asp-for' expression result type 'System.Nullable`1[[System.Boolean, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' for <input>. 'asp-for' must be of type 'System.Boolean' or 'System.String' that can be parsed as a 'System.Boolean' if 'type' is 'checkbox'.<br>
Any help will be heartly thankful. Thank you
This is because asp-for is always expecting a boolean parameter when input type is checkbox, or a string parameter that can be parsed as boolean.
This said, having the assumption that SendReport and SendInvoice are not boolean:
Unexpected 'asp-for' expression result type 'System.Nullable`
you will have to change these parameters into boolean parameters that will be false by default, or into string parameters that will contain "false" or "true" by default.
I ran into the same issue when working with EFcore.
From the database, I have:
namespace Project.EFCoreModels;
public partial class Account
{
public int AccountId {get; set;}
public bool? HasSaleTax {get; set;}
}
I want to display HasSalesTax as a checkbox input with asp tag helper:
<input type="checkbox" asp-for="HasSaleTax" class="form-control" />
This thows the error because the the input type checkbox does not accept nullable value. Fair enough.
To work around it, I created another partial class, same namespace, but on a different project directory (folder). This is a common pattern in .NetCore MVC when we want to add MetaData to an EFCore class.
namespace Project.EFCoreModels;
public partial class Account
{
public bool SalesTaxInput
{
get => this.HasSaleTax.GetValueOrDefault();
set {this.HasSaleTax = value;}
}
}
Then on the view, you just bind the input with the newly created prop:
<input type="checkbox" asp-for="SalesTaxInput" class="form-control" />
When happened use bit datatype for reparent true, false but column allow null checked
You can fixed by two way
First: Set Not Allow null or remove ? in filed
Example:
public bool? SendReport {get; set; }
// change to below code
public bool SendReport {get; set; }
Second: You can use normal html tag for checkbox input
<input type="checkbox" id="SendReport" name="SendReport" #((Model.SendReport== false ? "" : "checked")) />
It is an issue with: asp-for="SendReport". That is not valid because
the tag is input of type checkbox so asp-for is expecting a boolean
and you are sending it a something else than a boolean.
Refer this:
Asp.net MVC putting checkbox data in a list of booleans
If you use a
#Html.EditorFor(m => m.SendReport, new { #class = "form-control" }}
it will give you a dropdown box with options
<select id="SendReport" name="SendReport" class="list-box tri-state">
<option value="">Not Set</option>
<option value="true">True</option>
<option value="false">False</option>
</select>
at least I do, when using Bootstrap 4 and Visual Studio 2019, with .NET Core 3.1
Anyone running into this MVC core abandon the "for"
#Html.CheckBox("tblSubCategory.Enabled",Model.tblSubCategory.Enabled.HasValue? Model.tblSubCategory.Enabled:false)
tblSubCategory is a sub model on a view,
Enabled is a nullable boolean
Just removing ? do not work.
for me worked as i wrapped around a div claaa=checkbox
<div class="form-group">
<label asp-for="IsDeleted" class="control-label"></label>
<div class="col-md-10">
<div class="checkbox">
<input asp-for="IsDeleted" class="form-check" />
<span asp-validation-for="IsDeleted" class="text-danger"></span>
</div>
</div>
</div>
I have a basic form allowing users to input details which then gets posted and saved to a database - this works as expected without any issues:
#model R32.Register.Models.RegisterCar
#{
ViewBag.Title = "Edit Your R32";
}
<h2>Edit R32</h2>
<div>
#using (Html.BeginForm("UpdateCar", "Garage", FormMethod.Post))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Enter details</legend>
<ol>
<li>
#Html.LabelFor(m => m.NumberPlate)
#Html.EditorFor(m => m.NumberPlate, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.NumberPlate)
</li>
<li>
#Html.LabelFor(m => m.Edition)
#Html.EnumDropDownListFor(m => m.Edition, "Select an edition:", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Edition)
</li>
<li>
#Html.LabelFor(m => m.Colour)
#Html.EnumDropDownListFor(m => m.Colour, "Select a colour:", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Colour)
</li>
</ol>
<input type="submit" value="Save Changes" />
</fieldset>
}
</div>
Model snippet:
[Required]
[Display(Name="Edition")]
public MkEnum? Edition { get; set; }
Enum:
public enum MkEnum
{
[Display(Name="Mk4")]
Mk4 = 1,
[Display(Name="Mk5")]
Mk5 = 2
}
The control renders as expected, with the Edition dropdownlist having three values: "Select an edition", "Mk4", and "Mk5".
The user is able to select an edition, control is validated, then posted to the controller.
The Post is successful, and all selected values are sent to the controller - the app then persists the data in a database, and so on, without any problems.
The issue is when I pass this model back into the same View to allow the user to edit the saved data, the saved values for the enums are NOT being set as the selected value in the dropdownlist.
I can confirm that any saved string values, such as NumberPlate in this example, are being passed back into the view and loaded into the UI.
Putting a breakpoint on the viewmodel as it renders I can confirm that my #model contains the saved values for enum properties - Edition for example - but the end result is that the "Select an edition:" dropdown list is rendered containing the expected dropdown values, but it's value is the default "Select an edition:" instead of the actual value passed in via. m.Edition.
I have been able to get this working using DropDownListFor - but am having difficulties in understanding why this is not working using EnumDropDownListFor, as this clearly seems like a more elegant solution.
Does anyone have any help/advice for this?
I just ran into this problem myself. This happens because fields of type enum are being passed back to the browser serialized as their enum names, but #Html.EnumDropDownListFor generates its option values as integers. The browser can't match up the two so the dropdown stays at its default selection.
There are 3 ways to get around this.
Get the view model's enum field to serialize properly as an int.
Write a dropdown generator that uses enum names as option values.
Use javascript to manually select the option (includes razor syntax here)
$("#YourDropdownID option").each(function () {
if ($(this).html() == '#(Html.DisplayFor(o => o.YourEnumFieldName))') {
$(this).attr("selected", "selected");
return;
}
});
Ok, so from what I could see the problem was caused by using an ActionLink to pass back the full model of an item being edited. Everything was being sent back in a Query string, so my Enum values were being passed to the controller in the following way: mkEnum=Mk4.
I was then loading the UpdateCar view as seen above in my example - but the query string values were being persisted in the call back to the View.
EnumDropDownListFor is unable to interpret/convert the text value of enums into their actual values - if I manually edited the Query string to mkEnum=1, then the correct value wasloaded into the ViewModel.
In addition to this problem, it was not a good solution passing the full model back to the controller.
I've modified the code to pass back a single Id of the item being edited - the controller then verifies the user has access to that Id, retrieves the Model from the Database then passes it back to the same View as in my above example.
With this change my dropdowns are now being updated with their values without any issues.
TLDR; If you experience this issue check to make sure you don't have model properties, specifically enum values represented by their string values, in a query string when loading your view and using EnumDropDownListFor.
I have a html form that submits to a C# ashx handler that i'm hoping will insert/update the database
I've written this in PHP and Coldfusion, but I cannot figure out how to do this in C#
HTML form
<form id="copyto">
<input type="hidden" name="operation" value="update" />
<label><input type="checkbox" name="children[]" checked="checked" value="001">
Andrew Regan</label>
<label><input type="checkbox" name="children[]" checked="checked" value="101">
Arthur Regan, III</label>
<input type="checkbox" name="children[]" checked="checked" value="968">
Tim Reagan
</form>
C# ASHX handler
foreach(string key in context.Request.Params["children"])
{
ListDictionary updateParams = new ListDictionary();
updateParams.Add("rowid", key);
string sSql = #"insert into temp select * from children where c.id = :rowid";
dbi.ExecuteNonQuerySql(sSql, updateParams);
}
Typically i would iterate over the $_POST['children'] in php , and execute the sql
How exactly does this translate?
EDIT
ok ive almost gotten this, however my iterator goes over ALL of the request collection variables, i want it to go over only a specific named variable, in this case "children"
i.e localhost/page?operation=update&children=9&children=8&children=17
foreach(string key in context.Request.QueryString)
{
ListDictionary updateParams = new ListDictionary();
updateParams.Add("row_id", context.Request.QueryString[key]);
string sSql = #"insert into dug select :row_id from dual";
dbi.ExecuteNonQuerySql(sSql, updateParams);
}
i want it to ignore everything but the specific var
If you are doing a post. I think something like this would work.
<input type="checkbox" name="children" value="108"/>
<input type="checkbox" name="children" value="109"/>
<input type="checkbox" name="children" value="110"/>
<input type="checkbox" name="children" value="111"/>
The browser will send all of the values comma seperated to the server when the form is submited
Then on your server side you can do this:
var selected = context.Request.Form["children"].Split(',');
Selected will be an array of strings for each value that was passed in by the browser. You can then loop over them and do whatever you need to.
Hope this helps some.
I was just working on this yesterday. I ended up using a hidden field that will hold the multiple checked checkbox id's. So, if that route works for you, you could create a checkboxlist editor template or control. This could have a script such as:
(tempId will hold the common "name" attribute's value for your checkbox/checkboxlist, and we have the "somehiddenfield" hidden field to hold the selected values)
<script>
$(function () {
var arrTmp = [];
//Update array on selection change
$('input[name="#String.Format("{0}[]", tempId)"]').change(function () {
arrTmp = [];
$('input:checked[name="#String.Format("{0}[]", tempId)"]').each(function () { arrTmp.push($(this).val()); });
$('input[id="somehiddenfield"]').val(arrTmp.join(','));
});
});
</script>
Then, on postback on the server-side the form collection will simply have the hidden field we wrote the checked values into. Split that in whatever way works for you (like comma separated in my example) and you're good to go. My server-side is implemented in MVC but for WebForms you can pull the elements from the Request.Form dictionary (Request.Form["somehiddenfield"].ToString()) or even Request.Params as you are using.
Right after i put out the bounty of course -_-
foreach (string k in context.Request.QueryString)
{
if (k.StartsWith("children")){
foreach (string v in context.Request.QueryString.GetValues(k)){
ListDictionary updateParamss = new ListDictionary();
updateParamss.Add("row_id", v);
string Sql = #"insert into dug select :row_id from dual";
dbi.ExecuteNonQuerySql(Sql, updateParamss);
}
}
}
I was working on a project and came to a point where I need to do something like this:
foreach(var item in Model)
{
#:<div class="my-class"> this is some content </div>
#:<div class="my-other-class">this is some more content </div>
}
But, of course, it would be stupid to do it like this. So my question is:
-Is there a notation to escape several lines of html code like the example given above?
E.g.
#: <div>
<div>
<div> :#
Your help is much appreciated. Thanks :)
#{ <text><div></div></text> }
use <text></text>
Use #{ }
#{
<div>
<div>
<div>
}
Although you're not using the Razor engine for anything useful in this context, you could simply omit them.
As an alternative you could simply add an # before the foreach:
#foreach(var item in Model)
{
<div class="my-class"> #item.Property </div>
<div class="my-other-class">this is some more content </div>
}
You must use # only to scope access or delimit c-sharp/vb code in the view. Pure HTML can live alone as pure HTML, for exemple:
Delimits a valiable assignment:
#{
int x = 123;
string y = "because.";
}
Use the variable x into the code
<div>#x</div>
Use the variable y into the code
<div>#y</div>
Use x and y at the same time
#{
<div>#x</div>
<div>#y</div>
}
For:
#foreach(var item in Model)
{
<div class="my-class"> #item.SomeProperty </div>
<div class="my-other-class">this is some more content </div>
}
Ah yes, the problem was my structure. It's true that html code persists on its own.
The problem was I had a block in which I would insert a different starting tag according to a condition
if(cond) { insert <div> } else {insert other div}
And so I guess the CLR couldn't see the closing } .
Fixed it by putting the whole <div></div> structure inside the condition blocks.
Thanks for your replies tho, cheers!
So I have some HTML surrounding a field like this :
<div class="form-row style="display: none; ">
<label class="fld-lbl" for="Blah">Blah</label>
<div class="fld">
<select id="Make" name="Make"></select>
</div>
</div>
I want to select the 'Make' element, and work out if the parent div 'form-row' is visible or not.
I'm really struggling with WatIn to work out how this is possible.
I am trying something like this :
_make = _browser.Page.Make; //this is set with some other methods, but it is basically the 'Select' element mentioned above.
var makeVisible = _browser.Div(div =>
{
var ancestor = _make.BaseElement.Ancestor(Find.ByClass("form-row"));
return ancestor != null && string.Equals(ancestor.Style.Display, "none");
});
This doesn't seem to work, but i can take the select element and traverse up the DOM using parent.parent.parent.
But that is a bit naff, and doesn't allow the HTML to change.
Can anyone help?
Cheers
You can use JavaScript
string displayValue = _browser.Eval("$('#Make').closest('div.form-row').css('display');");