How to set mulipart attributes for html helpers? - asp.net-mvc-4

I want to set a multipart attribute for a html.Dropdownlist. How to do this?
#Html.DropDownList("ProductTypesId",DropdownHelper.GetAllProductTypes("-1"), new { #class="selectpicker", multiple title = "Select One" })
But I have error for the multiple title attribute.
Update
The error is:
The name multiple doesn't exist in the current context.

"multiple title" is not an attribute in HTML. Attributes are space-separated.
What you have is a single-label attribute "multiple" and the second attribute "title="Select one"
HTML allows for single-label attributes to have their name as a value - this has the same effect and is how XHTML supports single-label attributes, like so:
new { #class="selectpicker", multiple="multiple" title="Select One" }
this will be rendered like this:
<select class="select picker" multiple="multiple" title="Select One">

Also, you can write in htmlAttributes object like that
#multiple="multiple"

Related

Pass info between tag helpers?

I am writing a set of tag helpers that target, for example, <form> and <input> elements. I want to add a custom attribute to the <form> element, and retrieve the value of that attribute in the contained <input> element. So, if my HTML looks like this:
<form xx-value='123'>
<input asp-for='Something' />
</form>
then in my InputTagHelper I would want to retrieve the value 123 that was specified for the xx-value attribute.
Is there a designed-in way to pass data like this between tag helpers?
Consider the case where I have this markup:
<form xx-value='123'>
<input asp-for='Something' />
</form>
<form>
<input asp-for='SomethingElse' />
</form>
In this case, the first invocation of the InputTagHelper would get the value 123. But the second invocation of the InputTagHelper would get a value of 0 since its parent <form> tag didn't specify the magic xxx-value attribute.
The simple answer (which doesn't work for <form> and <input> tags - see blow) is for the "parent" tag helper to store the value in the context.Items dictionary and for the "child" tag helper(s) to retrieve the value from that same dictionary. A Google search for "child tag helper" yields many examples of this scheme.
The problem with this answer (in the context of the OP) is that, for some reason, the <form> tag helper executes after its child <input> tag helper. So, rather than receiving the value from the parent FormTagHelper, the InputTagHelper discovers that the context.Items dictionary is empty.
I created this SO post to ask about that weird behavior.

SelectList dropdown list showing multiple = "multiple" for current viewmodel

This kind of a bizarre issue and I can't figure out a solution how I want.
I'm using .net core 2.1. I have a orders view model like this:
public class OrdersFilterViewModel
{
[Display(Name = "Account Numbers:")]
public IEnumerable<SelectListItem> AccountNumbers { get; set; }
}
My viewmodel and SelectList in my orders controller is called like this:
var vm = new OrdersFilterViewModel
{
AccountNumbers = new SelectList(_context.Account.Where(m => m.UserID == userId), "AccountNumber", "AccountNumber", account)
};
return PartialView("_FilterOrders", vm);
The problem lies when trying to get a dropdown list in the view which looks like this:
<form asp-action="FilterOrders" asp-controller="Order" id="ordersFilterForm" method="post">
<div class="form-group">
<label asp-for="AccountNumbers" class="control-label"></label>
<select asp-for="AccountNumbers" class="form-control" asp-items="#Model.AccountNumbers">
</select>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</form>
This somewhat works but gives me a textarea type display where multiple = "multiple" is always tacked on in the browser. I've discovered that if I add something like the following to my viewmodel:
public int? AccountId { get; set; }
Then change my view to:
<select asp-for="AccountId" class="form-control" asp-items="#Model.AccountNumbers">
I can then have my dropdown list. However, I don't need that property for anything as far as I know. I tried a million things so it's possible I made some other slight changes I'm forgetting to get that to work, but that's the gist of it.
Is there any way around adding that extra property? Or do I need it for something I'm not aware of? Or is there any way to set multiple = "false" or something to that effect so I can get my dropdown list with my original viewmodel and such?
I haven't dealt with the post back to the controller yet, so maybe that will reveal the gotchas. I'm basically trying to create a modal type query filter that doesn't really do much other than modify some parameters and send them back to my query to update it. Thanks.
Is there any way around adding that extra property? Or do I need it
for something I'm not aware of?
Yes, you need this extra property, because in your select there are many items, and the user will select one or multiple items, and on the server side you'll need to know what the user selected, this is the purpose of the select tag.
And the multiple = "multiple" depends on what you put in the asp-for in the case of asp-for="AccountId" it is a single int value, so it won't use multiple, is you have an array in the asp-for then it will use the multiple.
Here is a pretty detailed description about the select tag helper:
Select Tag Helper in ASP.NET Core MVC

How to interpolate a variable into a nested component in Vue?

I have an app that has components nested inside. The app is called on the filter id. I have a data element named minTotalSpent. Currently, this contains "3" in the app. The first placement on the page displays appropriately. When I try to pass it in as a variable into vue-slider, however, it does not like it and throws an "invalid expression"warning on the counsel and does not respect the minimum.
<div id="filter">
<form id="search">
Search <input name="query" v-model="searchQuery">
</form>
{{minTotalSpent}}
<div class="filter-container-slider">
<vue-slider
:min="{{minTotalSpent}}"
:max="42"
:value="2"
>
Just elaborating as per #thanksd's answer.
When using any component, over here vue-slider component, if you use v-min = "..." or :min = "...", the value of v-min or :min is in a javascript expression and you cannot use mustaches inside javascript expression.
And when it comes to html attributes like id on any element, you should be using v-bind.
<div v-bind:id="dynamicId"></div>
Read more about them here: https://v2.vuejs.org/v2/guide/syntax.html#Attributes

#Html.DropDownListFor - How to set different color for a single item in list?

I wish to have one item in my DDL to be a different color (red). However the list comes from a table and is not hard coded in the page like
<option value="Option 1">Option 1</option>
but rather as
#Html.DropDownListFor(r => r.Journal.Frequency, Model.JournalFrequencyList, "Select a Frequency", new { #class = "form-control" })
Is there a way to make just one item a different color?
You can update your styles/css to make one item red color. Now you did not specify which specific item you want. With jQuery, you can select a specific option and set the color of that to red.
Assume your razor view renders a SELECT element like this
<SELECT id="fancySelect">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</SELECT>
And if you want to set the color of the option which has value attribute set to "2", you can use the below code
$(function(){
$("#fancySelect option[value='2']").css('color','red');
//you can also apply a css class if needed
});
If you want to update a different option, update your jQuery selector to get that.
EDIT : As per the comment
is there any way to use the text as opposed to the value? Example
change if text is "Deleted"
You can update your jQuery selector to get the option with a specific text.
$("#fancySelect").find("option:contains('Deleted')").css('color','red');
I suggest you rely on option value than the text, you can set the value as a code which you can program against.

Aurelia Validation on Select List

I have a simple select list in my Aurelia view which I'm trying to set a default value on of 'Select...'. I'm also using the aurelia-validation plugin to ensure that the value is changed before the form is submitted. The plugin works great for other field types in my project.
<div class="form-group">
<label for="agencies" class="control-label">Agency</label>
<select value.bind="agencyId" class="form-control">
<option value="">Select..</option>
<option repeat.for="agency of agencies" value.bind="agency.id">${agency.name}</option>
</select>
</div>
In the VM:
constructor(validation) {
this.agencies = null;
this.agencyId = 0;
this.validation = validation.on(this)
.ensure('agencyId')
.isNotEmpty();
}
activate() {
//call api and populate this.agencies
}
After the page initially loads I get my agencies in the list and my default value is correct, but it shows the validation error message:
Other form fields, like text boxes don't do this and show no error message until the user interacts with the form controls.
Is there something special I need to do for a select list to hide validation errors on the initial loading of the view? I suspect that binding the select list in the view is somehow triggering a change event.
Thanks to a kind Aurelia user on Gitter, the problem was solved by setting the initial value of this.agencyId to "". Originally I had the this.agencyId = null. That was my mistake. Because it was null and not "" (as was the default value in the select list) the values didn't match so the select list was invalid when the view loaded. At least, that's my understanding.
The lesson is, if you want to validate a select list, make sure you VM property is initialized to the same value as your select list's default value.
constructor() {
this.agencyId = ""; **//must match the bound property's initial value**
}
And in the view:
<div class="form-group">
<label for="agencies" class="control-label">Agency</label>
<select value.bind="agencyId" class="form-control">
<option value="" **<!-- this value must match the VM initial value -->** selected="true">Select...</option>
<option repeat.for="agency of agencies" value.bind="agency.id">${agency.name}</option>
</select>
</div>