Checkboxes with array model in angularjs using asp.mvc - javascript

I am using Asp.MVC 5 for an application and I want to generate many checkboxes with different angularjs models, and I thought the best option is by using array model in angularjs. I tried the code below inside a foreach:
#{
int i = 0;
foreach (var selectedVesselViewModel in Model.SelectedVesselViewModels)
{
using (Html.BeginForm("SelectNotificaiton", "Admin", new { area = "DashBoard" }, FormMethod.Post, new { id = "filterVesselsForm_" + i}))
{
#Html.HiddenFor(item => selectedVesselViewModel.VesselId, new {ng_model= "SelectedVessels[" + i + "].VesselId" })
<li class="row">
<div class="col-md-10">
<a href="#" class="text-admin-area">
#selectedVesselViewModel.VesselName
</a>
</div>
<div class="col-md-2">
<div class="pull-right">
<div class="checkbox checkbox-inline">
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng_model = "SelectedVessels[" + i + "].Selected"
})
<label for="SelectedVesselViewModels_#(i++)__Selected"></label>
</div>
</div>
</div>
</li>
}
}
}
i variable is an incrementing variable:
in the angularjs controller I have something like this:
(function (app) {
"use strict";
app.controller("DashboardCtrl", ['$scope',
function ($scope) {
function init() {
// $scope.SelectedVessels = [];
}
$scope.SelectedVessels = [];
init();
$scope.RefreshSideBarVessels = function() {
angular.forEach($scope.SelectedVessels, function (value, key) {
alert($scope.SelectedVessels[key].VesselId);
});
}
}]);
})(adminModule);
When I use angularjs foreach loop the $scope.SelectedVessels seems to be empty but I dont know why!
angular.forEach($scope.SelectedVessels, function (value, key) {
alert($scope.SelectedVessels[key].Selected);
});
Does anybody know where is the problem, why I cant access the inner properties of the $scope.SelectedVessels array and why it is empty ?

How you are adding values to your array ie. $scope.SelectedVessels is important
Please have a look at below example.
var values = {name: 'Raja', gender: 'male'};
var log = [];
angular.forEach(values, function(value, key) {
this.push(key + ': ' + value);
}, log);
expect(log).toEqual(['name: Raja', 'gender: male']);

Here is the solution to this problem:
I had to use ng-init to each checkbox to instantiate the ng-model.
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng_model = "SelectedVessels[" + i + "].Selected",
ng_init = "SelectedVessels[" + i + "].Selected="+ selectedVesselViewModel.Selected.ToString().ToLower()
})

First off , its ng-model not ng_model (- vs _) but that could be typo.
Second, try this code
$scope.onChange = function (index, value) {
$scope.SelectedVessels[index] = value;
}
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
SelectedVessels[i] = selectedVesselViewModel.Selected
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng-model = "SelectedVessels[" + i + "].Selected",
on-change="onChange(i,selectedVesselViewModel.Selected)
})

Related

I need to replace ActionLink for Dropdownlist

I'm having a foreach that it gives me a list of values that when click it call a controller:
#foreach (var item in Model)
{
<div>#Html.ActionLink(item.Text, "UpdateController",
new { subSectionID = item.Value, subsectionName = item.Text })</div>
}
I would like to do this but now using a dropdown list where clicking on the value redirects me to the controller.
If someone knows how to do it or do it in some other way, maybe using Select in html, it would help me, thanks!
Try the following:
<script type="text/javascript">
$('#subsec').change(function () {
var url = $(this).val();
if (url != null && url != '') {
window.location.href = url;
}
});
</script>
#Html.DropDownListFor(m => Model.GetEnumerator().Current,
Model.Select(d =>
{
return new SelectListItem() {
Text = d.Text,
Value = Url.Action("Your_Action_Name", "Your_Controller_Name", new { subSectionID = d.Value, subsectionName = d.Text })
};
}),
"-Select a value-",
new { id = "subsec" })
A similar solution you can find here: https://stackoverflow.com/a/6088047/6630084

How to set default selected text in ng-select or ng-options?

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];

