Why is the Dropdownlist in my MVC3 application disabled when I have set the SelectedItem? - asp.net-mvc-3

I have an MVC3 application that I have a view defined to have the possibility of passing values and setting the SelectedItem value.
List<SelectListItem> items = new SelectList(db.BILLING_COUNTRY, "ISO_Code_BillingCountry", "CountryName", Country).AsParallel().ToList();
items.Insert(0, (new SelectListItem { Text = "Select Your Country", Value = "0" }));
ViewBag.Countries = items;
I am setting the disabled = "disabled" attribute on the dropdownlist if a ViewBag.EnableDropDowns is false or not set.
#{ object displayMode = (ViewBag.EnableDropDowns) ? null : new { disabled = "disabled" };
#Html.DropDownList("Countries", null, new { disabled = displayMode, onchange = "LoadItems()" } )
}
I set the ViewBag.EnableDropDowns to true, it correctly sets all the values in the drop down list but they are disabled instead of enabled.
What is wrong?

Be careful with the dictionary declaration. It has to beDictionary<string, object>() otherwise you will face run time issues.
I have to disable the listbox based upon a condition.
#{
var sourceListOptions = new Dictionary<string, object>();
sourceListOptions.Add("style", "Height: 250px; width: 225px;");
if (Model.SourceColumns.Count() == Model.ImportMappings.Count())
{
sourceListOptions.Add("disabled", "disabled");
}
}
#Html.ListBox("SourceColumns", Model.SourceColumns, sourceListOptions)
or
#Html.DropDownList("SourceColumns", Model.SourceColumns, sourceListOptions)

I think you need to set enabled="enabled"
Try:
#{
bool displayMode = (ViewBag.EnableDropDowns) ? "enabled": "disabled";
};
#if(displayMode)
{
Html.DropDownList("Countries", null,
new { enabled= displayMode, onchange="LoadItems()" } );
}
else
{
Html.DropDownList("Countries", null,
new { disabled= displayMode, onchange="LoadItems()" } );
}

The select element will be disabled if the disabled attribute is present at all (regardless of its value). So you'll need something like this (specifying htmlAttributes as a Dictionary rather than an anonymous object, as it seems more convenient in this case):
#{
var displayMode = new Dictionary<string,object>();
displayMode.Add("onchange", "LoadItems()");
if (ViewBag.EnableDropDowns) displayMode.Add("disabled", "disabled");
}
#Html.DropDownList("Countries", null, displayMode)

Related

Setting dialog property value in SetValidate call does not work

