AngularJS Service not calling controller to get updated data after CRUD operation - angularjs

I am beginner in AngularJS and trying to create a master data entry screen, where upper portion containing form fields & lower portion containing table(GridView) to display all master entries. Grid showing all the data when i initially run the application. If i add/Edit any new/old records, the updated data not reflected in the gridview. (i.e) If i add any new entry, it is saving into the DB through service, but not reflecting in the GridView. Even if i navigate through menu also not displaying the updated data in the grid. But if i press Ctrl + F5, it is showing updated data in the Grid. Alsp If i close the browser & re run the application then the updated records displaying in the Gridview. Below is my code. Please help.. Thank you.!
Index.cshtml
<div class="row">
<div class="col-md-12">
<h3 class="page-header">
Component Master
</h3>
<div class="col-md-12">
<div class="alert alert-dismissible alert-danger" ng-show="ComponentForm.$invalid && submitted">
<button type="button" class="close" aria-hidden="true" data-dismiss="alert">
×</button>
<p ng-show="ComponentForm.ComponentName.$error.required && (ComponentForm.ComponentName.$dirty || submitted)">
- Component Name is required.</p>
<p ng-show="ComponentForm.ComponentName.$error.minlength && (ComponentForm.ComponentName.$dirty || submitted)">
- Component Name should be minimum 5 char long.</p>
<p ng-show="ComponentForm.Language.$error.required && (ComponentForm.Language.$dirty || submitted)">
- Language Selection is required.</p>
</div>
</div>
<div class="col-md-12">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">
Panel success</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-lg-12">
<!-- FORM : YOU CAN DISABLE, HTML5 VALIDATION BY USING "novalidate" ATTRIBUTE-->
<form name="ComponentForm" class="form-inline" novalidate>
<!-- COMPONENT NAME -->
<div class="form-group" ng-class="{ 'has-error' : ComponentForm.ComponentName.$invalid && (ComponentForm.ComponentName.$dirty || submitted) }"
style="margin: 10px;">
<label style="margin-right: 10px;">
Component Name</label>
<input type="text" name="ComponentName" ng-model="ComponentModel.ComponentName" class="form-control"
placeholder="Component Name..." ng-minlength="5" ng-required="true" />
<input type="hidden" data-ng-model="ComponentModel.ComponentID" />
<input type="hidden" data-ng-model="ComponentModel.IsActive" />
<input type="hidden" data-ng-model="UserID" />
</div>
<!-- LANGUAGE -->
<div class="form-group" style="margin: 10px;" ng-class="{ 'has-error' : ComponentForm.Language.$invalid && (ComponentForm.Language.$dirty || submitted) }">
<label style="margin-right: 10px;">
Language</label>
<select name="Language" data-ng-model="ComponentModel.Language" class="form-control"
ng-required="true">
<option value="" title="Select">Select</option>
<option value="English" title="English">English</option>
<option value="Spanish" title="Spanish">Spanish</option>
</select>
</div>
<!-- ng-disabled FOR ENABLING AND DISABLING SUBMIT BUTTON -->
<!-- SAVE BUTTON -->
#*<button type="submit" class="btn btn-info" ng-disabled="ComponentForm.$invalid" value="Add">Add</button>*#
<button type="submit" class="btn btn-primary" ng-click="SaveComponent(ComponentModel);"
ng-value="Add">
Add
</button>
<button type="submit" class="btn btn-warning" ng-click="ClearComponent();" value="Clear">
Clear
</button>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr class="success">
<th class="text-center">
ComponentID
</th>
<th class="text-center">
Component Name
</th>
<th class="text-center">
Language
</th>
<th class="text-center">
IsActive
</th>
<th class="text-center">
Last Modified By
</th>
<th class="text-center">
Last Modified Date
</th>
<th class="text-center">
Action
</th>
</tr>
<tr style="height: 250px; border: 2px solid #ecf0f1;" data-ng-show="ShowEmptyRow">
<th colspan="7" class="text-center" style="vertical-align: middle;">
<label class="control-label">
No Records Found.</label>
</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="Component in ComponentMaster" data-ng-show="!ShowEmptyRow" ng-class="{'danger':!Component.IsActive}">
<td style="vertical-align: middle; text-align: center;">
{{ Component.ComponentID}}
</td>
<td style="vertical-align: middle;">
{{ Component.ComponentName}}
</td>
<td style="vertical-align: middle;">
{{ Component.Language}}
</td>
<td style="vertical-align: middle; text-align: center;">
<div class="checkbox">
<label>
<input type="checkbox" disabled="disabled" ng-checked="Component.IsActive" /></label>
</div>
</td>
<td style="vertical-align: middle;">
{{ Component.ModifiedBy}}
</td>
<td style="vertical-align: middle; text-align: center;">
{{ Component.ModifiedDate}}
</td>
<th style="vertical-align: middle; text-align: center;">
<span class="btn btn-info btn-sm" ng-show="Component.IsActive" ng-click="EditComponent(Component.ComponentID);">
Edit</span> <span class="btn btn-danger btn-sm" ng-show="Component.IsActive" ng-click="ActivateDeActivateComponent(Component.ComponentID,false,ComponentModel.ModifiedBy);">
Delete</span> <span class="btn btn-info btn-sm" ng-show="!Component.IsActive" ng-click="ActivateDeActivateComponent(Component.ComponentID,true,ComponentModel.ModifiedBy);">
Activate</span>
</th>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Angular Script:
var AngularApp = angular.module("AngularApp", ['ngRoute']);
AngularApp.controller("ConfigurationController", ['$scope', 'ConfigurationService', function ($scope, ConfigurationService) {
$scope.ComponentMaster = [];
GetComponentMasterDetails();
/*------------- Save Component ---------------- */
// When i click Save btn - executing this function. control comes here...
$scope.SaveComponent = function (ComponentModel) {
$scope.submitted = true;
if ($scope.ComponentForm.$valid) {
ComponentModel.ModifiedBy = $scope.UserID;
// control comes here... & Calling method "SaveComponentMaster" inside ConfigurationService & returned execution message
var Msg = ConfigurationService.SaveComponentMaster(ComponentModel);
Msg.then(function (response) {
if (response.data != "") {
alert(response.data);
}
else {
// After Saved into DB showing below alert message.
alert("Data Saved Successfully.");
// Calling below method to get the updated records from DB
GetComponentMasterDetails();
}
}, function (error) {
alert(error.data);
});
}
else {
alert("Please correct errors!");
}
}
/**----------------------------------------------------- */
// Below method is calling...
function GetComponentMasterDetails() {
// Call moves to ConfigurationService Service method...
var ComponentMaster = ConfigurationService.GetComponentMasterDetails();
ComponentMaster.then(function (response) {
if (response.data != "") {
// This service call returning the old data only.
// Updated/Added entry details not reflecting in the returned object.
// This is the reason why it is showing old records only in the Grid.
$scope.ShowEmptyRow = false;
$scope.ComponentMaster.length = 0;
angular.extend($scope.ComponentMaster, response.data);
}
else {
$scope.ShowEmptyRow = true;
$scope.ComponentMaster.length = 0;
}
}, function (error) {
alert(error.data);
});
}
} ]);
AngularApp.service("ConfigurationService", function ($http) {
// Call comes here...
this.GetComponentMasterDetails = function () {
// Call comes here... But this $http.get - not calling MVC controller Action method.
// I kept my breakpoint in MVC controller method, but not executed the method.
// So this Service just returning old records. This is the reason the View showing old records.
// If i press Ctrl + F5, it is calling MVC controller message & showing the updated records.
return $http.get('/Configuration/GetComponentMasterDetails');
};
// Control comes here... Then calling MVC controller Action method.. Saving data into DB & returned execution message.
this.SaveComponentMaster = function (ComponentModel) {
var response = $http({
method: 'POST',
url: '/Configuration/SaveComponentMaster/',
data: { ComponentModel: ComponentModel }
});
return response;
};
});
MVC Controller
[NoCache]
[HttpGet]
public ActionResult GetComponentMasterDetails()
{
RNDDBContext dbContext = new RNDDBContext();
var result = dbContext.ExecuteStoreQuery<ComponentModel>("exec PROC_GET_COMPONENT_MASTER_DETAILS").ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}
[NoCache]
[HttpPost]
public JsonResult SaveComponentMaster(ComponentModel ComponentModel)
{
RNDDBContext dbContext = new RNDDBContext();
var result = dbContext.ExecuteStoreQuery<string>("exec PROC_SAVE_COMPONENT_MASTER #ComponentID,#ComponentName,#Language,#IsActive,#ModifiedBy",
new SqlParameter("ComponentID", ComponentModel.ComponentID),
new SqlParameter("ComponentName", ComponentModel.ComponentName),
new SqlParameter("Language", ComponentModel.Language),
new SqlParameter("IsActive", ComponentModel.IsActive),
new SqlParameter("ModifiedBy", ComponentModel.ModifiedBy)
).FirstOrDefault();
return Json(result, JsonRequestBehavior.AllowGet);
}
public class NoCache : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
}

