FooTable v2 allowed users to inject DOM elements - rows into a table - and sorting still kinda works. FooTable v3 is a complete re-write and the data in the table is completely managed by FooTable. The original DOM is restructured by FooTable.init. Adding to the DOM will mean FooTable sorting and filtering will be unaware of the added record. As far as I can tell, the proper way to add a new row to the FooTable v3 is to call the editing component's function 'addRow'.
The original author of FooTable has assumed many things - such as the developer will want to use a popup asking for values. In my case, when adding a row I do not want an editor window popping up asking for values. I merely want to add a blank row to the table programatically/dynamically without using any footable UI components.
How do I call this function? What is the proper syntax.
I init my table via ...
$(document).ready(function () {
$('.my-footable').footable({
"editing": {
"enabled":"true"
}
});
});
... and I have a click event on a button...
$(document).on("click", "#myButton", function (event) {
var editing = FooTable.get(".my-footable").use(FooTable.Editing);
});
... but I am stumped on how to invoke addRow - and what parameters I pass...
Any ideas?
$(document).ready(function() {
var columns_name = ['id', 'first name', 'last name', 'job title'],
columns = [],
rows = [{
'id': 1,
'first_name': 'Dennise',
'last_name': 'Fuhrman',
'job_title': 'High School History Teacher'
}];
/**
Creating a new object with the help of columns_name array with
having key title and name and then pushing it to the columns array. We'll
pass that array in the footable init object.
*/
for (var i = 0; i < columns_name.length; i++) {
var column = columns_name[i];
/**
In name key replacing spaces with underscore so that it will match with
the keys in row array of object
*/
columns.push({
title: column,
name: column.replace(/ /g, "_")
});
}
var ft_init_options = {
columns: columns,
rows: rows,
editing: {
enabled: true,
alwaysShow: true,
allowAdd: true,
allowEdit: false,
addRow: function() {
/**
Creating new row with empty columns having input field
*/
var values = {
'id': '<input type="text">',
'first_name': '<input type="text">',
'last_name': '<input type="text">',
'job_title': '<input type="text">'
}
ft.rows.add(values);
},
deleteRow: function(row) {
if (confirm('Are you sure you want to delete the row?')) {
row.delete();
}
}
}
};
var ft = FooTable.init('#editing-example', ft_init_options);
});
/**
Remove the following comments if you want to remove the border from the inputs
and want to display when they are in focus
*/
/**
textarea:focus, input:focus{
border-width: 2px;
border-style: inset;
border-color: initial;
border-image: initial;
}
textarea, input {
border : none;
}
**/
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://fooplugins.github.io/FooTable/compiled/footable.bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-footable/3.1.6/footable.js"></script>
<div class="container-fluid">
<hr>
<h1 class="text-center"> FooTable Editing Example with inputs in row</h1>
<hr>
<table id="editing-example" class="table"></table>
</div>
If code snippet is not working then have a look on jsfiddle
Related
Can anyone assist me in inserting a row into a DGRID? The way I am doing it now is cloning a row, add it to the collection with the use of directives and then try to apply it to the grid. Below is the code I am using but the new row ends up getting added to the bottom instead of being inserted.
// Clone a row
theTable = tmxdijit.registry.byId(tableName);
firstRow = theTable.collection.data[theTable.collection.data.length-1];
firstRowDom = theTable.row(firstRow.id);
var cloneRow = json.stringify(firstRow);
cloneRow = json.parse(cloneRow);
// Get the row I want to add before
var theSelected = Object.keys(theTable.selection)[0];
if(theSelected.length > 0) {
var theRowID = theSelected[0];
}
theTable.collection.add(cloneRow, {beforeId: theRowID});
theTable.renderArray([cloneRow]);
There are two general ways to handle data insertion. One is to manually add data to an array, ensure it's properly sorted, and then tell the grid to render the array. A better way is to use an OnDemandGrid with a trackable store.
For dgrid/dstore to support simple dynamic insertion of rows, make sure the store is trackable, and that data items have some unique id property:
var StoreClass = Memory.createSubclass(Trackable);
var store = new StoreClass({ data: whatever });
var grid = new OnDemandGrid({
columns: { /* columns */ },
collection: store
});
By default dstore assumes the id property is "id", but you can specify something else:
var store = new StoreClass({ idProperty: "name", data: whatever });
If you want the data to be sorted, a simple solution is to set a sort on the grid (the grid will sort rows in ascending order using the given property name):
grid.set('sort', 'name');
To add or remove data, use the store methods put and remove.
var collection = grid.get('collection');
collection.put(/* a new data item */);
collection.remove(/* a data item id */);
The grid will be notified of the store update and will insert or remove the rows.
The dgrid Using Grids and Stores tutorial has more information and examples.
Instead of this, why don't you add the data directly to the grid store? See if this helps
https://dojotoolkit.org/reference-guide/1.10/dojox/grid/example_Adding_and_deleting_data.html
Adding and Deleting data
If you want to add (remove) data programmatically, you just have to add (remove) it from the underlying data store. Since DataGrid is “DataStoreAware”, changes made to the store will be reflected automatically in the DataGrid.
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.data.ItemFileWriteStore");
dojo.require("dijit.form.Button");
.
<div>
This example shows, how to add/remove rows
</div>
<table data-dojo-type="dojox.grid.DataGrid"
data-dojo-id="grid5"
data-dojo-props="store:store3,
query:{ name: '*' },
rowsPerPage:20,
clientSort:true,
rowSelector:'20px'
style="width: 400px; height: 200px;">
<thead>
<tr>
<th width="200px"
field="name">Country/Continent Name</th>
<th width="auto"
field="type"
cellType="dojox.grid.cells.Select"
options="country,city,continent"
editable="true">Type</th>
</tr>
</thead>
</table>
<div data-dojo-type="dijit.form.Button">
Add Row
<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
// set the properties for the new item:
var myNewItem = {type: "country", name: "Fill this country name"};
// Insert the new item into the store:
// (we use store3 from the example above in this example)
store3.newItem(myNewItem);
</script>
</div>
<div data-dojo-type="dijit.form.Button">
Remove Selected Rows
<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
// Get all selected items from the Grid:
var items = grid5.selection.getSelected();
if(items.length){
// Iterate through the list of selected items.
// The current item is available in the variable
// "selectedItem" within the following function:
dojo.forEach(items, function(selectedItem){
if(selectedItem !== null){
// Delete the item from the data store:
store3.deleteItem(selectedItem);
} // end if
}); // end forEach
} // end if
</script>
</div>
.
#import "{{ baseUrl }}dijit/themes/nihilo/nihilo.css";
#import "{{ baseUrl }}dojox/grid/resources/nihiloGrid.css";
I use a cell filter to show multiple properties of a bound entity in one cell. Therefore there is no one field name because it is a computed field. How can I force the grid to reevaluate the cell filter if one of the involved properties changes?
The column definition:
columnDefs: [
{ field: 'xxx', displayName: 'Something', cellFilter: 'concatSomeProps:this' }
]
The filter:
myApp.filter('concatSomeProps', function () {
return function (cellValue, scope) {
var entity = scope.row.entity;
return entity.prop1 + ", " + entity.prop2;
};
});
If have tried to use notifyDataChanged or the refresh function of the grid api but it doesn't work.
I'd probably use a cellTemplate, and not a filter in this case:
{ field: 'xxx', displayName: 'Something', cellTemplate:'template.html' }
And
<script type="text/ng-template" id="template.html">
<div>
{{row.entity.name + row.entity.age}}
</div>
</script>
See this Plnkr I made for you to see what I'm talking about. Edit either one of the first two fields and you will see the concat field change. You'd also change your template to use row.entity.prop1 + row.entity.prop2 to make it work, as my template is for my columns.
Hi I have Created a html, java script. I am able to bind the json data to kendo UI dropdown list and able to display that list on Html page . When is select any data in the list I am able to retrieve the selected value . Now I am trying to replace the drop down list with kendo ui grid and want to retrieve the selected row cells value . below is the code for kendo drop down list . Help would be highly appreciated.
HTML file
<table style="padding-top: 20px; padding-left: 10px; display: table;" id="selectAccountTable"> <tbody>
<tr>
<td>Existing Account Found</td>
</tr>
<tr>
<td>
<!--need to display kendo grid UI , kendo drop down is created at this input
<input id="accountSelect" style="width: 350px;">
</td>
</tr>
JavaScript code
function DisplayActiveAccounts(res)
{
var accounts = [];
var response = $.parseJSON(res);
for (var idx = 0; idx < response.length; idx++)
{
accounts.push({ 'name': response[idx].Name, 'id': response[idx].Id, 'code':
response[idx].Code,'city':response[idx].City,'state':response[idx].State,'ce':response[idx].CE});
}
$('#selectAccountTable').show();
selectAccountVisible = true;
//need to create kendo ui grid instead of kendo ui drop down list
$('#accountSelect').kendoDropDownList({
dataTextField: "name",
dataValueField: "accountid",
dataSource: accounts
});
}
function _okClick()
{
if (closeWindow) {
//If the account select table is visible pass back selected account code
//need to retrieve the selected row values in returnValues variable
if (selectAccountVisible) {
var dropDownSelect = $("#accountSelect").data ("kendoDropDownList");
var listData = dropDownSelect.dataSource;
//Get data from selecte value in drop down
var selectedData = listData._data.filter(function (account) { return account.id == dropDownSelect.value() });
var returnValues = { testID: selectedData[0].id, testCode: selectedData[0].code };
}
closeWindow();
}
}
Here's the scenario:
There are a number of rows of selectable data
One column (#1) has dropdown editor with two options
The next column (#2) can have either a text editor, or dropdown editor - depending on the option selected in the first dropdown, see example:
_________Column #1_________|_________Column #2_________
1 select opt 1 | *dropdown editor*
2 select opt 1 | *dropdown editor*
3 select opt 1 | *dropdown editor*
4 select opt 2 | *text editor* <--- is this possible?
5 select opt 1 | *dropdown editor*
6 select opt 1 | *dropdown editor*
Is it even possible to change the editor of a single cell based on the input/change of another cell? It appears as though you can't change editors on a cell level, but only on a column level.
Any help is greatly appreciated, many hours spent on this already; and haven't found a solution or even similar question. Thanks
Update
This is getting close perhaps:
var currentRowIndex = object.grid.getActiveCell().row,
nextCellIndex = object.grid.getActiveCell().cell + 1;
object.grid.setActiveCell(currentRowIndex, nextCellIndex);
object.grid.editActiveCell(this.editors.textEditor);
But this doesn't ensure that the editor remains; for example^ a text editor. When changing the value in the first column (#1), and enabling the text editor in column #2 as above - after this edit takes place - the original editor is still in place in column #2.
I want the editor to remain the same - but can't find how to do this on a cell level rather than a column level. Thanks
Browsing the source (getEditor line 1381) pertaining to the retrieval of editors reveals a few different options are available.
column metadata
column definition
editorFactory grid option
Given that you require a different column value from within the row, I would approach the problem using the column metadata as it receives the rowIndex as an argument.
var viewModel = {options: ['LongText', 'Text', 'Checkbox']}
function apply() {
var grid, data = [];
var options = {
editable: true,
enableCellNavigation: true,
asyncEditorLoading: false,
autoEdit: true,
forcefitColumns: false
};
var columns = [{
id: "data",
name: "Editor Type",
field: "type",
width: 120,
cssClass: "cell-title" ,
formatter: function(row){
var key = 'input'+row;
if(!viewModel[key]){
viewModel[key] = ko.observable();
viewModel[key].subscribe(function(nv){
data[row].type = nv
})
}
setTimeout(function(){ ko.applyBindings(viewModel, document.getElementById(key)) }, 250);
return '<select id="'+key+'", data-bind="options: options, value: '+key+'"></select>'
}
},
{
id: "other",
name: "Other",
field: "other",
width: 120,
cssClass: "cell-title",
}];
for (var i = 0; i < 5; i++) {
var d = (data[i] = {});
d["type"] = "";
d["other"] = "Default " + i;
}
grid = new Slick.Grid("#myGrid", data, columns, options);
//ko.applyBindings(viewModel)
data.getItemMetadata=function(row){
var rowData = data[row]
//console.log(rowData)
var metaData = {columns:{other: {}}}
metaData.columns.other.editor = Slick.Editors[rowData.type]
return metaData
}
}
apply()
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<link rel="stylesheet" type="text/css" href="http://JLynch7.github.io/SlickGrid/slick.grid.css">
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>
<script src="http://JLynch7.github.io/SlickGrid/slick.dataview.js"></script>
<script src='http://mleibman.github.io/SlickGrid/lib/jquery.event.drag-2.2.js'></script>
<script src='http://JLynch7.github.io/SlickGrid/slick.core.js'></script>
<script src='http://JLynch7.github.io/SlickGrid/slick.grid.js'></script>
<script src='http://JLynch7.github.io/SlickGrid/slick.formatters.js'></script>
<script src='http://JLynch7.github.io/SlickGrid/slick.editors.js'></script>
<div id='container'>
<div id="myGrid" style="width:600px;height:300px;"></div>
</div>
I have a table with ng-grid, and the problem is that i'm not sure how to collect the selected row(s) id or variable to pass into my delete function.
here is a quick mockup of what i'm trying to do
http://plnkr.co/edit/zy653RrqHmBiRJ7xDHlV?p=preview
the following code is from my html, a clickable delete button that takes in 2 parameters, the array of checkbox ids and the index at the corresponding table. This delete method was obtained from this tutorial : http://alexpotrykus.com/blog/2013/12/07/angularjs-with-rails-4-part-1/
<div class="btn-group">
<button class="my-btn btn-default button-row-provider-medical-services" ng-click="deleteProviderMedicalService([], $index)">Delete</button>
</button>
</div>
<div class="gridStyle ngGridTable" ng-grid="gridOptions">
</div>
The following code grabs the json data from a url, queries it and returns it. It also contains the delete function that gets called from the controller in the html page.
app.factory('ProviderMedicalService', ['$resource', function($resource) {
function ProviderMedicalService() {
this.service = $resource('/api/provider_medical_services/:providerMedicalServiceId', {providerMedicalServiceId: '#id'});
};
ProviderMedicalService.prototype.all = function() {
return this.service.query();
};
ProviderMedicalService.prototype.delete = function(providerId) {
this.service.remove({providerMedicalServiceId: providerId});
};
return new ProviderMedicalService;
}]);
The following is my controller(not everything, just the most important bits). $scope.provider_medical_services gets the json data and puts it into the ng-grid gridOptions.
After reading the ng-grid docs, i must somehow pass the checkbox ids from the selectedItems array and pass it into html doc to the delete function. Or, i'm just doing this completely wrong, as i hacked this together. Solutions and suggestions are greatly appreciated
(function() {
app.controller('ModalDemoCtrl', ['$scope', 'ProviderMedicalService', '$resource', '$modal', function($scope, ProviderMedicalService, $resource, $modal) {
var checkBoxCellTemplate = '<div class="ngSelectionCell"><input tabindex="-1" class="ngSelectionCheckbox" type="checkbox" ng-checked="row.selected" /></div>';
$scope.provider_medical_services = ProviderMedicalService.all();
$scope.deleteProviderMedicalService = function(ids,idx) {
$scope.provider_medical_services.splice(idx, 1);
return ProviderMedicalService.delete(ids);
};
$scope.gridOptions = {
columnDefs: [
{
cellTemplate: checkBoxCellTemplate,
showSelectionCheckbox: true
},{
field: 'name',
displayName: 'CPT Code/Description'
},{
field: 'cash_price',
displayName: 'Cash Price'
},{
field: 'average_price',
displayName: 'Average Price'
},
],
data: 'provider_medical_services',
selectedItems: []
};
i think the easiest option is pass an (array index) as data-id to your dom, which u can pick it from there.
{{$index}} is a variable you can use in ng-repeat
======= ignore what i said above, since i normaly writes my own custom stuff ======
I just had a look at ng-grid, i took their example. i've added a delete all selected function, as well as someone elses delete current row function ( these is pure angular way ) to see the code, hover over the top right corner < edit in jsbin >
http://jsbin.com/huyodove/1/
Honestsly i don't like it this way, you would be better off use something like lodash to manage your arrays and do your own custom grid. Using foreach to find the row index isn't good performance.
In their doc, it says you can change the row template, and which you should, so you can add the {{index}} to that row, and filter your data through that index rather which is a little bit better. anyway beware of deleting cells after you have filter your table.
I don't quite get much your question, but you can access to selectedItems of ng-grid as following: $scope.gridOptions.$gridScope.selectedItems (see ng-grid API for more information, but technically this array holds the list of selected items in multiple mode - or only one item in single mode)
For your case, the deleteAll() function could be someething like this:
$scope.deleteAll = function() {
$scope.myData = [];
}
The delete() function which delete selected items can be:
$scope.delete = function() {
$.each($scope.gridOptions.$gridScope.selectedItems, function(index, selectedItem) {
//remove the selected item from 'myData' - it is 2-ways binding to any modification to myData will be reflected in ng-grid table
//you could check by either name or unique id of item
});
}