Given the following formflow setup...
return builder
.Field(new FieldReflector<CarValuationDialog>(nameof(Mileage))
.SetValidate(async (state, value) =>
{
var result = new ValidateResult { IsValid = true };
if (int.TryParse(value.ToString(), out int mileage))
{
state.Mileage = mileage;
result.IsValid = true;
}
else
{
result.Feedback = "That isn't valid number. Can you enter it again please?";
result.IsValid = false;
}
return result;
}))
.Field(new FieldReflector<CarValuationDialog>(nameof(HappyWithAnswersBuying))
.SetActive(carValuationDialog => carValuationDialog.ValuationOption == ValuationOptions.LookingToOwn)
.SetPrompt(CreateHappyWithAnswersBuyingPrompt())
.SetDefine(HappyWithAnswersDefinitionMethod))
.OnCompletion(GetValuationAndDisplaySummaryToUser)
.Build();
I want to try out custom validation on the mileage answer given by the user. The code in SetValidate executes, and given a valid integer, that number is assigned to state.Mileage.
However, when the prompt asking the user if they are happy with the answers is shown, the mileage is still set to 0..
Here is the code for the prompt..
private static PromptAttribute CreateHappyWithAnswersBuyingPrompt()
{
StringBuilder sb = new StringBuilder(100);
sb.Append("Are you happy with your answers? <br /><br />");
sb.Append("{&RegistrationNumber}: {RegistrationNumber} <br />");
sb.Append("{&Mileage}: {Mileage:N0} miles {||}");
return new PromptAttribute(sb.ToString())
{
ChoiceStyle = ChoiceStyleOptions.Buttons,
FieldCase = CaseNormalization.InitialUpper
};
}
Before I added the SetValidate code, the mileage was shown perfectly fine in the prompt. But since I'm now manually setting state.Mileage, it's not being persisted across for some reason.
Man, I seriously need to "check the plug" on my code...
Basically I had not set the Value property of the ValidateResult instance...
.SetValidate(async (state, value) =>
{
var result = new ValidateResult { IsValid = true, Value = value };
....
}
After doing that, the mileage value now appears in the prompt...

hide forms tab in a form head crm dynamics 365

I have an entity which contains 2 forms, I want to prevent navagation between these 2 forms based on the value of two option field. In other words if the value of need prescoring is yes navigation is not possible and the inverse, how can I do this ?
Is it possible to simply hide the list ?
Thanks,
No, you cannot dynamically change the forms the user can select. This can only be done statically based on security roles.
Instead I suggest using a single form, where you hide and show the relevant fields/sections/tabs based on the value of your Need Processing field.
You can decide based on your project complexity wrt number of form controls/tabs/sections. We did something like this to maintain & forced navigation based on form control value.
var taskFormOptionSet = {
Form1: 1,
Form2: 2,
};
var FormNames = {
Form1: "Form1",
Form2: "Form2",
};
var myform = Xrm.Page.getAttribute("need_Prescoring").getValue();
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
if (myform == taskFormOptionSet.Form1 && formLabel != FormNames.Form1) {
var items = Xrm.Page.ui.formSelector.items.get();
for (var i in items) {
var form = items[i];
var formId = form.getId();
var formLabel = form.getLabel();
if (formLabel == FormNames.Form1) {
form.navigate();
return;
}
}
}
As it's not supported I used another solution which is to check if the boolean is true and the name of the, if the user tries to change the form he will be redirected to the right form until he changes the value of the boolean.
DiligenceSwitch: function(){
if (Xrm.Page.ui.formSelector.getCurrentItem() != null) {
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
}
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
var kycId = Xrm.Page.data.entity.getId();
SDK.REST.retrieveRecord(kycId, "kyc_Kycdiligence", "kyc_Needprescoring", null, //field for searching the targeted field, entity, targeted field, ...
function (kyc) {
if (kyc != null || kyc.kyc_Needprescoring != null) {
if (formLabel != "Pre-Scoring" && kyc.kyc_Needprescoring == true) {
var windowOptions = { openInNewWindow: false };
var parameters = {};
parameters["formid"] = "4B0C88A9-720C-4BFA-8F59-7C1D5DD84F02";
Xrm.Utility.openEntityForm("kyc_kycdiligence", kycId, parameters, windowOptions);
alert("Vous devez faire le pre-scoring");
}
}
},
function (error) {
Xrm.Utility.alertDialog(error.message);
});
},

Why does my selected value not get added to my SelectListItem as the “Text” and “Value” properties do?

I am trying to set a default value of a list in a partial view. The partial view is called using this…
#Html.Action("Acton", "Controller", new { department = item.Data.departmentNumber, defaultValue="someValue" })
Then in the controller I have…
[ChildActionOnly]
public ActionResult Categories(int? id, int? department, string defaultValue)
{
var typeList = from e in db.Rubrics where e.DepartmentID == department select e;
var selectedRubrics = typeList.Select(r => r.Category);
List<String> rubricsList = selectedRubrics.ToList();
var categories = new List<SelectListItem>();
for (int i = 0; i < rubricsList.Count(); i++)
{
categories.Add(new SelectListItem
{
Text = rubricsList[i],
Value = rubricsList[i],
Selected = (defaultValue == "defaultValueGetsSentToView")
});
}
var ViewModel = new RubricsViewModel
{
Category = "Select a Category",
Categories = categories
};
return View(ViewModel);
}
Why does my selected value not get added to my SelectListItem as the “Text” and “Value” properties are? Thanks for any help!
Assuming the values in the code are the literal values you are using, "defaultValue" is "someValue" and you are setting selected with the comparison defalutValue == "defaultValueGetsSentToView".
"someValue" == "defaultValueGetsSentToView" evaluates to false.

Get list on basis of dropdownlist data in asp.net mvc3

I have two dropdownlists in my module.
In one dropdownlist, I have hardcoded all the operators like <,>,<=,>=,==
In second dropdownlist, I have hardcoded salary of employees like 1000,2000,3000,4000....50000
Now if I select < from one list and 2000 from second list and click on submit button I should get list of employees who have salary less than 2000.
I want to do this in asp.net mvc3
How can I accomplish this task? Do I need to write a stored procedure for this?
I have created dropdownlist like:
viewModel.OperatorsList = new[]
{
new SelectListItem { Value = "<", Text = "<" },
new SelectListItem { Value = ">", Text = ">" },
new SelectListItem { Value = "<=", Text = "<=" },
new SelectListItem { Value = ">=", Text = ">=" },
new SelectListItem { Value = "==", Text = "==" }
};
viewModel.SalaryList = new[]
{
new SelectListItem { Value = "1000", Text = "1000" },
new SelectListItem { Value = "2000", Text = "2000" },
new SelectListItem { Value = "3000", Text = "3000" },
// and so on
};
and I have used this to show dropdownlist in view:
<%: Html.DropDownListFor(x => x.Operators, Model.OperatorsList)%>
well, you could do something like that
assuming viewModel is... your viewModel, and you've got an entity Employee with a property Salary (int in this sample, it's probably a decimal in real world)
create a static helper class
public static class MyHelper
{
// a dictionary for your operators and corresponding ExpressionType
public static Dictionary<string, ExpressionType> ExpressionTypeDictionary = new Dictionary<string, ExpressionType>
{
{"<", ExpressionType.LessThan},
{">", ExpressionType.GreaterThan},
{">=", ExpressionType.GreaterThanOrEqual}
//etc
};
//a method to filter your queryable
public static IQueryable<Employee> FilterSalary(this IQueryable<Employee> queryable, int salary, string operatorType)
{
//left part of the expression : m
var parameter = Expression.Parameter(typeof(Employee), "m");
//body is the right part of the expression : m
Expression body = parameter;
//m.Salary
body = Expression.Property(body, "Salary");
//m.Salary <= 1000 (for example)
body = Expression.MakeBinary(ExpressionTypeDictionary[operatorType], body, Expression.Constant(salary));
//m => m.Salary <=1000
var lambda = Expression.Lambda<Func<Employee, bool>>(body, new[] { parameter });
//so it will be queryable.Where(m => m.Salary <= 1000)
return queryable.Where(lambda);
}
}
usage
var queryable = context.All<Employee>();//or something like that, returning an IQueryable<Employee>
queryable = queryable.FilterSalary(viewModel.Salary, viewModel.Operators);

