Angular html not loading properly - html

Sorry if this has a really obvious answer, I'm fairly new to Angular JS and this is something that I have been stuck on for an annoyingly long time.
To give you a bit of background, I am calling ng-repeat on a directive as follows:
<div ng-controller = 'salesctrl'>
<salecell ng-repeat = "kpi in kpis" kpi ="kpi"></salecell>
</div>
With the directive being described as follows:
.directive("salecell", function(){
return{
templateUrl: "sale-cell-template.html" ,
restrict: 'E',
scope: {
kpi: '='
},
link: function(scope){
return scope;
},
controller: function($scope){
if(typeof $scope.kpi != 'undefined'){
$scope.kpi.value = 0;
$scope.increment = function(){
$scope.kpi.value++;
}
$scope.decrement = function(){
if($scope.kpi.value != 0){
$scope.kpi.value--;
}
}
}
}
};
})
and the attached controller:
.controller("salesctrl", function($scope, $rootScope, SalesSvc){
SalesSvc.query().$promise.then(function(data){
$scope.kpis = data;
});
$scope.submit = function(){
SalesSvc.save($scope.kpis).$promise.then(function(){
for(var i = 0; i < $scope.kpis.length; i++){
$scope.kpis[i].value = 0;
}
});
$rootScope.$emit('salecreate');
}
})
The issue that I am having is that, regardless of the contents of my associated template, only the outer element is being rendered. For example if I have:
<tr>
<div class="col-md-6"> <label class="control-label">{{kpi.title}}</label></div>
<div ng-show="!kpi.dollar" class="col-md-6">
<div id="spinner4">
<div class="input-group" style="width:150px;">
<div class="spinner-buttons input-group-btn">
<button ng-click="decrement()" type="button" class="btn spinner-up btn-warning">
<i class="fa fa-minus"></i>
</button>
</div>
<input ng-model="kpi.value" type="text" class="spinner-input form-control" maxlength="3" >
<div class="spinner-buttons input-group-btn">
<button ng-click="increment()" type="button" class="btn spinner-down btn-primary">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
</div>
</div>
<div ng-show="kpi.dollar" class="col-md-6">
<div class="input-group m-bot15" style="width: 150px;">
<span class="input-group-addon">$</span>
<input ng-model="kpi.value" type="text" class="form-control">
</div>
</div>
Nothing will load on the page, and likewise, if I have:
<tr>
<h1> Hello World! </h1>
</tr>
Nothing is loaded either.
Things I have already checked:
-I have made sure that both $scope.kpis and $scope.kpi are defined
-I have ensured that the template is actually being called (both by inspecting elements and by calling a console.log from within the template)
-A bit of searching around suggested that it might be an error within the template, but this seems strange given that it doesn't work even with a near-empty template.
The only other thing that I can think to add is that when I was using console.log in the template that was visible in the element inspector (Chrome), but nothing else has been.
Let me know if you need anything else, and once again I hope this isn't something really stupid that I have missed.

Ensure that the content inside the table are wrapped in <td> tags. Currently they are directly inside <tr> tags and is invalid HTML.
<tr>
<td>
<div class="col-md-6"> <label class="control-label">{{kpi.title}}</label></div>
...
</td>
</tr>

Related

ng-model taking for all inputs after clicking edit

