row add using angular code. Input box model name is "code". when click this input box a model open and when any row select using angularjs then there is a problem when I assign value using $scope.code it will assign to all input box in but I want to assign that value by which ng-click performed.
<table class="table table-bordered table-hover table-condensed">
<tr style="font-weight: bold">
<td style="width:35%">Code</td>
</tr>
<tr ng-repeat="user in users">
<td>
<!-- editable username (text with validation) -->
<span ng-show="editDel">
#{{ user.name || 'empty' }}
</span>
#{{code}}
<input type="text" name="" ng-model="code" ng-show="saveCancel" ng-click="getCode()">
</td>
<td style="white-space: nowrap">
<!-- form -->
<form ng-show="saveCancel" class="form-buttons form-inline">
<button type="submit" class="btn btn-primary">
save
</button>
<button type="button" ng-click="isCancel()" class="btn btn-default">
cancel
</button>
</form>
<div class="buttons" ng-show="editDel">
<button class="btn btn-primary" ng-click="editUser($index)">edit</button>
<button class="btn btn-danger" ng-click="removeUser($index)">del</button>
</div>
</td>
</tr>
</table>
$scope.users = [];
$scope.saveCancel = false;
$scope.editDel = true;
$scope.saveUser = function(data, id) {
//$scope.user not updated yet
angular.extend(data, {id: id});
return $http.post('/saveUser', data);
};
// remove user
$scope.removeUser = function(index) {
$scope.users.splice(index, 1);
};
// add user add row
$scope.addUser = function() {
$scope.inserted = {
id: $scope.users.length+1,
name: '',
status: null,
group: null
};
// $scope.taxNamePopup();
$scope.users.push($scope.inserted);
};
$scope.getCode = function(){
// alert(input_id);
this.code = 'nameValue';//**this assin value to selected box**
// jQuery("#tax_modal").modal("hide");
var request = $http({
method: "get",
url: base_url+"/load-tax",
data: {
},
}).then(function successCallback(response) {
jQuery("#tax_list").modal("show");
$scope.tax_data1 = response;
}, function errorCallback(response) {
});
}
$scope.getSelected = function(id,code,desc,rate){
alert(code);
this.code = code;//**but i want to assign value to selected input box from here**
jQuery("#tax_list").modal("hide");
}
$scope.safeApply(function() {
$scope.editUser = function($id){
this.saveCancel = true;
this.editDel = false;
}
});
$scope.isCancel = function(){
this.saveCancel = false;
this.editDel = true;
}
it is because ng-model is codefor every input.
Change it with following code example
<input type="text" name="" ng-model="code_$index" ng-show="saveCancel" ng-click="getCode($index)">
Now above code will change the ng-model unique for each input field and retrieve the value in getCode on the basis of index.
the model should be different for each ng-repeat item
EDIT change from getCode(user.code) to getCode(user)
<input type="text" name="" ng-model="user.code" ng-show="saveCancel" ng-click="getCode(user)">
use the param how ever you want ;)
$scope.getCode = function(user){
angular.forEach($scope.users, function (value, key) {
if (value.id == user.id) {
$scope.users[key]=user;
}
});
}
Related
In the following piece of code, I am trying to pass 4 values to my controller through an AJAX call. The variable "NewType" loses its value, while the other three variables do not. NewType is pulling its value from a drop down list, while the other three are from text boxes. If I debug and step through the code, the variable retains its value. If I run the code through, the value is cleared out. Looking through similar problems, it seems obvious that it has something to do with the asynchronous Ajax call. Any ideas appreciated!!!
HTML
<tbody>
<!--Row created for each pesticide listed in Pesticides db table pulled in by Owner-->
#foreach (PesticideModel p in Model)
{
// Only show rows where IsDeleted == 0 (false)
if (#p.IsDeleted == false)
{
<tr class="toggler ui-sortable-handle" onclick="GetPestDetails()">
<!--Column for Owner-->
<td class="OwnerTD" id="OwnerBox">#p.Owner</td>
<!--Column for Brand Name-->
<td class="form-group-sm"><input type="text" name="BrandName" id="BrandName" disabled style="width:100%" value="#p.BrandName" /></td>
<!--Column for Original Brand Name-->
<td class="form-group-sm" style="display:none" id="OrigBrandName">#p.BrandName</td>
<!--Column for Pesticides Id-->
<td class="form-group-sm" style="display:none" id="PestIdBox">#p.PesticidesID</td>
<!--Column for EPA Reg No-->
<td class="form-group-sm"><input type="text" name="EPARegNo" id="EPARegNoBox" disabled style="width:100%" value="#p.EPARegNo" /></td>
<!--Column for Type-->
<td class="form-group-sm">
#*<td class="form-group-sm"><input type="text" name="Type" id="TypeBox" style="width:100%" value="#p.Type" disabled /></td>*#
#Html.DropDownListFor(x => #p.Type, (SelectList)ViewBag.Types, #p.Type, new { #class = "form-group-sm", #disabled = "disabled", id = "PType", name = "PType", onchange = "SetHiddenField(); return true;" } ) </td>
<!--Column for HiddentType --hidden column-->
<td class="HiddenType" id="HiddenType" hidden>#p.Type</td>
<!--Column for Editing Buttons-->
<td class="btn-group-sm">
<button type="button" class="btn btn-primary btn-warning" id="EditPesticideButton" name="EditButton" onclick="EditPesticideAction()">Edit</button>
<button type="button" class="btn btn-primary" id="SavePesticideButton" style="display:none" onclick="SavePesticideConfirm()">Save</button>
<button type="button" class="btn btn-primary" id="DeleteButton" style="display:none" onclick="DeletePesticideConfirm()">Delete</button>
<button type="button" class="btn btn-primary" id="CancelPesticideButton" style="display:none" onclick="CancelPesticideAction()">Cancel</button>
</td>
<!--Column for IsDeleted --hidden column-->
<td class="IsDeleted" id="IsDeleted" hidden>#p.IsDeleted</td>
</tr>
} // end if statement
} #*end foreach statement*#
</tbody>
JavaScript
var SavePesticide = function () {
var NewActiveIngredientName; //saves new textbox ActiveIngredient field
var NewEPARegNo;
var NewType;
var PesticideID;
// SaveButton click events
$("#PesticideTable").on("click", '#SavePesticideButton', function (event) {
// variables to set Name, Owner, and Id values
NewType = $(event.currentTarget).closest('tr').find('.PType').text();
NewActiveIngredientName = $(event.target).closest('tr').find('#ActiveIngredient').val();
NewEPARegNo = $(event.target).closest('tr').find('#EPARegNoBox').val();
PesticideID = $(event.currentTarget).closest('tr').find('.PesticideId').text();
// Make sure values are not empty or null
if ((NewActiveIngredientName != "" && NewActiveIngredientName != null) && (NewEPARegNo != "" && NewEPARegNo != null)) {
// send values to UpdatePestices function in controller, then to update database with new values
$.ajax({
type: "POST",
url: '#Url.Action("UpdatePesticides")',
datatype: 'json',
contentType: "application/json",
data: JSON.stringify({PType: NewType, PesticideID: PesticideID, ActiveIngredient: NewActiveIngredientName, EPARegNo: NewEPARegNo}),
success: function (data) {
alert(data);
// on success: disable all textbox fields
$("#PesticideTable").find("input[type=text]").prop("disabled", true);
$(event.target).closest('tr').find("input[type=text]").prop("disabled", true);
// on success: show edit button AND hide save, cancel, and delete buttons
$(event.target).closest('tr').find('#EditButton').show();
$(event.target).closest('tr').find('#SavePesticideButton').hide();
$(event.target).closest('tr').find('#CancelBrandButton').hide();
$(event.target).closest('tr').find('#DeleteButton').hide();
// enable edit buttons
$(".btn-warning").prop("disabled", false);
// refresh values
GetPesticideBrands();
}
});
} else {
// refresh values
GetPesticideBrands();
alert("Active Ingredient and EPA Number must contain a value")
}
})
}
Controller
public string UpdatePesticides(string Owner, string PestType, string OrigBrandName, string BrandName, string EPARegNo)
{
try
{
ADOHelper helper = new ADOHelper();
helper.UpdatePesticides(Owner, OrigBrandName, BrandName, EPARegNo, PestType);
return "Updated Successfully";
}
catch (Exception e)
{
AgRSys.Classes.Utility.Elmah_Helper.RaiseException(e);
return null;
}
}
I need to add rows and inputs dynamically, in addition to filling each entry in these fields, but at the moment of wanting to fill the input I get a error, with this add the rows:
$scope.detalleTransCover = {
details: []
};
$scope.addDetail = function () {
$scope.detalleTransCover.details.push('');
};
$scope.submitTransactionCobver = function () {
angular.forEach($scope.detalleTransCover, function(obj)
{
console.log(obj.cuenta);
});
};
now in the html:
<tr ng-repeat="detail in detalleTransCover.details">
<td>
<input type="text" class="form-control" ng-model="detail.cuenta">
</td>
<td>
<input type="text" class="form-control" ng-model="detail.debeDolar">
</td>
<td>
<input type="text" class="form-control" ng-model="detail.haberDolar">
</td>
</tr>
<button ng-click="addDetail()" class="btn btn-block btn-primary">
Agregar fila
</button>
<button ng-click="submitTransactionCobver()" class="btn btn-block btn-primary">
Agregar
</button>
on the html when I try to fill the input example "cuenta" haver error:
TypeError: Cannot create property 'cuenta' on string ''
When you push a new input to your array, you need to push an object not a string:
// wrong
$scope.addDetail = function () {
$scope.detalleTransCover.details.push('');
};
// right
$scope.addDetail = function () {
$scope.detalleTransCover.details.push({})
});
Strings can't have properties the same way objects can.
In my App I have an $http.get() request that stores data into the array $scope.requirements and a boolean into $scope.requirementsFulfilled.
I have a directive using the same controller as the page. They both do an ng-repeat on the $scope.requirements. When the requirementsFulfilled is false only the directive version shows, when true only the containing page.
The problem is when I envoke $http.get() after the first time the results are only being stored in the directive version. How do I make sure this information is bound to both?
Within the controller...
$scope.requirementsFulfilled;
$scope.requirements = [];
$scope.getRequirements = function(url) {
$http.get(url)
.then(function(res){
$scope.requirements = res.data.requirements;
$scope.setFulfilled( res.data.fulfilled );
});
};
$scope.submitRequirementScan = function() {
if ($scope.checkRequirement() ) {
$scope.getRequirements('tempjson/requiredPartsFulfilled.json');
}
};
$scope.setFulfilled = function( inputFulfilled ) {
$scope.requirementsFulfilled = inputFulfilled;
};
$scope.getRequirements('tempjson/requiredParts.json');
The page gets the requirements and populates the page. Then the user takes actions which fires off checkRequirement() and then fetches the new json if true. From this point only the directive is updating.
I believe that a child scope is being created for the directive, but I am not certain exactly what is happening. Here is the entirity of the directive info.
.directive("operationRequirements", function () {
return {
restrict: "E",
templateUrl: "requirements/requirements.html"
};
});
What is going on with it?
edit - Html for the directive
<div class="col-md-6 col-md-offset-3">
<h5>Scan Requirements</h5>
<form ng-submit="submitRequirementScan()" ng-controller="operationCtrl">
<label> <div class="glyphicon glyphicon-barcode ng-hide" ng-hide="requirement.scanned"></div>
<input type="text" ng-model="text" name="text" placeholder="Scan Barcode" autofocus /></label>
<input type="submit" id="submit" value="Submit Scan" class="btn" />
<table class="table table-hover">
<tr ng-repeat="requirement in requirements | filter : unScannedFilter">
<td>{{$index + 1 }}</td>
<td>
<div class="glyphicon glyphicon-barcode ng-hide" ng-hide="requirement.scanned"></div>
<div class="glyphicon glyphicon-check ng-show" ng-show="requirement.scanned"></div>{{requirement.scanned}}
<div class="col-md-4">
<input type="checkbox" ng-model="requirement.scanned">
</div>
</td>
<td>{{requirement.partId}} - {{requirement.partDescription}}</td>
</tr>
</table>
</form>
</div>
edit 2 -- Html that invokes the directive operation-Requirements and the on page display of the requirements hidden with ng-show.
<div class="row" ng-hide="requirementsFulfilled" >
<operation-Requirements></operation-Requirements>
</div>
<div class="col-md-12" ng-show="requirementsFulfilled">
<table class="table table-hover">
<tr ng-repeat="requirement in requirements">
<td>{{$index + 1 }}</td>
<td>
<div class="glyphicon glyphicon-barcode ng-hide" ng-hide="requirement.scanned"></div>
<div class="glyphicon glyphicon-check ng-show" ng-show="requirement.scanned"></div>
</td>
<td>{{requirement.partId}} - {{requirement.partDescription}}</td>
</tr>
</table>
</div>
So maybe this will help point you in the right direction. What I've done is pulled out the requirements stuff into its own service. Now you have a singleton that handles everything that deals with parts. When its updated in one place its updated everywhere. The directive no longer needs that other controller.
http://plnkr.co/edit/Nej79OI3NrKcrkMNix3D?p=preview
app.service('partsService', function() {
return {
requirementsFulfilled: false,
requirements: [],
getRequirements: function () {
this.requirements.push({partId: 1, partDescription: 'Some Desc', scanned: false});
this.requirements.push({partId: 2, partDescription: 'Some Desc 2', scanned: true});
},
submitScan: function (id) {
this.requirements.filter(function (part) {
return part.partId === id;
}).map(function (part) {
part.scanned = true;
});
this.requirementsFulfilled = this.requirements.filter(function (part) { return !part.scanned }).length === 0;
}
};
});
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Batch editable table</title>
<link rel='stylesheet prefetch' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css'>
<link rel='stylesheet prefetch' href='https://cdn.rawgit.com/esvit/ng-table/v0.8.1/dist/ng-table.min.css'>
<link rel='stylesheet prefetch' href='css/nqjzro.css'>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div ng-app="myApp" class="container-fluid">
<div class="row">
<div class="col-xs-12">
<h2 class="page-header">Batch editable table</h2>
<div class="row">
<div class="col-md-6">
<div class="bs-callout bs-callout-info">
<h4>Overview</h4>
<p>Example of how to create a batch editable table.</p>
</div>
</div>
<div class="col-md-6">
<div class="bs-callout bs-callout-warning">
<h4>Notice</h4>
<p>There are several directives in use that track dirty state and validity of the table rows. Whilst they are reasonally capable they are <em>not production tested - use at your own risk!</em> More details...</p>
<div ng-show="isExplanationOpen">
<p>If you look at the declarative markup for the <code>ngTable</code> you'll see a bunch of nested <code>ngForm</code> directives, with a common ancestor <code>ngForm</code> at the level of the table element. Each nested <code>ngForm</code> propogates their <code>$dirty</code> and <code>$invalid</code> state to this top level <code>ngForm</code>. This works great as you can enable/disable the buttons for saving the table based on the status of this single top-level <code>ngForm</code>.</p>
<p>This works up till the point that the user select's a new page to display in the table. At which point the existing nested <code>ngForm</code> directives are swapped out for new instances as the new data page is loaded. These new <code>ngForm</code> directives are always pristine and valid and this status propogates setting the corrosponding state on the top-level to be pristine and valid even though rows from the previous page are dirty and possibly invalid.</p>
<p>The solution is to have a set of directives that sit parallel to the <code>ngForm</code> directives that remember the state of the rows when the corrosponding <code>ngFrom</code> directives are destroyed and recreated. When <code>ngForm</code> directives are recreated they have their status reset by the directives that have remembered this state.</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" ng-controller="demoController as demo">
<h3>ngTable directive</h3>
<div class="brn-group pull-right">
<button class="btn btn-default" ng-if="demo.isEditing" ng-click="demo.cancelChanges()">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button class="btn btn-primary" ng-if="!demo.isEditing" ng-click="demo.isEditing = true">
<span class="glyphicon glyphicon-pencil"></span>
</button>
<button class="btn btn-primary" ng-if="demo.isEditing" ng-disabled="!demo.hasChanges() || demo.tableTracker.$invalid" ng-click="demo.saveChanges()">
<span class="glyphicon glyphicon-ok"></span>
</button>
<button class="btn btn-default" ng-click="demo.add()">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div>
<table ng-table="demo.tableParams" class="table table-bordered table-hover table-condensed editable-table" ng-form="demo.tableForm" disable-filter="demo.isAdding" demo-tracked-table="demo.tableTracker">
<colgroup>
<col width="70%" />
<col width="12%" />
<col width="13%" />
<col width="5%" />
</colgroup>
<tr ng-repeat="row in $data" ng-form="rowForm" demo-tracked-table-row="row">
<td title="'Name'" filter="{name: 'text'}" sortable="'name'" ng-switch="demo.isEditing" ng-class="name.$dirty ? 'bg-warning' : ''" ng-form="name" demo-tracked-table-cell>
<span ng-switch-default class="editable-text">{{row.name}}</span>
<div class="controls" ng-class="name.$invalid && name.$dirty ? 'has-error' : ''" ng-switch-when="true">
<input type="text" name="name" ng-model="row.name" class="editable-input form-control input-sm" required />
</div>
</td>
<td title="'Age'" filter="{age: 'number'}" sortable="'age'" ng-switch="demo.isEditing" ng-class="age.$dirty ? 'bg-warning' : ''" ng-form="age" demo-tracked-table-cell>
<span ng-switch-default class="editable-text">{{row.age}}</span>
<div class="controls" ng-class="age.$invalid && age.$dirty ? 'has-error' : ''" ng-switch-when="true">
<input type="number" name="age" ng-model="row.age" class="editable-input form-control input-sm" required/>
</div>
</td>
<td title="'Money'" filter="{money: 'number'}" sortable="'money'" ng-switch="demo.isEditing" ng-class="money.$dirty ? 'bg-warning' : ''" ng-form="money" demo-tracked-table-cell>
<span ng-switch-default class="editable-text">{{row.money}}</span>
<div class="controls" ng-class="money.$invalid && money.$dirty ? 'has-error' : ''" ng-switch-when="true">
<input type="number" name="money" ng-model="row.money" class="editable-input form-control input-sm" required/>
</div>
</td>
<td>
<button class="btn btn-danger btn-sm" ng-click="demo.del(row)" ng-disabled="!demo.isEditing"><span class="glyphicon glyphicon-trash"></span></button>
</td>
</tr>
</table>
</div>
<div class="col-md-6" ng-controller="dynamicDemoController as demo">
<h3>ngTableDynamic directive</h3>
<div class="brn-group pull-right">
<button class="btn btn-default" ng-if="demo.isEditing" ng-click="demo.cancelChanges()">
<span class="glyphicon glyphicon-remove"></span>
</button>
<button class="btn btn-primary" ng-if="!demo.isEditing" ng-click="demo.isEditing = true">
<span class="glyphicon glyphicon-pencil"></span>
</button>
<button class="btn btn-primary" ng-if="demo.isEditing" ng-disabled="!demo.hasChanges() || demo.tableTracker.$invalid" ng-click="demo.saveChanges()">
<span class="glyphicon glyphicon-ok"></span>
</button>
<button class="btn btn-default" ng-click="demo.add()">
<span class="glyphicon glyphicon-plus"></span>
</button>
</div>
<table ng-table-dynamic="demo.tableParams with demo.cols" class="table table-bordered table-condensed table-hover editable-table" ng-form="demo.tableForm" disable-filter="demo.isAdding" demo-tracked-table="demo.tableTracker">
<colgroup>
<col width="70%" />
<col width="12%" />
<col width="13%" />
<col width="5%" />
</colgroup>
<tr ng-repeat="row in $data" ng-form="rowForm" demo-tracked-table-row="row">
<td ng-repeat="col in $columns" ng-class="rowForm[col.field].$dirty ? 'bg-warning' : ''" ng-form="{{col.field}}" demo-tracked-table-cell>
<span ng-if="col.dataType !== 'command' && !demo.isEditing" class="editable-text">{{row[col.field]}}</span>
<div ng-if="col.dataType !== 'command' && demo.isEditing" class="controls" ng-class="rowForm[col.field].$invalid && rowForm[col.field].$dirty ? 'has-error' : ''" ng-switch="col.dataType">
<input ng-switch-default type="text" name="{{col.field}}" ng-model="row[col.field]" class="editable-input form-control input-sm" required />
<input ng-switch-when="number" type="number" name="{{col.field}}" ng-model="row[col.field]" class="editable-input form-control input-sm" required />
</div>
<button ng-if="col.dataType === 'command'" class="btn btn-danger btn-sm" ng-click="demo.del(row)" ng-disabled="!demo.isEditing"><span class="glyphicon glyphicon-trash"></span></button>
</td>
</tr>
</table>
</div>
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js'></script>
<script src='https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.js'></script>
<script src="js/index.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular-route.js"></script>
</body>
</html>
The above is html code
angular.module("myApp", ["ngTable", "ngTableDemos"]);
(function() {
"use strict";
angular.module("myApp").controller("demoController", demoController);
demoController.$inject = ["NgTableParams", "ngTableSimpleList"];
function demoController(NgTableParams, simpleList) {
var self = this;
var originalData = angular.copy(simpleList);
self.tableParams = new NgTableParams({}, {
dataset: angular.copy(simpleList)
});
self.deleteCount = 0;
self.add = add;
self.cancelChanges = cancelChanges;
self.del = del;
self.hasChanges = hasChanges;
self.saveChanges = saveChanges;
//////////
function add() {
self.isEditing = true;
self.isAdding = true;
self.tableParams.settings().dataset.unshift({
name: "",
age: null,
money: null
});
// we need to ensure the user sees the new row we've just added.
// it seems a poor but reliable choice to remove sorting and move them to the first page
// where we know that our new item was added to
self.tableParams.sorting({});
self.tableParams.page(1);
self.tableParams.reload();
}
function cancelChanges() {
resetTableStatus();
var currentPage = self.tableParams.page();
self.tableParams.settings({
dataset: angular.copy(originalData)
});
// keep the user on the current page when we can
if (!self.isAdding) {
self.tableParams.page(currentPage);
}
}
function del(row) {
_.remove(self.tableParams.settings().dataset, function(item) {
return row === item;
});
self.deleteCount++;
self.tableTracker.untrack(row);
self.tableParams.reload().then(function(data) {
if (data.length === 0 && self.tableParams.total() > 0) {
self.tableParams.page(self.tableParams.page() - 1);
self.tableParams.reload();
}
});
}
function hasChanges() {
return self.tableForm.$dirty || self.deleteCount > 0
}
function resetTableStatus() {
self.isEditing = false;
self.isAdding = false;
self.deleteCount = 0;
self.tableTracker.reset();
self.tableForm.$setPristine();
}
function saveChanges() {
resetTableStatus();
var currentPage = self.tableParams.page();
originalData = angular.copy(self.tableParams.settings().dataset);
}
}
})();
(function() {
"use strict";
angular.module("myApp").controller("dynamicDemoController", dynamicDemoController);
dynamicDemoController.$inject = ["NgTableParams", "ngTableSimpleList"];
function dynamicDemoController(NgTableParams, simpleList) {
var self = this;
var originalData = angular.copy(simpleList);
self.cols = [{
field: "name",
title: "Name",
filter: {
name: "text"
},
sortable: "name",
dataType: "text"
}, {
field: "age",
title: "Age",
filter: {
age: "number"
},
sortable: "age",
dataType: "number"
}, {
field: "money",
title: "Money",
filter: {
money: "number"
},
sortable: "money",
dataType: "number"
}, {
field: "action",
title: "",
dataType: "command"
}];
self.tableParams = new NgTableParams({}, {
dataset: angular.copy(simpleList)
});
self.deleteCount = 0;
self.add = add;
self.cancelChanges = cancelChanges;
self.del = del;
self.hasChanges = hasChanges;
self.saveChanges = saveChanges;
//////////
function add() {
self.isEditing = true;
self.isAdding = true;
self.tableParams.settings().dataset.unshift({
name: "",
age: null,
money: null
});
// we need to ensure the user sees the new row we've just added.
// it seems a poor but reliable choice to remove sorting and move them to the first page
// where we know that our new item was added to
self.tableParams.sorting({});
self.tableParams.page(1);
self.tableParams.reload();
}
function cancelChanges() {
resetTableStatus();
var currentPage = self.tableParams.page();
self.tableParams.settings({
dataset: angular.copy(originalData)
});
// keep the user on the current page when we can
if (!self.isAdding) {
self.tableParams.page(currentPage);
}
}
function del(row) {
_.remove(self.tableParams.settings().dataset, function(item) {
return row === item;
});
self.deleteCount++;
self.tableTracker.untrack(row);
self.tableParams.reload().then(function(data) {
if (data.length === 0 && self.tableParams.total() > 0) {
self.tableParams.page(self.tableParams.page() - 1);
self.tableParams.reload();
}
});
}
function hasChanges() {
return self.tableForm.$dirty || self.deleteCount > 0
}
function resetTableStatus() {
self.isEditing = false;
self.isAdding = false;
self.deleteCount = 0;
self.tableTracker.reset();
self.tableForm.$setPristine();
}
function saveChanges() {
resetTableStatus();
var currentPage = self.tableParams.page();
originalData = angular.copy(self.tableParams.settings().dataset);
}
}
})();
(function() {
"use strict";
angular.module("myApp").run(configureDefaults);
configureDefaults.$inject = ["ngTableDefaults"];
function configureDefaults(ngTableDefaults) {
ngTableDefaults.params.count = 5;
ngTableDefaults.settings.counts = [];
}
})();
/**********
The following directives are necessary in order to track dirty state and validity of the rows
in the table as the user pages within the grid
------------------------
*/
(function() {
angular.module("myApp").directive("demoTrackedTable", demoTrackedTable);
demoTrackedTable.$inject = [];
function demoTrackedTable() {
return {
restrict: "A",
priority: -1,
require: "ngForm",
controller: demoTrackedTableController
};
}
demoTrackedTableController.$inject = ["$scope", "$parse", "$attrs", "$element"];
function demoTrackedTableController($scope, $parse, $attrs, $element) {
var self = this;
var tableForm = $element.controller("form");
var dirtyCellsByRow = [];
var invalidCellsByRow = [];
init();
////////
function init() {
var setter = $parse($attrs.demoTrackedTable).assign;
setter($scope, self);
$scope.$on("$destroy", function() {
setter(null);
});
self.reset = reset;
self.isCellDirty = isCellDirty;
self.setCellDirty = setCellDirty;
self.setCellInvalid = setCellInvalid;
self.untrack = untrack;
}
function getCellsForRow(row, cellsByRow) {
return _.find(cellsByRow, function(entry) {
return entry.row === row;
})
}
function isCellDirty(row, cell) {
var rowCells = getCellsForRow(row, dirtyCellsByRow);
return rowCells && rowCells.cells.indexOf(cell) !== -1;
}
function reset() {
dirtyCellsByRow = [];
invalidCellsByRow = [];
setInvalid(false);
}
function setCellDirty(row, cell, isDirty) {
setCellStatus(row, cell, isDirty, dirtyCellsByRow);
}
function setCellInvalid(row, cell, isInvalid) {
setCellStatus(row, cell, isInvalid, invalidCellsByRow);
setInvalid(invalidCellsByRow.length > 0);
}
function setCellStatus(row, cell, value, cellsByRow) {
var rowCells = getCellsForRow(row, cellsByRow);
if (!rowCells && !value) {
return;
}
if (value) {
if (!rowCells) {
rowCells = {
row: row,
cells: []
};
cellsByRow.push(rowCells);
}
if (rowCells.cells.indexOf(cell) === -1) {
rowCells.cells.push(cell);
}
} else {
_.remove(rowCells.cells, function(item) {
return cell === item;
});
if (rowCells.cells.length === 0) {
_.remove(cellsByRow, function(item) {
return rowCells === item;
});
}
}
}
function setInvalid(isInvalid) {
self.$invalid = isInvalid;
self.$valid = !isInvalid;
}
function untrack(row) {
_.remove(invalidCellsByRow, function(item) {
return item.row === row;
});
_.remove(dirtyCellsByRow, function(item) {
return item.row === row;
});
setInvalid(invalidCellsByRow.length > 0);
}
}
})();
(function() {
angular.module("myApp").directive("demoTrackedTableRow", demoTrackedTableRow);
demoTrackedTableRow.$inject = [];
function demoTrackedTableRow() {
return {
restrict: "A",
priority: -1,
require: ["^demoTrackedTable", "ngForm"],
controller: demoTrackedTableRowController
};
}
demoTrackedTableRowController.$inject = ["$attrs", "$element", "$parse", "$scope"];
function demoTrackedTableRowController($attrs, $element, $parse, $scope) {
var self = this;
var row = $parse($attrs.demoTrackedTableRow)($scope);
var rowFormCtrl = $element.controller("form");
var trackedTableCtrl = $element.controller("demoTrackedTable");
self.isCellDirty = isCellDirty;
self.setCellDirty = setCellDirty;
self.setCellInvalid = setCellInvalid;
function isCellDirty(cell) {
return trackedTableCtrl.isCellDirty(row, cell);
}
function setCellDirty(cell, isDirty) {
trackedTableCtrl.setCellDirty(row, cell, isDirty)
}
function setCellInvalid(cell, isInvalid) {
trackedTableCtrl.setCellInvalid(row, cell, isInvalid)
}
}
})();
(function() {
angular.module("myApp").directive("demoTrackedTableCell", demoTrackedTableCell);
demoTrackedTableCell.$inject = [];
function demoTrackedTableCell() {
return {
restrict: "A",
priority: -1,
scope: true,
require: ["^demoTrackedTableRow", "ngForm"],
controller: demoTrackedTableCellController
};
}
demoTrackedTableCellController.$inject = ["$attrs", "$element", "$scope"];
function demoTrackedTableCellController($attrs, $element, $scope) {
var self = this;
var cellFormCtrl = $element.controller("form");
var cellName = cellFormCtrl.$name;
var trackedTableRowCtrl = $element.controller("demoTrackedTableRow");
if (trackedTableRowCtrl.isCellDirty(cellName)) {
cellFormCtrl.$setDirty();
} else {
cellFormCtrl.$setPristine();
}
// note: we don't have to force setting validaty as angular will run validations
// when we page back to a row that contains invalid data
$scope.$watch(function() {
return cellFormCtrl.$dirty;
}, function(newValue, oldValue) {
if (newValue === oldValue) return;
trackedTableRowCtrl.setCellDirty(cellName, newValue);
});
$scope.$watch(function() {
return cellFormCtrl.$invalid;
}, function(newValue, oldValue) {
if (newValue === oldValue) return;
trackedTableRowCtrl.setCellInvalid(cellName, newValue);
});
}
})();
This is javascript file
The above code is angularjs. It displays table loading data with add row, delete, edit.
Please solve this. Am getting error [$injector:modulerr] . Please help me to solve
Edit: They created different codepen for ngTableDemos look here
To run your sample you need to load that ngTableDemos related code first then your sample.
For codepen, to understand what are the files they are using to run any sample check Pen Setting JavaScript tab carefully.
Probably you didn't load "ngTableDemos" module, so if it is needed load associate file or remove it like
angular.module("myApp", ["ngTable"]);
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>