I have a select list looking like this:
<select
class="form-control"
ng-model="locationList"
ng-options="location.place group by location.type for location in locationlist | orderBy:['type']"
ng-change="addMissingLocation(locationList)">
<option value="">From</option>
</select>
The last item of the ng-options list is called "Add location", and triggers the following function through ng-change:
$scope.addMissingLocation = function (locationList) {
if (locationList.place == "Add location") {
$('.addMissingLocation').modal('show');
}
}
A modal shows, and it allows the user to add a new location using the following function:
$scope.addLocationOtherExtra = function () {
$scope.locationlist.push({ place: $scope.formLocationOther, type: "-Secondary Locations", main:false});
jsonToLocationLocalStorage($scope.locationlist);
$scope.formLocationOther = '';
$('.addMissingLocation').modal('hide');
};
What I am trying to accomplish, is that once the user introduces a new location and the modal closes, the selected value in the select, is this newly added value.
I'm not even sure if such thing is possible.
Any tips?
After adding new option you should point ngModel to added option. Try this to select the last option (new one):
$scope.addLocationOtherExtra = function () {
$scope.locationlist.push({ place: $scope.formLocationOther, type: "-Secondary Locations", main:false});
$scope.locationList = $scope.locationlist[$scope.locationlist.length - 1];
jsonToLocationLocalStorage($scope.locationlist);
$scope.formLocationOther = '';
$('.addMissingLocation').modal('hide');
};
Related
I'm fairly new to C# and javascript, so feel free to correct me if I'm wrong :P
I'm trying to make a dropdown to depend on another dropdown in C# where I've faced the issue of the value taken from the first dropdown being null when nothing has been selected from the dropdown.
I have two classes in the controller, one for the first dropdown that consists of the "categories" and one that consists of the "under-categories/sub categories":
public ActionResult RenderCategories(int id)
{
DataTable UserTbl = new DataTable();
using (SqlConnection sqlConn = new SqlConnection(connectionstring))
{
sqlConn.Open();
SqlDataAdapter sqlDa = new SqlDataAdapter("SELECT Category_Title,CID FROM CategoryTbl", sqlConn);
sqlDa.Fill(UserTbl);
}
return View(UserTbl);
}
[HttpGet]
public JsonResult RenderUnderCategories(int? value) // This value is null when no value has been choosen from dropdown 1
{
System.Diagnostics.Debug.WriteLine(value);
DataTable UserTbl = new DataTable();
using (SqlConnection sqlConn = new SqlConnection(connectionstring))
{
value = 1;
if (value != null) {
sqlConn.Open();
SqlDataAdapter sqlDa = new SqlDataAdapter("SELECT uCID,under_category_Title FROM UndercategoryTbl where CID =" + value + "", sqlConn);
sqlDa.Fill(UserTbl);
}
}
return Json(new { data = UserTbl }, JsonRequestBehavior.AllowGet);
}
I then have two different views with the respective dropdown:
Dropdown 1:
<select id="Categories-Dropdown">
<option>- Select Category -</option>
#for (int i = 0; i < Model.Rows.Count; i++)
{
<option value="#Model.Rows[i]["CID"]" name="CategoryID">#Model.Rows[i]["Category_Title"]</option>
}
</select>
I also have some script for dropdown 1 that takes the value (which is an id) to the controller:
<script>
var dropdown = document.getElementById('Categories-Dropdown');
dropdown.addEventListener('change', function () {
showValue(this.value);
})
function showValue(val)
{
console.log(val);
$.getJSON('/ScannableNotes/RenderUnderCategories/?value=' + val)
}
</script>
The value taken from the onchange event is crucial because that determines which values will be shown in dropdown 2, making the dropdowns dependant on each other.
In order to make the dropdowns appear in the same view, I'm using the render action method in a third view:
#{Html.RenderAction("RenderCategories","ScannableNotes");}
#{Html.RenderAction("RenderUnderCategories", "ScannableNotes");} //error appears here
However, when executing the code the following error appears at the render action of dropdown 2:
System.Web.HttpException: 'Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.'
I assume this is because the value taken from dropdown 1 to the controller of dropdown 2 (RenderUnderCategories) is null when no value has been choosen. And the value won't be true until I choose something in dropdown 1 which will trigger the onchange event.
So my question is, how can I set a default value on the Select for dropdown 1 and then take that value to the controller?
How to update new value choosing from select box on click save button.
I am using ng-click function like this in my JS function for update button:
$scope.updateDealDetail = function updateDealDetail (){
$scope.showEditView = !$scope.showEditView;
$scope.dealDetail.decisionMakerDetail.email = $scope.selectedid;
}
My function for edit button:
$scope.editUserDetail = function editUserDetail(){
$scope.showEditView = !$scope.showEditView;
$scope.showSubmitView = !$scope.showSubmitView;
deal.getIdData($scope.accountDetail. accountUsers[0].role,$scope.accountDetail.id).then(function successCb(data){
$scope.editIdOptionsData=data;
$scope.selectedid = $scope.editIdOptionsData[0].email;
});
};
and my HTML for bitton click is like this :
<select ng-model="selectedid" class="form-control">
<option ng-selected="selectedid" ng-repeat="eiod in editIdOptionsData" value="{{eiod.email}}">{{eiod.email}}
<button ng-click="updateDealDetail(eoid.email)" ng-disabled="dealDataSaveButtonDisabled">Update</button>
I am trying to this through ng-repeat because of by using ng-options my data through API is now showing in the box. But My data which is on first index is only getting set. What to do to set the a default value for the selection box and by selection any value, onclick need to update that value.
Don't use ngRepeat to render options, this is your problem. Correct code would be:
<select class="form-control"
ng-model="selectedid"
ng-options="eiod.email as eiod.email for eiod in editIdOptionsData">
</select>
Best practice to use ng-options, ng-model and ng-change on the <select> element
Online demo - https://plnkr.co/edit/Gaa8sMgerRv6chio4iYa?p=preview
html
<select
ng-model="selectedItem"
ng-change="onSelectedItemChanged()"
ng-options="item as item.email for item in items"></select>
js
app.controller('MainCtrl', function($scope) {
$scope.items = [{
email: 'asd1#asd.com'
}, {
email: 'asd2#asd.com'
}];
$scope.selectedItem = $scope.items[0];
$scope.onSelectedItemChanged = function() {
alert('you changed it to ' + $scope.selectedItem.email);
}
});
I want my select box to change depending which option I choose in the first select, and I want to hide the values that are not from that option/
My HTML here:
<select id="localidad">
#foreach (ja_era.Models.Localidades localidad in ViewBag.localidades)
{
<option value="#localidad.Id">#localidad.Zona</option>
}
</select>
<select name="Localidad" id="barrio">
#foreach (ja_era.Models.Barrios barrio in ViewBag.barrios)
{
<option class="#barrio.Localidad" value="#barrio.Id">#barrio.Barrio</option>
}
</select>
The Localidad select has 4 options and bring the countries, then I have the second select that brings the cities all in one select box. Which ones are well defined in my database.
You can see here that "Barrios" has the column localidad where I insert the localidad id
I have tried some js code but can't figure it out how to make it work.
$(document).ready(function() {
$('#localidad').change(function () {
});
})
Basically you need to get the value of the selected option of the first dropdown, send it to your an action method and let it return the data for the second dropdown in json format. Then you will go through the items in the JSON array and build the markup for the options in the second dropdown.
$(document).ready(function() {
$('#localidad').change(function () {
var v = $(this).val();
var urlToGetData="#Url.Action("GetBarrios","Home")";
var items="";
$.getJSON(urlToGetData+"?id="+v,function(a,item){
items+="<option value='"+item.Value+"'>"+item.Text+"</option>";
})
$("#barrio").html(items);
});
})
Assuming you have GetBarrios action method like this
public ActionResult GetBarrios(int id)
{
var items=db.Barrios.Where(s=>s.Localidad==id)
.Select(s=> new SelectListItem {
Value=s.Id.ToString(),
Text = s.Barrio
}).ToList();
return Json(items,JsonRequestBehaviour.AllowGet);
}
I am currently working on a random number generator type of project, and the following code below has a double-dropdown that once chosen, calls the function tied to whatever you have chosen from the list of options in the drop-down. This works fine and all, but I would much rather have the strings generate after the submit/generate button is pushed. Is there anyway to make this happen?
See code below as well as a live example at http://hawkgen.com/gen/
<!-- The first select list -->
<select name="slist1" onchange="SList.getSelect('slist2', this.value);">
<option>- - -</option>
<option value="amazon">Amazon</option>
<option value="apple">Apple</option>
<option value="keurig">Keurig</option>
<option value="nike">Nike</option>
</select>
<!-- Tags for the seccond dropdown list, and for text-content -->
<span id="slist2"></span> <div id="scontent"></div>
<div id="display">Hello World (placeholder text, code will generate here.)</div>
<script><!--
/* Script Double Select Dropdown List, from: coursesweb.net/javascript/ */
var SList = new Object(); // JS object that stores data for options
// HERE replace the value with the text you want to be displayed near Select
var txtsl2 = '';
/*
Property with options for the Seccond select list
The key in this object must be the same with the values of the options added in the first select
The values in the array associated to each key represent options of the seccond select
*/
SList.slist2 = {
"amazon": ['Kindle Fire HD', 'Kindle Charger', 'Kindle Fire HDX'],
"apple": ['MacBook', 'iMac', 'iPhone', 'iPad'],
"keurig": ['Platinum', 'Vue'],
"nike": ['Fuel Band']
};
/*
Property with text-content associated with the options of the 2nd select list
The key in this object must be the same with the values (options) added in each Array in "slist2" above
The values of each key represent the content displayed after the user selects an option in 2nd dropdown list
*/
SList.scontent = {
"Kindle Fire HD": 'kindlefirehd',
"Kindle Charger": 'kindlecharge',
"Kindle Fire HDX": 'kindlefirehdx',
"MacBook": 'macbook',
"iMac": 'imac',
"iPhone": 'iphone',
"iPad": 'ipad',
"Platinum": 'platinum',
"Vue": 'vue',
"FuelBand": 'fuelband'
};
/* From here no need to modify */
// function to get the dropdown list, or content
SList.getSelect = function(slist, option) {
document.getElementById('scontent').innerHTML = ''; // empty option-content
if(SList[slist][option]) {
// if option from the last Select, add text-content, else, set dropdown list
if(slist == 'scontent'){;
var selected = SList[slist][option];
functions[selected]();
}
else if(slist == 'slist2') {
var addata = '<option>- - -</option>';
for(var i=0; i<SList[slist][option].length; i++) {
addata += '<option value="'+SList[slist][option][i]+'">'+SList[slist][option][i]+'</option>';
}
document.getElementById('slist2').innerHTML = txtsl2+' <select name="slist2" onchange="SList.getSelect(\'scontent\', this.value);">'+addata+'</select>';
}
}
else if(slist == 'slist2') {
// empty the tag for 2nd select list
document.getElementById('slist2').innerHTML = '';
}
}
var functions = {
kindlefirehd: function(){
var secondPossible = 'ABCDEFGHJKLMNPQRSVWY123456';
var firstPossible = '123456';
var firstLength = 1;
var secondLength = 2;
var firstString = Array.apply(null, new Array(firstLength)).map(function () {
return firstPossible[Math.floor(Math.random() * firstPossible.length)];
}).join('');
var secondString = Array.apply(null, new Array(secondLength)).map(function () {
return secondPossible[Math.floor(Math.random() * secondPossible.length)];
}).join('');
document.getElementById("display").innerHTML='D0FB A0A0 343' + firstString + ' 0A' + secondString
},
kindlecharge: function(){window.alert("func1 called")},
kindlefirehdx: function(){window.alert("func1 called")},
macbook: function(){window.alert("func1 called")},
imac: function(){window.alert("func1 called")},
iphone: function(){window.alert("func1 called")},
ipad: function(){window.alert("func1 called")},
platinum: function(){window.alert("func1 called")},
vue: function(){window.alert("func1 called")},
fuelband: function(){window.alert("func1 called")}
}
</script>
I answered without testing and missed an important part. Leaving original answer below.
I set up an example of one way to do this at
http://bsoist.cloudvent.net/so/23096335.html
===ORIGINAL ANSWER===
One approach would be ...
Replace this
<select name="slist1" onchange="SList.getSelect('slist2', this.value);">
with this
<select name="slist1" onchange="setOption(this.value);">
and then add the button
<input type="submit" onsubmit="void(SList.getSelect('slist2'));">
edit the Slist.getSelect function by changing this
SList.getSelect = function(slist, option) {
to this
SList.getSelect = function(slist) {
create a global variable called option instead, and then add this function.
function setOption(value) {
option = value;
}
I have got this so far with knockout js and jQuery.
Its fairly elagant. The reasons why:
It turns your JSON list into usable objects with properties
All bindings (element updates) are taken care of by knockout
The previous point allows you to write the code that matters leaving it clean
I use a view model to take care of all the code, knockout takes care of the bindings:
var viewModel = function () {
var self = this;
self.makes = ko.observableArray($.map(makesArray, function (item) { return new makeModel(item); }));
self.selectedMake = "";
self.subMakes = ko.observable(null);
self.subMakesArray = ko.observableArray([]);
self.selectedSubMake = "";
self.firstListBoxChange = function () {
self.subMakesArray(self.selectedMake.subMakes);
}
self.submitSomething = function () {
// do something here
}
}
With the data-bind you can have anything fire off an event to do something:
data-bind="options: makes,optionsText: 'name', value: selectedMake,event: { change: firstListBoxChange() }"
This is in the first select and when it is changed will fire off the firstListBoxChange() function in the view model.
data-bind="click: submitSomething"
This is in the button, and fires of submitSomething. However, the first select event can be mimicked in the second select if you want that one to fire off an event.
I'm trying to update Textbox's with the selected items info(properties). Can I get the selected Items Name instead of the Id, or in other words how can I get the properties of whats in my ViewData in the javascript upon selecting an item and then set it to a txtbox?
#Html.ListBox("ListBoxName", new SelectList((IEnumerable<Epic>)ViewData["selectedestimate"], "Id", "Name", "EstimatedTime"), new {#class = "ListBoxClass", #style = "height: 325px;"})
#Html.TextBoxFor(model => model.Name, new {#class = "TimeClass"})
<script type="text/javascript">
$(function () {
$(".ListBoxClass").click(function (event) {
var selectedid = $(this).find("option:selected").val();
// get items properties and info so that the value can be set to a textbox
//set textbox value to Name of selected Value
$(".TimeClass").val(selectedid);
event.preventDefault(); // Stop the browser from redirecting as it normally would
$.get('#Url.Action("UserStoriesList", "Estimate")', { id: selectedid }, function (result) {
$('#stories').html(result);
});
});
});
</script>
A ListBox is like a DropDownList except that it allows for multiple items to be selected. It uses the same HTML tag (<select>) but it adds the multiple attribute. So when rendered your markup will look like this:
<select id="ListBoxName" name="ListBoxName" multiple="multiple">
<option value="id1">text 1</option>
<option value="id2">text 2</option>
<option value="id3">text 3</option>
...
</select>
So as you can see you have information about the id and the text inside the DOM. If you wanted to fetch some other information about the selected item you will need to send an AJAX request to the server and pass the selected id to retrieve it. So if you only wanted to show the text:
$(function() {
$('.ListBoxClass option').click(function() {
if ($(this).is(':selected')) {
var selectedId = $(this).val();
var selectedText = $(this).text();
$('.TimeClass').val(selectedText);
...
}
});
});
The click handler will run everytime the user clicks on an element in the listbox but the if condition will be satisfied only if he selected the item.