How to set the value of a select element's selected property - razor

I am using webmatrix, razor syntax and cshtml file.
I have an "edit" page for a database record which contains a select box(id="selStatus"). I am trying to set the "selected" value of the select box dynamically, based on the value of the current record being edited.
I have the current value or its index in local var's but i cant seem to assign this value back to the select.
if (currentStatus=="Completed"){
selStatus.options[1].selected=true;
}
RES = error: The name 'selStatus' does not exist in the current context.
I am missing something obvious here but can't seem to get it. Any ideas appreciated. Thanks

If you have a static list of options, for example, for Marital Status, you can keep it more legible (for some of us) like this:
<select>
<option value="Single" #(marStat == "Single" ? "selected" : "")>Single</option>
<option value="Married" #(marStat == "Married" ? "selected" : "")>Married</option>
<option value="Divorced" #(marStat == "Divorced" ? "selected" : "")>Divorced</option>
<option value="Widowed" #(marStat == "Widowed" ? "selected" : "")>Widowed</option>
</select>
What this does is that if your razor variable marStat containing the value that you retrieved from the database matches the string in the condition, it renders "selected" into the HTML.
It's a bit of "brute" style but I believe it's very readable.

in the layout site:
#{
if (!IsPost)
{
PageData["accountType"] = 0; /* default value */
}
}
<html>
<head></head>
<body>
<form action="#Href("~/")" method="post">
<select name="accountType">
<option value="0"#(PageData["accountType"] == 0 ? " selected" : "")>Standard</option>
<option value="1"#(PageData["accountType"] == 1 ? " selected" : "")>Golden</option>
<option value="2"#(PageData["accountType"] == 2 ? " selected" : "")>Ultimate</option>
</select>
</form>
</body>
<html>
and on the other site you can access it with something like
var accountType = Convert.ToInt32(Request["accountType"]);
later set it for your needs with
PageData["accountType"] = (required int value);

In .NET 6:
use asp-for="#selectedValue"
#{
string selectedValue = "en-us"
}
<select name="culture" asp-for="#selectedValue">
<option value="pt-br">Português (Brasil)</option>
<option value="en-us">English (United States)</option>
</select>
At runtime .NET will set the selected attribute tag.

Besides using Javascript you can set the selected item when you create the dropdown.
This will work when you have a dynamically generated dropdown. If your dropdown is static then you need to use javascript.
First create the data that will fill the dropdown:
var selectQ = "SELECT StatusName, StatusID FROM MyStatusTable";
List<SelectListItem> statusdropdownlistdata = new List<SelectListItem>();
bool isSelected = false;
foreach(var item in db.Query(selectQ)){
isSelected = false;
if(item.StatusName == "Completed"){
isSelected = true;
}
statusdropdownlistdata.Add(new SelectList Item
{
Text = item.StatusName,
Value = item.StatusID.ToString(),
Selected = isSelected
});
}
The above will create the data you want to add to your dropdown and select an item that meets criteria. You'll have to modify to work with your specific criteria and logic.
Next, add this to the HTML part of your cshtml:
#Html.DropDownList("StatusTypes", statusdropdownlistdata)
The above will render the dropdown list with an ID="StatusTypes" and your dropdown data with selected item.
Look up Html.DropdownList and you'll probably be able to find other options and ways to do this.
I'm not sure if this code will work, since I'm writing it by memory

Felt it good to add this as well - which is how I did it. You can also pass the value to the ViewBag from with the controller and grab it and make the comparison within the view. See below:
Here in the view I pass the value to to the ViewBag -
ViewBag.degreeLevel = userInfo.educationlevel; (user info is just my object)
Then, I make the comparisons in the view, like below:

Related

Data binding <select> element's selected index with Angular

