Binding Viewbag Data to Angular JS - angularjs

I have a List in my controller which is being of type Student(class in the model)
public class DefaultController : Controller
{
// GET: Default
public ActionResult Index()
{
List<Student> obj = new List<Student>() {
new Student() { ID=1,Name="titi",Address="bbsr"},
new Student() { ID=1,Name="titi1",Address="bbsr"},
new Student() { ID=1,Name="titi2",Address="bbsr"}
};
ViewBag.data = obj;
return View();
}
}
I am using Angular JS (Beginner to Angular JS)
<html>
<head>
<title>Index</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-app="EFView">
#{ var a = ViewBag.data;}
<div ng-init="init(#Html.Raw(a)">
<table>
<tr ng-repeat="x in a">
<td >
{{x.ID}}
</td>
<td>
{{x.Name}}
</td>
<td>
{{x.Address}}
</td>
</tr>
</table>
</div>
</body>
</html>
Not getting the output as expected.. where & what I am missing, I tried with all trial

Related

Click flag to highlight issue

I have a table that lists various fields from a customer database. I'd like to add a new column with a grey flag (indicates no issues) If the user clicks the flag I'd like the flag to turn red (indicates there is an issue)
I'm using MVC, Angularjs and Font Awesome.
Could someone point me in the best direction please?
using System;
using System.Data.Entity;
using System.Linq;
using System.Web.Mvc;
using Florence.Authentication;
using Florence.Data;
using Florence.Website.Models;
using Florence.Website.Models.Job;
namespace Florence.Website.Controllers
{
/// <summary>
/// </summary>
public class JobController : Controller
{
/// <summary>
/// Search jobs
/// </summary>
/// <returns>Job list</returns>
[AuthorizationFilter(PermissionList = "CanListJobs")]
public ActionResult Index()
{
return View("~/views/job/index.cshtml");
}
[AuthorizationFilter(PermissionList = "CanViewJobs", AllowLocalRequests = true)]
public ActionResult PdfView(int id)
{
using (var context = new FlorenceContext())
{
var job = context.Jobs
.Include(c => c.Customer)
.Include(c => c.Customer.Address)
.First(c => c.Id == id);
if (!HttpContext.Request.IsLocal && job.BelongsToCompanyId != DataBag.LoggedOnCompany.Id)
{
return new HttpUnauthorizedResult();
}
return View("~/views/job/pdf/view.cshtml", job);
}
}
It depends on your table structure, but you need to create either a new property in your array, for each row, or a new array with the same length as the original one. Then simply add a new column and detect any changes to that new property/array.
Here is a simple demo (click on text Icon to change the flag):
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.array = [
{"ID":12345,"Details":"ABC"},
{"ID":23456,"Details":"BCD"},
{"ID":34567,"Details":"CDE"},
{"ID":45678,"Details":"DEF"}
];
// a new array of the same length (a `map` of it)
$scope.flags = $scope.array.map(function(_){return false;});
$scope.submit = function(){
console.log($scope.flags); // (extra)
}
});
table, th, td {
border: 1px solid black;
}
.red {
color: red;
}
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<form ng-submit="submit()">
<table>
<tr>
<th ng-repeat="(key,value) in array[0]">
{{key}}
</th>
<th>
Flag
</th>
</tr>
<tr ng-repeat="data in array">
<td ng-repeat="(key,value) in data">
{{value}}
</td>
<td>
<span ng-click="flags[$index] = !flags[$index]">
<i ng-class="{'red':flags[$index]}">Icon</i>
</span>
</td>
</tr>
</table>
<!-- (extra) -->
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>

Unexpected End of Expression when used with #Html.Raw(Model)