Initialize your $scope.ComponentMaster on the top of controller
AngularApp.controller("ConfigurationController", ['$scope', 'ConfigurationService', function ($scope, ConfigurationService) {
$scope.ComponentMaster = [];
GetComponentMasterDetails();
and just empty that, then repopulate once you call GetComponentMasterDetails()
function GetComponentMasterDetails() {
var ComponentMaster = ConfigurationService.GetComponentMasterDetails();
ComponentMaster.then(function (response) {
if (response.data != "") {
$scope.ShowEmptyRow = false;
// Empty the ComponentMaster array
$scope.ComponentMaster.length = 0;
// Add the retrieved data
angular.extend($scope.ComponentMaster, response.data)
}
else {
$scope.ShowEmptyRow = true;
// Empty the ComponentMaster array
$scope.ComponentMaster.length = 0;
}
}, function (error) {
alert(error.data);
});
}
This issue is similar to this

Related

How to avoid loading data from server every time doing sorting/paging with ngtable

I am using ngtable (1.0.0) to display records fetched from server side. My controller js looks like this:
ristoreApp.controller("fmCtrl",
['$scope', '$filter', 'fmFactory', 'NgTableParams', function($scope, $filter, fmFactory, NgTableParams) {
var self = this;
$scope.selection = '0';
$scope.fmSearch = function () {
if ($scope.selection == '0') {
self.tableParams = new NgTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
frReportId: 'asc'
}
}, {
getData: function (params) {
return fmFactory.getAll()
.then(function(response) {
var reports = response.data;
params.total(reports.length);
console.log(params.total());
var sorted = params.sorting() ? $filter('orderBy')(reports, params.orderBy()) : reports;
return sorted.slice((params.page() - 1) * params.count(), params.page() * params.count());
});
}
});
}
}
}]
)
HTML for the table:
<div ng-controller="fmCtrl as fm">
<div class="container">
<div class="row top-margin-80">
<div class="col-md-12">
<div class="input-group" id="adv-search">
<input type="text" class="form-control" ng-model="keyword" placeholder="Enter MRN or report ID" />
<div class="input-group-btn">
<div class="btn-group" role="group">
<div class="dropdown dropdown-lg">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><span class="caret"></span></button>
<div class="dropdown-menu dropdown-menu-right" role="menu">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="filter">Search by</label>
<select class="form-control" ng-model="selection">
<option value="0" selected>All Reports</option>
<option value="1" >MRN</option>
<option value="2">ReportID</option>
</select>
</div>
<div class="form-group">
<input class="form-control" type="text" ng-model="optionword" ng-hide="selection == '0'"/>
</div>
</form>
</div>
</div>
<button type="button" class="btn btn-primary" ng-click="fmSearch()"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<table ng-table="fm.tableParams" class="table table-bordered table-striped table-condensed" show-filter="false">
<tr ng-repeat="report in $data">
<td data-title="'ReportId'" filter="{frReportId: 'text'}" sortable="'frReportId'" class="text-center">
{{report.frReportId}}</td>
<td data-title="'BlockId'" filter="{frBlockId: 'text'}" sortable="'frBlockId'" class="text-center">
{{report.frBlockId}}</td>
<td data-title="'MRN'" filter="{mrn: 'text'}" sortable="'mrn'" class="text-center">
{{report.mrn}}</td>
<td data-title="'Name'" filter="{frFullName: 'text'}" sortable="'frFullName'" class="text-center">
{{report.frFullName}}</td>
<td data-title="'Diagnosis'" filter="{frDiagnosis: 'text'}" sortable="'frDiagnosis'" class="text-center">
{{report.frDiagnosis}}</td>
<td data-title="'File'" class="text-center"><a ng-href="{{report.filepath}}">{{report.frReportId}}.xml</a>
</td>
</tr>
</table>
</div>
</div>
It works, well sort of. Problem is whenever I click on the titles to sort and page button to go to next page, it makes an ajax call to server to retrieve data again. I have over 2000 records in the database, every time I do something to the table, it takes 5 seconds to respond which is very annoying. How do I make it load the data only the first time and cache it on client side for future manipulation?
Finally got it to work. Solution is to move the ajax call var Ajax = fmFactory.getAll(); outside ngtable constructor.
var Ajax = fmFactory.getAll();
self.tableParams = new NgTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
frReportId: 'asc'
}
}, {
getData: function (params) {
return Ajax.then(function(response) {
var reports = response.data;
params.total(reports.length);
console.log(params.total());
var sorted = params.sorting() ? $filter('orderBy')(reports, params.orderBy()) : reports;
return sorted.slice((params.page() - 1) * params.count(), params.page() * params.count());
});
}
});