Could I please ask what I am doing wrong in the following:
Firstly, the following works fine:
I have the following variables in my .ts component:
public m_array = ["one", "two", "three", "four"];
public m_selectedValueIndex = "two";
and in my html I have:
<select [(ngModel)]="m_selectedValueIndex">
<option *ngFor = 'let num of m_array'>
{{num}}
</option>
</select>
All works fine, and I can see that I have two-way binding on m_selectedValueIndex.
But If I change to the code below things do not work as I expected they would:
.TS code:
public m_array = ["one", "two", "three", "four"];
public m_selectedValueIndex = 2; // THIS IS NOW A NUMBER
html code:
<select [(ngModel)]="m_array[m_selectedValueIndex]"> // THIS IS NOW AN INDEX TO ARRAY
<option *ngFor = 'let num of m_array'>
{{num}}
</option>
</select>
Initially it looks like it's working because the initially selected item is indeed the one with and index of m_selectedValueIndex. But if I use the list box then the values listed actually change.
I may initially have:
one
two
three
four
(where italics indicates that it is selected). This is as I would expect because m_selectedValueIndex = 2.
But if I click on any item (say "four" for example) then the listbox contents change to:
one
two
four
four
i.e. it is replacing item at index m_selectedValueIndex with my selection. Also the value of m_selectedValueIndex remains 2.
Just wanted to see if I could bind by index instead of value.
Thanks for any help.
You need to bind the option value to the array's index using [value]="ndx", (after defining it using let ndx = index within *ngFor)
like the following:
<select [(ngModel)]="m_selectedValueIndex"> // THIS IS NOW AN INDEX TO ARRAY
<option *ngFor="let num of m_array; let ndx = index" [value]="ndx">
{{ num }}
</option>
</select>

Setting default selected value in select dropdown Vue.Js