MVC 3 + knockoutjs: adding the data-bind attribute when using EditorFor for a boolean field

Using #Html.EditorFor(model =>model.IsClient), where IsClient is a boolean, renders a drop down list with Not Set, Yes and No as the options.
All well and good.
Now I want to use knockoutjs with the resulting dropdownlist, that I like, so how do I add the data-bind attribute using #Html.EditorFor, that I need for knockoutjs to work with this drop down?
I have tried:
#Html.EditorFor(model => model.IsClient, new Dictionary<string, object> { { "data-bind", "value: Account.IsClient" } })
However, this uses the object additionalViewData parameter, and it doesn't render the data-bind attribute. Which is probably quite natural, as this parameter is probably nothing to do with Html Attributes for the rendered tag.
However, can't find any reasonable documentation, and none of the other overloads look likely candidates for what I want.
TIA any suggestions.
Brad Wilson blogged about display and editor templates in ASP.NET MVC 2. So you could modify the default template for boolean and add the attributes you need (~/Views/Shared/EditorTemplates/MyTemplate.cshtml):
#{
bool? value = null;
if (ViewData.Model != null)
{
value = Convert.ToBoolean(ViewData.Model, System.Globalization.CultureInfo.InvariantCulture);
}
var triStateValues = new List<SelectListItem>
{
new SelectListItem
{
Text = "Not Set",
Value = String.Empty,
Selected = !value.HasValue
},
new SelectListItem
{
Text = "True",
Value = "true",
Selected = value.HasValue && value.Value
},
new SelectListItem
{
Text = "False",
Value = "false",
Selected = value.HasValue && !value.Value
},
};
}
#if (ViewData.ModelMetadata.IsNullableValueType)
{
<!-- TODO: here you can use any attributes you like -->
#Html.DropDownList(
"",
triStateValues,
new {
#class = "list-box tri-state",
data_bind="value: " + ViewData.TemplateInfo.GetFullHtmlFieldName("") // you could also use ViewData.ModelMetadata.PropertyName if you want to get only the property name and not the entire navigation hierarchy name
}
)
}
else
{
#Html.CheckBox("", value ?? false, new { #class = "check-box" })
}
and finally:
#Html.EditorFor(model => model.IsClient, "MyTemplate")
or decorate the IsClient property on your view model with the UIHint attribute:
[UIHint("MyTemplate")]
public bool? IsClient { get; set; }
and then:
#Html.EditorFor(x => x.IsClient)
will automatically pick the custom editor template.
Addendum for knockoutjs users:
#Darin Dimitrov's answer is great, but slightly too rigid to use with knockoutjs, where complex views may lead to viewModels that don't entirely map to the #Model parameter.
So I have made use of the object additionalViewData parameter. To access the additionalViewData parameter from your Custom EditorTemplate, see the following SO question:
Access additionalViewData from Custom EditorTemplate code
Digression:
The additionalViewData param is confusing in that it does nothing with the default editor. It only comes into its own with a custom editor template.
Anyway, my amendments to Darin's code are as follows:
#if (ViewData.ModelMetadata.IsNullableValueType)
{
var x = ViewData["koObservablePrefix"];
if ((x != "") && (x != null)) { x = x + "."; }
#Html.DropDownList(
"",
triStateValues,
new {
#class = "list-box tri-state",
data_bind="value: " + x + ViewData.TemplateInfo.GetFullHtmlFieldName("") // or you could also use ViewData.ModelMetadata.PropertyName if you want to get only the property name and not the entire navigation hierarchy name
}
)
}
else
{
#Html.CheckBox("", value ?? false, new { #class = "check-box" })
}
Note the lines:
var x = ViewData["koObservablePrefix"];
if ((x != "") && (x != null)) { x = x + "."; }
koObservablePrefix is there so that I can add an arbitrary prefix to my viewModel ko.observable. You could do other things if you so choose.
I use the variable x as follows:
data_bind="value: " + x + ViewData.TemplateInfo.GetFullHtmlFieldName("")
That way, if I don't pass in the additionalViewData "koObservablePrefix" it all still works.
So, now I can write:
#Html.EditorFor(model => model.IsClient, "koBoolEditorFor", new { koObservablePrefix = "Account" })
that will render as:
<select class="list-box tri-state" data-bind="value: Account.IsBank" id="IsBank" name="IsBank">
Note the "value: Account.IsBank" data-bind attribute value.
This is useful if, for example, your views strongly typed model is of type Account, but in your accountViewModel for your page, you have a more complex structure, so you need to package your observables in an account object. EG:
function account(accountId, personId, accountName, isClient, isProvider, isBank) {
this.AccountId = ko.observable(accountId);
this.PersonId = ko.observable(personId);
this.AccountName = ko.observable(accountName);
this.IsClient = ko.observable(isClient);
this.IsProvider = ko.observable(isProvider);
this.IsBank = ko.observable(isBank);
}
function accountViewModel() {
var self = this;
this.selectedCostCentre = ko.observable('');
this.Account = new account(#Model.AccountId, #Model.PersonId, '#Model.AccountName', '#Model.IsClient','#Model.IsProvider', '#Model.IsBank');
// etc. etc
}
If you don't have this kind of structure, then, the code will pick up the structure. It is just a matter of tailoring your viewModel js to this, uhmmm, flexible convention.
Hope this isn't too confusing...

Resources