Html.DropdownListFor troubleshoot - asp.net-mvc-4

I'm trying to learn the syntax for DropDownListFor.
Given the following in a for loop:
#Html.DropDownListFor(
model => model.SalutationID, Model.AvailableSalutations.Select(option => new SelectListItem
{
Selected = (option.ID == staff.SalutationID),
Text = option.Desc.ToString(),
Value = option.ID.ToString()
}
),
"Choose...")
... and given that staff.SalutationID does echo correct values (when, for example, I just use #Html.ValueFor(model => staff.SalutationID)), why does every dropdown echoed in my loop default to "Choose..." and not the Selected option?

What decides what is the selected option in the drop down list is the value of the model property specified by the lambda in the first parameter in the Html.DropDownListFor. In your case model => model.SalutationID.
Verify that model.SalutationID has the expected value in the model. If not, specify it in the controller's action, before rendering the view.

Related

MVC Viewbag correct Result count but displaying only item 1

Trying to use a viewbag on a create form (view) to let the user pick an "item" on the dropdown.
The dropdown displays and shows correct number of rows (tested) but only displays the first item for the X number of rows.
https://i.imgur.com/2179GTD.png "Image1"
Code of the view controller below as I didn't find any answers to this.
List<SelectListItem> Contracts = (from a in
db.v_xxx_yyyy_aaaa_contracts.Where(m => m.GroupID.ToString() ==
#group).Distinct().OrderBy(a => a.ContractID).ToList()
select new SelectListItem()
{
Value = a.ContractID,
Text = a.ContractID
}).ToList();
ViewBag.ContractID = Contracts;
Try something like
var contracts = db.v_xxx_yyyy_aaaa_contracts.Where(m => m.GroupID.ToString() == #group).Distinct().OrderBy(a => a.ContractID);
ViewBag.ContractID = new SelectList(contracts, "ContractID", "ContractID"); // here second one for display
The solution I found for this specific problem is found here!
Had to bypass the viewmodel with ViewData (SelectList) for it to work as I wanted.

Access form field object in Template

In playframework-2.2 I have a custom form with a List<Long> selected
In the template, how can I access this List for iteration?
form("selected").value gives me the string representation
however
form("selected[0]").value gives me the value at posistion 0.
You could use #repeat helper.
E.g provided by play docs
#repeat(myForm("emails"), min = 1) { emailField =>
#inputText(emailField)
}
See more

Dynamically changing jQuery unobtrusive validation attributes

I have a page built in ASP.NET MVC 4 that uses the jquery.validate.unobtrusive library for client side validation. There is an input that needs to be within a range of numbers. However, this range can change dynamically based on user interactions with other parts of the form.
The defaults validate just fine, however after updating the data-rule-range attribute, the validation and message are still triggered on the original values.
Here is the input on initial page load:
<input id="amount" data-rule-range="[1,350]" data-msg-range="Please enter an amount between ${0} and ${1}">
This validates correctly with the message Please enter an amount between $1 and $350 if a number greater than 350 is entered.
After an event fires elsewhere, the data-rule-range is updated and the element looks as such:
<input id="amount" data-rule-range="[1,600]" data-msg-range="Please enter an amount between ${0} and ${1}">
At this point if 500 is entered into the input it will fail validation with the same previous message stating it must be between $1 and $350. I have also tried removing the validator and unobtrusiveValidation from the form and parsing it again with no luck.
$('form').removeData('validator');
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
Is there a clean way to change the validation behavior based on the input attributes dynamically?
As Sparky pointed out changing default attributes dynamically will not be picked up after the validation plugin has been initialized. To best work around this without rewiring how we register validated fields and rules, I found it easiest to register a custom adapter in the unobtrusive library:
jQuery.validator.unobtrusive.adapters.add("amount", {}, function (options) {
options.rules["amount"] = true;
options.messages["amount"] = function () { return $(options.element).attr('data-val-amount'); };
});
jQuery.validator.addMethod("amount", function (val, el, params) {
try {
var max = $(el).attr('data-amount-max');
var min = $(el).attr('data-amount-min');
return val <= max && val >= min;
} catch (e) {
console.log("Attribute data-amount-max or data-amount-min missing from input");
return false;
}
});
Because the message is a function, it will be evaluated every time and always pick up the latest attribute value for data-val-amount. The downside to this solution is that everytime there is a change we need to change all three attributes on the input: data-amount-min, data-amount-max, and data-val-amount.
Finally here is the input markup on initial load. The only attribute that needs to be present on load is data-val-amount.
<input id="amount" data-val-amount="Please enter an amount between ${0} and ${1}" data-val="true">
You cannot change rules dynamically by changing the data attributes. That's because the jQuery Validate plugin is initialized with the existing attributes on page load... there is no way for the plugin to auto re-initialize after dynamic changes are made to the attributes.
You must use the .rules('add') and .rules('remove') methods provided by the developer.
See: http://jqueryvalidation.org/rules/
you can try this one:
// reset the form's validator
$("form").removeData("validator");
// change the range
$("#amount").attr("data-rule-range", "[1,600]");
// reapply the form's validator
$.validator.unobtrusive.parse(document);
charle's solution works! you cannot have model attributes to use it though, I build my inputs like:
#Html.TextBoxFor(m => Model.EnterValue, new
{
#class = "form-control",
id="xxxx"
data_val = "true",
data_val_range = String.Format(Messages.ValueTooBig, Model.ParamName),
data_val_range_max = 6,
data_val_range_min = 2,
data_val_regex_pattern = "^\\d+(,\\d{1,2})?$"
})
and then in javascript:
$("form").removeData("validator");
$("#xxxx").attr('data-val-range-max', 3)
$("#xxxx").attr('data-val-range-min', 0)
$.validator.unobtrusive.parse(document);

DropDownListFor and Multiple Select Value

I'm trying to generate a select tag with multiple options enabled, on the server side im generating a SelectListItem with NGO Objects, and a SelectedNGOes string array representing the values that should be selected:
#Html.DropDownListFor(x => x.SelectedNGOes,
new SelectList(Model.Ngoes, "Value", "Text"), new { #class = "span6", multiple = "true" })
Everything works well except the selected value are ignored during rendering, i made sure that the SelectedNGOes have the right values, not sure why the selections are being ignored.
DropDownListFor sets the selected value to the value of the lambda and ignores the selected value in the select list. set your lambda on the controller
Model.SelectedNGOes = "Selected Value";
and that value will be set on the view as long as it matches a value in the list

Programmatically assign a View to a Region in Drupal 7

During the install of a module, I need to assign a View to a Region, and unassign a Block from that region. It's something that would take 3 seconds in the UI, but this has to be done programmatically.
The view is called 'legal-footer' and it needs to be assigned to the region 'footer'.
Similarly, I have a block called 'footer-logos' that's currently in the 'footer' region but needs to be removed.
I think I want hook_block_info_alter, but I'm not sure if it works on a View, and there's a note in the API docs that it can't be used to unassign a block...
I'm new to Drupal, and I can whatever I want in the UI pretty easily, but I'm having a hard time with the API.
to assign block to a region use 'region' key in the array returned info that contain the name of the region that this block should be assigned to
E.g
function module_block_info() {
$blocks = array();
$blocks[0] = array(
'info' => t('Block Title'),
'region' => 'name-of-the-region', // here is the name of the region
'status' => 1, // 1 if you want the block to be enabled by default
);
return $blocks;
}
and you can Disable exist block by using such query
db_update('block')->fields(array('region' => '', 'status' => 0))->condition('bid', $block_id)->execute();
replace $block_id with the id of the block that you want to disable
UPDATE:
you can use hook_block_info_alter to disable exist block
function hook_block_info_alter(&$blocks, $theme, $code_blocks) {
// Disable the login block.
$blocks['defining_module']['delta']['status'] = 0;
}
good luck