AngularJs datatable dynamic table change - javascript

I am working on a project and i want to do some things which are new to me. I am new in AngularJS and newer in angular data tables.
I got angular data table from here and is a little bit tricky for me because i don't really know how to use it. Examples are not very explanatory for me.
What i want to do:
i have a sigle page with some checkboxes on the left
on the right i want a data table with data provided by server after user clicks on a checkbox
data table must change dinamicaly because depends on the request i have other headers for data table. For example when user click on "role" objects returned have only 2 fields id and role, i want to render role column but not id. When user clicks on "users" data returned by server has multiple objects which have much more fields, for example : "accNonExp", "accNonLocked", "email", "username" and others.
How can i do this ?
here is my conde right now :
js :
depo.controller('masterMainController', ['$scope', '$http', function ($scope, $http) {
$scope.listOfTables = null;
$scope.tableData = {};
$scope.onClick = function(){
$scope.tableData = getTableData($scope.valueSelected);
};
$http.post('/master/listOfTables').success(function (response) {
$scope.listOfTables = response;
console.log(response);
});
function getTableData(table) {
$http.post('/master/tableData/' + table).success(function (response) {
console.log(response);
return response;
});
}
$scope.dataTable = function(DTOptionsBuilder, DTColumnBuilder) {
var vm = this;
vm.dtOptions = DTOptionsBuilder.fromJson($scope.tableData)
.withPaginationType('full_numbers');
/* vm.dtColumns = [
DTColumnBuilder.newColumn('id').withTitle('ID'),
DTColumnBuilder.newColumn('firstName').withTitle('First name'),
DTColumnBuilder.newColumn('lastName').withTitle('Last name').notVisible()
];*/
}
}]);
JSP:
<%# include file="/WEB-INF/views/includes/onlyForLoggedUsers.jsp" %>
<html>
<head>
<title>Main Master</title>
</head>
<script content="text/javascript" src="/res/custom_script/admin/masterMain.js"></script>
<body ng-app="depo">
<div class="container-fluid" ng-controller="masterMainController">
<p class="logout_paragraph">Logged as <strong>${pageContext.request.userPrincipal.name}</strong> | <a
id="logout_link" onclick="formSubmit()">Logout</a></p>
<form action="/logout" method="post" id="logoutForm" style="display: none;">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
<div class="jumbotron">
<h2>Welcome !</h2>
</div>
<div>
<div id="divChkListOfTables" class="admin_left_menu pre-scrollable col-md-2">
<div id="chkListOfTables" class="admin_tables_list radio">
<h4>Tables</h4>
<label ng-repeat="table in listOfTables.tables" class="admin_tables_list_chk_box">
<input type="radio" name="chkTablesRadio" ng-model="$parent.valueSelected" ng-change="onClick()"
ng-value="table" class="radio-button"> {{table}}
</label>
</div>
</div>
<div id="admin_data_table" class="col-md-10">
<table datatable="dataTable" dt-options="masterMainController.dtOptions" dt-columns="masterMainController.dtColumns" class="row-border hover">
</table>
</div>
</div>
</div>
</body>
</html>
Spring RestController:
#RestController
#RequestMapping(value = "/master")
public class MasterMainRest {
#Autowired
UnitService unitService;
#Autowired
RoleService roleService;
#Autowired
UsersService usersService;
#RequestMapping(value = "/listOfTables", method = RequestMethod.POST)
public MasterTablesDTO getListOfTables(){
List<String> tables = new ArrayList<>();
tables.add("unit");
tables.add("role");
tables.add("users");
MasterTablesDTO masterTablesDTO = new MasterTablesDTO();
masterTablesDTO.setTables(tables);
return masterTablesDTO;
}
#RequestMapping(value = "/tableData/{table}", method = RequestMethod.POST)
public List getTablesData(#PathVariable String table){
List list = null;
switch (table){
case "unit":
list = unitService.findAll();
break;
case "role":
list = roleService.findAll();
break;
case "users":
list = usersService.findAll();
break;
}
return list;
}
}
When i reach this page i gat this error :
TypeError: Cannot read property 'aDataSort' of undefined
at U (jquery.dataTables.min.js:63)
at xa (jquery.dataTables.min.js:67)
at HTMLTableElement.<anonymous> (jquery.dataTables.min.js:91)
at Function.n.extend.each (jquery-2.1.3.min.js:2)
at n.fn.n.each (jquery-2.1.3.min.js:2)
at m [as dataTable] (jquery.dataTables.min.js:83)
at h.fn.DataTable (jquery.dataTables.min.js:159)
at Object.g [as renderDataTableAndEmitEvent] (angular-datatables.min.js:6)
at Object.h [as doRenderDataTable] (angular-datatables.min.js:6)
at Object.d.render (angular-datatables.min.js:6)
Yes i know this error is beause $scope.tableData is empty, or this is what i read on some forums.
How can i make first checkbox checked and $scope.tableData loaded with data acording to that checkbox checked ?
Thank you in advance !