I have a problem getting the default selected value using select in VueJs. I have tried in two instances:
Passing id and v-model fields in the select as:
<select v-model="sort_brand" id="sort-brand" class="form-control">
<option value="all" selected="selected">All(Brands)</option>
<option v-for="brand in brands" :value="brand.id">{{ brand.name }}</option>
</select>
The selected default value is empty in this case.
Passing sort_brand without id to select:
<select id="brand-id" class="form-control">
<option value="all" selected="selected">All(Brands)</option>
<option v-for="brand in brands" :value="brand.id">
{{ brand.name }}
</option>
</select>
The default selected value is populated but then i don't have the form binding for VueJs. Anyone please assist with this:
Vue.js will manipulate the selected attribute based on the v-model of the select and the option value. Thus trying to set the selected attribute will not work.
For your "All" option, you could assign the null value like this:
<option :value="null">All(Brands)</option>
And then set your sort_brand variable to null. Then vue.js will match the null sort_brand to the option with the null value.
Note: I used null here because that's the way I usualy do it, but I could use any other value. You could use the 'all' string also.
Update sort_brand to all in created hook which will set the option will value 'all' as default:
created (){
this.sort_brand = 'all';
}
You can also initialize the model in data itself.
data (){
return {
sort_brand : 'all'
}
}
The answers above (e.g. #Lunfel) work if your selection values are simple (null, "All", etc). If your combo is bound to complex JSON objects, then it's very difficult to set the bound variable and let it auto-select.
I found it much easier to find the option I wanted, based on the display text, in the mounted function() using JQuery, and then set the 'selected' attribute. How you do this depends on your version of JQuery. In recent versions (not sure when it changed, I'm running 1.10.2), you can use something like:
$("#sort-brand option").filter(function () {
return $(this).prop("label") == 'All';
}).prop("selected", true);
Older versions of JQuery don't have the prop() function, but had a somewhat better selector for the find() function. Try:
$('#sort-brand').find('option[text="All"]').attr('selected', 'selected');
See How to select an option by its text? for more discussion on selecting dropdown options with jQuery.

Searchable select element in React

I'm trying to build searchable select element in React. What is really important to me is:
Avoide jQuery
Posibility to set one of options as default selected
I have list of options, which now looks like that:
<select
onChange={props.onChange}
id={props.id}
className={props.style || "form-control"}>
{!props.defaultOption ?
<option value="" selected>Select</option> :
<option value={props.defaultOptionValue} disabled selected>{props.defaultOption}</option>}
{props.options.map((item, i) => {
if (item.id === props.defaultOptionValue) return false;
return <option key={i} value={item.id}>{item.name}</option>
})}
</select>
Nothing really complicated. I pass onChange handler, id and styles. If i provide defaultOptionValue and defaultOption in props, then it means i need to check this one as selected.
Datalist works great for me, but it doesn't support safari and i want to display label inside my input, not a value, as value is id and label name of the object.
I have already checked react-select, but it's missing option to set default value.

Add an attribute on a condition with angular 2

I have a simple dropdown that is populated from an array.
Users will be editing a record in a form where the priority of the record can be selected from the mentioned dropdown. I'm having difficulty with setting the selected item in that dropdown.
Here's my code for that dropdown:
<select *ngIf="formModel" [(ngModel)]="record.priority" formControlName="priority">
<option value="-1">Select priority</option>
<option *ngFor="let priority of formModel.priorities"
[ngValue]="priority"
[innerHtml]="priority.name"
[selected]="priority.id == record.priority.id"></option>
</select>
The selected priority of the record is however not selected, the resulting HTML shows selected="true".
When I change the code to the following:
[selected]="(priority.id == record.priority.id ? '' : null)"
The result is selected="", but the option is stil NOT selected.
I have already confirmed that that particular option should be selected.
Also when I change the HTML in Firebug to just selected the option is selected.
So my question is: how can I add an attribute on a certain condition so that the attribute is not added to other elements with an empty value?
Using two-way-binding is discouraged in reactive forms. The point is to utilize the form controls instead. Why use reactive form, if you are using two-way-binding? That would mean the model driven form is totally redundant. So if you want to solve this problem using the model-driven form, I'd suggest the following:
Since you are using a separate object (record.priority) it cannot automatically be bound as the pre-selected value, you'd have to somehow create a reference. So when building a form you can do this:
this.myForm = this.fb.group({
priority: [this.formModel.priorities.find(x => x.id == this.record.priority.id)]
});
And the template would look like this:
<form [formGroup]="myForm">
<select *ngIf="formModel" formControlName="priority">
<option value="-1">Select priority</option>
<option *ngFor="let priority of formModel.priorities"
[ngValue]="priority"
[innerHtml]="priority.name"></option>
</select>
</form>
Now the value object you are getting from the form holds this value.
if having the record coming async, you can set a boolean flag to not show the form until the values have been set. Or you can build an empty form initially and then use setValue() for the form control.
DEMO
EDIT: Looking closer, that you want to have the condition to set null if there is no value for record.priority? That can be done well in the form control as well:
priority: [this.record.priority ? this.formModel.priorities.find(x => x.id == this.record.priority.id) : null]
Try this :
<select *ngIf="formModel" [(ngModel)]="record.priority.id" formControlName="priority">
<option value="-1">Select priority</option>
<option *ngFor="let priority of formModel.priorities"
[ngValue]="priority.id"
[innerHtml]="priority.name"></option>
</select>
[ngValue]="priority.id" and [(ngModel)]="record.priority.id" should point to the same value , and it will work automatically ,
There is no need to write [selected]="priority.id == record.priority.id"

Java web: Load another data into second <select> when selection changed for first <select> [duplicate]

Suppose I am having three dropdownlist controls named dd1, dd2 and dd3. The value of each dropdownlist comes from database. dd3's value depends upon value of dd2 and dd2's value depends on value of dd1. Can anyone tell me how do I call servlet for this problem?
There are basically three ways to achieve this:
Submit form to a servlet during the onchange event of the 1st dropdown (you can use Javascript for this), let the servlet get the selected item of the 1st dropdown as request parameter, let it obtain the associated values of the 2nd dropdown from the database as a Map<String, String>, let it store them in the request scope. Finally let JSP/JSTL display the values in the 2nd dropdown. You can use JSTL (just drop jstl-1.2.jar in /WEB-INF/lib) c:forEach tag for this. You can prepopulate the 1st list in the doGet() method of the Servlet associated with the JSP page.
<select name="dd1" onchange="submit()">
<c:forEach items="${dd1options}" var="option">
<option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select name="dd2" onchange="submit()">
<c:if test="${empty dd2options}">
<option>Please select parent</option>
</c:if>
<c:forEach items="${dd2options}" var="option">
<option value="${option.key}" ${param.dd2 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select name="dd3">
<c:if test="${empty dd3options}">
<option>Please select parent</option>
</c:if>
<c:forEach items="${dd3options}" var="option">
<option value="${option.key}" ${param.dd3 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
Once caveat is however that this will submit the entire form and cause a "flash of content" which may be bad for User Experience. You'll also need to retain the other fields in the same form based on the request parameters. You'll also need to determine in the servlet whether the request is to update a dropdown (child dropdown value is null) or to submit the actual form.
Print all possible values of the 2nd and 3rd dropdown out as a Javascript object and make use of a Javascript function to fill the 2nd dropdown based on the selected item of the 1st dropdown during the onchange event of the 1st dropdown. No form submit and no server cycle is needed here.
<script>
var dd2options = ${dd2optionsAsJSObject};
var dd3options = ${dd3optionsAsJSObject};
function dd1change(dd1) {
// Fill dd2 options based on selected dd1 value.
var selected = dd1.options[dd1.selectedIndex].value;
...
}
function dd2change(dd2) {
// Fill dd3 options based on selected dd2 value.
var selected = dd2.options[dd2.selectedIndex].value;
...
}
</script>
<select name="dd1" onchange="dd1change(this)">
<c:forEach items="${dd1options}" var="option">
<option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select name="dd2" onchange="dd2change(this)">
<option>Please select parent</option>
</select>
<select name="dd3">
<option>Please select parent</option>
</select>
One caveat is however that this may become unnecessarily lengthy and expensive when you have a lot of items. Imagine that you have 3 steps of each 100 possible items, that would mean 100 * 100 * 100 = 1,000,000 items in JS objects. The HTML page would grow over 1MB in length.
Make use of XMLHttpRequest in Javascript to fire an asynchronous request to a servlet during the onchange event of the 1st dropdown, let the servlet get the selected item of the 1st dropdown as request parameter, let it obtain the associated values of the 2nd dropdown from the database, return it back as XML or JSON string. Finally let Javascript display the values in the 2nd dropdown through the HTML DOM tree (the Ajax way, as suggested before). The best way for this would be using jQuery.
<%# page pageEncoding="UTF-8" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 2263996</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('#dd1').change(function() { fillOptions('dd2', this); });
$('#dd2').change(function() { fillOptions('dd3', this); });
});
function fillOptions(ddId, callingElement) {
var dd = $('#' + ddId);
$.getJSON('json/options?dd=' + ddId + '&val=' + $(callingElement).val(), function(opts) {
$('>option', dd).remove(); // Clean old options first.
if (opts) {
$.each(opts, function(key, value) {
dd.append($('<option/>').val(key).text(value));
});
} else {
dd.append($('<option/>').text("Please select parent"));
}
});
}
</script>
</head>
<body>
<form>
<select id="dd1" name="dd1">
<c:forEach items="${dd1}" var="option">
<option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
</c:forEach>
</select>
<select id="dd2" name="dd2">
<option>Please select parent</option>
</select>
<select id="dd3" name="dd3">
<option>Please select parent</option>
</select>
</form>
</body>
</html>
..where the Servlet behind /json/options can look like this:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String dd = request.getParameter("dd"); // ID of child DD to fill options for.
String val = request.getParameter("val"); // Value of parent DD to find associated child DD options for.
Map<String, String> options = optionDAO.find(dd, val);
String json = new Gson().toJson(options);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
Here, Gson is Google Gson which eases converting fullworthy Java objects to JSON and vice versa. See also How to use Servlets and Ajax?
Judging by your question, you're really not using a web framework but using servlets to render html.
I'll be nice and say that you're about a decade behind the times :), people use JSPs (and a web framework like struts) for this sort of thing. However, having said that, here goes:
Create a hidden field in your form and set the value to '1', '2' or '3' depending on which drop down is to be populated;
In your servlet, capture this value (request.getParamter()) and use it a 'case'/if/else statement to return the appropriate dropdown values.
I'll say it again, just use a web-framework, or atleast plain old jsp to do this.
You may need multiple servlets for this.
Servlet 1: Load the values for the first drop down list from the database. On the JSP page construct the drop down list. On the user selecting a value submit to servlet two.
Servlet 2: retrieve the value from the first list and perform your database search for the values of the second list. Construct the second list. When the user selects the second value submit it to servlet 3.
Servlet 3: retrieve the value selected in the second drop down and perform the database search to get values for the last drop down.
You may want to consider AJAX to make the populating of the lists appear seamless to the users. jQuery has some very nice plugins for making this quite easy if you are willing to do that.
<form action="servlet2.do">
<select name="dd1" onchange="Your JavaScript Here">
<option>....
</select>
</form>
You can write JavaScript that submits the form in the onchange event. Again, If you use an existing library like jQuery it will be 10 times simpler.
That was an awesome simple solution. I like how small the JQuery code is and really appreciate the link to the GSON API. All the examples made this an easy implementation.
Had one issue on building the JSON server URL with the reference to the parent SELECT ( e.g. $(this).val() ) [needed to specify the :selected attribute]. I've modified the script a little to include the suggested updates. Thanks for the initial code.
<script>
$(document).ready(function()
{
$('#dd1').change(function() { fillOptions('dd1', 'dd2'); });
$('#dd2').change(function() { fillOptions('dd2', 'dd3'); });
});
function fillOptions(parentId, ddId)
{
var dd = $('#' + ddId);
var jsonURL = 'json/options?dd=' + ddId + '&val=' + $('#' + parentId + ' :selected').val();
$.getJSON(jsonURL, function(opts)
{
$('>option', dd).remove(); // Clean old options first.
if (opts)
{
$.each(opts, function(key, value)
{
dd.append($('<option/>').val(key).text(value));
});
}
else
{
dd.append($('<option/>').text("Please select parent"));
}
});
}
</script>