Uncaught TypeError: Cannot read property 'file' of undefined(…)

I am trying to upload an image from my html an on click of save button, i am calling an upload function in the controller. When i enter the upload function in controller, i am not able to access $scope to check the $scope.file.name.
//upload image.html
<div class="horizontal">
<table border=1 frame=void rules=rows class="ui celled table" >
<thead style="text-align: center;">
<tr>
<th> Id </th>
<th> Question </th>
<th> Option A </th>
<th> Option B </th>
<th> Option C </th>
<th> Option D </th>
<th> Answer </th>
<th> Section id </th>
<th> Image </th>
<th> Edit</th>
</tr></thead>
<tbody ng-repeat="ques in questionObj | filter: searchText" style="text-align: center;">
<tr>
<td>{{$index + 1}}</td>
<td><span ng-show="editEnabled" ng-model="Title">
{{ ques.Title || 'empty' }}
</span>
<div ng-hide="editEnabled">
<textarea ng-model="ques.Title"></textarea>
</div>
</td>
<td><span ng-show="editEnabled" ng-model="Title">{{ques.Option_a || 'empty'}} </span>
<div ng-hide="editEnabled" class="option">
<textarea ng-model="ques.Option_a"></textarea>
</div>
</td>
<td><span ng-show="editEnabled" ng-model="Title">{{ques.Option_b || 'empty'}} </span>
<div ng-hide="editEnabled" class="option">
<textarea ng-model="ques.Option_b"></textarea>
</div>
</td>
<td><span ng-show="editEnabled" ng-model="Title">{{ques.Option_c || 'empty'}} </span>
<div ng-hide="editEnabled" class="option">
<textarea ng-model="ques.Option_c"></textarea>
</div>
</td>
<td><span ng-show="editEnabled" ng-model="Title">{{ques.Option_d || 'empty'}} </span>
<div ng-hide="editEnabled" class="option">
<textarea ng-model="ques.Option_d"></textarea>
</div>
</td>
<td><span ng-show="editEnabled" ng-model="Title">{{ques.Answer || 'empty'}} </span>
<div ng-hide="editEnabled" class="option">
<textarea ng-model="ques.Answer"></textarea>
</div>
</td>
<td><span ng-show="editEnabled" ng-model="Title">{{ques.Section_id || 'empty'}} </span>
<div ng-hide="editEnabled" class="option">
<input type="text" ng-model="ques.Section_id"></input>
</div>
</td>
<td>
<span ng-if="ques.Image != 'nil'" ng-show="editEnabled" ng-model="Title"> <img ng-src="{{ques.Image}}" class="image-container" /></span>
<span ng-if="ques.Image === 'nil'" ng-show="editEnabled" ng-model="Title">No Image</span>
<div ng-if="ques.Image != 'nil'" ng-hide="editEnabled" class="option">
<img ng-src="{{ques.Image}} " class="image-container" />
</div>
<div ng-if="ques.Image === 'nil'" ng-hide="editEnabled" class="option">
<input class="bottom-marg-15" type="file" name="file" file onchange="angular.element(this).scope().imageLoad(this)"></input>
<!-- Progress Bar -->
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="{{ uploadProgress }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ uploadProgress }}%;">
{{ uploadProgress == 0 ? '' : uploadProgress + '%' }}
</div>
</div>
<div ng-repeat="step in stepsModel">
<img class="small-thumb" ng-src="{{step}}" />
</div>
</div>
</td>
<td style="white-space: nowrap">
<div class="buttons" ng-show="editEnabled" ng-show="editEnabled">
<button class="btn btn-primary" ng-click="editEnabled = !editEnabled">edit</button>
<button class="btn btn-danger" ng-click="question.removeUser($index,ques.Id)">del</button>
</div>
<div ng-hide="editEnabled" class="form-buttons form-inline">
<button ng-model="Title" ng-disabled="editQuestionForm.$waiting" ng-click=" upload(); editEnabled = !editEnabled" class="btn btn-primary">
save
</button>
<button type="button" ng-click="editEnabled = !editEnabled" class="btn btn-default">
cancel
</button>
</div>
</td>
</tr>
</tbody>
this is the controller which has the upload function. I am not able to access $scope inside upload function.
'use strict';
angular.module('onlineTestAngularApp')
.controller('editQuestionCtrl', function($scope, GetQuestionsService, $window, $location, localStorageService, ENV) {
var vm = this;
vm.success = false;
vm.auth_token = localStorageService.get('rec-auth-token');
vm.role = localStorageService.get('role');
$scope.editEnabled = true;
$scope.access_key = ENV.access_key;
$scope.secret_key = ENV.secret_key;
$scope.bucket = "q-auth/angular_test/";
$scope.stepsModel = [];
$scope.imageLoad = function(element){
var reader = new FileReader();
reader.onload = $scope.imageIsLoaded;
reader.readAsDataURL(element.files[0]);
}
$scope.imageIsLoaded = function(e){
$scope.$apply(function() {
$scope.stepsModel.push(e.target.result);
});
}
$scope.upload = function($scope){
console.log("inside upload");
}
});
Your upload() is having a parameter called $scope, remove it.
Change:
$scope.upload = function($scope){
console.log("inside upload");
}
To:
$scope.upload = function(){
console.log("inside upload");
};
Because when you call the function upload() it will expect to pass an argument, $scope in the function is taken as local variable of that function, hence becoming undefined.
Once you enter the controller's function you have access to its $scope. There's no need to pass it as a parameter:
Controller
$scope.upload = function() {
console.log($scope.stepsModel) // or any other property
}
It seems you mix two techniques for accessing controller's scope: vm and $scope. My advice is to use vm only for exposing the controller variables to the view. Using $scope will soon be deprecated and I use it mainly for $watching changes in the view.

