I am trying to learn AngularJS.
The grid displays properly. It loads page properly.
It does NOT go into edit mode.
Double click does not go into edit mode.
F2 does not go into edit mode.
ProductTitle (the second column below) is the example I am using.
I recieve no errors in Chrome. No missing libraries.
I have spent hours researching this (and learned so much) but
I can't get it to go into edit mode.
Does anyone know what I am doing wrong?
module:
app = angular.module('UIGrid_App', [
'ngAnimate', // support for CSS-based animations
'ngTouch', //for touch-enabled devices
'ui.grid', //data grid for AngularJS
'ui.grid.pagination', //data grid Pagination
'ui.grid.resizeColumns', //data grid Resize column
'ui.grid.moveColumns', //data grid Move column
'ui.grid.pinning', //data grid Pin column Left/Right
'ui.grid.selection', //data grid Select Rows
'ui.grid.autoResize', //data grid Enabled auto column Size
'ui.grid.exporter', //data grid Export Data
'ui.grid.edit'
]);
})();
controller:
app.controller('ProductsCtrl', ['$scope', 'CRUDService', 'uiGridConstants',
function ($scope, CRUDService, uiGridConstants) {
$scope.gridOptions = [];
//ui-Grid Call
$scope.GetProducts = function () {
$scope.gridOptions = {
enableCellSelection: true, // jenny changed to editable
enableCellEdit: false, // jenny changed to editable - to be set below ( setting to true doesnt work)
enableCellEditOnFocus: true, // jenny changed to editable
useExternalPagination: true,
useExternalSorting: true,
enableFiltering: true,
enableSorting: true,
enableRowSelection: true,
enableSelectAll: true,
enableGridMenu: true,
columnDefs: [
{
name: "ProductID",
displayName: "Product ID",
width: '10%',
headerCellClass: $scope.highlightFilteredHeader
},
{
name: "ProductTitle",
title: "Product Title",
width: '40%',
enableCellEdit: true, // jenny change to editable
headerCellClass: $scope.highlightFilteredHeader
},
more columns
As per the documentation we need module, flags and attribute.
The ui.grid.edit feature allows inline editing of grid data. To enable, you must include the 'ui.grid.edit' module and you must include the ui-grid-edit directive on your grid element.
For individual cells to enable/disable use something like below in the column definition if you don;t want to enable all columns editable:
{ name: 'address.city', enableCellEdit: true, }
You need to add grid edit on your html (ui-grid-edit ui-grid-row-edit)
<div id="grid-create-profile" ui-grid="$ctrl.gridOptions" ui-grid-pagination ui-grid-cellNav ui-grid-edit ui-grid-row-edit ui-grid-resize-columns ui-grid-selection class="grid"></div>
Related
Having Issues with getting the data for my ui grid? Not sure what I'm doing wrong here, but I console.log the data so I know i'm getting it back.
My data is coming back as a object and i'm trying to reach the team members array in the object to reference.
function loadProjectDetails(){
return MrktRsrchPrjtDataService.getProjectSubsection(MrktRsrchPrjtDataService.getCurrentReportId(), "ProjectSummary")
.then(function (data){
vm.project = data;
console.log(data);
vm.teamGridOptions = {
enableGridMenu: false,
enableSorting: true,
enableHorizontalScrollbar: 0, /*always hide horizontal scroll bar*/
enableVerticalScrollbar: 1, /*always show vertical scroll bar*/
rowHeight: 46,
columnDefs: [
{
enableHiding: false,
enableColumnMenu: false,
displayName: 'First Name',
field: 'memberId',
cellClass: 'ui-grid-cell-contents',
cellTemplate: '<span>{{row.entity.teamMembers.memberId}}</span>'
},
],
data: vm.project
};
});
}
//HTML
<div ui-grid="vm.teamGridOptions" ui-grid-auto-resize class=""></div>
In the html you call vm.teamGridOptions. What is the name of your controllor? AngularJS convention is to name the controller "ctrl", so this would mean you should be calling ctrl.teamGridOptions.
I'm using Ag-Grid to try and display a series of search results from a database. Almost everything works, the grid table appears, the search field, button, etc. all work, the correct REST interface is called and the data is returned as a Java List...for the example I'm using there are 16 results, and when I run the search what I basically see is 16 blank rows appear in the grid. It seems that it's getting as far as realizing it needs to populate the 16 entries, but something I've misconfigured prevents it from doing so. The event listener even works and kicks off the proper method, it's just that since nothing appears in the individual rows, the arg it collects is just null. Does anyone know what I'm doing wrong? Thanks!
Here is the HTML:
<div id="SearchTable" ng-controller="docSearch">
<div class="searchlabel">
Search Keyword Libraries<br> Search: <input name="searchField"
placeholder="Search..." type="text" ng-model="data.searchField" />
<button ng-click='searchKeywordLibs(data.searchField)'>Find</button>
<br>
</div>
<div ag-grid="SearchKeywordsTableGrid"
style="width: 500px; height: 200px;" class="ag-fresh"></div>
<div ng-if="status" id="status">
<b layout="row" layout-align="start center" class="md-padding">
</b>
</div>
</div>
Here is the grid definition:
$scope.SearchKeywordsTableGrid = {
columnDefs : [ {
headerName : 'Keyword Library Name',
editable : false,
filter: 'text'
},
{
headerName : 'Path',
editable : false,
filter: 'text'
},
],
rowSelection: 'single',
enableSorting: true,
enableColResize: true,
enableFilter: true,
suppressLoadingOverlay: true,
suppressNoRows: true,
sizeColumnsToFit: true
};
And here is the controller function:
$scope.searchKeywordLibs = function(search_term) {
$http.get('/trm/get_keyword_search_results?search_term='+search_term).success(
function(data) {
$scope.data = data;
$scope.SearchKeywordsTableGrid.api.setRowData($scope.data);
// add event listener
if($scope.SearchKeywordsTableGrid.api != 'undefined') {
$scope.SearchKeywordsTableGrid.api.addEventListener('rowDoubleClicked', openSearchResultPage);
}
});
};
Okay Jarod's comment steered me to where I needed to be...it was a simple flub, I didn't have the field attributes defined in the column definitions. It should have been:
$scope.SearchKeywordsTableGrid = {
columnDefs : [ {
headerName : 'Keyword Library Name',
field: 'name',
editable : false,
filter: 'text'
},
{
headerName : 'Path',
field: 'path',
editable : false,
filter: 'text'
},
],
rowSelection: 'single',
enableSorting: true,
enableColResize: true,
enableFilter: true,
suppressLoadingOverlay: true,
suppressNoRows: true,
};
Thanks!
I am using Kendo library for grid. I want to have a toolbar in that grid.
I have followed this link -
http://demos.kendoui.com/web/grid/toolbar-template.html
and created a toolbar at the top
I also want to add another toolbar at the bottom of grid. Below or above pagination bar. I could not find any way to create this extra toolbar. Please help.
There are two ways of getting it:
You let Kendo UI generate in the top and then you move it to the bottom
You generate it to the bottom.
The first approach is fast and if you don't need header toolbar is the best. Just add the following code:
$("#grid).data("kendoGrid").wrapper.append($(".k-toolbar"));
See it here : http://jsfiddle.net/OnaBai/WsRqP/1/
The second approach -using as base the example that you mention in your original question- would be something like this:
Step 1: Define a template, you might use the same than in the example:
<script type="text/x-kendo-template" id="template">
<div class="toolbar">
<label class="category-label" for="category">Show products by category:</label>
<input type="search" id="category" style="width: 150px"/>
</div>
</script>
Step 2: Initialize the grid, as you are doing now (in my case I will not include the toolbar as header but only as footer):
var grid = $("#grid").kendoGrid({
dataSource: {
type : "odata",
transport : {
read: "http://demos.kendoui.com/service/Northwind.svc/Products"
},
pageSize : 20,
serverPaging : true,
serverSorting : true,
serverFiltering: true
},
height : 430,
sortable : true,
pageable : true,
columns : [
{ field: "ProductID", title: "Product ID", width: 100 },
{ field: "ProductName", title: "Product Name" },
{ field: "UnitPrice", title: "Unit Price", width: 100 },
{ field: "QuantityPerUnit", title: "Quantity Per Unit" }
]
}).data("kendoGrid");
Step 3: Add a dataBound handler for creating the footer after the grid has been initialized. We have to do it on dataBound otherwise the Grid is still not correctly formatted and the footer will look wrong. I've implemented creating the footer toolbar in a separate function to do not mess dataBound in case you do more stuff here.
dataBound : function () {
initFooterToolbar(this, kendo.template($("#template").html()));
}
Step 4: Implement this initFooterToolbar:
function initFooterToolbar(grid, template) {
if (!this._footer) {
this._footer = $("<div class='k-toolbar k-grid-toolbar k-widget'></div>")
.append(template);
grid.wrapper.append(this._footer);
// Other code for initializing your template
...
}
}
What initFooterToolbar does is first check that it has not already been initialized otherwise if you do pagination of refresh the data you might end-up with multiple footer toolbars.
Finally append the toolbar to grid.wrapper.
So the important part for creating a footer toolbar is invoking grid.wrapper.append(...) and doing it when the grid is already created.
The original example modified here : http://jsfiddle.net/OnaBai/WsRqP/
I avoid using kendo toolbars and just make an external 1 which you can then tweak with greater control.
For example,
#Html.DropDownList("Year", (SelectList)ViewBag.YearList, "All years")
transport: {
read: {
url: '#Url.Action("_List", "Applications")',
data: refreshGridParams,
type: 'POST'
},
function refreshGridParams() {
return {
Year: $('#Year').val()
};
}
$('#Year').change(function () {
theGrid.dataSource.read({
Year: $('#Year').val()
});
});
Then in my controller,
[HttpPost]
public JsonResult _List(int? Year, int skip, int take)
{
Last
_db.Blargh.Where(w => w.Year== Year).Skip(skip).Take(take).ToList().ForEach(x => { waList.Add(new WAListDTO(x)); });
This should cover all the core code needed but means you can keep adding as many toolbars/dropdowns/datepickers/text searchs or etc and just alter each stage to include the additional data.
Here is another hack which uses column footertemplate. When databound is triggered, footertemplate table is arranged to have one column with colspan equals to the number of grid columns.
http://plnkr.co/edit/1BvMqSC7tTUEiuw4hWZp
$("#grid").kendoGrid({
columns:[{
field:'name',
footerTemplate : "Row Count: #= data.name.count #"
},{
field:'age'
}],
dataSource: new kendo.data.DataSource({
aggregate: [{
field:"name",
aggregate: "count"
}],
data: [{
name: "Jane",
age: 31
}, {
name: "John",
age: 33
}]
}),
dataBound: function() {
var footer = this.wrapper.find('.k-footer-template');
footer.children(":first").attr('colspan', this.columns.length);
footer.children().not(':first').remove();
}
});
I am developing a simple JavaScript-based plugin architecture which allows for any JavaScript control from any framework (jQueryUI, ExtJS, etc). to be plugged into and reused on any web page. My plugins below happen to use ExtJS 4.
The first plugin renders fine in the first tab. However, since the second tab hasn't yet rendered when the page loads, the second plugin (also a grid) is first rendering to the document body, and then it renders properly (the HTMLElement/div is moved) inside the tab when the tab is selected. I'd like the plugin content to be hidden prior to rendering inside the tab. Also, when it it does render [when the tab is selected], horizontal scrollbars don't show unless I resize a column.
Any ideas how to fix this?
Ideas: use something other than contentEl; leverage various ExtJS config options; change my architecture.
Here is the plugin code:
(function(MyNamespace) {
var gridDataStore = ...
MyNamespace.Plugin.Chart = MyNamespace.Plugin.extend({
return {
initialize: function() {
// ...
},
render: function() {
var stockGrid = Ext.create('Ext.grid.Panel', {
autoRender: true,
autoShow: true,
store: gridDataStore,
header: false,
stateId: 'stateGrid',
columns: [
{text: 'Symbol', width: 75, sortable: true, dataIndex: 'symbol'},
{text: 'Description', width: 200, sortable: true, dataIndex: 'description'},
{text: 'Quantity', width: 75, sortable: true, dataIndex: 'quantity'},
{text: 'Last Price', width: 85, sortable: true, dataIndex: 'last_price'}
],
viewConfig: {
stripeRows: true,
enableTextSelection: true
}
});
return stockGrid.getEl().dom;
}
};
}
})(MyNamespace);
And here's code using the plugin:
var chart = new MyNamespace.Plugin.Chart();
var anotherPlugin = new MyNamespace.Plugin.Another();
var stocksWindow = Ext.create('Ext.Window', {
title: 'Stocks',
width: 600,
height: 450,
layout: 'fit',
items: [
Ext.create('Ext.tab.Panel', {
activeTab: 0,
items: [{
title: 'Chart',
autoScroll: true,
contentEl: chartPlugin.render() // RENDER FIRST PLUGIN IN FIRST TAB
},{
title: 'Something Else',
autoScroll: true,
contentEl: anotherPlugin.render() // RENDER SECOND PLUGIN IN SECOND TAB
}]
})
]
});
I can add it to an invisible container, but it feels dirty doing so:
var container = document.createElement('div');
document.getElementsByTagName('body')[0].appendChild(container);
container.style.visibility = 'hidden';
var stockGrid = Ext.create('Ext.grid.Panel', {
...
renderTo: container
...
});
Here's an example
Here are a few problems with your code.
What you are calling plugins are not plugins, they are just subclasses of Ext.grid.Panel. A plugin is something that adds functionality to an Ext.Component, but that is not what Stocks is doing. It's just what we call a preconfigured class.
Here's what I would do, just make MyNamespace.Plugin.Stocks be a subclass of Ext.grid.Panel, you can now easily pass those as the items of a Ext.tab.Panel. Make sure you rename it, it's not a plugin.
By giving your widget subclasses the alias: 'widget.stock-grid', you can create them using just an object definition, without having to instantiate them, the framework will take care of rendering it only when needed (the tab is activated)
Ext.create('Ext.tab.Panel', {
activeTab: 0,
items: [{
title: 'Stocks',
autoScroll: true,
xtype: 'stock-grid'
},{
title: 'Orders',
autoScroll: true,
xtype: 'stock-grid'
}]
})
When using managed layouts, you cannot just simply copy a node into another container, because the node you copied in there won't have a managed layout.
Here's a modified version of your code that is written more like Ext-JS intended it. http://jsfiddle.net/NVfRH/10/
You can look into the generated HTML and you'll notice that the grid under orders only renders when you activate that tab.
You should also notice that your grids weren't properly sizing themselves to fill the window, my code fixes that since they are correctly placed in the layout pipeline and obey the fit layout.
Remaining Problems
Your grids are sharing a store, notice that when you sort one, the other gets sorted, so you can't have them with different sorting.
You were using a stateId, but then you were creating two instances with the same stateId, all stateIds must be unique
And lastly, I must ask, were you really relieved when Chad Johnson changed his name to Chad Ochocinco? :)
I want to be able to reorder the rows within a single grid. Im relatively new to extjs and have tried searching for this but all the resources i find are for older ext js versions and some of properties defined in those aren't valid anymore. eg- http://www.vinylfox.com/getting-started-with-grid-drag-drop/
xtype: 'grid',
id: 'row-grid',
hideHeaders: true,
store: 'SelectedRowStore',
//enableDragDrop: true,
//ddGroup: 'rowgrid-dd',
columns: [
{
header: 'Rows',
flex: 1,
sortable: false,
dataIndex: 'DisplayName'
},
{
id: 'button-column',
dataIndex: 'ID',
sortable: true,
hideable: false,
width: 35,
renderer: PA.common.RendererHelper.renderButtonForAddRowMainGrid
}
]
I'd really appreciate any help/advice on this issue.
Take a look at the grid to grid drag-n-drop example. It works with two grids, but I'm sure it can be easily modified to allow rearranging rows within one grid.
You can follow the sencha sample as Rene said or follow this:
Add this to your grid:
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
containerScroll: true,
dragGroup: 'someuniquenameforyourgrid',
dropGroup: 'someuniquenameforyourgrid'
},
},
And, only if you need some listener to do some anction, add (inside viewConfig):
listeners: {
drop: 'onDropGrid'
}
and event handler code in your controller:
onDropGrid: function (node, data, dropRec, dropPosition) {
...
}