I'm trying to hide an portion of HTML that I've included in my index.html. What happens right now is when I search for a user a table, along with contents, gets rendered on the page. The behavior that I want is when "Clear" is pressed that included HTML table, along with its contents, is removed. Right now the table will only show if the $scope.user has a value and that check is done with ng-if. When I click the "Clear" button I set $scope.user to "false" which I thought would remove the include. I've also tried adding it to the table DOM element but that doesn't work either. What am I not getting? I'm sure it's a fairly simple fix for someone who knows more about Angular.
index.html
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{ message }}</h1>
<div>{{ error }}</div>
<form name="searchUser" ng-submit="search(username)">
<input type="search" required placeholder="Username..." ng-model="username" />
<input type="submit" value="Search" />
<button ng-click="clearSearch()">Clear</button>
</form>
<div ng-include="'userDetails.html'" ng-if="user"></div>
</body>
</html>
script.js
(function() {
var app = angular.module("githubViewer", []);
var MainController = function($scope, $http) {
var onUserComplete = function(response) {
$scope.user = response.data;
$http.get($scope.user.repos_url)
.then(onRepos, onError);
};
var onRepos = function(response) {
$scope.repos = response.data;
}
var onError = function(reason) {
$scope.error = "Could not fetch the data";
}
$scope.search = function(username) {
$http.get("https://api.github.com/users/" + username)
.then(onUserComplete, onError);
}
$scope.clearSearch = function() {
return ($scope.user = false);
}
$scope.message = "Github Viewer";
$scope.repoSortOrder = "+name";
};
app.controller("MainController", ["$scope", "$http", MainController])
}());
userDetail.html
<div>
<h2>{{ user.name }}</h2>
<img ng-src="http://www.gravatar.com/avatar/{{ user.gravatar_id }}" />
<h2>User Repositories</h2>
Order By:
<select ng-model="repoSortOrder">
<option value="+name">Name</option>
<option value="-stargazers_count">Stars</option>
<option value="+language">Language</option>
</select>
<table>
<thead>
<tr>
<th>Repository Name</th>
<th>Stars</th>
<th>Language</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="repo in repos | orderBy:repoSortOrder">
<td>{{ repo.name }}
</td>
<td>{{ repo.stargazers_count | number }}</td>
<td>{{ repo.language }}</td>
</tr>
</tbody>
</table>
</div>
I ended up figuring it out. The problem was that the
<button ng-click="clearSearch()">Clear</button>
was in the <form> so when I clicked the "Clear" button the Search function was being executed again. I noticed this via the Chrome console since I had XHR requests turned on...when I clicked "Clear" another GET was being executed.
I moved the button outside of the <form> and the functionality works as expected.
clearSearch() should be setting the value of $scope.user instead of returning a value:
$scope.clearSearch = function() {
$scope.user = false;
}
Related
I am working on angularjs routing where i have an array of employees in factory and the homecontroller displays those arrays in the view and view to html page (please correct me if my sequence or construction is wrong). I do edit and add employee operation on them . While doing edit operation , as soon as i click on the edit link, it routes to edit.html page and the view is controlled by EditController. However, i want the text boxes to contain and retain there original values, like empId:1, empName:John, empLocation:Mumbai when in edit.html page, but all the values doesn't come . Please help.
app.js
angular.module("Swabhav.Employee",['ngRoute'])
.config(['$routeProvider',function($routeProvider){
$routeProvider
.when('/',{
controller:"HomeController",
templateUrl:"home.html"
})
.when('/add',{
controller:"AddController",
templateUrl:"add.html"
})
.when('/home',{
controller:"HomeController",
templateUrl:"home.html"
})
.when('/edit/:empId',{
controller:"EditController",
templateUrl:"edit.html"
})
}])
EmployeeService Factory
angular.module("Swabhav.Employee")
.factory("EmployeeService",["$log",function($log){
var employees=[{"empId":1,"name":"John","location":"Mumbai"},
{"empId":2,"name":"Nikita","location":"Mumbai"},
{"empId":3,"name":"Saurab","location":"Pune"},
{"empId":4,"name":"Ankita","location":"Bangalore"},
{"empId":5,"name":"Harsh","location":"Chennai"},
{"empId":6, "name":"Geeta","location":"Vellore"}];
var obj={};
obj.displayAll=function(){
return employees;
}
obj.getById = function(Id){
var employee=[];
$log.log("emp id = "+ Id)
angular.forEach(employees,function(value,key){
if(value.empId==Id){
$log.log("inside");
$log.log(employees);
$log.log(value.location)
employee.push({empId:value.empId,name:value.name,location:value.location});
$log.log(employee)
}
return (employee);
})
}
obj.addEmployee=function(Id,Name,Location){
$log.log(employees)
employees.push({empId:Id,name:Name,location:Location})
return employees;
}
obj.editEmployee=function(employeeId,employeeName,employeeLocation){
var index;
for(index=0;index<employees.length;index++){
if(employees.indexOf(employeeId) != -1){
$log.log("edit employee = "+ employees[index])
employees.empId=employeeId;
employees.name=employeeName;
employees.location=employeeLocation;
}
}
return employees;
}
return obj;
}])
HomeController
angular.module("Swabhav.Employee")
.controller("HomeController",
["$scope","EmployeeService","$log","$window",function($scope,
EmployeeService,$log,$window){
$log.log (EmployeeService.displayAll());
$scope.data=EmployeeService.displayAll();
}])
AddController
angular.module("Swabhav.Employee")
.controller("AddController",
["$scope","EmployeeService","$log","$window",function($scope,
EmployeeService,$log,$window){
$scope.add=function(empId,name,location){
$scope.Id=empId;
$scope.Name=name;
$scope.Location=location
EmployeeService.addEmployee($scope.Id,$scope.Name,$scope.Location);
$window.location.href = "#/home";
}
}])
EditController
angular.module("Swabhav.Employee")
.controller("EditController",
["$scope","EmployeeService","$log","$window","$routeParams",
function($scope,EmployeeService,$log,$window,$routeParams){
$scope.employeeData=EmployeeService.displayAll();
$log.log("$scope.employeeData = "+ $routeParams.empId )
$scope.empIdvalue = $routeParams.empId;
$scope.editDisplay=
EmployeeService.getById($scope.empIdvalue);
$log.log("EmployeeService.getById(3)"+EmployeeService.getById(3));
$scope.edit= function(empId,name,location){
$scope.Id=empId;
$scope.Name=name;
$scope.Location=location
EmployeeService.editEmployee($scope.Id,$scope.Name,$scope.Location);
$window.location.href = "#/home";
}
}])
home.html
<article>
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Location</th>
<th> Edit </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="employee in data" >
<td>{{employee.empId}} </td>
<td>{{employee.name}} </td>
<td>{{employee.location}}</td>
<td>Edit
</td>
</tr>
</tbody>
<br>
Add Employee
</table>
</article>
edit.html
<article>
<h3>Edit Page</h3>
<br><br>
empId:<input type="text" ng-value=empIdvalue ng-model="employeeId">
empName:<input type="text" ng-value=empNamevalue ng-model="employeeName">
empLocation:<input type="text" ng-value=empLocationvalue ng-
model="employeeLocation">
<button type="button" ng-
click="edit(employeeId,employeeName,employeeLocation)">Edit</button>
</article>
index.html
<html ng-app="Swabhav.Employee">
<head>
<title>Employee</title>
<script src="angular.js"></script>
<script src="angular-route.js"></script>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
</script>
</head>
<body>
<script src="app.js"></script>
<section ng-view></section>
</body>
</html>
You should not use ng-value. You can use the $scope.editDisplay variable as model. You can change your code like this.
edit.html
<article>
<h3>Edit Page</h3>
<br><br>
empId:<input type="text" ng-model="editDisplay.empId">
empName:<input type="text" ng-model="editDisplay.name">
empLocation:<input type="text" ng-model="editDisplay.location">
<button type="button" ng-
click="edit(editDisplay)">Edit</button>
</article>
EditController
angular.module("Swabhav.Employee")
.controller("EditController",
["$scope","EmployeeService","$log","$window","$routeParams",
function($scope,EmployeeService,$log,$window,$routeParams){
$scope.employeeData=EmployeeService.displayAll();
$log.log("$scope.employeeData = "+ $routeParams.empId )
$scope.empIdvalue = $routeParams.empId;
$scope.editDisplay=
EmployeeService.getById($scope.empIdvalue);
$log.log("EmployeeService.getById(3)"+EmployeeService.getById(3));
$scope.edit= function(editDisplay){
EmployeeService.editEmployee(editDisplay.empId,editDisplay.name,editDisplay.location);
$window.location.href = "#/home";
}
}])
You need to change you editcontroller like this:
angular.module("Swabhav.Employee")
.controller("EditController",
["$scope","EmployeeService","$log","$window","$routeParams",
function($scope,EmployeeService,$log,$window,$routeParams){
$scope.param1 = $routeParams.empId;
$scope.employeeData=EmployeeService.displayAll();
$scope.empIdvalue = $routeParams.empId;
$scope.editDisplay=
EmployeeService.getById($scope.empIdvalue);
$scope.param2 = $scope.editDisplay[0]["location"];
$scope.param3 = $scope.editDisplay[0]["name"];
$scope.edit= function(empId,name,location){
$scope.Id=empId;
$scope.Name=name;
$scope.Location=location;
EmployeeService.editEmployee($scope.Id,$scope.Name,$scope.Location);
$window.location.href = "#/home";
}
}])
param1 param2 and param3, will be used in your ng-model in edit.html.
<article>
<h3>Edit Page</h3>
<br><br>
empId:<input type="text" disabled="disabled" ng-model="param1">
empName:<input type="text" ng-value="editDisplay[0]['name']" ng-model="param2">
empLocation:<input type="text" ng-value="editDisplay[0]['location']" ng-model="param3">
<button type="button" ng-click="edit(editDisplay[0]['empId'],param2,param3)">Edit</button>
</article>
return
Another error you have comitted in getById function, thinking that foreach promises return a value to the container parent function, no it just throws back to the nearer promise, it is rather adviced to use a filter selector like this:
obj.getById = function(Id){
return employees.filter(function(value,key){
if(value.empId==Id)
return 1;
else
return 0;
})
}
Finally there is another substiantial change in editEmployee function, you seem to jumble it a whole.
obj.editEmployee=function(employeeId,employeeName,employeeLocation){
var index=employees.map((id)=>id.empId).indexOf(employeeId);
if(index != -1){
$log.log("edit employee = "+ employees.map((id)=>id.name)[index])
employees[index].empId=employeeId;
employees[index].name=employeeName;
employees[index].location=employeeLocation;
}
return employees;
}
forked here
On my home screen ,I seacrh some data by calling angular controller(SeacrhController),then I click on a button(Start) on home page,which open another tab.On clicking done button on second tab,that second tab is closed and parent page is refreshed.
I want to have data searched earlier on my parent page.Can anyone please tell,how I can achieve this.How can I maintain session.
I tried Cookies and localStorage ,but could not get things working.Any help pls.
common.js :
var myApp = angular.module('MyApp', []);
myApp.controller('SearchController', function($scope,$http) {
$scope.clientVO = {};
$scope.getClientDetail = function(bcidNo) {
var response=$http.get('/testWeb/rest/clientData/'+ id);
response.success(function(data) {
console.log("getActor data: " + angular.toJson(data, false));
$scope.clientVO = data;
})
response.error(function(data, status, headers, config) {
alert("AJAX failed to get data, status=" + status);
})
}
});
home.html :
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<script src="../javascripts/common/common.js"></script>
</head>
<!--some code -->
<div ng-controller="SearchController">
<form class="content-left-body">
<div class="client-details">
<span class="content-right-header">Client Details</span>
<table>
<tr><td>
<label>Client ID:</label></td>
<td><input type="text" name="id" id="Search"
placeholder="Search" ng-model="id" class="search-box"/>
<img alt="Search" src="../images/search_img.png" ng-click= "getClientDetail(id);" style="margin-left:-15% ; margin-top:2.5%">
</td>
<td>
<div ng-show="clientVO.clientName==''"><label style="color:red">ID not found in database.</label></div>
</td>
</table>
<div>
<div>
<table style="width: 100%">
<tr >
<td><label>Client Name:</label></td>
<td><span ng-show="!clientVO.clientName">-</span><label ng-bind="clientVO.clientName"></label></td>
<td><label>AccNo:</label></td>
<td><input type="text" ng-disabled="!clientVO.clientName"></td>
</tr>
<tr >
<td><label>Contact Name:</label></td>
<td><span ng-show="!clientVO.contactName">-</span><label ng-bind="clientVO.contactName"></label></td>
<td><label>Validation Level:</label></td>
<td>
<select ng-disabled="!clientVO.clientName">
<option value="">-Please Select-</option>
<option value="">Level 1</option>
<option value="">Level 2</option>
<option value="">Level 3</option>
<option value="">Level 4</option>
</select>
</td>
</tr>
</table>
</div>
<div class="Data-details">
<div class="data">
<div class="content-left-body">
<span class="content-left-header">Data details</span>
<span class="content-left-header-small">Data classification</span>
<label id="clientClassification" ></label> <br><br>
<button id="btn-yellow" onClick=window.open("classification.html","fullscreen=yes");>Start</button>
</div>
</div>
</div>
</form>
<!---some code -->
</html>
I have this simple service to store data in localStorage (note that localStorage won't work here in SO)
angular.module('app', [])
.controller('AppCtrl', ['StorageSrv', function(StorageSrv){
StorageSrv.set('user', {first: 'John', last: 'Doe'})
console.log(StorageSrv.get('user'));
}]);
// This service can live in a separate file
angular.module('app')
.service('StorageSrv', ['$rootScope', function ($rootScope) {
var self = this,
prefix = 'your_prefix',
ls = window.localStorage;
self.set = function(key, val){
var obj = {};
_.set(obj, key, val);
ls.setItem(prefix, JSON.stringify(obj));
};
self.get = function(keyPath){
if (!keyPath || !_.size(keyPath))
return JSON.parse(ls.getItem(prefix));
else
return _.get(JSON.parse(ls.getItem(prefix)), keyPath, null);
};
self.delete = function(keyPath){
var key = prefix + '_'+_.trimStart(key, prefix);
var current = self.get(key);
_.unset(current, keyPath);
if (!_.size(current)){
self.update(key, {})
}
else {
self.update(key, current);
}
};
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="AppCtrl"></div>
I am building an angularjs app which starts from a login page but when I execute my login page,i get below error in console.
[$injector:modulerr] Failed to instantiate module bookApp due to:
ReferenceError: 'when' is undefined
at Anonymous function
PFB The relevant files.Any help is much appreciated.Thanks in advance.
P.S. Please let me know if any more information is required.
HTML :
<!doctype html>
<!--Mention the module name to <html> -->
<html ng-app="bookApp">
<head>
<title>Angular Assignment</title>
<style type="text/css">
#import "styles/style.css";
</style>
<script src="lib/Angular/angular.js"></script>
<script src="lib/Angular/angular-route.js"></script>
<script src="js/controllers.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<center>
<!--include header.html -->
<div ng-include="'Header.html'"></div>
</center>
<!-- Add the required controller to this div.
Associate the models for username and password.-->
<div align="center" ng-controller="LoginCtrl">
<h2> Login </h2>
<div class="LoginFormDiv">
<table border="0">
<tr>
<td> Username </td>
<td>:
<input ng-model="username" class="input" placeholder="Enter Username"/>
</td>
</tr>
<tr>
<td> Password</td>
<td>:
<input ng-model="password" class="input" placeholder="Enter Password"/>
</td>
</tr>
<tr>
<td colspan="2">
<!-- On click of the button, call validate(user) method declared in controller-->
<input type="submit" class="button" value="Login" ng-click="validate()"/>
</td>
</tr>
</table>
</div>
</div>
<!-- include footer.html -->
<center>
<div ng-include="'Footer.html'"></div>
</center>
</body>
</html>
Controller.js
var Controllers = angular.module('Controllers', ['ngRoute']);
Controllers.controller('LoginCtrl', ['$scope', '$location', '$http', '$rootScope',
function($scope, $location, $http, $rootScope) {
alert("I am in LoginCtrl")
$scope.validate = function() {
alert("I am in validate function");
$http.get('data/roles.json').success(function(data) {
$scope.roles = data;
});
var count = 0;
angular.forEach($scope.roles, function(role) {
if ($scope.username == role.username && $scope.password == role.password) {
alert("login successful");
count = count + 1;
if ($scope.roles == "student") {
$location.path("/home/student");
} else {
$location.path("/home/librarian");
}
} else if (count != 1) {
alert("Please provide valid login credentials");
$location.path("/main")
}
});
}
}]);
app.js
var bookApp = angular.module('bookApp', ['Controllers', 'ngRoute']);
bookApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.when('/main', {
templateUrl : 'Login',
controller : 'LoginCtrl'
}).when('/home/student', {
templateUrl : 'ViewBooks_Student.html',
controller : 'BookListCtrl_Student'
});
when('/home/librarian', {
templateUrl : 'ViewBooks_Librarian.html',
controller : 'BookListCtrl_Librarian'
});
when('/issue/:bookId', {
templateUrl : 'IssueBook.html',
controller : 'IssueBookCtrl'
});
when('/return/:bookId', {
templateUrl : 'ReturnBook.html',
controller : 'ReturnBookCtrl'
});
otherwise({
redirectTo : '/main'
});
}]);
routeProvider.when().when().when() works.
routeProvider.when();when();when() doesn't. Semicolons matter.
What changes need to be made to get the code below to successfully call the same validation directive from multiple different forms using AngularJS? Note that the first form is able to validate correctly, in that it checks for an even number of open parens ( and close parens ) and alerts the user immediately if the number is not equal.
However, when I try to get the second form to share the first directive, the second form fails to have the parens validation. And when I create a duplicate directive with a different name and call the duplicate directive from the second form, the second form's validation disables submit when there are unequal numbers of open and close parens BUT FAILS TO NOTIFY THE USER.
It seems silly to have redundant directives when the same validation will be used on many forms in a site.
This might (or might not) be complicated by the fact that each form is in a different include that is exchanged in the same index.html in a single-page web application. To rule out this possibility, I am including all the code required to reproduce the problem as follows:
index.html is:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>iPlotmy</title>
<link rel="stylesheet" type="text/css" href="resources/css/my.css">
</head>
<body ng-app="myApp">
<!-- build:js({app,.tmp}) scripts/main.js -->
<script src="js/lib/angular.js"></script>
<script src="js/lib/angular-resource.js"></script>
<script src="js/lib/angular-ui-router.js"></script>
<script src="js/lib/angular-ui-router-statehelper.js"></script>
<script src="js/lib/angular-animate.js"></script>
<script src="js/lib/angular-cookies.js"></script>
<script src="js/lib/angular-storage.js"></script>
<script type="text/javascript" src="myController.js"></script>
<div ng-controller="myController">
<table width=100%>
<tr>
<td colspan=3 align=center>
<table>
<tr>
<th>
<button ng-click="firstLink()">first link</button>
</th>
<th>
<button ng-click="secondLink()">second link</button>
</th>
</table>
</td>
</tr>
<tr>
<td>
<div ng-if="linktype == 'first'">
<div ng-include="'index_firstinclude.html'"></div>
</div>
<div ng-if="linktype == 'second'">
<div ng-include="'index_secondinclude.html'"></div>
</div>
</td>
</tr>
</table>
</div>
</body>
</html>
The index_firstinclude.html is:
<table>
<tr>
<td width=200>
<form name="userForm" ng-submit="firstForm(userForm.$valid)" novalidate>
<input type="text" name="func1" ng-model="firstplot.func1" required data-countparens=""/>
<p ng-show="userForm.func1.$error.required && !userForm.func1.$pristine" class="help-block">Function is a required field.</p>
<p ng-show="userForm.func1.$error.countparens" class="help-block">The number of open parentheses ( does not equal the number of close parentheses ) !</p>
<br>
<button type="submit" ng-disabled="userForm.$invalid" >Click to Submit</button>
</form>
</td>
</tr>
</table>
The index_secondinclude.html is:
<table>
<tr>
<td width=200>
<form name="mysecondForm" ng-submit="secondForm(mysecondForm.$valid)" novalidate>
<input type="text" name="func1" ng-model="secondplot.func1" required data-countparens=""/>
<p ng-show="mysecondForm.func1.$error.required && !mysecondForm.func1.$pristine" class="help-block">Function is a required field.</p>
<p ng-show="mysecondForm.func1.$error.countparenssecond" class="help-block">The number of open parentheses ( does not equal the number of close parentheses ) !</p>
<br>
theta min: <input type="text" ng-model="secondplot.tmin"/>
<br>
theta max: <input type="text" ng-model="secondplot.tmax"/>
<button type="submit" ng-disabled="mysecondForm.$invalid" >Click to Submit</button>
</form>
</td>
</tr>
</table>
The relevant parts of the myController.js file:
// create angular app
var myApp = angular.module('myApp', []);
// create angular controller
myApp.controller('myController', ['$scope', '$http', function($scope, $http) {
$scope.linktype = 'home';
$scope.firstplot = {type:"firstplot", func1: 'some (test) value'};
$scope.secondplot = {type:"secondplot", func1: 'another (test) value'};
$scope.firstForm = function(isValid) {
// check to make sure the form is completely valid
if (isValid) {
var funcJSON = {type:"firstplot", func1: $scope.firstplot.func1};
$http.post('/path/to/first-server-url', funcJSON).then(function(response) {
$scope.firstplot = response.data;
});
}
};
$scope.secondForm = function(isValid) {
console.log("inside secondForm")
if (isValid) {
$scope.secondplot.uri = "resources/images/plot-second-equation.gif";
var funcJSON = {type:"secondplot", func1: $scope.secondplot.func1};
$http.post('/path/to/second-server-url', funcJSON).then(function(response) {
$scope.secondplot = response.data;
});
}
};
//below functions handle navigation links
$scope.firstLink = function() {
$scope.linktype = 'first';
}
$scope.secondLink = function() {
$scope.linktype = 'second';
}
}]);
/// below directive(s) for form validation
myApp.directive('countparens', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.countparens = function(modelValue, viewValue) {
return ctrl.$isEmpty(modelValue) ||
((modelValue.match(/\)/g) || []).length == (modelValue.match(/\(/g) || []).length);
};
}
};
});
myApp.directive('countparenssecond', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.countparenssecond = function(modelValue, viewValue) {
return ctrl.$isEmpty(modelValue) ||
((modelValue.match(/\)/g) || []).length == (modelValue.match(/\(/g) || []).length);
};
}
};
});
I have a table and in of it's column I want user when click on button that is inside this column pop up window appear which have checkboxes and after user checked checkbox it will be appear as output in same column which were have a button as well as post these values of selected checkboxes and user name to database (PHP). I'm a beginner and i wish anyone help me.
help.html code :
<html>
<head>
<SCRIPT LANGUAGE="JavaScript">
myPopup = '';
function openPopup(url) {
myPopup = window.open(url,'popupWindow','width=640,height=480');
if (!myPopup.opener)
myPopup.opener = self;
}
</SCRIPT>
</script>
</head>
<body>
<table border="1">
<tr>
<th> user name </th>
<th>product selected</th>
</tr>
<tr>
<td> <input type="text"/></td>
<td> <button onclick="openPopup('f.html')">select</button></td>
</body>
</html>
And this my f.html code:
<HTML>
<HEAD>
</HEAD>
<BODY>
<FORM NAME="popupForm">
<INPUT TYPE="checkbox" >Cell phone</br>
<INPUT TYPE="checkbox" >TV</br>
<INPUT TYPE="checkbox" >Book</br>
<INPUT TYPE="BUTTON" VALUE="Submit">
</FORM>
</BODY>
With AngularJS you would do it like this:
Get the data from server with an ajax request. In the demo I've used static data to reduce complexity.
Create a ng-repeat to create the table
Add the selected data that is stored in an array into the table cell.
Make the list clickable by adding ng-click that opens a bootstrap modal to the table cell or wrap the selected data in a button.
In the modal create a form with ng-repeat with your selected products. Testing if the current item is clicked can be done with array.indexOf(item) !== -1 that returns true if the item is in the array.
With every click to the checkboxes update the product array.
After OK button click, close modal and post the updated data to the server with an ajax request. (A check if the data have changed would be good.)
You could also do it with-out AngularJS but I think there you would have to do a lot more code to get that behaviour.
(I'm also pretty new to javascript and AngularJS, so the code is not perfect, but it works.)
There are probably somethings that could be improved e.g. work with services to do the ajax requests.
There is one bug in the script:
The cancel click is not working as expected. The data will be changed even with cancel click.
You can fix this by working with a copy of the scope data or restore the original data if cancel is clicked.
DEMO
Please find the demo below (it is not working here because it seems that bootstrap.ui uses cookies that are not allowed at SO) and here at jsFiddle. Check it at jsFiddle. There it works.
var app = angular.module('myApp', ['ui.bootstrap']);
app.controller('mainController', function($scope, $modal, $log) {
$scope.products = ['coffee', 'beer', 'wine', 'tea', 'milk'];
// userData will be later from server with $http.get('/phpscript').success(...)
// just dummy userData here because no backend available
$scope.userData = [
{
name: 'John Doe',
selectedProducts: [
'coffee',
'beer',
'wine']
},
{
name: 'Jane Doe',
selectedProducts: [
'coffee',
'tea']
}
];
$scope.changeProducts = function(userData) {
//$scope.items = ['item1', 'item2', 'item3'];
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
//size: size,
resolve: {
user: function() {
return userData;
},
selectedProducts: function() {
return userData.selectedProducts;
},
products: function () {
//console.log($scope.selectedProducts);
return $scope.products; // get all available products
}
}
});
modalInstance.result.then(function (selectedItems) {
//products = selectedItems;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
app.controller('ModalInstanceCtrl', function ($scope, $http, $modalInstance, products, selectedProducts, user) {
//console.log('user', user);
$scope.products = products;
$scope.selected = selectedProducts;
$scope.chkChange = function(item) {
console.log(item);
var index = $scope.selected.indexOf(item);
if (index > -1) {
$scope.selected.splice(index, 1);
}
else {
// not selected --> we have to add it
$scope.selected.push(item);
}
console.log($scope.selected);
};
//console.log(selectedProducts);
$scope.ok = function () {
// prepare everything for sending to sever
// --> probably check here if the data have changed or not (not implemented yet)
console.log('new selection', $scope.selected);
var data = $.param({
json: JSON.stringify({
user: user.name,
products: $scope.selected
})
});
$http.post('/echo/json/', data)
.success(function(data, status) {
console.log('posted the following data:', data);
});
$modalInstance.close();//); $scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
//custom filter to display the selected products.
app.filter('array', function() {
return function(input) {
//console.log(input);
return input.join(', ');
};
});
body {
padding: 5px;
}
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.1.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<div ng-app="myApp">
<div ng-controller="mainController">
<script type="text/ng-template" id="myModalContent.html">
<!-- template for modal -->
<div class="modal-header">
<h3 class="modal-title">Choose your products!</h3>
</div>
<div class="modal-body">
<form>
<div class="checkbox" ng-repeat="item in products">
<label>
<input type="checkbox" ng-click="chkChange(item)" ng-checked="selected.indexOf(item) !== -1"/>
{{item}}
</label>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<table class="table">
<tr>
<th>User name</th>
<th>products selected</th>
</tr>
<tr ng-repeat="user in userData">
<td>{{user.name}}</td>
<td><button ng-click="changeProducts(user)">{{( user.selectedProducts | array ) || 'nothing selected!' }}</button></td>
</tr>
</table>
</div>
</div>
This snippet will pop up the box. And the submit will submit everything. I do not think this is what you want. I am guess there will be more products.
Select opens popup
Submit submits to product.php
function openPopup(){
var pop = document.getElementById('pop').style.display='block';
}
#pop{
font:400 1em Arial,sans-serif;
width:20em;
display:none;
position:absolute;
top:0;left:0;
background:#ff0;
color:#000;
height:8em;
z-index:10;
}
#frm{width:100%;}
<FORM id="frm" action="product.php" method="post"><div>
<div id="pop">
<INPUT TYPE="checkbox" >Cell phone</br>
<INPUT TYPE="checkbox" >TV</br>
<INPUT TYPE="checkbox" >Book</br>
<INPUT TYPE="submit" VALUE="Submit">
</div>
</div>
<table border="1">
<tr><th> user name </th><th>product selected</th></tr>
<tr><td> <input type="text"/></td>
<td> <button type="button" onclick="openPopup()">Select</button></td>
</tr></table>
</form>
This snippet will pop up the box. you could get the check box values with JS but I think it would be better to submit to a PHP script at this point. but only you know this. I am now working on submitting everything to a script.
Select opens popup
Submit closes popup
function openPopup(){
var pop = document.getElementById('pop').style.display='block';
}
function closePopup(){
var pop = document.getElementById('pop').style.display='none';
}
#pop{
font:400 1em Arial,sans-serif;
width:20em;
display:none;
position:absolute;
top:0;left:0;
background:#ff0;
color:#000;
height:8em;
z-index:10;
}
#frm{width:100%;}
<div id="pop">
<FORM id="frm" NAME="popupForm"><div>
<INPUT TYPE="checkbox" >Cell phone</br>
<INPUT TYPE="checkbox" >TV</br>
<INPUT TYPE="checkbox" >Book</br>
<INPUT TYPE="BUTTON" VALUE="Submit"onclick="closePopup()">
</div></FORM>
</div>
<table border="1">
<tr>
<th> user name </th>
<th>product selected</th>
</tr>
<tr>
<td> <input type="text"/></td>
<td> <button onclick="openPopup()">select</button></td>