I am trying to use AngularJs with ASP.NET MVC - this is my first attempt.
Index.html
#model string
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container" ng-init="courses = [{'name':'first'},{'name':'second'},{'name':'third'}]">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="course in courses">
<td>{{ course.name }}</td>
</tr>
</tbody>
</table>
_Layout.cshtml
<!DOCTYPE html>
<html ng-app>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<script src="~/Scripts/angular.min.js"></script>
<title></title>
</head>
<body>
#RenderBody()
</body>
</html>
Above works fine and grid is displayed with Name as header and first, second and third as 3 rows. So my next step is to use
courses = #Html.Raw(Json.Encode(Model))
instead of
courses = [{'name':'first'},{'name':'second'},{'name':'third'}]
CourseController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace AngularJsMvc.Controllers
{
public class CoursesController : Controller
{
// GET: Courses
public ActionResult Index()
{
return View("Index", "", "[{'name':'first'},{'name':'second'}, {'name':'third'}]"); //This works fine when used with #Html.Raw(Model) in index.html
//return View("Index", "", GetCourses()); //This doesn't work when used with with #Html.Raw(Model) in index.html
}
public string GetCourses()
{
var courses = new[]
{
new Course { Name = "First" },
new Course { Name = "Second" },
new Course { Name = "Third" }
};
var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
return JsonConvert.SerializeObject(courses, Formatting.None, settings);
}
}
public class Course
{
public string Name { get; set; }
}
}
This works fine if I use
return View("Index", "", "[{'name':'first'},{'name':'second'},{'name':'third'}]");
But if I use
return View("Index", "", GetCourses());
Then, below is the error I get. Please help - I have been struggling for almost entire day yesterday. I tried with or without Json.Encode
angular.min.js:123 Error: [$parse:ueoe]
http://errors.angularjs.org/1.6.4/$parse/ueoe?p0=courses%20%3D
at angular.min.js:6
"<div class="container" ng-init="courses = " [{\"name\":\"first\"},{\"name\":\"second\"},{\"name\":\"third\"}]""="">"
The following worked for me:
<div class="container" ng-init="courses = #Newtonsoft.Json.JsonConvert.DeserializeObject(Model)">
This also works:
<div class="container" ng-init="courses = #HttpUtility.HtmlDecode(Model)">
It's all about how angular treats the object it tries to parse and since you're passing an HTML decoded string it will treat as a string and therefore it won't be able to iterate threw it.

Trying to populate data in ASP.Net controller and fetch it view using angularjs

I am trying to populate data through controller and display it in view using angular js. I am using a function to return JSON data and use the data in the view.However i am not getting the data due to some error.
Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Angular4DotnetMvc.Controllers
{
public class CourseController : Controller
{
// GET: Course
public ActionResult Index()
{
return View("Index","",GetCourses());
}
private object GetCourses()
{
var courses = new []{
new CourseVm {Number = "1", Name = "Science", Instructor= "Sai"},
new CourseVm {Number = "2", Name = "Geography", Instructor= "Ram"}
};
var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver()};
return JsonConvert.SerializeObject(courses, Formatting.None, settings);
}
}
public class CourseVm
{
public string Number { get; set; }
public string Name { get; set; }
public string Instructor { get; set; }
}
}
Index.cshtml
#model string
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container" ng-app>
<div class="row">
<table class="table table-condensed table-hover">
<tr ng-init="courses = #Html.Raw(Model)">
<th>Course</th>
<th>Course Name</th>
<th>Instructors</th>
</tr>
<tr ng-repeat="course in courses">
<td>{{course.Number}}</td>
<td>{{course.Name}}</td>
<td>{{course.Instructor}}</td>
</tr>
</table>
</div>
</div>
Layout.cshtml
<html>
<head>
<title>Angular4DotNet</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="~/Scripts/jQuery/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/bootstrap/bootstrap.js"></script>
<link href="~/Scripts/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/Scripts/bootstrap/bootstrap.css" rel="stylesheet" />
#RenderSection("JavaScriptInHeader",required:false)
</head>
<body ng-app>
#RenderBody()
</body>
</html>
I am getting the following error:
Error: [$parse:ueoe] http://errors.angularjs.org/1.6.1/$parse/ueoe?p0=courses%20%3D%20%5B%7B
Why the data binding not happening?
The error is :
I am not sure why ="" after "instructor":"ram"}] is being added in the end in #Html.Raw(Model). i believe because of this it fails and agular cannot parse.
I would do on this way:
Create an action just to return the json content:
// GET: Course
public ActionResult Index()
{
return View();
}
public ActionResult GetCourses()
{
var courses = new []{
new CourseVm {Number = "1", Name = "Science", Instructor= "Sai"},
new CourseVm {Number = "2", Name = "Geography", Instructor= "Ram"}
};
return Json(courses, JsonRequestBehavior.AllowGet)
}
Then create an Angular controller:
angular.module('yourApp').controller('CoursesCtrl', ['$scope',function($scope)
{
$scope.courses = [];
$scope.loadCourses = function () {
$http.get('/Course/GetCourses').then(function (response) {
$scope.courses = response.data;
}, function (data) {
//error
});
}
}]);
After that insert the controller in the view:
<div class="container" ng-app="yourApp">
<div ng-controller="CoursesCtrl">
<div class="row">
<table class="table table-condensed table-hover" data-ng-init="loadCourses();">
<tr>
<th>Course</th>
<th>Course Name</th>
<th>Instructors</th>
</tr>
<tr ng-repeat="course in courses">
<td>{{course.Number}}</td>
<td>{{course.Name}}</td>
<td>{{course.Instructor}}</td>
</tr>
</table>
</div>
</div>
</div>
I hope this can help you.