Since the getTableData(table) function isn't returning any value $scope.tableData is undefined as you mentioned. This is because of the AJAX request being asynchronous.
To fix this you have to supply a callback to the $http success where you fill the $scope.tableData. To learn more about promises checkout angulars documentation for the q implementation:
https://docs.angularjs.org/api/ng/service/$q
Something like this should fix it.
$scope.onClick = function(){
getTableData($scope.valueSelected).success(function(response) {
$scope.tableData = response.data
});
};
function getTableData(table) {
return $http.post('/master/tableData/' + table);
}

Related

Use MVC Session to store Client-side values (e.g. filter text) between visits

In an MVC View, is there an efficient way to store client-side values for use on subsequent page visits?
Typical scenario
An Index page has a table that's getting a bit long so I add a filter (I know paging is another option) and use an input control with some JavaScript to limit the table rows without having to perform another "Get" from the server.
This works fine but, if I navigate off (say) into an edit page then return back to the Index page, the filter is clearly no longer there.
After a bit of searching I never found anything simple so I post my meagre answer below.
The View contains a form at the top of the page into which a user can type filter text (on form "Get", text is set from a session value):-
<form id="frmEdit">
#Html.AntiForgeryToken()
<div class="form-group row">
<div class="col-sm-6">
#Html.ActionLink("Create New", "Create", null, new { #class = "nav-item nav-link" })
</div>
<label for="search" class="col-sm-2 col-form-label text-right">Filter</label>
<div class="col-sm-4">
<input type="text" placeholder="Filter" class="form-control" id="search" value=#Session["SparesSectionFilter"]>
</div>
</div>
</form>
A script section contains the filtering JavaScript but also a postback to the controller
#section Scripts{
<script type="text/javascript">
// on load
PerformFilter();
// hook up events
$(function () {
$("input#search").on("keydown keyup", function () {
PerformFilter();
// post back to session for reuse
$.post('SparesSections/Session_Add', { __RequestVerificationToken: $('[name=__RequestVerificationToken]').val(), itemName: 'SparesSectionFilter', itemValue: $("#search").val() });
});
})
</script>
}
I have a custom base-class for my controller into which I've added the following actions. These are usable from any controller using this class. The Razor view loads the session value but I've included a "Get" in the controller for client-side options.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Session_Add(string itemName, string itemValue)
{
Session.Add(itemName, itemValue);
return Json(new { itemName = itemName, itemValue = itemValue }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public ActionResult Session_Get(string itemName)
{
return Json(new { itemName = itemName, itemValue = Session[itemName] ?? string.Empty }, JsonRequestBehavior.AllowGet);
}

Return content for it to be shown - Right now nothing comes out

When I have picked my json from my controller, so when I have to write it in index.cshtml side so but when I type "module." then there's nothing up around img, text or ID, etc.
by my ng-repeat will it count as I want appears as it should.
The problem here just in that it will not enter text and img whether it is empty or not. both my questions that appear on the page has no image but right now the picture is shown on the page.
It gives me such a helping hand to know what to write about it must be img or text or otherwise.
Opgaver.html
<input type="hidden" ng-init="Id='2'" ng-model="Id" />
<div ng-repeat="module in Newslist" style="clear:both; margin:7px 0; min-height:110px; margin:5px 0;">
<div class="col-md-8">
<p>{{module.text}}</p>
</div>
<div class="col-md-3" ng-show="module.Img != null">
<img class="img-responsive img-rounded mb-lg" src="img/projects/project.jpg">
</div>
</div>
Opgaver.js
var app = angular.module('Opgaver', []);
app.controller('OpgaverCheck', function ($scope, $http) {
//GET
$scope.$watch("Id", function() {
var url = "/opgaver/kategori/" + $scope.Id;
$http.get(url).success( function(response) {
$scope.Newslist = response;
});
});
});
Controller:
[HttpGet]
public JsonResult kategori(int Id)
{
var db = Helpers.HelperToTables.DbValue;
List<ListOpgave> list = db.LektionerOpgaves.Where(i => i.fk_LektionerId == Id).OrderByDescending(i => i.id).Select(x => new ListOpgave
{
Id = x.id,
Img = x.LektionerOpgaveImg.value,
Text = x.text,
}).ToList();
return Json(list, JsonRequestBehavior.AllowGet);
}
First, you have "module.text", but in your MVC Controller, you have "Text". They must be exactly the same including case. Try changing "module.text" to "module.Text". Also, make sure your Json is actually returning a list by putting breakpoints in both controllers.
I think you want $scope.Newslist = response.data;
The response object has five properties and the information you want is contained in one of them. So as you have it written, Newslist is equal to the entire response, including the status and headers, rather than just the response data.
See the documentation on $http.

how to loop through json data based on single column value using angularjs in mvc

I need to display data from two tables which are associated with foreign key
using angularjs in mvc. I am able repeat question but my requirement is display question with 4 options i couldnt get the solution for this, am new to angularjs,I will be thankful if anyone can help me
> Controller code :
public JsonResult displayQuestion()
{
var result = from q in Db.questions
join a in Db.answers on q.Qid equals a.questionID
select new { q.QText, q.Qid, a.answer1 };
return Json(result, JsonRequestBehavior.AllowGet);
}
> angular view code:
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/angular.min.js"></script>
<script>
var myApp = angular.module("QuestionDisplayModule", [])
.controller("QuestionDisplayController", function ($scope,$http,$log) {
$http.get("displayQuestion").then(function(response)
{
$log.info(response);
$scope.questionsData = response.data;
})
})
</script>
<title>dispaly</title>
</head>
<body ng-app="QuestionDisplayModule">
<div ng-controller="QuestionDisplayController">
<div ng-repeat="q in questionsData">
<h6>{{q.QText}}</h6>
<p><input type="radio" name="answers" ng-repeat = "a in q.answer1" />{{a.answer1}}</p>
</div>
</div>
</body>
json data result:
[
{"QText":"result of 2+2","Qid":2,"answer1":"2"},
{"QText":"result of 2+2","Qid":2,"answer1":"4"},
{"QText":"result of 2+2","Qid":2,"answer1":"6"},
{"QText":"result of 2+2","Qid":2,"answer1":"8"}
]
view result: Link

how to load json data returned via ajax call in custom modal dialog

I'm newbie and wanna favor that is I have a link to open a custom modal dialog( not a bootstrap modal) as following
<div class="uk-modal" id="edit_quiz">
<div class="uk-modal-dialog">
<form:form method="post" commandName="quiz" htmlEscape="false" cssClass="uk-form-stacked">
<div class="uk-margin-medium-bottom">
<label for="task_title">Quiz Title</label>
<form:hidden path="quizId"/>
<form:input type="text" cssClass="md-input" id="quiz_title" path="quizTitle"/>
</div>
<div class="uk-margin-medium-bottom">
<label for="task_description">Description</label>
<form:textarea cssClass="md-input" id="quiz_description" path="quizDescription"/>
</div>
<div class="uk-modal-footer uk-text-right">
<button type="button" class="md-btn md-btn-flat uk-modal-close">Close</button>
<input type="submit" class="md-btn md-btn-flat md-btn-flat-primary" id="quiz_new_save" value="Update Quiz"/>
</div>
</form:form>
</div>
</div>
and at last my ajax script is
<script type="text/javascript">
$('#edit_quiz').click(function (event){
event.preventDefault();
$.ajax({
type : "GET",
url : "${pageContext.request.contextPath}/quiz/1",
data : {
"quizTitle" : "${quizTitle}"
},
success: function(data){
$('#edit_quiz_title').val(data.quizTitle);
}
})
return false; //for good measure
});</script>
this opens up the dialog but there are some issues those are:
the data is loaded using the
url : "${pageContext.request.contextPath}/quiz/1", I want to be this dynamic means Is there any way to get the id of selected quiz from a list of quizzes and get the data accordingly in modal form?
the data is shown in the form input field when it is focused how can data be filled without focus?
My RestController
#RestController
public class AdminRestController {
#Autowired
private QuizService quizService;
#RequestMapping(value = "/quiz_list/", method = RequestMethod.GET, headers="Accept=*/*", produces="application/json")
public ResponseEntity<Set<Quiz>> quizList() {
Set<Quiz> quizs = quizService.findAllQuizzes();
if(quizs.isEmpty()){
return new ResponseEntity<Set<Quiz>>(HttpStatus.NO_CONTENT);
}else{
return new ResponseEntity<Set<Quiz>>(quizs, HttpStatus.OK);
}
}
#RequestMapping(value = "/quiz/{id}", method = RequestMethod.GET, headers="Accept=*/*", produces="application/json")
public ResponseEntity<Quiz> quizById(#PathVariable("id") Long quizId) {
Quiz quiz = quizService.getQuizById(quizId);
if(quiz == null){
return new ResponseEntity<Quiz>(HttpStatus.NO_CONTENT);
}else{
return new ResponseEntity<Quiz>(quiz, HttpStatus.OK);
}
}
}
in success callback you are try to get id which is not exist in your page
replace this
$('#edit_quiz_title').val(data.quizTitle);
with this
$('#quiz_title').val(data.quizTitle);

Submitting form by AngularJs in spring mvc

I am new to Angularjs and trying to save table by using angularjs in spring mvc.
My table and controller is :
#Entity
public class StudentSkills {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private int skillId;
private String skillName;
private int expMonth;
private int expYear;
private String experties;
#ManyToOne
#JoinColumn(name= "student")
#JsonIgnore
private Student student;
// Getters Setters
My jsp page is : The Angularjs Coding is probably not correct
<script>
var skillApp = angular.module('skillApp', []);
skillApp.controller('skills', function($scope, $http) {
$scope.refreshSkill = function(){
$http.get('/user/getuserskills')
.success(function(data) {
$scope.allSkills = data;
});
};
$scope.addSkill = function(skill){
$http.put('/user/addskill/'+skill)
.success($scope.refreshSkill());
};
});
</script>
<title>Add Skill</title>
</head>
<body>
<div ng-app="skillApp">
<div ng-controller="skills" ng-init="refreshSkill()">
<div ng-repeat="skill in allSkills">
<div class="col-sm-6 col-lg-3">
<div class="thumbnail">
<div class="caption">
<h5>Name : {{skill.skillName}}</h5>
<h5>Name : {{skill.expMonth}}</h5>
<h5>Name : {{skill.expYear}}</h5>
<h5>Name : {{skill.experties}}</h5>
</div>
</div>
</div>
</div>
<form novalidate ng-submit="addSkill(skill)">
<input type="text" ng-model="skill.skillName">
<input type="text" ng-model="skill.expMonth">
<input type="text" ng-model="skill.expYear">
<input type="text" ng-model="skill.experties">
<input type="button" id="submit" value="Submit">
</form>
</div>
</div>
</body>
My Controller is :
#RequestMapping(value= "getuserskills", method = RequestMethod.GET)
public #ResponseBody List<StudentSkills> getStudentSkills(Model model){
List<StudentSkills> skills = studentService.getAllSkills(getStudentName());
return skills;
}
#RequestMapping(value = "/addskill", method = RequestMethod.PUT)
#ResponseStatus(value = HttpStatus.NO_CONTENT)
public void update(#PathVariable("skill") StudentSkills skills) {
skills.setStudent(studentService.getStudent(getStudentName()));
studentService.addStudentSkill(skills);
}
I want to fetch all the skills saved by using refreshSkill() function, and submit new skills through form. It is not working and i have tried but could not get it to work. How to link form like we can link using #modelAttribute. Or any other way to submit form using ajax. Thank You.
maybe you should follow some Angular JS tutorial or example, such as Angular phone tutorial, and this guide of the notion scope.
There are several problems in your codes :
1, you should define the json object skill in your controller, so that your view can recognize it : $scope.skill={};.
2, as the api of $http.put shows, the syntax should be : put(url, data, [config]);. So you should modify your code to
$http.put('/user/addskill/', $scope.skill).success($scope.refreshSkill());
3, in the server side, you should use the annotation #RequestBody for the StudentSkills parameter, like this :
public void update(#RequestBody StudentSkills skills) {
// your codes ...
}
Because the annotation #PathVariable is for the uri parameter, and when you use http put, the parameter is stored in the request body.
Hope help!

Categories