I am using AngularJS. I am generating pipeline-like structure. At first onload I am having one default ng-repeat value. After clicking "add more" I am displaying another list. It goes on adding as long as I am clicking the "add" button.
Here is my HTML:
Add button
<button data-ng-click="addNew()">Add New Workboard</button>
New pipeline will be created with Pipeline Names and one text box to add stageNames
<div data-ng-show="listOfLists.length > 0">
<div data-ng-repeat="list in listOfLists">
<div data-ng-repeat="pipeline in workboardstages track by $index">
<div class="added-eachboard">
<div class="form-group">
<input name="pipelineName" id="pipelineName" data-ng-
model="pipeline.pipelineName" type="text">
</div>
<ul class="simpleDemo workboard-drags" data-ng-repeat="(key,
workboardlist) in pipeline.workBoardStageMap">
<li data-ng-if="pipeline.pipelineName == key" ng-repeat="workboard in
workboardlist">{{workboard.stageName}}
<a href ="javascript:void(0)" data-ng-
click="editWorkboardStage(workboard.stageId)"><img src =
"resources/zingy/images/Edit-Small.png" class="TableIcon"></a>
</li>
</ul>
<div>
<p class="weak">Stage Name:</p>
<div class="form-group">
<input name="stageName" id="stageName" data-ng-
model="newworkboard.stageName" type="text">
</div>
</div>
</div>
</div>
</div>
</div>
Controller.js
$scope.listOfLists = [];
$scope.workboardStagesWithDefault = [
{
Name:"Test"
},
{
Name:"Test2"
},
{
Name:"Test3"
}
];
$scope.addNew = function(){
var clonedList = angular.copy($scope.workboardStagesWithDefault);
$scope.listOfLists.push(clonedList);
};
$scope.editWorkboardStage = function(stageId){
AccountService.editWorkboardStage(stageId).then(function(response){
$scope.newworkboard = response.data;
});
}
$scope.getAllWorkboardStages = function(){
AccountService.getAllWorkboardStages().then(function(response){
$scope.workboardstages = response.data;
$scope.listOfLists.push($scope.workboardstages);
});
}
After clicking edit i am displaying stage name in that particular text box.But the problem is it is displaying same for neighbouring pipeline also.I want to display only for that current pipeline.As i am displaying using ng-model it is taking for all pipelines.How to display the value only for that particular pipeline?
So, the problem is related to indexing. I made $scope.newworkboard index wise.
This is the solution: (newworkboard is based on pipeline index and pass index from editWorkboardStage function.)
<input name="stageName" id="stageName" data-ng-model="newworkboard[$index].stageName" type="text">
AND
<a href ="javascript:void(0)" data-ng-click="editWorkboardStage(workboard.stageId, $parent.$parent.$index)"><img src =
"resources/zingy/images/Edit-Small.png" class="TableIcon"></a>
HTML
<div data-ng-show="listOfLists.length > 0">
<div data-ng-repeat="list in listOfLists">
<div data-ng-repeat="pipeline in workboardstages track by $index">
<div class="added-eachboard">
<div class="form-group">
<input name="pipelineName" id="pipelineName" data-ng-
model="pipeline.pipelineName" type="text">
</div>
<ul class="simpleDemo workboard-drags" data-ng-repeat="(key,
workboardlist) in pipeline.workBoardStageMap">
<li data-ng-if="pipeline.pipelineName == key" ng-repeat="workboard in
workboardlist">{{workboard.stageName}}
<a href ="javascript:void(0)" data-ng-
click="editWorkboardStage(workboard.stageId, $parent.$parent.$index)"><img src =
"resources/zingy/images/Edit-Small.png" class="TableIcon"></a>
</li>
</ul>
<div>
<p class="weak">Stage Name:</p>
<div class="form-group">
<input name="stageName" id="stageName" data-ng-
model="newworkboard[$index].stageName" type="text">
</div>
</div>
</div>
</div>
</div>
</div>
Controller
In the controller make an array of newworkboard and assign response.data index wise.
$scope.newworkboard = [];
$scope.editWorkboardStage = function(stageId, index){
AccountService.editWorkboardStage(stageId).then(function(response){
$scope.newworkboard[index] = response.data;
});

How to change ng-include inside firebase firestore function

When I click on continue button it checks clients ID in firestore database and if ID does'nt exist then $scope.filePath = "createClient.htm" is called. everything is working fine but when I call this piece of code inside firebase function nothing happens
Inside HTML
<div ng-include="filePath" class="ng-scope">
<div class="offset-1 offset-sm-2 col-11 col-sm-7">
<h2>Enter Client ID</h2>
<br>
<div class="form-group">
<label for="exampleInputEmail1">ID</label>
<input id="client_id" type="text" class="form-control" placeholder="Client ID">
</div>
<div class="float-right">
<button type="button" class="btn btn-danger">Cancel</button>
<button type="button" ng-click="searchClient()" class="btn btn-success">Continue</button>
</div>
</div>
</div>
Internal Script
<script>
$scope.searchClient = function()
{
//$scope.filePath = "createClient.htm"; it works here
var id= document.getElementById('client_id').value;
db.collection("clients") // db is firestore reference
.where("c_id","==",id)
.get()
.then(function(querySnapshot)
{
querySnapshot.forEach(function(doc)
{
if(!doc.exists)
{
console.log("Client Does'nt Exist");
$scope.filePath = "createClient.htm"; // but doesnt works here inside this firebase function
}
}
);
}
);
}
};
</script>
when console.log is shown and firebase function are fully executed then if I click on "Continue" Button again it works fine and content of createClient.htm is shown inside ng-include="filePath". why i need to click twice ?