cascading the dropdown menu

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.

need help to resolve - Uncaught ReferenceError: data is not defined

I know there are many questions/tutorials for this subject, but cannot solve my problem.
I have to ask for your help. Second day cannot find out the solution to this simple problem.
I am trying as in this tutorial - http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/cascading-dropdownlist-in-Asp-Net-mvc/
That is working fine, but once i try from DB, i am getting error "Uncaught ReferenceError: data is not defined"
Here is my web page
#model testEmpty.Models.Address
#{
ViewBag.Title = "Create";
}
#Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/myScripts/myScripts.js"></script>
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Address</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group col-md-10">
#Html.Label("Zone")
#Html.DropDownList("ZoneId", ViewBag.ZoneName as SelectList, "--Select a Zone--", new { id = "ZoneId" })
#Html.ValidationMessage("Zone", "*")
</div>
<div class="form-group">
<div class="col-md-10">
#Html.Label("Districts of SZ")
<select id="DistrictSZ" name="DistrictSZ"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Controller
private myContext db = new myContext();
// GET: Addresses
public ActionResult Index()
{
var zones = db.Addresses.Include(a => a.Zone);
ViewBag.ZoneName = new SelectList(zones, "Value", "Text");
return View(zones.ToList());
}
public JsonResult DistrictList(int id)
{
var district = from s in db.Districts
where s.ZoneId == id
select s;
return Json(new SelectList(district.ToArray(), "ZoneId", "Name"), JsonRequestBehavior.AllowGet);
}
Script
$(function () {
$('#ZoneId').change(function () {
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts (data));
});
});
function getDistricts(data) {
var items = '<option>Select a District</option>';
$.each(data, function (i, district) {
items += "<option value='" + district.Value + "'>" + district.Text + "</option>";
});
$('#DistrictSZ').html(items);
}
As i understand, my problem is with JSON. what am I doing wrong?
Firstly you do not need to return a SelectList (javascript knows nothing about a c# class)
public JsonResult DistrictList(int id)
{
var district = db.Districts.Where(d => d.ZoneId == id).Select(d => new
{
Value = d.ZoneId, // this look wrong - see note below
Text = d.Name
});
return Json(district, JsonRequestBehavior.AllowGet);
}
Then in your script
var url = '#Url.Action("DistrictList")'; // ensure your url's are properly generated
var districts = $('#DistrictSZ'); // cache it
$('#ZoneId').change(function () {
$.getJSON(url, { id: $(this).val() }, function (data) {
districts.empty(); // remove existing options
districts.append($('</option>').val('').text('Select a District'));
$.each(data, function (i, district) {
districts.append($('</option>').val(district.Value).text(district.Text));
});
});
});
In fact, since ZoneId is always the same, you could just return a collection of the Name values
var district = db.Districts.Where(d => d.ZoneId == id).Select(d => d.Name);
and
$('#ZoneId').change(function () {
var zoneID = $(this).val();
$.getJSON(url, { id: zoneID }, function(data) {
districts.empty(); // remove existing options
districts.append($('</option>').val('').text('Select a District'));
$.each(data, function (i, district) {
districts.append($('</option>').val(zoneID).text(district));
});
});
});
However your code is generating all options with the same value (ZoneId) which does not make much sense, so I suspect you really want to use another property of District - i.e. its Id (or DistrictId?) property.
You're passing the returned value of getDistricts to the callback variable of $.getJSON.
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts (data));
You need to pass the function reference like this
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts);
maybe you should handle your callback function with a anonymous function like this:
$.getJSON('DistrictList/' + $('#ZoneId').val(), success(data){
getDistricts(data);
})

How to mark checkbox as checked in Angular controller