Angular table last added row not loading bootstrap calendar

I am using angular to load meeting information into a table. When i try to add a new row to the table, the added row does not load the last bootstrap calendar because angular hasn't yet finished loading the row when i call a function to dynamically load the datepicker. How can i call load the datepicker after Angular has finished loading the new row?
Here's my code:
<div ng-controller="virtualmeetingdetails" id="virtualmeetingdetails">
<div class="row" id="proposedaddboards">
<div class="form-group required">
<label id="adboardnumber" class="control-label col-sm-4" for="spinner1">Proposed Number of Advisory Boards</label>
<div class="col-sm-4">
<div id="spinnerDiv1" class="input-group spinner">
<asp:TextBox id="spinner1" cssclass="form-control" value="0" runat="server" />
<div class="input-group-btn-vertical">
<button class="btn btn-default" type="button" ng-click="addUser()"><i class="fa fa-caret-up"></i></button>
<button class="btn btn-default" type="button"><i class="fa fa-caret-down"></i></button>
</div>
</div>
</div>
</div>
</div>
<div class="row" id="tblVirtualMeeting">
<div class="form-group required">
<div class="col-sm-12" >
<table class="table table-bordered table-striped" jq-table>
<thead style="background-color:#cad4d9">
<tr>
<th>Proposed Date</th>
<th>Virtual Meeting</th>
<th>Location City</th>
<th>State</th>
<th>Country</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="meeting in meetings">
<td>
<div class="input-group input-append date" id="dtpicker{{$index}}" data-date-format="mm/dd/yyyy" style="width:150px;">
<span class="text-center" ng-show="editMode">{{meeting.proposedbegindate}}</span>
<input type="text" class="form-control col-sm-3" runat="server" ng-hide="editMode" ng-model="meeting.proposedbegindate" />
<span class="input-group-addon add-on" ng-hide="editMode">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</td>
<td>
<select ng-model="meeting.isvirtualmeeting" ng-hide="editMode"
ng-options="option.text for option in virtualmeetingoptions track by option.value" class="form-control">
</select>
<span class="text-center" ng-show="editMode">{{meeting.isvirtualmeeting.text}}</span>
</td>
<td>
<span class="text-center" ng-show="editMode">{{meeting.venuecity}}</span>
<input type="text" class="form-control" ng-hide="editMode" ng-model="meeting.venuecity" />
</td>
<td>
<select ng-model="meeting.venuestateID" ng-hide="editMode" ng-options="state.StateConst for state in statesList track by state.StateID" class="form-control"></select>
<span class="text-center" ng-show="editMode">{{meeting.venuestateID.StateConst}}</span>
</td>
<td>
<select ng-model="meeting.venuecountryid" ng-hide="editMode" ng-options="country.CountryName for country in countriesList track by country.CountryID" class="form-control"></select>
<span class="text-center" ng-show="editMode">{{meeting.venuecountryid.CountryConst}}</span>
</td>
<td style="width:170px">
<span class="glyphicon glyphicon-pencil" style="color: green; font-size: medium; cursor: pointer" ng-show="editMode" ng-click="editMode = false; editUser(participant)"></span>
<span class="glyphicon glyphicon-floppy-save" style="color: #337ab7; font-size: medium; cursor: pointer" ng-hide="editMode" ng-click="editMode = true;saveField(meeting, <%=_CurrentUserID %>);"></span>
<span class="glyphicon glyphicon-remove-circle" style="color: red;font-size:medium;cursor:pointer" ng-click="removeItem($index)"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
Controller:
app.controller("virtualmeetingdetails", function ($scope, $http) {
$http.get("../Services/EngagementDataService.asmx/GetVirtualMeetings", { params: { 'mid': getParameterByName('mid')} })
.success(function (response) {
var j = response.length;
var i = 0;
if (response.length > 0) {
while (i < j) {
response[i].proposedbegindate = moment(response[i].proposedbegindate).format("MM/DD/YYYY");
i++
}
}
....more code goes here (removed)
$scope.addUser = function () {
$scope.editing = true;
var meetingcount;
if (typeof $scope.meetings === "undefined")
meetingcount = 0
else meetingcount = $scope.meetings.length;
$scope.inserted = {
engagementproposedinfoid: 0,
id: meetingcount + 1,
venuecity: '',
proposedbegindate: '',
venuestateid: 0,
venuecountryid: 1,
isvirtualmeeting: 0
};
$scope.meetings.push($scope.inserted);
rendercalendars(meetingcount);
};
});
Function to render datepicker:
function rendercalendars(rows) {
var nowDate = new Date();
var today = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), 0, 0, 0, 0);
var j = rows;
var i = 0;
while (i < j) {
$('#dtpicker' + i).datepicker({ autoclose: true, startDate: today });
i++
}
}
The issue happens when $scope.addUser gets called... it loads the table row before the rendercalendars function gets called so the datepickers don't get loaded.
Any help will be appreciated.
My guess would be something like this:
With this line you change your scope and on your next digest cycle your repeat will be "redone". So your html gets adjusted.
$scope.meetings.push($scope.inserted);
Then you call your render function and its all messed up if the digest hit before.
rendercalendars(meetingcount);
But that's just a guess of mine.
BTW there is an angular implementation for bootstrap components (ui-boostrap) then you don't have to do jQuery stuff.
Home this is some sort of help.