Controller not recognized by HTML after $state.go()

I'm fairly new to Angular and very new to using the ui-router, so I could be missing something obvious.
If I launch my results.html page on its own, everything from the Web API is bound correctly through the controller and shows up as expected.
When I start from index.html and click on the button that calls $state.go(), I am navigated to the results.html page .. but none of the data from the controller shows up. The controller & service are still being called though - because I put console.log() statements to verify that the object I want is being returned after $state.go() and it is - the template just isn't registering it.
Here is my code for my ui-router and main controller:
// script.js
var app = angular.module('BN', ['ui.router']);
// configure our routes
app.config(function ($locationProvider, $stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('');
$stateProvider
.state('default',{
url:'/',
templateURL:'index.html',
controller: 'MainController'
})
.state('results', {
url:'/results',
controller: 'ResultsController',
controllerAs: 'vm',
templateUrl: 'Results/Results.html'
})
.state('instructor', {
url:'/api/instructors/:id',
templateUrl: 'Instructors/Instructor.html'
});
$locationProvider.html5Mode(true);
});
app.controller('MainController', MainController);
function MainController ($state) {
var vm = this;
vm.Submit=function( ){
$state.go('results');
};
}
So Results.html renders perfectly fine launched on it's own, but when navigated to - the controller is called but not bound to the html template.
You have your index.html file set up properly, but after that you're using ui-router incorrectly.
In your index.html file where you have:
<body ui-view>
this tells ui-router to load the contents of your templates into the body of your document, so your templates should just be snippets of html to be rendered within your body tag. So you should delete everything from results.html until all that remains is this:
<div id="headerBar" >
<div class="form-group" id="headerBar" >
<input class="form-control input-lg" type="text" id="inputlg" placeholder="Zipcode" />
<button id="sub" class="btn btn-default btn-lg" type="submit" ng-click="vm.getInstructors()">Find an Instructor!</button>
</div>
</div>
<table>
<tr ng-repeat="Instructors in vm.instructors">
<td style="padding-top:5px;">
<div>
<nav class="navbar">
<div class="container-fluid">
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="searchString" >
</div>
<button type="submit" class="btn btn-default" value="Filter">Search</button>
</form>
</div><!-- /.container-fluid -->
</nav>
</div>
</td>
</tr>
</table>
<div class="col-md-8">
</div>
<aside class="sidebar" ui-view="map">MAP</aside>
A few other things. You have the controller setup in your routes, so you don't need to specify it anywhere in results.html. Also you should not be able to navigate to results.html. Instead you would just navigate to (your domain)/results.

Knockout Clone Whole Item In foreach

