Is there any elegant way to create something like this
<select>
<option value="" disabled selected>Select your option</option>
<option value="1">Option1</option>
</select>
using #Html.DropDownListFor helper in ASP.NET MVC 4?
http://jsfiddle.net/wLAt8/
Unfortunately not. There is no way to add attributes to a SelectListItem, which is what gets rendered as an <option>.
You would need to extend the SelectListItem class, and then extend the DropDownListFor to use it. It is unfortunately not very straightforward... It would have been nice for there to be an Attributes dictionary on SelectListItem for this purpose.
Here is an implementation of a custom attribute being applied:
Adding html class tag under <option> in Html.DropDownList
Here's one way you could do it using tag helpers.
<select asp-for="#Model.Orders.FruitsId" class="form-control">
<option value="">Select a Fruit</option>
#foreach (var Fruit in Model.Fruits )
{
if (barber.Name.Equals("Orange"))
{
<option disabled="disabled" value="#Fruit.Id">#Fruit.Name </option>
}
else
{
<option value="#Fruit.Id">#Fruit.Name </option>
}
}
</select>
After struggling I've done this via js function:
function handleSubAction(select) {
var item = document.getElementById(select);
item.children[0].disabled = true;
item.children[0].hidden= true;
return false;
}
and event handler in HTML:
<body onload="handleSubAction('subAction');"/>
Related
Rather than loading a new template, is there a way to force Meteor to initiate an iteration (using {{#each}}) of an array in Meteor? For example, if the user selects a value in a pull down selector, to then initiate Meteor to iterate through an array within that template to populate another multiple selector list rather than load a whole new template with the new selector list.
Let's say this is within a template:
.
.
.
<form class="input-field col s6 card-selector">
<select multiple">
<option value="" disabled selected>Select Students</option>
{{#each StudentList1}}
<option value= '{{FullName}}'>{{formatName FullName}} ({{Level}}) {{RoomWk1}}</option>
{{/each}}
</select>
</form>
.
.
.
When a user selects a value in a different selector in that template:
<select class="week-selector">
<option value="" disabled selected>Week</option>
<option value="Week1">Week 1</option>
<option value="Week2">Week 2</option>
<option value="Week3">Week 3</option>
<option value="Week4">Week 4</option>
<option value="Week5">Week 5</option>
</select>
it will force a reiteration of the first #each to:
<form class="input-field col s6 card-selector">
<select multiple">
<option value="" disabled selected>Select Students</option>
{{#each StudentList1}}
<option value= '{{FullName}}'>{{formatName FullName}} ({{Level}}) {{RoomWk2}}</option>
{{/each}}
</select>
</form>
It would be more efficient than loading a new template that's the same except for the multi selector values.
Sessions are reactive and you can achieve this by using sessions (check if you have session package).
//we don't want the session value from the previous search/events
Template.templateName.onRendered(function(){
Session.set('sessionName', undefined);
});
//I'd probably use onDestroyed instead of onRendered
Template.templateName.onDestroyed(function(){
Session.set('sessionName', undefined);
});
//template events
'change .week-selector': function(){
var selected = $('.week-selector').find(":selected").text();
Session.set('sessionName', selected)
}
//template helper
StudentList1: function(){
var session = Session.get('sessionName');
if(session !== undefined){
//return some documents using the session value in your find()
} else {
//return documents without session value
}
}
EDIT: I found .text() of the selected option in the event but you are free to return value or do whatever you want with the found value/text.
I want to set the value of an HTML <select> element reactively, without changing the various options for the element. I have found a solution, but it in not elegant.
To test, create a barebones Meteor app with create meteor select and change the contents of the select.html and select.js files to the following:
select.html
<body>
{{> select}}
</body>
<template name="select">
<label for="select">{{category}}</label>
<select id="select">
<option value='' disabled selected style='display:none;'>Select...</option>
<option value="Animal">Animal</option>
<option value="Vegetable">Vegetable</option>
<option value="Mineral">Mineral</option>
</select>
</template>
select.js
if (Meteor.isClient) {
Session.set("category", "")
Session.set("label", "Category")
Template.select.onRendered(function () {
setSelectValue()
})
Template.select.helpers({
category: function () {
setSelectValue()
return Session.get("label")
}
});
function setSelectValue() {
var select = $("#select")[0]
if (select) {
select.value = Session.get("category")
}
}
}
Now launch your app. In the browser console, you can change the value of the category Session variable:
Session.set("category", "Animal")
However, the select element will not update until you change the label:
Session.set("label", "category") // was "Category'
Now the select element updates, and any subsequent change the category Session variable will also update the select element.
Session.set("category", "Vegetable") // Now the select element updates
Is it possible to achieve the same effect directly, without using this clumsy workaround?
Yes. You can do it as follows:
<select id="select">
<option value="Animal" {{animalSelected}}>Animal</option>
<option value="Vegetable" {{vegetableSelected}}>Vegetable</option>
<option value="Mineral" {{mineralSelected}}>Mineral</option>
</select>
And helpers that looks something like this:
Template.select.helpers({
animalSelected: function () {
return (someCondition === true) ? 'selected' : '';
},
vegetableSelected: function () {
return (someOtherCondition) ? 'selected' : '';
}
});
A better way might be something like this though:
<select id="select">
{{#each options}}
<option value="{{value}}" {{selected}}>{{label}}</option>
{{/each}}
</select>
And then you can use this in the helpers to decide what is selected and what isn't.
Another option is just using standard jQuery to change the select box. Something like this:
$('[name=options]').val( 3 );
Or this SO answer.
If you want the selection set dynamically I usually use a handlebar helper like this
Template.newtask.helpers({
filler: function(element){
return Session.get(element);
}
});
then in html
<select class="browser-default" id="selectedService" name="jobtype">
<option id="zero" value="{{filler 'type'}}">{{filler 'type'}}</option>
I currently have a drop down navigation that opens a modal lightbox window.
I would like to not open the the window if there in an option with no URL selected which is the first default option.
I have tried a number of techniques such as:
- returning false on the onsubmit event of the form.
- Attempting to bind a click event to the goURL a href link using jQuery that would then either
1) call event.preventDefault or 2)stop propagation events.
- coding an onclick event to the goURL a href link.
Below is the html code
<h3>Request a <span>Quote</span></h3>
<form action="#">
<div class="select">
<select id="URL" name="URL" onchange="$('#goLink').attr('href', $('#URL').val());">
<option value="">- Choose a Link -</option>
<option value="/node/1/lightbox2">Link 1</option>
<option value="/node/2/lightbox2">Link 2</option>
<option value="/node/3/lightbox2">Link 3</option>
<option value="/node/4/lightbox2">Link 4</option>
<option class="last" value="/node/5/lightbox2">Link 5</option>
</select>
</div>
</form>
GO
You have to remove the rel attribute if you need a simple link without lightbox effect. The href attribute does not affect it.
Here is a sample of a jQuery code (not necessary the perfect one but just as an example):
$("#url").change(function(){
var selected = $('url :selected'), // Get the selected option
selectedVal = selected.val(); // Get the selected option value
if (selectedValue == "") {
$('#goLink').removeAttr('rel'); // Remove the rel if the value is empty
} else {
$("#goLink").attr('href',selectedVal).attr('rel','lightframe'); // Add rel=lightframe attribute and the href
}
});
My JSP snippet is as follows:
<form:select path="rules[${counter.index}].assignedTo.assignedToName">
<form:options items="${assignmentRulesForm.assignedToList}"
itemLabel="assignedToName"
itemValue="assignedToName"/>
</form:select>
The assignedTo property refers to this object:
public class AssignmentDTO {
private String assignedToName;
// No other members
assignedToList then is a List<AssignmentDTO>
Really, what I want to happen is for the drop-down to contain all entries in the assignedToList, but to select the value associated with rule[i].assignedto.assignedToName
Presently, what I am seeing is that it does not perform the selection part, and the first item in the drop-down is displayed.
Any help is appreciated.
Thanks
This should work for you, the path is not the name but the assignedTo:
<form:select path="rules[${counter.index}].assignedTo">
<form:options items="${assignmentRulesForm.assignedToList}"
itemLabel="assignedToName"
itemValue="assignedToName"/>
</form:select>
If you have implemented a .equals for your assignedTo, it should just work.
<html>
<head>
<script>
function show() {
var op= window.document.getElementById('select');
var selItem= op.options[op.selectedIndex].value;
if(selItem=="Others") {
document.getElementById('text').style.visibility = 'visible';
}
else {
document.getElementById('text').style.visibility = 'hidden';
}
}
</script>
</head>
<select id="select" onchange="show();">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
<option value="Others">Others</option>
</select>
<br>
<input type="text" id="text" style="visibility:hidden">
</html>
I have 2 dropdown lists on my webform and using jquery trying to filter/reset filter 2nd dropdown elements based on 1st dropdown selection.
$(document).ready(function()
{
$('#dropdown1').change(function(e)
{
switch ($(this).val())
{
case "4":
//this removal works
$('#dropdown2').filter(function()
{
return ($(this).val() == 16);
}).remove();
break;
.................
default:
//how would I restore filter here?
}
}
});
Removing part works, so it filters item with no problem, but I have difficulty restoring the filter on dropdown 2 if something else is chosen in dropdown 1. I was trying to use .hide() and .show() instead of .remove() but it doesn't seem to work on IE6 at least.
At the start of your document ready take a copy of the values in dropdown2 like this:
var drp2values = $('#dropdown2').html();
then whenever you want to reset the values in dropdown2 to its original state do this:
$('#dropdown2').html(drp2values);
The actual value in the var will be something like :
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="16">16</option>
just tried it:
This code works:
$(document).ready(function()
{
var drp2values = $('#dropdown2').html();
$('#dropdown1').change(function(e)
{
switch ($(this).val())
{
case "4":
//this removal works... now ;)
$('#dropdown2').find('option').filter(function()
{
alert('in4 filt' + drp2values + $(this).val());
return ($(this).val() == 16);
}).remove();
break;
default:
//how would I restore filter here?
$('#dropdown2').html(drp2values);
}
});
});
With this HTML
<BODY>
<select id='dropdown1'>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id='dropdown2'>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="16">16</option>
</select>
</BODY>
The original code you posted where you said the remove worked, it didnt remove the individual option with value 16, it removed the entire dropdown as you were not geting the options before you filtered, you were removing the dropdown :)
Hope this helps.