Linking rendered template with Angular js - javascript

My controller is defined as :
broConsoleApp.controller('actionCreateController', ['$scope', '$stateParams', '$sce', function ($scope, $stateParams, $sce) {
$scope.html = "";
var resp = [];
var params = {};
/* lot of other things here */
$scope.getHtml = function (type) {
$scope.html = "";
$.get(apiHost + "/action/type/defn/" + type).success(function (response) {
resp = response['RESPONSE']['ActionsParams']['param'];
console.log(resp);
if (resp instanceof Array) {
resp.forEach(function (entry) {
$scope.html = $scope.html + $.hbs("/web/templates/actionCreate.hbs", entry);
});
}
else
$scope.html = $scope.html = $scope.html + $.hbs("/web/templates/actionCreate.hbs", resp);
$scope.$apply(function () {
$scope.html = $sce.trustAsHtml($scope.html);
});
})
.error(function (jqXHR, textStatus, errorThrown) {
console.log("Failed to fetch XML.")
});
};
$scope.add = function(){
console.log(" entered add ...");
var $key = $("<input type='text' class='input-small form-control' placeholder='Key'>");
var $value = $("<input type='text' class='input-small form-control' placeholder='Value'>");
$('form #'+name).append($key);
$('form #'+name).append($value);
};
}]);
My get HTML function gets all the HTML and renders it against a JSON . My .hbs file looks like :
{{#if_eq type "MAP_VALUED"}}
<div class="col-lg-10 col-lg-offset-1 MAP_VALUED" id="{{name}}">
<label class="control-label col-lg-3">{{label}}</label>
<form class="col-lg-9 controls form-inline">
<input type="text" class="input-small form-control" placeholder="Key">
<input type="text" class="input-small form-control" placeholder="Value">
<button type="button" class="btn btn-primary pull-right" ng-click="add()">+</button>
</form>
<br><br>
</div>
{{/if_eq}}
Here I want an onClick action to call the method $scope.add() defined in the controller. The ' + ' button adds new key value forms basically.
I am binding this rendered HTML as :
<div ng-app="broConsoleApp" ng-controller="actionCreateController">
<div ng-bind-html="html"></div>
</div>
Since the rendered HTML ultimately is defined under broConsoleApp , the ng-cick should work right? Well it is not working. Can someone help me out here. Even if I use a jquery method onClick or something how do I do so without creating a new file. I want it to be in my controller.
Been stuck since morning.

Please check working example : https://jsfiddle.net/Shital_D/oyx0fd6e/3/
HTML
<div ng-app="broConsoleApp" ng-controller="actionCreateController">
<div compile="html"></div>
</div>
Create directive
app.directive('compile', function ($compile) {
return function (scope, element, attrs) {
scope.$watch(
function (scope) {
return scope.$eval(attrs.compile);
},
function (value) {
element.html(value);
$compile(element.contents())(scope);
}
);
};
});
And
Controller
app.controller('myController', function ($scope, $compile) {
$scope.html ='<div><button ng-click="callMe()">clickme</button><div>';
});

Related

View not updating when splicing user from list in AngularJS

I have this problem in my app, when I use slice to remove the user from the list. However, it does not remove from the list. I am getting the user with a API url call. But for some reason, it does not remove the user from the list. Please, have a look at my code. If, you guys want the full code, I have put it in my github. I hope we both can solve this. Thank you in advance.
Here is my code:
<div ng-controller="MyCtrl">
<div ng-repeat="person in userInfo.lawyers | filter : {id: lawyerId}">
<a class="back" href="#/lawyer">Back</a>
<button type="button" class="edit" ng-show="inactive" ng-click="inactive = !inactive">
Edit
</button>
<button type="submit" class="submit" ng-show="!inactive" ng-click="inactive = !inactive">Save</button>
<a class="delete" ng-click="confirmClick(); confirmedAction(person);" confirm-click>Confirm</a>
<div class="people-view">
<h2 class="name">{{person.firstName}}</h2>
<h2 class="name">{{person.lastName}}</h2>
<span class="title">{{person.email}}</span>
<span class="date">{{person.website}} </span>
</div>
<div class="list-view">
<form>
<fieldset ng-disabled="inactive">
<legend>Basic Info</legend>
<b>First Name:</b>
<input type="text" ng-model="person.firstName">
<br>
<b>Last Name:</b>
<input type="text" ng-model="person.lastName">
<br>
<b>Email:</b>
<input type="email" ng-model="person.email">
<br>
<b>Website:</b>
<input type="text" ng-model="person.website">
<br>
</fieldset>
</form>
</div>
</div>
</div>
App.js
var app = angular.module("Portal", ['ngRoute', 'ui.bootstrap' ]);
app.controller('MyCtrl', function($scope, $window) {
$scope.inactive = true;
$scope.confirmedAction = function (lawyer) {
$scope.$apply(function () {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
console.log($scope.userInfo.lawyers);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$window.location.href = '#/lawyer';
});
};
});
app.directive('confirmClick', ['$q', 'dialogModal', function($q, dialogModal) {
return {
link: function (scope, element, attrs) {
// ngClick won't wait for our modal confirmation window to resolve,
// so we will grab the other values in the ngClick attribute, which
// will continue after the modal resolves.
// modify the confirmClick() action so we don't perform it again
// looks for either confirmClick() or confirmClick('are you sure?')
var ngClick = attrs.ngClick.replace('confirmClick()', 'true')
.replace('confirmClick(', 'confirmClick(true,');
// setup a confirmation action on the scope
scope.confirmClick = function(msg) {
// if the msg was set to true, then return it (this is a workaround to make our dialog work)
if (msg===true) {
return true;
}
// msg can be passed directly to confirmClick('Are you sure you want to confirm?')
// in ng-click
// or through the confirm-click attribute on the
// <a confirm-click="Are you sure you want to confirm?"></a>
msg = msg || attrs.confirmClick || 'Are you sure you want to confirm?';
// open a dialog modal, and then continue ngClick actions if it's confirmed
dialogModal(msg).result.then(function() {
scope.$eval(ngClick);
});
// return false to stop the current ng-click flow and wait for our modal answer
return false;
};
}
}
}])
/*
Modal confirmation dialog window with the UI Bootstrap Modal service.
This is a basic modal that can display a message with yes or no buttons.
It returns a promise that is resolved or rejected based on yes/no clicks.
The following settings can be passed:
message the message to pass to the modal body
title (optional) title for modal window
okButton text for YES button. set false to not include button
cancelButton text for NO button. ste false to not include button
*/
.service('dialogModal', ['$modal', function($modal) {
return function (message, title, okButton, cancelButton) {
// setup default values for buttons
// if a button value is set to false, then that button won't be included
cancelButton = cancelButton===false ? false : (cancelButton || 'No');
okButton = okButton ===false ? false : (okButton || 'Yes');
// setup the Controller to watch the click
var ModalInstanceCtrl = function ($scope, $modalInstance, settings) {
// add settings to scope
angular.extend($scope, settings);
// yes button clicked
$scope.ok = function () {
// alert("Lawyer is confirmed");
$modalInstance.close(true);
};
// no button clicked
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
// open modal and return the instance (which will resolve the promise on ok/cancel clicks)
var modalInstance = $modal.open({
template: '<div class="dialog-modal"> \
<div class="modal-header" ng-show="modalTitle"> \
<h3 class="modal-title">{{modalTitle}}</h3> \
</div> \
<div class="modal-body">{{modalBody}}</div> \
<div class="modal-footer"> \
<button class="btn btn-primary" ng-click="ok()" ng-show="okButton">{{okButton}}</button> \
<button class="btn btn-warning" ng-click="cancel()" ng-show="cancelButton">{{cancelButton}}</button> \
</div> \
</div>',
controller: ModalInstanceCtrl,
resolve: {
settings: function() {
return {
modalTitle: title,
modalBody: message,
okButton: okButton,
cancelButton: cancelButton
};
}
}
});
// return the modal instance
return modalInstance;
}
}])
app.config(function ($routeProvider) {
$routeProvider
.when("/lawyer", {
controller: "HomeController",
templateUrl: "partials/home.html"
})
.when("/lawyer/:id", {
controller: "LawyerController",
templateUrl: "partials/about.html"
})
.otherwise({
redirectTo: '/lawyer'
});
});
But the element is getting deleted from list right?
If yes then, Try this :
$scope.confirmedAction = function (lawyer) {
$scope.$apply(function () {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
console.log($scope.userInfo.lawyers);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$window.location.href = '#/lawyer';
});
});
Or
$scope.confirmedAction = function (lawyer) {
$timeout(function () {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
console.log($scope.userInfo.lawyers);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$state.go($state.current, {}, {reload: true});
// $window.location.href = '#/lawyer';
},1100);
});
The problem is that you don't get the index from IndexOf when you using it on an array of objects like you do. Read more about the IndexOf here.
Instead, use map and then use IndexOf on that
Try it like this:
$scope.confirmedAction = function (lawyer) {
var index = $scope.userInfo.lawyers.map(function(e) { return e.id; }).indexOf(lawyer.id);
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$window.location.href = '#/lawyer';
};
And also, the controller changes will by default be detected by the digest loop of angular so no need to use $scope.$apply.
Also, simplifyed your plunker with the basic get array list and remove function. Use that to build your way forvered
https://plnkr.co/edit/w6NuVLcqzc5Rjs7L6Cox?p=preview

Get input value in a variable in Angularjs before submit to call a webapi

I would like to access the input field value inside a variable that could be used in AngularJS so that I could add it to a string with the help of which I could call a rest api.
kindly help.
<body ng-app="myApp">
<div ng-controller="myCtr">
<form name="myForm">
<input type="text" ng-model='pinCode' id="zip" onBlur="myZipcode">
{{city}}
{{state}}
</form>
</div>
<script>
var zip;
var pat1;
function myZipcode(){
zip = document.getElementById("zip").value;
pat1 = 'http://ziptasticapi.com/'+zip;
}
var myApp = angular.module('myApp' , []);
myApp.controller('myCtr', function($scope, $http){
var path = 'http://ziptasticapi.com/12345'
$http.get(pat1).success(function (response) {
$scope.city = response.city;
$scope.state = response.state;});
});
</script>
</body>
Here in http.get service if I use path variable instead of pat1 it works.
Another thing that I want the state and city to come dynamically without the form to be submitted and to be called from an REST API. That is why I am trying to get the input value inside a variable to accomplish the task
No need to define extra var for pinCode because of you used ng-model so you can access pinCode from your controller. Also should use ng-blur instead of onBlur.
You can use like
HTML:
<input type="text" ng-model='pinCode' id="zip" ng-blur="myZipcode()">
Controller:
var myApp = angular.module('myApp' , []);
myApp.controller('myCtr', function($scope, $http){
$scope.pinCode= ''; // defaulr empty
var path = 'http://ziptasticapi.com/';
$scope. myZipcode = function() {
$http.get(path + $scope.pinCode).success(function (response) {
$scope.city = response.city;
$scope.state = response.state;
});
};
});
You should not access html elements from your controller code. Angular's two way data-binding already transfers the form input's value into the $scope.pinCode variable. So you only need some action to trigger your server call. See this sample in the angular docs: https://docs.angularjs.org/api/ng/directive/ngSubmit
myApp.controller('myCtr', function($scope, $http) {
$scope.doCall = function() {
// $scope.pinCode() is set here
$scope.$http.get(...).then(
function(response) {
$scope.city = response.data.city; // or similar
}
);
}
});
just bind zip and pat1 on controller's scope
Controller:
myApp.controller('myCtr', function($scope, $http){
$scope.zip = document.getElementById("zip").value || 0;
$scope. pat1 = 'http://ziptasticapi.com/'+ $scope.zip || '';
$scope.myZipcode();
});
and then in zipcode
Zipcode function:
$scope.myZipcode = function myZipcode(){
$scope,zip = document.getElementById("zip").value;
$scop.pat1 = 'http://ziptasticapi.com/'+zip;
$http.get(pat1).success(function (response) {
$scope.city = response.city;
$scope.state = response.state;}
}
Complete code:
<body ng-app="myApp">
<div ng-controller="myCtr">
<form name="myForm">
<input type="text" ng-model='pinCode' id="zip" ng-blur="myZipcode">
{{city}}
{{state}}
</form>
</div>
<script>
myApp.controller('myCtr', function($scope, $http){
$scope.zip = document.getElementById("zip").value || 0;
$scope. pat1 = 'http://ziptasticapi.com/'+ $scope.zip || '';
$scope.myZipcode();
$scope.myZipcode = function myZipcode(){
$scope,zip = document.getElementById("zip").value;
$scop.pat1 = 'http://ziptasticapi.com/'+zip;
$http.get(pat1).success(function (response) {
$scope.city = response.city;
$scope.state = response.state;}
}
});
</script>
</body>

How to edit input fields using Angularjs?

I have my code that when you click on the "Add User" button a popup window shows up on the screen, and then I can type data in the input fields. After clicking on the "Save" button the data gets displayed on the page (inside of a table). I also have an "Edit" button which allows me to edit those fields. My question is...How to enable the Edit button so that when I click on it I get the popup window back and do the editing from there? this means that when I click on the Edit button I should get the popup with the data I typed in previously. Please someone help me. Thank you so much.
Here's my code:
var App = angular.module('App', ['ui.bootstrap'])
App.controller('mainController', function ($scope, $modal, $log, $filter) {
$scope.People = [];
$scope.openPopupScreen = function () {
var modalInstance = $modal.open({
template: '<div class="modal-header"> <a class="close" data-dismiss="modal" ng-click="cancel()"><i class="fa fa-times-circle-o" style="margin:10px;color:black;font-size:35px;"></i></a><h1>.</h1></div><div class="modal-body"><form >' +
' <label class="col-sm-3 control-label no-padding-right ng-binding">NAME:</label><input style = "width:200px;"type="text" class="form-control ng-scope ng-pristine ng-valid" ng-model="person.name"></br>' +
' <label class="col-sm-3 control-label no-padding-right ng-binding">LASTNAME:</label><input style = "width:200px;" type="text" class="form-control ng-scope ng-pristine ng-valid" ng-model="person.Lastname"></br>' +
' <label class="col-sm-3 control-label no-padding-right ng-binding">AGE:</label><input style = "width:200px;" type="number"class="form-control ng-scope ng-pristine ng-valid" ng-model="person.age"></br>' +
' <button id = "myid" type="button" class="btn btn-success" ng-click="add()"><i class="ace-icon fa fa-check"></i>Save</button>' +
' <button type="reset" class="btn ">Clear</button>' +
' </form>' +
'</div>' +
'<div class="modal-footer">' +
' <a data-dismiss="modal" aria-hidden="true" class="btn btn-primary" ng-click="cancel()">close</a>' +
'</div>',
controller: ModalInstanceCtrl
});
modalInstance.result.then(function (newPerson) {
$scope.People.push(newPerson);
});
};
var ModalInstanceCtrl = function ($scope, $modalInstance) {
$scope.person = {
name: '',
Lastname: '',
age: ''
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.add = function () {
$modalInstance.close($scope.person);
};
};
});
I have modified your fiddle. and it is working now as you said
http://codepen.io/anon/pen/XmGYaE?editors=001
$scope.editPerson = function(person){
console.log("pr", person);
var modalInstance = $modal.open({
template: modalTemplate ,
controller: ModalInstanceCtrl,
resolve: {
person: function () {
return person;
}
}
});
I have modified your(#Zohaib Ijaz) codepen.I do not use editperson function, I am just passing the person value in openPopupScreen and sending the people value through resolve. So we can reuse openPopupScreen function for both cases. I think it is better to reuse a function.
$scope.openPopupScreen = function(people) {
var modalInstance = $modal.open({
template: modalTemplate ,
controller: ModalInstanceCtrl,
resolve: {
person: function(){
return people;
}
}
});
};

I am calling a function on ng-keyup to search in database and after getting the result i am showing the result in a DIV..?

but when the input search is empty then also it is showing the result but I dont want the result to show when Input Search is Empty
here is my
Services:--
angular.module('a2BClientApp')
.service('AdminSearchService', ['$q', '$http', '$rootScope',
function ($q, $http, $rootScope,$cookies) {
var baseUrl = window.location.origin;
this.searchUser = function(authToken, data){
var deferred = $q.defer();
$http.post(baseUrl+'/api/v1/admin/users',
{searchString: data},
{headers: { 'Authorization': 'Bearer '+ authToken }})
.success(function (response) {
deferred.resolve(response);
$rootScope.user = response;
})
.error(function(err){
deferred.reject(err);
})
return deferred.promise;
}
}]);
and my controller is:
.controller('adminSearchCtrl', function ($scope, $rootScope, $location, AdminSearchService, $cookies){
// $rootScope.user = JSON.parse($cookies.get('AtoB')).user;
var userToken = JSON.parse($cookies.get('AtoB')).user;
$scope.searchUser = function(){
AdminSearchService.searchUser(userToken.token, $scope.userSearchData.searchByUser)
.then(function(response){
$scope.resppppp = response.results;
})
.catch(function(err){
$scope.error = err.message;
});
}
});
and my Html File where I am Showing the Details from server is
<div class="col-md-12 col-sm-12 col-xs-12 userSearchBar" ng-hide="showme">
<div class="search">
<span class="glyphicon glyphicon-search search_icon"></span>
<input class="query" placeholder="Search By User" name="searchByUser" ng-model="userSearchData.searchByUser" id="inputSearch" ng-keyup="searchUser()" />
</div>
<div ng-show="resppppp.length > 0">
<ul ng-repeat="rep in resppppp"><li>{{rep.email}}</li></ul>
</div>
<div ng-show="resppppp.length == 0">NO Result</div>
</div>
Please Help Me Out How to do that.I have added Screen Shot also for UnderStanding I am getting the result even search bar is empty
I got answer for the above question just simply check that input box is empty or not accordingly SHOW and HIDE your DIV
I have put condition in my controller like this inside function after this line
$scope.searchUser = function(){
if(inputSearch.value==0){
$("#dataFetchedFromServer").hide();
}
else{
$("#dataFetchedFromServer").show();
}
}
the id dataFetchedFromServer is given to this DIV
<div ng-show="resppppp.length > 0" id="dataFetchedFromServer"></div>

Why can't I do a $scope update within a jQuery scope?

I'm using typeahead to get some suggestions on an input text, this is inside a div controlled by an Angular controller.
The code for the suggestion tasks works with a jQuery plugin, so when I select, something I'm trying to assign a value to $scope, however this is NEVER happening.
I already tried getting the scope of the element with var scope = angular.element($("#providersSearchInput").scope() and then assign it as suggested here but it didn't work.
This is what I'm trying:
<div class="modal-body" ng-controller="ProvidersController" ng-init="orderReviewTab = 'observations'">
<input type="text" id="providersSearchInput" data-provide="typeahead" class="form-control input-md" placeholder="Buscar proovedores">
{{currentProvider}}
</div>
The controller looks like this:
tv3App.controller('ProvidersController', function($scope, $rootScope, $http, $timeout) {
var resultsCache = [];
$("#providersSearchInput").typeahead({
source: function (query, process) {
return $.get("/search/providers/?query=" + query, function (results) {
resultsCache = results;
return process(results);
},'json');
},
matcher: function (item) {
var name = item.name.toLowerCase();
var email = item.email.toLowerCase();
var contact_name = item.contact_name.toLowerCase();
//console.log(name);
var q = this.query.toLowerCase();
return (name.indexOf(q) != -1 || email.indexOf(q) != -1 || contact_name.indexOf(q) != -1);
},
scrollHeight: 20,
highlighter: function (itemName) {
var selected = _.find(resultsCache,{name:itemName});
var div = $('<div></div>');
var name = $('<span ></span>').html('<strong style="font-weight:bold">Empresa: </strong> ' + selected.name);
var contact = $('<span ></span>').html(' <strong style="font-weight:bold">Contacto: </strong> ' + selected.contact_name);
var email = $('<span ></span>').html(' <strong style="font-weight:bold">e-mail:</strong> ' + selected.email);
return $(div).append(name).append(contact).append(email).html();
},
minLength: 3,
items: 15,
afterSelect: function (item) {
console.log(item);
$scope.$emit('providerSelected',item);
}
});
$scope.$on('providerSelected', function (event,provider) {
console.log(provider);
$scope.currentProvider = provider;
$scope.$apply();
});
});
Edit
I tried this to check any changes:
$scope.$watch('currentProvider',function (newValue,oldValue) {
console.log(oldValue);
console.log(newValue);
});
So when selecting something it actually triggers and $scope.currentProvider seems to be updated but its never getting rendered at view ...
get https://angular-ui.github.io/bootstrap/
once you do, in your code make sure
angular.module('myModule', ['ui.bootstrap']);
and for typeahead have
<input type="text" ng-model="currentProvider" typeahead="provider for provider in getProviders($viewValue) | limitTo:8" class="form-control">
In your controller make sure you have
$scope.getProviders = function(val){
return $http.get('/search/providers/?query=' + val).then(function(response){
return response.data;
})
}
This should do the trick although I haven't tested

Categories

Resources