Displaying data using Bootstrap modal/angularjs from asp.net webapi

I'm new to bootstrap. I want to do CRUD operations on the employee data from asp.net WebAPI using Bootstrap-Modal. I'm able to display the data from webapi to angularJS using a table(ng-repeat). In every row, at the end, I've three buttons VIEW, DELETE and EDIT and another outside the table ADD.
I want, whenever a user clicks on the ADD, VIEW, DELETE and EDIT button, a bootstrap modal should pop up and we should be able to perform CRUD operations.
I've tried many instances but no luck on how to get the data on Modal. Please help.
The code is as follows:
WEBAPI:
public class EmployeeService
{
SampleDatabaseEntities sampleDBEntities = new SampleDatabaseEntities();
//ADD USER
public int saveEmployee(EmployeeTable employeeTable)
{
sampleDBEntities.EmployeeTables.Add(employeeTable);
sampleDBEntities.SaveChanges();
return employeeTable.E_ID;
}
public EmployeeTable getEmployeeById(int id)
{
return sampleDBEntities.EmployeeTables.Find(id);
}
public List<EmployeeTable> getEmployees()
{
return sampleDBEntities.EmployeeTables.ToList();
}
public void updateEmployee(int x, EmployeeTable employeeTable)
{
if (employeeTable.E_ID == x)
{
sampleDBEntities.Entry(employeeTable).State = EntityState.Modified;
sampleDBEntities.SaveChanges();
}
}
public void deleteEmployee(int id)
{
var employee = sampleDBEntities.EmployeeTables.Find(id);
if(employee !=null)
{
sampleDBEntities.Entry(employee).State = EntityState.Deleted;
sampleDBEntities.SaveChanges();
}
}
Angular Service:
angular.module('mainApp', []).
factory('employeeService', function ($http) {
var baseAddress = 'http://localhost:53254/api/employee/';
//var baseAddress = 'http://localhost:49595/MobileService/api/UserService/';
var url = "";
return {
getEmployeesList: function () {
url = baseAddress;
return $http.get(url);
},
getUser: function (employee) {
url = baseAddress + "Get/" + employee.E_id;
return $http.get(url);
},
addUser: function (employee) {
url = baseAddress + "post";
return $http.post(url, employee);
},
deleteUser: function (employee) {
url = baseAddress + "Delete/" + employee.E_Id;
return $http.delete(url);
},
updateUser: function (employee) {
url = baseAddress + "put/" + employee.E_Id;
return $http.put(url, employee);
}
};
});
Angular Controller:
angular.module('mainApp')
.controller('getEmployeeCrl', ['$scope', 'employeeService', function ($scope, employeeService) {
employeeService.getEmployeesList().then(function (response) {
$scope.employees = response.data;
}, function (err) {
$scope.errMessage = "Something wrong with server. Please try again.";
})
}]);
HTML:
<!DOCTYPE html>
<html ng-app="mainApp">
<head>
<title></title>
<meta charset="utf-8" />
<script src="../Scripts/angular.js"></script>
<script src="../mainApp.js"></script>
<script src="../Utilities/ConstantsFactory.js"></script>
<script src="../Services/EmployeeService.js"></script>
<script src="../Controllers/EmployeeController.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body ng-controller="getEmployeeCrl">
<div>
<h2 style="text-align:center; color:darkblue">PROJECT 51</h2>
</div>
<div class="container">
<div style="background-color:dimgray;color:white;padding:20px;">
<input type="button" value="Go to Employees" class="btn btn-info" />
<input type="button" value="Go to Clients" class="btn btn-info" style="width:145px" />
<button class="glyphicon glyphicon-plus btn btn-primary" value="Add" data-toggle="tooltip" data-placement="top" title="Add Data" style="float:right; width:50px"></button>
</div>
<br />
<table class="table table-bordered table table-condensed" ng-hide="!employees">
<thead style="background-color:palevioletred">
<tr style="text-decoration:solid;color:darkblue;">
<th>Id</th>
<th>Name</th>
<th>Job</th>
<th>Hire Date</th>
<th>Manager</th>
<th>Salary</th>
<th>Commission</th>
<th colspan="2">Edit/Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="emp in employees ">
<td>{{emp.E_ID}}</td>
<td>{{emp.E_NAME}}</td>
<td>{{emp.E_JOB}}</td>
<td>{{emp.HIRE_DATE}}</td>
<td>{{emp.MANAGER_ID}}</td>
<td>{{emp.SALARY}}</td>
<td>{{emp.COMMISSION}}</td>
<td colspan="2" style="width:170px">
<input type="button" ng-model="emp.E_Id" value="View" class="btn btn-primary" style="width:70px" />
<input type="button" value="Edit" class="btn btn-primary" style="width:70px" />
<input type="button" value="Delete" class="btn btn-primary" style="width:70px" />
</td>
</tr>
</tbody>
</table>
<p class="alert alert-danger" ng-show="!employees">{{errMessage}} <span class="glyphicon glyphicon-refresh" ng-show="!employees"></span></p>
</div>
</body>
</html>
How can I make use of Bootstrap Modal for CRUD operations

can not add text box input in table

I have the following code :
http://plnkr.co/edit/RqLurBaCsgjQjOYMtl8r?p=preview
here there is a textbox and when user add something to the textbox and push add button then the entered text should be added to the table Here is my javaScript code:
var app = angular.module('app', []);
app.factory('Service', function() {
var typesHash = [ {
id : '1',
name : 'lemon',
price : 100,
unit : 2.5
}, {
id : '2',
name : 'meat',
price : 200,
unit : 3.3
} ];
var service = {
addTable : addTable,
getData : getData,
};
return service;
function addTable(data) {
typesHash.push(data);
}
function getData() {
return typesHash;
}
});
app.controller('table', function(Service) {
//get the return data from getData funtion in factory
this.typesHash = Service.getData();
this.testData = {
id : '1',
name : "test",
price : 100,
unit : 2.5
};
//get the addtable function from factory
this.addTable = Service.addTable;
});
here as far as testData is static as follow it works:
this.testData = {
id : '1',
name : "test",
price : 100,
unit : 2.5
};
but here the text in the textbox is not added so I changed the above code as follow:
this.testData = {
id : '1',
name : $("#txt").val(),
price : 100,
unit : 2.5
};
the name gets nothing and row is added but name spot is empty?
Just a quick note that this is a simpler version of my real code and I have a reason to use factory.
Can ahyone help me to find out why this table does not connect to textbox correctly?
Modified version of the plnkr (ooo nice design changes SO).
Updated pasted a bad plnkr link before.
http://plnkr.co/edit/4g7LGRLBNEH2LeuEm1qN?p=preview
code from the post, let me know if this doesn't cover some scenario you were imagining. I tried getting rid of all the style cruft, that should be done in CSS or using things like text-right or text-center provided by bootstrap.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link data-require="bootstrap#*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<title>Insert title here</title>
<script>
var app = angular.module('app', []);
app.factory('Service', function() {
var typesHash = [ {
id :1,
name : 'lemon',
price : 100,
unit : 2.5
}, {
id : 2,
name : 'meat',
price : 200,
unit : 3.3
} ];
var localId = 3;
var service = {
addTable : addTable,
getData : getData,
};
return service;
function addTable(name) {
typesHash.push({id:localId++, name:name, price:100,unit:1});
}
function getData() {
return typesHash;
}
});
app.controller('table', function(Service) {
//get the return data from getData funtion in factory
this.typesHash = Service.getData();
//get the addtable function from factory
this.addTable = Service.addTable;
});
</script>
</head>
<body ng-app="app" ng-controller="table as tableTools">
<form>
<div class="row commonRow">
<div class="col-xs-1 text-right">
item:
</div>
<div class="col-xs-5">
<input id="txt" type="text" style="width: 100%;" ng-model="tableTools.inputData" />
</div>
<div class="col-xs-2">
<button class="btn btn-primary" ng-click="tableTools.addTable(tableTools.inputData);tableTools.inputData=''">
click me
</button>
</div>
</div>
</form>
<div class="row commonRow">
<div class="col-xs-1"></div>
<div class="col-xs-10">
<table class="table table-hover">
<thead>
<tr>
<th>item</th>
</tr>
</thead>
<tbody ng-controller="table as iterateTb">
<tr ng-repeat="x in iterateTb.typesHash track by x.id">
<td>
<div>{{x.name}}</div>
</td>
<td>
<input type="text" ng-model="x.name"/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
here is the updated plunker :-
http://plnkr.co/edit/uDIEAjRtpM7MnQu72LAA?p=preview
I just added data.name=$("#txt").val(); before pushing the data into array.
function addTable(data) {
data.name=$("#txt").val();
typesHash.push(data);
}
Hope it helps :-)

Resources