Update row in angular-smart-table

In my app i list users in a table via angular smart table. Now i would like to update a record once i modified it. I can't find any function with which i can change the user in my rowCollection so my list view reflects those changes directly.
This is my Service to receive my users from the API
services.factory('Users', function($resource) {
return $resource('/api/v1.0.0/users/:id', {id: '#id'}, {
update: {
method: 'PUT'
}
});
});
This is my List Controller to get the data from my factory. It also has the delete function. The delete function works fine - it just removes one index from the usersRowCollection. The API removes it from the DB.
app.controller('UsersCtrl', ['$scope', '$resource', 'Users',
function ($scope, $resource, Users) {
// Defines how many items per page
$scope.itemsByPage = 10;
// Create a reference object of usersRowCollection for smart table
$scope.usersRowCollection = Users.query();
$scope.usersDisplayedCollection = [].concat($scope.usersRowCollection);
/**
* Function to send a DELETE request to the API
* and to remove the row from the table
* #param user The row item
*/
$scope.deleteUser = function (user) {
// Send request to the API
user.$delete(function () {
// Remove this line from the table
var index = $scope.usersRowCollection.indexOf(user);
if (index !== -1) {
$scope.usersRowCollection.splice(index, 1);
}
})
}
}]);
This is my edit controller where i try to make the magic happen. the $scope.user.$update() function sends the changed data to the API - now i just need to get the changes reflected in my users list to which i redirect via $state.go('app.users.list') (ui-router)
app.controller('UsersEditCtrl', ['$scope', '$state', '$stateParams', 'Users',
function ($scope, $state, $stateParams, Users) {
$scope.updateUser = function () {
$scope.user.$update(function () {
$state.go('app.users.list');
//console.log($scope.user);
//console.log($scope.usersRowCollection);
//var index = $scope.usersRowCollection.indexOf($scope.user);
//console.log($scope.user.id);
// Remove this line from the table
var index = $scope.usersRowCollection.indexOf($scope.user);
if (index !== -1) {
$scope.usersRowCollection.splice(index, 1);
}
//$scope.user = Users.get({id: $scope.user.id});
//$scope.usersRowCollection.update();
// todo Update the changed entry in the table
});
};
// Loads the users json data from the REST Api
$scope.loadUser = function () {
//console.log('loadUser');
$scope.user = Users.get({id: $stateParams.id});
};
$scope.loadUser();
}]);
Thats my HTML - as you can see i use the st-safe-src attribute. If i understood correctly, it should recognice the changes and reflect them automatically.
<table st-table="usersDisplayedCollection" st-safe-src="usersRowCollection" class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>NAME</th>
<th>EMAIL</th>
<th>ACTIVE</th>
<th>CREATED_AT</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in usersDisplayedCollection">
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.active }}</td>
<td>{{ user.created_at }}</td>
<td>
<button type="button" confirm-button="deleteUser(user);" confirm-message="Wirklich löschen?"
class="btn btn-sm btn-danger">
<i class="fa fa-times"></i> Delete
</button>
<a href="#" ui-sref="app.users.edit({id:user.id})" class="btn btn-sm btn-warning">
<i class="fa fa-pencil"></i> Edit
</a>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="7" class="text-center">
<div st-pagination="" st-items-by-page="itemsByPage" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>
Edit form:
<form class="form-horizontal" role="form" ng-submit="updateUser()">
<div class="form-group">
<label>ID</label>
<input type="text" disabled="disabled" class="form-control" value="{{ user.id }}">
</div>
<div class="form-group">
<label for="name">NAME</label>
<input type="text" ng-model="user.name" class="form-control" id="name" placeholder="YOUR NAME">
</div>
<div class="form-group">
<label for="email">E-MAIL</label>
<input type="email" ng-model="user.email" class="form-control" id="email" placeholder="YOUR EMAIL">
</div>
<div class="radio">
<label>
<input type="radio" ng-model="user.active" name="active" id="active" value="1">
ACTIVE
</label>
<label>
<input type="radio" ng-model="user.active" name="active" id="inactive" value="0">
INACTIVE
</label>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
ABBRECHEN
<button type="submit" class="btn btn-default">SPEICHERN</button>
</div>
</div>
</form>
So, how can i reflect the changes i do in my form view directly after saving in my list view?

