I am fairly new to AngularJS and I have been reading some answers here but nothing worked out. I have a json file from a controller that I display in a select. I want to set the selected value based on the text value.This is what I have so far.
HTML:
<div ng-app="userModule" ng-controller="userCtrl">
<div class="row">
<div class="col-md-6">
<label>User Name:</label> <br />
<select ng-model="users.selectedUser" class="form-control" ng-options="item.UserName as item.UserName for item in users.availableOptions"></select>
</div>
Controller:
<script>
var _$http;
var _$scope;
var oldUser = #Html.Raw(Json.Serialize(ViewData["UserName"]));
var oldRole = #Html.Raw(Json.Serialize(ViewData["RoleName"]));
angular.module('userModule', [])
.controller('userCtrl', xConstructor);
function xConstructor($scope, $http) {
_$http = $http;
_$scope = $scope;
$http.get("/RoleManagement/GetUserData").then(xReceive);
$http.get("/RoleManagement/GetRoleData").then(roleReceive);
_$scope.submit = function () {
//alert("Here:" + _$scope.selectedUser);
$http.get("/RoleManagement/PutUserRoleData?UserId=" + _$scope.selectedUser.UserId + "&RoleId=" + _$scope.selectedRole.RoleId).then(writeSuccess);
}
}
function xReceive(userObject) {
_$scope.users = {
availableOptions: userObject.data,
**selectedUser: { UserId: oldId, UserName: oldUser } //What to put here?**
};
alert(JSON.stringify(JSON.stringify(_$scope.users.selectedUser));
}
</script>
Or any other suggestions on how to do this?
The problem is you are not mapping the model to any element in the array you have.
Assuming you have the id of the user you want to select this is what you do:
function xReceive(userObject) {
_$scope.users = {
availableOptions: userObject.data,
selectedUser: null
};
let selectedUser;
for (let i = 0; i < userObject.data.length; i++) {
if (userObject.data[i].id === oldId) {
selectedUser = userObject.data[i];
break;
}
}
if (selectedUser) {
_$scope.users.selectedUser = selectedUser;
}
alert(JSON.stringify(JSON.stringify(_$scope.users.selectedUser));
}
Also note, you can do this to just select the first one:
_$scope.users.selectedUser = _$scope.users.availableOptions[0];
This is how i am loading on page load state and city dropdown:
My Controller method:
This is the first method which is calling when page is loaded.
public ActionResult Index()
{
var states = GetStates();
var cities = Enumerable.Empty<SelectListItem>();
ViewBag.States = states;
ViewBag.Cities = cities;
}
private IEnumerable<SelectListItem> GetStates()
{
using (var db = new DataEntities())
{
return db.States.Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() });
}
}
[HttpGet]
public ActionResult GetCities(int id)
{
using (var db = new DataEntities())
{
var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
}
My View:
IEnumerable<SelectListItem> States = ViewBag.States;
IEnumerable<SelectListItem> Cities = ViewBag.Cities;
#Html.DropDownList("State", States, "Select State", new { onchange="loadCities(this)"})
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"})
function loadCities(obj) {
$.ajax({
url: "/Home/GetCities",
data: { id: $(obj).val() },
contentType:"application/json",
success:function(responce){
var html = '<option value="0">Select City</option>';
$(responce).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
}
});
}
Any better way then this to load state and city dropdown?
public class HomeController : Controller
{
public ActionResult Index(int id=0)
{
Person model = null;
var states = GetStates().ToList();
var cities = Enumerable.Empty<SelectListItem>();
if (id > 0)
{
using (var db = new DataEntities())
{
model = db.People.Include("City").FirstOrDefault(d => d.Id == id);
if (model == null)
model = new Person();
else
{
states.First(d => d.Value == model.City.StateId.ToString()).Selected = true;
cities = db.Cities.Where(d => d.StateId == model.City.StateId).ToList().Select(d => new SelectListItem { Text = d.CityName,Value=d.Id.ToString(),Selected=d.Id==model.CityId });
}
}
}
else
{
model = new Person();
}
ViewBag.States = states;
ViewBag.Cities = cities;
ViewBag.Persons = GetPersons();
return View(model);
}
[HttpGet]
public ActionResult GetCities(int id)
{
using (var db = new DataEntities())
{
var data = db.Cities.Where(d=>d.StateId==id).Select(d => new { Text = d.CityName, Value = d.Id }).ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
}
public ActionResult SavePersonDetail([Bind(Exclude = "Id")] Person model)
{
// var employeeDal= new Emploee();
//employee.firstname=model.
if (ModelState.IsValid)
{
var Id = model.Id;
int.TryParse(Request["Id"], out Id);
using (var db = new DataEntities())
{
if (Id > 0)
{
var person = db.People.FirstOrDefault(d => d.Id == Id);
if (person != null)
{
model.Id = Id;
db.People.ApplyCurrentValues(model);
}
}
else
{
db.People.AddObject(model);
}
db.SaveChanges();
}
}
if (!Request.IsAjaxRequest())
{
ViewBag.States = GetStates();
ViewBag.Persons = GetPersons();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
return View("Index");
}
else
{
return PartialView("_personDetail",GetPersons());
}
}
public ActionResult Delete(int id)
{
using (var db = new DataEntities())
{
var model = db.People.FirstOrDefault(d => d.Id == id);
if (model != null)
{
db.People.DeleteObject(model);
db.SaveChanges();
}
}
if (Request.IsAjaxRequest())
{
return Content(id.ToString());
}
else
{
ViewBag.States = GetStates();
ViewBag.Persons = GetPersons();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
return View("Index");
}
}
private IEnumerable<SelectListItem> GetStates()
{
using (var db = new DataEntities())
{
return db.States.ToList().Select(d => new SelectListItem { Text = d.StateName, Value =d.Id.ToString() });
}
}
private IEnumerable<Person> GetPersons()
{
using (var db = new DataEntities())
{
return db.People.Include("City").Include("City.State").ToList();
}
}
public ActionResult HomeAjax()
{
ViewBag.States = GetStates();
ViewBag.Cities = Enumerable.Empty<SelectListItem>();
using (var db = new DataEntities())
{
var data = db.States.Include("Cities").Select(d => new { Id = d.Id, Name = d.StateName, Cities = d.Cities.Select(x => new { Id=x.Id,Name=x.CityName}) }).ToList();
ViewBag.CityStateJson = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(data);
}
ViewBag.Persons = GetPersons();
return View();
}
}
#model IEnumerable<Person>
<div>
<table>
<tr>
<th>
First Name
</th>
<th>
Last Name
</th>
<th>
Email
</th>
<th>
City
</th>
<th>
State
</th>
<th>
Edit
</th>
</tr>
#if (Model.Count() == 0)
{
<tr>
<td colspan="6">
<h3>No data available</h3>
</td>
</tr>
}
else {
foreach (var item in Model) {
<tr data-id="#item.Id">
<td data-id="fn">#item.FirstName</td>
<td data-id="ln">#item.LastName</td>
<td data-id="email">#item.Email</td>
<td data-id="cn">#item.CityName<input type="hidden" value="#item.CityId" /></td>
<td>#item.StateName</td>
<td>
#if (ViewBag.Title == "Home Ajax" || Request.IsAjaxRequest())
{
Update
<span>#Ajax.ActionLink("Delete", "Delete", new { id = item.Id }, new AjaxOptions {OnSuccess="deleteSuccess",OnBegin="showLoader",OnComplete="hideLoader" })</span>
}
else {
<span>#Html.ActionLink("Update", "Index", new { id = item.Id })</span>
<span>#Html.ActionLink("Delete", "Delete", new { id = item.Id })</span>
}
</td>
</tr>
}
}
</table>
</div>
#model Person
#{
ViewBag.Title = "Home Ajax";
IEnumerable<Person> persons = ViewBag.Persons;
IEnumerable<SelectListItem> States = ViewBag.States;
IEnumerable<SelectListItem> Cities = ViewBag.Cities;
IEnumerable<State> fullStates=ViewBag.CityStates;
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
</hgroup>
</div>
</section>
}
#section styles{
<style type="text/css">
td,th {
border:1px solid;
padding:5px 10px;
}
select {
padding:5px 2px;
width:310px;
font-size:16px;
}
</style>
}
#section scripts{
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
var jsonArray = #Html.Raw(ViewBag.CityStateJson)
function clearValues() {
$("input[type='text'],select").val('');
$("input[type='hidden'][name='Id']").val(0);
}
function loadCities(obj) {
for (var i = 0; i < jsonArray.length; i++) {
if (jsonArray[i].Id == parseInt($(obj).val())) {
fillCity(jsonArray[i].Cities);
break;
}
}
}
function Edit(obj, Id) {
// alert("hi")
$("input[type='hidden'][name='Id']").val(Id);
var tr = $(obj).closest("tr");
$("#txtfirstName").val($("td[data-id='fn']", tr).text().trim());
$("#txtlastName").val($("td[data-id='ln']", tr).text().trim());
$("#txtemail").val($("td[data-id='email']", tr).text().trim());
var city = $("td[data-id='cn'] input[type='hidden']", tr).val();
var state;
for (var i = 0; i < jsonArray.length; i++) {
for (var j = 0; j < jsonArray[i].Cities.length; j++) {
if (jsonArray[i].Cities[j].Id == parseInt(city)) {
state = jsonArray[i].Id;
break;
}
}
if (state) {
fillCity(jsonArray[i].Cities);
break;
}
}
$("#ddlState").val(state);
$("#ddlCity").val(city);
}
function fillCity(obj) {
var html = '<option value="0">Select City</option>';
$(obj).each(function () {
html += '<option value="' + this.Id + '">' + this.Name + '</option>'
});
$("#ddlCity").html(html);
}
function deleteSuccess(responce) {
alert("record deleted successfully");
$("tr[data-id='" + responce + "']").remove();
}
function insertSuccess() {
alert("Record saved successfully");
clearValues();
}
function showLoader() {
$("#overlay").show();
}
function hideLoader() {
$("#overlay").hide();
}
</script>
}
<h3>Add Personal Detail</h3>
#using (Ajax.BeginForm("SavePersonDetail", "Home", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "personList" ,OnSuccess="insertSuccess",OnBegin="showLoader",OnComplete="hideLoader"}))
{
#Html.HiddenFor(m => m.Id);
<ol class="round">
<li>
#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName, new { id = "txtfirstName" })
#Html.ValidationMessageFor(m => m.FirstName)
</li>
<li>
#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName, new { id = "txtlastName" })
#Html.ValidationMessageFor(m => m.LastName)
</li>
<li>
#Html.LabelFor(m => m.Email)
#Html.TextBoxFor(m => m.Email, new { id = "txtemail" })
#Html.ValidationMessageFor(m => m.Email)
</li>
<li>
#Html.Label("State")
#Html.DropDownList("State", States, "Select State", new { onchange = "loadCities(this)", id = "ddlState" })
</li>
<li>
#Html.LabelFor(m => m.CityId)
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id = "ddlCity" })
#Html.ValidationMessageFor(m => m.CityId)
</li>
</ol>
<input type="submit" value="Save" />
<input type="button" value="Cancel" onclick="clearValues();"/>
}
<h2>
Person List
</h2>
<div style="position:fixed;text-align:center;top:0;bottom:0;left:0;right:0;z-index:10;background-color:black;opacity:0.6;display:none;" id="overlay">
<img style="position:relative;top:370px" src="~/Images/ajax-loader.gif" />
</div>
<div id="personList">
#Html.Partial("_personDetail", persons)
</div>
You approach using ajax is fine although I would recommend a few better practices including using a view model with properties for StateID, CityID StateList and CityList, and using Unobtrusive JavaScript rather than polluting you markup with behavior, and generating the first ("please select") option with a null value rather than 0 so it can be used with the [Required] attribute
HTML
#Html.DropDownList(m => m.StateID, States, "Select State") // remove the onchange
#Html.DropDownListFor(m => m.CityID, Cities, "Select City") // why change the default ID?
SCRIPT
var url = '#Url.Action("GetCities", "Home")'; // use the helper (dont hard code)
var cities = $('#CityID'); // cache the element
$('#StateID').change(function() {
$.getJSON(url, { id: $(this).val() }, function(response) {
// clear and add default (null) option
cities.empty().append($('<option></option>').val('').text('Please select'));
$.each(response, function(index, item) {
cities.append($('<option></option>').val(item.Value).text(item.Text));
});
});
});
If you were rendering multiple items (say you were asking the user to select their last 10 cities they visited), you can cache the result of the first call to avoid repeated calls where their selections may include cities from the same state.
var cache = {};
$('#StateID').change(function() {
var selectedState = $(this).val();
if (cache[selectedState]) {
// render the options from the cache
} else {
$.getJSON(url, { id: selectedState }, function(response) {
// add to cache
cache[selectedState] = response;
.....
});
}
});
Finally, in response to your comments regarding doing it without ajax, you can pass all the cities to the view and assign them to a javascript array. I would only recommend this if you have a few countries, each with a few cities. Its a matter of balancing the slight extra initial load time vs the slight delay in making the ajax call.
In the controller
model.CityList = db.Cities.Select(d => new { City = d.CountryID, Text = d.CityName, Value = d.Id }).ToList();
In the view (script)
// assign all cities to javascript array
var allCities= JSON.parse('#Html.Raw(Json.Encode(Model.CityList))');
$('#StateID').change(function() {
var selectedState = $(this).val();
var cities = $.grep(allCities, function(item, index) {
return item.CountryID == selectedState;
});
// build options based on value of cities
});
This is a correct approach, but you can simplify your javascript:
function loadCities(obj) {
$.getJSON("/Home/GetCities", function (data) {
var html = '<option value="0">Select City</option>';
$(data).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
});
}
Further possible simplification:
Add the default item (Select City) server-side, so your javascript will be smaller.
Here's how I'd do it without the page refresh, assuming the list of cities isn't too long.
I'm assuming you can create a GetStatesAndCities method to return a Dictionary.
public ActionResult Index()
{
Dictionary<string, List<String>> statesAndCities = GetStatesAndCities();
ViewBag.StatesAndCities = Json(statesAndCities);
}
Then in the view:
var states = JSON.parse(#ViewBag.StatesAndCities);
function loadCities(obj) {
var cities = states[$(obj).val()];
var html = '<option value="0">Select City</option>';
$(cities).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'
});
$("#ddlCity").html(html);
}
This way when the state is changed the cities field with update immediately with no need for callback.
disclaimer: This is not a code answer, there are plenty other answers.
I think best way to keep yourself happy to seperate UI pages from data => turn them into API calls:
/GetCities
/GetStates
Now you can simply leave the select's empty on Razor rendering the page. And use a Jquery/Bootstrap plugin to create an AJAX select box.
This way when the user stops typing his search, this search string can than be send with the AJAX call (eg: /GetStates?search=test) and then a small result set can be send back to the website.
This gives:
Better separation in serveside code
Better User eXperience.
Smaller page loads (since you no longer send all the options to user when he requests the page, only when he opens the select box).
How about using Knockout?
Knockout is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model
You have to use ajax for your cities. But with knockout you dont need to write
var html = '<option value="0">Select City</option>';
$(responce).each(function () {
html += '<option value="'+this.Value+'">'+this.Text+'</option>'});
$("#ddlCity").html(html);
in your javascript.Knockout makes it simple.
You can simply write:
function CityModel() {
var self = this; // that means this CityModel
self.cities = ko.observableArray([]);
self.getCities = function () {
$.ajax({
url: "/Home/GetCities",
data: { id: $(obj).val() },
contentType: "application/json",
success: self.cities
});
}
}
ko.applyBindings(new CityModel());
thats all. But you have to bind your data into html elements.
Instead of using :
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity"})
You can use:
<select data-bind="options:cities,optionsValue:"Id",optionsText:"CityName",optionsCaption:"Select City""></select>
or you can mix razor and knockout:
#Html.DropDownListFor(m => m.CityId, Cities, "Select City", new { id="ddlCity",data_bind:"options:cities,optionsValue:\"Id\",optionsText:\"CityName\""})
One more thing you have to call GetCities when State changes, you can :
#Html.DropDownList("State", States, "Select State", new {data_bind:"event:\"change\":\"$root.GetCities\""})
Dont be scare with \"\" things this because " is an escape character and we have to say to razor i want to use " by using \ before it.
You can find more info about knockout :Knockout
And mixing with razor: Razor and Knockout
Ps: yes using knockout is suspend us from Razor and Mvc. You have to write another ViewModel . But like this situations ko is helpful. Mixing razor and knockout is another option for you.
I'm trying to figure out why the post functions at the end of the following code do not have access to the userID variable (I'm assuming it's a scope issue as logging userId immediately before the functions returns the correct value).
$.get("/set_languages_user", function(res) {
console.log(res)
if ( res.length === 0 ) {
var getUserInfo = $.get('/set_user', function(res){
var langConfirmSource = $('#language-confirmation-template').html();
var langConfirmCompiled = Handlebars.compile(langConfirmSource);
var langConfirmTemplate = langConfirmCompiled(res)
$('body').append(langConfirmTemplate)
$('html').toggleClass('disable_scrolling')
var userId = res.id
var native_language = res.native_language
var learning_language = res.learning_language
$(document).on('submit', '#language_confirmation', function(e){
e.preventDefault()
// prevent user from continuing if they haven't checked that they agree to the term's of use
if ( $('#touCheck').is(':checked')) {
console.log('checked!!!')
// this function finds the ID of the User's defined languages
var getUserInfo = $.get('/languages.json', function(lang){
// Find the ID of the languages the User is supporting in order to submit to languages_users db
for (i = 0; i < lang.length; i++) {
if (lang[i].language === native_language) {
var confirmedUserNativeInt = lang[i].id
}
}
for (i = 0; i < lang.length; i++) {
if (lang[i].language === learning_language) {
var confirmedUserLearningInt = lang[i].id
}
}
console.log(confirmedUserNativeInt)
console.log(confirmedUserLearningInt)
console.log(userId)
// creates a new instance in languages_user for the learningLanguage (level 1)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserLearningInt, user_id: userId, level: 1 }})
// creates a new instance in languages_user for the nativelanguage (level 5)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserNativeInt, user_id: userId, level: 5 } })
$('.signon_language_confirmation').remove()
$('html').toggleClass('disable_scrolling')
});
} else {
console.log('not checked!!!')
$('.wrapper_tou_signup').append('<p class="message_form_error">You must agree to Lexody\'s Terms of Use to continue.</p>')
}
})
});
}
})
Here is the handlebars template that is being rendered:
<script id="language-confirmation-template" type="text/x-handlebars-template">
<div class="signon_language_confirmation">
<p class="title_langconf">Welcome to</p>
<img src="">
<div class="wrapper_form_dark language_confirmation_form wrapper_form_sign_on">
<form id="language_confirmation">
<div class="form_section">
<div class="wrapper_input col_16_of_16">
<p>I speak {{native_language}} <svg class="icon_standard"><use xlink:href="#{{native_language}}"/></svg></p>
<p>I am learning {{learning_language}} <svg class="icon_standard"><use xlink:href="#{{learning_language}}"/></svg></p>
<div class="wrapper_tou_signup">
<p><input type="checkbox" name="tou" value="agree" id="touCheck"> I agree to Lexody's terms of use.</p>
</div>
<div class="submit_cancel">
<input type="submit" value="Submit" class="btn_primary submit">
</div>
</div>
</div>
</form>
</div>
</div>
When I submit I'm getting "Uncaught ReferenceError: userId is not defined(…)". How do I make that variable accessible to those functions and why is that variable not accessible but the others ('confirmedUserLearningInt' and 'confirmedUserNativeInt') are?
Thanks in advance.
you have not declared the var's somewhere where the post method can reach, as you can see in your code the vars are inside a if statement which is inside a for loop, you should declare the var before the for loop like this:
$.get("/set_languages_user", function(res) {
console.log(res)
if ( res.length === 0 ) {
var getUserInfo = $.get('/set_user', function(res){
var langConfirmSource = $('#language-confirmation-template').html();
var langConfirmCompiled = Handlebars.compile(langConfirmSource);
var langConfirmTemplate = langConfirmCompiled(res)
$('body').append(langConfirmTemplate)
$('html').toggleClass('disable_scrolling')
var userId = res.id
var native_language = res.native_language
var learning_language = res.learning_language
$(document).on('submit', '#language_confirmation', function(e){
e.preventDefault()
// prevent user from continuing if they haven't checked that they agree to the term's of use
if ( $('#touCheck').is(':checked')) {
console.log('checked!!!')
// this function finds the ID of the User's defined languages
var getUserInfo = $.get('/languages.json', function(lang){
// Find the ID of the languages the User is supporting in order to submit to languages_users db
var confirmedUserNativeInt; //<<<<<<<<<<<<<<
for (i = 0; i < lang.length; i++) {
if (lang[i].language === native_language) {
confirmedUserNativeInt = lang[i].id
}
}
var confirmedUserLearningInt;//<<<<<<<<<<<<<<<<
for (i = 0; i < lang.length; i++) {
if (lang[i].language === learning_language) {
confirmedUserLearningInt = lang[i].id
}
}
console.log(confirmedUserNativeInt)
console.log(confirmedUserLearningInt)
console.log(userId)
// creates a new instance in languages_user for the learningLanguage (level 1)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserLearningInt, user_id: userId, level: 1 }})
// creates a new instance in languages_user for the nativelanguage (level 5)
$.post( "/languages_users", { languages_user:{ language_id: confirmedUserNativeInt, user_id: userId, level: 5 } })
$('.signon_language_confirmation').remove()
$('html').toggleClass('disable_scrolling')
});
} else {
console.log('not checked!!!')
$('.wrapper_tou_signup').append('<p class="message_form_error">You must agree to Lexody\'s Terms of Use to continue.</p>')
}
})
});
}
})
I have two lists that are coming from an API that represent two different classes. I want to display the two lists according to their proprieties in one general list where the elements are sorted by their date.
I need to separate the two lists because the proprieties to display are different and they only share the Date.
I manage to display the two list separately but cannot merge the two... Does anyone have an idea on that? Thank you very much.
here is the .js and view:
.js:
function activityController($http) {
var vm = this;
vm.race= [];
vm.try= [];
vm.errorMessage = "";
vm.isBusy = true;
$http.get("/api/race")
.then(function (response) {
//Sucess
angular.copy(response.data, vm.race);
}, function (error) {
//Failure
vm.errorMessage = "Failed to load the data" + error;
})
$http.get("/api/try")
.then(function (response) {
//Sucess
angular.copy(response.data, vm.try);
}, function (error) {
//Failure
vm.errorMessage = "Failed to load the data" + error;
})
.finally(function () {
vm.isBusy = false;
});
}
View :
<div class="col-md-offset-7">
<div class="text-danger" ng-show="vm.errorMessage">{{ vm.errorMessage}}</div>
<wait-cursor ng-show="vm.isBusy"></wait-cursor>
<ul class="well" ng-repeat="activities in vm.race| orderBy: 'date':true">
<li> {{activities.title}}</li>
<li>Date : {{activities.date | date :'dd-MM-yyyy'}}</li>
<li>Temps : {{activities.time}}</li>
</ul>
<ul class="well" ng-repeat="activities in vm.try| orderBy: 'date':true">
<li> {{activities.person}}</li>
<li>Date : {{activities.date | date :'dd-MM-yyyy'}}</li>
<li>Temps : {{activities.type}}</li>
</ul>
The way I would do it is:
<ul class="well" ng-repeat="activities in vm.getRacesAndTrys()| orderBy: 'date':true">
<li> {{activities.title}}</li>
<li>Date : {{activities.date | date :'dd-MM-yyyy'}}</li>
<li>Temps : {{activities.time}}</li>
</ul>
With a function in your vm:
vm.getRacesAndTrys = function() {
var result = [];
for (var i = 0; i < vm.try.length; i++) {
var item = vm.try[i];
result.push({
title: item.person,
date: item.date,
time: item.type
});
}
for (var i = 0; i < vm.race.length; i++) {
result.push(vm.race[i]);
}
return result;
}
This will create a combined array and also convert all the try objects so that their fields match that of the race objects.
this is jquery function-
now i am able to pass the city name and save it to database but how to change locality with change in city name. i am zero at jquery.Unable to understand this line $.getJSON(localityUrl, { ID: $(this).val() }, function (data) { plzzz suggest me some changes to be made--
<script type="text/javascript">
$(document).ready(function () {
var localityUrl = '#Url.Action("FetchLocalities")';
var localities = $('#SelectedLocality');
$('#SelectedCity').change(function () { localities.empty();
subLocalities.empty();
$.getJSON(localityUrl, { ID: $(this).val() }, function (data) {
if (!data) {
return;
}
localities.append($('<option></option>').val('').text('Please select'));
$.each(data, function (index, item) {
localities.append($('<option></option>').val(item.Value).text(item.Text));
// localities.append($('<option data-lat=' + item.Latitude + ' data-lng=' + item.Longitude + '></option>').text(item.Text));
});
});
})
and my city drop down is like this ---------
<div class="editor-label">
#Html.LabelFor(model => model.SelectedCity)
</div>
<div class="editor-field">
<select id="SelectedCity" name="SelectedCity">
#foreach (var thisCity in Model.CityList)
{
<option value="#thisCity.Name" data-lat="#thisCity.Latitude" data-long="#thisCity.Longitude" data-name="#thisCity.Name" >#thisCity.Name</option>
}
</select>
#Html.ValidationMessageFor(model => model.SelectedCity)
</div>
and my cities in the service layer are like this---
public List<City> FetchCities()
{
List<City> cities = new List<City>();
cities.Add(new City() { Id = 1, Name = "--Select Your City--", Latitude = 28.6139M, Longitude = 77.2090M });
cities.Add(new City() { Id = 2, Name = "Faridabaad", Latitude = 28.4211M, Longitude = 77.3078M });
return cities;
}
and my localities are like this---
public List<Locality> FetchLocalities()
{
List<Locality> localities = new List<Locality>();
localities.Add(new Locality() { Id = 1, CityName = "Faridabaad", Name = "East Faridabaad" });
localities.Add(new Locality() { Id = 2, CityName = "Faridabaad", Name = "West Faridabaad" });
return localities;
}
now my controller is something like this to fetch localities--
public JsonResult FetchLocalities(string name)
{
var data = _localityService.FetchLocalities()
//.Where(l => l.CityId == Id)
.Where(l => l.CityName == name)
.Select(l => new { Value = l.CityName, Text = l.Name });
return Json(data, JsonRequestBehavior.AllowGet);
}
localityUrl is the url your calling- in your case it would be var localityUrl = '#Url.Action("FetchLocalities", "yourControllerName")';
{ ID: $(this).val() } is the data your passing to the controller, in your case it needs to be { name: $(this).val() } because your method has parameter string name (not ID) and $(this).val() equates to the value of the selected option
and data in function (data) is the data your returning back from the controller method, in your case a collection of objects containing 2 properties, Value and Text
Instead of using $.getJSON() you can make an ajax call to your controller action and reload all the localities separately by passing the desired parameter.