I have a form, which I'm using to enter new service requests, as well as display and edit those requests. A part of this form is a list of labeled check-boxes, representing all countries.
When the existing request is displayed using this form, I need to be able to compare each country check-box with a list of countries, which were initially selected, and marked each match as "checked". Another words, I need to restore the state of the check-box list to reflect what was checked originally. Should this type of logic handled in the controller by iterating over two nested loops (all countries Vs Selected countries), or is there a better way to do this using directives?
Here is my check-box list:
<div class="form-group">
<label for="selectbasic">What country is the data for</label>
<div>
<div style='height:100px;overflow-y:auto;border:solid 1px #aaa;'>
<div ng-repeat="item in countries">
<input type='checkbox' ng-model="item.checked" ng-change="checkit()" /> {{item.name}}
</div>
</div>
</div>
</div>
And here is the part of my controller in which I may be able to handle this:
function getServiceRequestById(Id) {
dataFactory.getServiceRequestById(Id)
.success(function (request) {
$scope.OID = request.OID;
$scope.Description = request.Description;
$scope.RequestorName = request.RequestorName;
$scope.RequestorBusinessUnit = request.RequestorBusinessUnit;
$scope.CustomerName = request.CustomerName;
$scope.CscContactPerson = request.CscContactPerson;
$scope.IsWbsCodeAvailable = request.IsWbsCodeAvailable;
$scope.SalesforceIdNumber = request.SalesforceIdNumber;
$scope.ProjectCtv = request.ProjectCtv;
$scope.RequestedCompletionDate = request.RequestedCompletionDate;
$scope.ToBeUsedForCloudMigration = request.ToBeUsedForCloudMigration;
$scope.ToBeUsedForDatacenterMove = request.ToBeUsedForDatacenterMove;
$scope.ToBeUsedForServerRefresh = request.toBeUsedForServerRefresh;
$scope.DataRequirements = request.DataRequirements;
$scope.DataProtectionRequirements = request.DataProtectionRequirements;
$scope.ProjectedDataAvailability = request.ProjectedDataAvailability;
$scope.DiscoveryLeadName = request.DiscoveryLeadName;
$scope.SelectedCountries = request.SelectedCountries;
$scope.ManualDiscovery = request.ManualDiscovery;
$scope.AutomatedDiscovery = request.AutomatedDiscovery;
$scope.DataLoadUsingMasterTemplate = request.DataLoadUsingMasterTemplate;
$scope.DataLoadUsingAutomatedInterface = request.DataLoadUsingAutomatedInterface;
$scope.DataLoaderRequiresSitizenship = request.DataLoaderRequiresSitizenship;
var list = [];
var countries = request.SelectedCountries.split(',');
console.log('number of countries: ' + countries.length);
console.log('countries[0]: ' + countries[0] + ' --- ' + countries[1]);
$scope.checkit = function () {
for (var p in $scope.countries) {
if ($scope.countries[p].checked) {
list.push($scope.countries[p].name);
console.log("selected country: " + $scope.countries[p].name + " " + $scope.ProjectedDataAvailability);
}
} return list;
}
console.log('EditServiceRequestCtrl request : ' + request);
})
.error(function (error) {
console.log('getServiceRequestById returned error ');
});
}
Try something like this:
function getServiceRequestById(Id) {
dataFactory.getServiceRequestById(Id)
.success(function (request) {
$scope.data = request;
$scope.selectecCountries = []; //make sure to clear selections
$scope.countries = request.SelectedCountries.split(',');
});
}
$scope.updateSelectedCountries = function() {
var list = [];
angular.forEach($scope.countries, function(country) {
if(country.selected) list.push(country);
});
$scope.selectedCountries = list;
};
Then in your view:
<div ng-repeat="country in countries track by $index">
<input type="checkbox" ng-model="country.selected" ng-change="updateSelectedCountries()"/>
</div>
<h4>Demo Output</h4>
<pre>{{ selectedCountries | json}}</pre>
It looks like you are getting a list of countries, where each item has a "checked" member.
I'm also assuming you want to display all countries, not just the checked ones.
If that's the case, it's pretty simple.
<div ng-repeat="item in countries">
<input type='checkbox' ng-model="item.checked" /> {{item.name}}
</div>
$scope.countries = [ {name: "USA", checked: true},
{name: "GBR", checked: false},
{name: "GER", checked: true}];
See a working plunker.

Categories