I am trying to clone elements when clicking a button. I was trying to use ko.toJS. On page load it works fine, but when I want clone the items, it is unable to bind the items (like, value, Text, etc.).
Here is the HTML:
<div class="stockItems-inner" data-bind="foreach: StockItems">
<div data-bind="if: Type=='Input'">
<div class="stock_container_input">
<input type="text" data-bind="value: Value" />
</div>
</div>
<div data-bind="if: Type=='Radio'">
<div class="stock_container_control">
<div data-bind="foreach: Options">
<div class="stockLbl">
<input type="radio" data-bind="text: Text, checked:$parent.Value, attr:{'id':Id, 'name': $parent.Text, 'value': Value}" />
<label data-bind="attr:{'for':Id}, text: Text"></label>
</div>
</div>
</div>
</div>
</div>
<div class="addItem">
<button type="button" data-bind="click: CloneItem"><img src="images/add.png" alt="" /></button>
</div>
The View Model:
ConfigurationStockViewModel = function() {
var self = this;
this.StockItems = ko.observableArray();
this.ApplyData = function(data){
self.StockItems(data.Items);
}
this.CloneItem = function(StockItems){
self.StockItems.push(ko.toJS(StockItems));
};
};
When clicking the button, an error is thrown: Unable to process binding. I am using JSON data for binding.
Not exactly sure what end result you want without working code, but sounds like you want to clone the last item in array and add to array?
If so, I think you have an error - your add button click binding will never pass anything to the function you defined, since it is outside the foreach. You need something like this:
this.CloneItem = function() {
var toClone = self.StockItems()[self.StockItems().length - 1]
self.StockItems.push(toClone);
};
Here is a simplified example without radio buttons, etc:
http://jsfiddle.net/5J47L/

show a div on a button click using angularjs and HTML

I want to show a div on a button click using angularjs and HTML
I am learning angularJs.
I want to design a webpage in which on click of 'Add' button a div(EmployeeInfoDiv) is shown.
When I fill the textboxes in it and save it the data should reflect in table within the div(EmpDetTable).
Here is the HTML page code:
<body ng-app="MyApp">
<div ng-controller="EmpDetCtrl">
<div ng-model="EmpDetTable" class="container body" ng-hide="addEmp">
<label class="TabHeadings">Employee Details</label>
<div class="EmployeeInfo">
<table ng-model="Employee" border="1">
<thead><tr><th>Name</th><th>Designation</th><th>Salary</th></tr></thead>
<tbody>
<tr ng-repeat="emp in employees">
<td>{{emp.name}}</td>
<td>{{emp.desg}}</td>
</tr>
</tbody>
</table>
<button ng-model="AddEmp" ng-click="ShowAddEmployee()">Add</button>
</div>
</div>
<div ng-model="EmployeeInfoDiv" class="popover right EmployeeInfo" style="width:1500px;" ng-show="addEmp" >
<label class="TabHeadings" style="width:830px;">Employee Details</label>
<div class="EmployeeInfo">
<table>
<tr><td><label class="table_label">Name:</label></td><td><input type="text" ng-model="name" class="textbox"/></td>
<td><label class="table_label">Designation:</label></td><td><input type="text" ng-model="desg" class="textbox"/></td>
</tr>
</table>
<div ng-model="botton_container">
<button ng-model="save" class="save_buttons" ng-click="SaveData();">Save</button>
<button ng-model="cancel" class="cancel_buttons" ng-click="ShowViewEmployee();">Cancel</button>
</div>
</div>
</div>
</div>
</body>
Controller Code:
function EmpDetCtrl($scope) {
$scope.employees = [
{ name: 'A',desg: 'C'}
];
$scope.addNew = function () {
$scope.employees.push({
name: $scope.name,desg: $scope.desg
});
}
$scope.ShowAddEmployee= function () {
return $scope.EmployeeInfoDiv=true;
}
$scope.ShowViewEmployee=function () {
return $scope.EmployeeInfoDiv = false;
}
}
I don't know whether this code is correct or not.
I just tried it.
Can anyone please help me out.
Thanks in advance.
Your ng-click is updating the EmployeeInfoDiv variable. So, reference that in ng-show and ng-hide:
<div ng-hide="EmployeeInfoDiv" class="container body">
...
<div ng-show="EmployeeInfoDiv" class="popover right EmployeeInfo" style="width:1500px;">
You do not need ng-model in the div to make that work.
ng-model="EmployeeInfoDiv"
Update
A few more issues. Most important is that (at least in the code posted) MyApp isn't defined anywhere, and your controller is defined on the global scope. So you need to change your html to:
<div ng-app>
<div ng-controller="EmpDetCtrl">
...
However, note that this is not the recommended method. See the angular documentation for controllers.
Here is a working demo: http://jsfiddle.net/wittwerj/xrB77/