Loading partial view into the main view AngularJS

I have a partial view, which I plan to include in different pages.
I tried out the following to load the partial view but the view doesn't display the values stored in the model.
Angular controller:
//This gets the required data as JSON
AdminService.getSettings(function (callback) {
$scope.attributes = callback;
$scope.groups = _.groupBy($scope.attributes, "Group");
$scope.previous = angular.copy($scope.attributes);
//This gets the partial view and adds to the main view
CommonService.SettingsListView_get(function (callback) {
angular.element('#settingsList').html(callback);
});
});
MVC Controller:
public ActionResult SettingsList()
{
return PartialView();
}
View: Main
<body ng-app="AngularAdmin" ng-cloak>
<div ng-controller="SettingsCtrl" id="top" ng-init="init()">
<br />
<div id="settingsList" >
</div>
View:partial
<div class="panel-group" id="accordion">
<div style="padding:5px 0"><button ng-click="updateAttributes(attributes)" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> Update Settings</button></div>
<div class="panel panel-primary" data-ng-repeat="(items, item) in groups" ng-style="$index < 11 ? panelStyle[$index] : commonPanelStyle">
<div class="panel-heading" ng-style="$index < 11 ? panelHeaderStyle[$index] : commonPanelHeaderStyle">
<a data-toggle="collapse" href="#accordion{{$index}}" ng-style="anchorStyle">
<h4 class="panel-title">
{{ items }}
</h4>
</a>
</div>
<div id="accordion{{$index}}" class="panel-collapse collapse">
<div class="panel-body" ng-style="$index < 11 ? panelBodyStyle[$index] : commonPanelBodyStyle">
<table class="table">
<tr>
<th>Attribute</th>
<th>Description</th>
<th>Value</th>
<th>Taken from</th>
<th>Editable</th>
<th>Delete</th>
</tr>
<tr data-ng-repeat="i in item">
<td> {{ i.AttributeName }} </td>
<td> {{ i.Description }} </td>
<td> <input type="text" ng-model="i.Value" class="form-control" ng-disabled="{{!i.Editable}}" />
</td>
<td><span ng-bind="i.TakenFrom | settingsfilter">{{ Heritage }}</span> </td>
<td><span ng-class="i.Editable | activefilter : { icon1 : 'glyphicon-edit', icon2 : 'glyphicon-remove'}" class="glyphicon" style="font-weight: bolder"></span></td>
<td><span ng-click="deleteAttribute(i.AttributeGuid)" ng-class="i.TakenFrom | deletefilter : 1" class="glyphicon" style="font-weight: bolder"></span></td>
</tr>
</table>
<button style="float:right" class="btn btn-default" ng-click="updateAttributes(item)"><span class="glyphicon glyphicon-floppy-disk"></span> Update <em>{{ items }}</em> Settings </button>
</div>
</div>
Issue:
I can't display the settings data I can see {{ items }} and nothing else in the view.
The preferred way to achieve this is to create a "settingsList" directive and set the templateUrl to the url of the partial view. You could get rid of this:
CommonService.SettingsListView_get(function (callback) {
angular.element('#settingsList').html(callback);
});
and replace this:
<div id="settingsList" >
</div>
with this:
<div settingsList></div>
If for some reason this isn't possible in your situation, try changing your controller code the following (you'll need to inject the $compile service):
CommonService.SettingsListView_get(function (callback) {
var element = angular.element(callback);
$compile(element)($scope);
angular.element('#settingsList').append(element);
$scope.digest();
});
this code working good :
CommonService.SettingsListView_get(function (callback) {
var element `enter code here`= angular.element(callback);
$compile(angular.element('#settingsList').append(element))($scope);
});

Resources