Within an AngularJS directive, I trigger a callback function that needs access to a directive-level object that has been injected.
I am using a KendoUI template function for this, however I think this is more an issue about scope than the function.
Directive:
app.directive('projectEditorGrid', function (dataSourceFactory) {
var dataSourceFactory = new dataSourceFactory("/odata/ProjectEditor");
return {
link: function ($scope, $element, $attrs) {
$element.kendoGrid({
dataSource: dataSourceFactory.projects(),
pageable: true,
height: 400,
toolbar: ["create"],
columns: [
{ field: "WebsiteName", editable: true, width: 190, title: "Project Name", validation: { required: { message: "Project name is required" } } },
{ field: "WebsiteNotes", title: "Project Notes" },
{ field: "WebsiteGUID", title: "Project API ID", editable: false },
{ field: "DefaultContentType", title: "Default Content Type", width: "160px", editor: defaultContentTypeDropDownEditor, template: "#=ContentTypes.Descriptions#" },
{ command: ["edit", "destroy"] }
],
editable: "inline"
});
function defaultContentTypeDropDownEditor(container, options) {
console.log(container + " : " + options);
var dataSourcFactory = dataSourceFactory("/odata/ContentType");
var dsContentTypes = dataSourceFactory.contentTypes(); // returns a kendo.data.DataSource() object
$('<input required data-text-field="Description" data-value-field="ContentTypeId" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: dataSourceFactory.contentTypes()
}); // kendoDropDownList
}
}
}
});
dataSourceFactory is injected into the directive and successfully used to display the data.
When a row edit is triggered, defaultContentTypeDropDownEditor is called with its default parameters, container, options. If I could pass the dataSourceFactory to this function I'd be set, but not clear on how to accomplish this from the activating call.
options:
Object {field: "DefaultContentType", editor: function, model: n.extend.o}
editor: function defaultContentTypeDropDownEditor(container, options) {
field: "DefaultContentType"
model: n.extend.o
__proto__: Object
container:
[<td role="gridcell" data-container-for="DefaultContentType"></td>]
As you can see, dataSourceFactory is visible at the function level (injected into the directive), however is not accessible from within the defaultContentTypeDropDownEditor. Can someone please explain how to accomplish this?
The injected object is dataSourceFactory. By renaming the initial initialization to dataSourceFactory1 and the function callback's use of it to dataSourceFactory2, I was able to get this working.
Thanks to Nikos for pointing me in the right direction.
Related
I made a kendo grid with a toolbar to create new records, but when the update button is pressed the create function in the data source I expect to be called isn't being called. I took this code from another page in the code where it works perfectly fine and I scanned both page to make sure I'm not missing any sort of library and on top of that the debugger isn't outputting anthing either.
var RegionalMappingDataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
$.ajax({
url: siteRoot + '/Admin/RegionMapping/GetRegionMappings',
type: 'GET',
success: function(result) {
options.success(result);
},
error: function(result) {
options.error(result);
}
});
},
create: function () { // This is the method I expected to be called
console.log("it hits create");
},
save: function () { // Checked to make sure this method isn't called
console.log("it hits save");
}
}
});
$("#Regionmappinggrid").kendoGrid({
dataSource: RegionalMappingDataSource,
groupable: false,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
editable: "inline",
toolbar: [{ name: "create", text: "Update Other Region Name" }], // where I tried to bind to method
columns: [
{
title: "Country Name",
field: "CountryCode",
editor: function(container, options) {
var input = $('<input required id="mapping" name="' + options.field + '"/>');
input.appendTo(container);
input.kendoDropDownList({
autoBind: true,
optionLabel: 'Please Select Country....',
dataTextField: "Value",
dataValueField: "Key",
dataSource: getCountryName,
value: options.model.Key,
text: options.model.Value
}).appendTo(container);
}
},
{
title: "Region Name",
field: "RegionName",
editor: function(container, options) {
var input = $('<input required id="mapping1" name="' + options.field + '"/>');
input.appendTo(container);
input.kendoDropDownList({
autoBind: false,
optionLabel: 'Please Select Region....',
dataTextField: "Value",
dataValueField: "Key",
dataSource: getRegionName,
value: options.model.Key,
text: options.model.Value
}).appendTo(container);
}
},
{
title: "Region ID",
field: "RegionId",
hidden: true
},
{
title: "Other Name",
field: "Name"
},
{
title: "Updated On",
field: "UpdatedDate",
format: "{0: yyyy-MM-dd HH:mm:ss}",
editable: function() { return false; }
},
{
command: ["edit", "destroy"]
}
]
});
The Create function of the DataSource is called when the user presses the "Update" button that is rendered on the row of the new item. Can you confirm that upon pressing the "Update" button, the function is executed as expected?
As per automatically calling the Create function after the "Add new item" button is clicked, you should set the AutoSync property of the DataSource to "true". This would cause it to update automatically right after every change.
[https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/configuration/autosync][AutoSync property]
What I'm trying to do is store some data in a specific column that is calculated by using the data from another column.
I currently have a function that returns the number of available licenses for the given Id in JSON
function getAvailableLicenses(id) {
var url = "/Host/Organization/AvailableLicenses/" + id;
$.get(url, function (data) {
return data.AvailableLicenses;
});
}
How do I go about storing this number in a column named "AvailableLicenses"?
Here is my current Grid:
$("#OrganizationGrid").kendoGrid({
dataSource: viewModel.get("orgDataSource"),
filterable: {
extra: false
},
sortable: true,
pageable: true,
columns: [
{ field: "Id", hidden: true },
{ field: "Name", template: "<a href='/Host/Organization/Detail/#:Id#'>#:Name#</a>" },
{ field: "LicenseNumber", title: "Number of Licenses" },
{ field: null, title: "Available Licenses", template: "#= getAvailableLicenses(Id) #" },
{ field: "LicenseExpiration", title: "License Expiration", format: "{0:MM/dd/yyyy}" },
{ field: "State" },
{ field: "Active" }
],
editable: false
});
As you can see, I tried to create a null column with a template that calls the function for the given Id.
By using Fiddler I can see that the function is indeed being called for all of the rows, but the AvailableLicenses column just displays Undefined for every row.
Is there something I'm missing here to get this to work?
I think the better way to do this is on dataSource parse() function
First: you column configuration must change like this:
{ field: "AvalableLicenses", title: "Available Licenses" },
You alaways can use you template .
And second, inside your dataSource() you can add:
schema: {
parse: function(response) {
for (var i = 0; i < response.length; i++) {
response[i].AvalableLicenses= null;
response[i].AvalableLicenses = getAvailableLicenses(response[i].Id)
}
return response;
}
}
EDIT:
If you prefer using you way, I dont see any problem in your configuration, probably your $.get is returning undefined, or something you don't expect.
For conviniance I did an example working.
http://jsfiddle.net/jwocf897/
Hope this help
I searched Over the Google. I didn't get any source for my requirement.
My output is like
If I click the 1st column linkbutton eFocus011 or other rows linkbutton means it will go to new web bage, but the toolbar Add new record was not working, because I used template for System Name columns field. How to get the correct output?
My code:
var grid= $("#DivGrid").kendoGrid(
{
dataSource: DataSource4,
scrollable: true,
sortable: true,
filterable: false,
reorderable: true,
resizable: true,
pageable: true,
toolbar: [ { text : "Add new record",name: "popup",iconClass: "k-icon k-add"} ],
editable : {
mode : "inline"
// template: kendo.template($("#customPopUpTemplate").html())
},
navigable: true,
columns:
[
{
field: "SystemName",
title: "System Name",
width:"130px",
// template: '<a href >#: SystemName # </a>'
template:"<a onclick='NewWindow(this.id)' id=\"#= SystemId #\" href='\\#'>#= SystemName #</a>"
// template:'<a href class="list k-Linkbutton" onclick="NewWindow(this.id)" id="#= SystemId#" >#= SystemName #</a>'
// template: '<a href="\\#" onclick="NewWindow(this.id)" id="#= SystemId#" >#= SystemName #</a>'
},
{
field: "SystemIP",
title: "System IP",
width:"100px"
},
{
field: "SystemType",
title: "Type",
width:"80px",
editor: function (container, options) {
$("<input />")
.attr("data-bind", "value:SystemType")
.appendTo(container)
.kendoDropDownList({
dataSource: [ { text: "--Select--" ,value: "0"},{ text: "PC" ,value: "1"},{ text: "LAPTOP" ,value: "2" }],
dataTextField: "text",
dataValueField: "text"
});
}
},
{
field: "OSKey",
title: "OS Key",
width:"200px"
},
{
command: ["edit","destroy"],
title: " ",
width: "190px"
}
]
}).data("kendoGrid");
$(".k-grid-popup", grid.element).on("click", function ()
{
var popupWithOption =
{
mode: "popup",
template: kendo.template($("#customPopUpTemplate").html()) ,
window: {
title: "Add New Record"
}
};
grid.options.editable = popupWithOption ;
grid.addRow();
$(".k-window-action")
{
//visibility: hidden ;
}
grid.options.editable = "inline";
});
};
</script>
Also I used two types of editing. If I click toolbar, means I used popup Kendo editing edit and Delete means inline editing?
I think error is in
template:"<a onclick='NewWindow(this.id)' id=\"#= SystemId #\" href='\\#'>#= SystemName #</a>"
If I changed this line to:
template:"<a onclick='NewWindow(this.id)' id=\"#= SystemId=0 #\" href='\\#'>#= SystemName #</a>"
It will work only toolbar, columns linkbutton is not working.
Thanks in advance!!!
Your code is looking good to me
Confirm whether SystemId is present in models, if not then Rectify "SystemId" to "SystemIP"
and make a check
template:"<a onclick='NewWindow(this.id)' id=\"#= SystemIP#\" href='\\#'>#= SystemName #</a>"
I have a KENDO Grid and the fields and columns in that are populated from a datasource which is intern populated from an action.
Now i want to bind a particular cell content in that grid to another controller action and pass that ID of the cell also. How do I accomplish this. Below is the code for my grid. I could find answers in kendo UI docs but they use HTML Helpers to achieve this. I want it in the same style as below. Let us take the readername as the cell content for which this binding is required. Anybody tried this before?
$("#eventsgrid").kendoGrid(
{
dataSource: eventsDataSource,
navigatable: true,
pageable:
{
input: true,
numeric: false
},
columns:[
{
field:"",width:"30px", template:'<input type="checkbox" id="selectevent"/>'
},
{
field:"CardNumber",width:"80px"
},
{
field: "Image", width: "45px", title: "Type", template: "<img src='/Content/Themes/Default/images/AlarmType.png' id='AlarmType'/>"
},
{
field: "Priority", width: "60px", title: "Priroty"
},
{
field: "Origin", title:"Event Time"
},
{
field:"Description", title:"Alarm Title"
},
{
field: "ReaderName", title: "Location"
},
{
field: "", title: "Actions and Interactions", width: "160px", template: '<input type="button" value="Acknowledge" onclick="CheckAck" id="Acknowledge" /><br/><a href="javascript:performActions()" >3 Actions</a>'
},
{
field: "Image", title: "More", width: "60px", template: "<img src='/Content/Themes/Default/images/Door.png' onclick='showDetails()' id='door' width='20' height='20'/><div id='cardholderdetails'></div>"
}
],
}).data("kendoGrid");
Now i have a function which calls a $.POST call with the parameters. This function is hooked to the click event of the button. Is there a different way to do this?
I have following problem. I have grid with tbar. Inside tbar I have number of Ext.form.field.Trigger.
When the user click on trigger button I want to filter the store using function that is provided with grid. I want to define functionality of triggerclick inside defined class, so I can reuse this component with different grid.
So, in short I want to find the panel where clicked component is placed and call panel function, or pass reference of panel to triggerclick, or fire an event with some parameter that will calculated based on where the button was clicked, or maybe there is a better method to accomplish this.
The code (FilterField -> extension of trigger):
Ext.define('GSIP.core.components.FilterField', {
extend: 'Ext.form.field.Trigger',
alias: 'widget.filterfield',
initComponent: function() {
this.addEvents('filterclick');
this.callParent(arguments);
},
onTriggerClick: function(e, t) {
//Ext.getCmp('gsip_plan_list').filterList(); - working but dont want this
//this.fireEvent('filterclick'); - controller cant see it,
//this.filterList; - is it possible to pass scope to panel or reference to panel
//e.getSomething() - is it possible to get panel via EventObject? smth like e.getEl().up(panel)
}
});
code of panel:
Ext.define('GSIP.view.plans.PlanReqList', {
extend: 'Ext.grid.Panel',
alias: 'widget.gsip_devplan_list',
id: 'gsip_plan_list',
title: i18n.getMsg('gsip.view.PlanReqList.title'),
layout: 'fit',
initComponent: function() {
this.store = 'DevPlan';
this.tbar = [{
xtype: 'filterfield',
id: 'filter_login',
triggerCls: 'icon-user',
//scope:this - how to pass scope to panel without defining onTriggerClick here
// onTriggerClick: function() {
// this.fireEvent('filterclick'); //working event is fired but controller cant see it
// this.filterList; //this is working but i dont want to put this code in every filterfield
// },
// listeners : {
// filterclick: function(btn, e, eOpts) { //this is working
// }
// },
}];
this.columns = [{
id: 'id',
header: "Id",
dataIndex: "id",
width: 50,
sortable: true,
filterable: true
}, {
header: "Name",
dataIndex: "name",
width: 150,
sortable: true,
filterable: true
}, {
header: "Author",
dataIndex: "author",
sortable: true,
renderer: this.renderLogin,
filterable: true
}];
this.callParent(arguments);
},
filterList: function() {
this.store.clearFilter();
this.store.filter({
property: 'id',
value: this.down("#filter_id").getValue()
}, {
property: 'name',
value: this.down("#filter_name").getValue()
});
},
renderLogin: function(value, metadata, record) {
return value.login;
}
});
part of code of Controller:
init: function() {
this.control({
'attachments': {
filesaved: this.scanSaved,
}
}, {
'scan': {
filesaved: this.attachmentSaved
}
}, {
'#filter_login': {
filterclick: this.filterStore //this is not listened
}
});
},
filterStore: function() {
console.log('filtering store');
this.getPlanListInstance().filter();
},
Controller can listen to anything. Just need to specify exactly what to. But I would fire events on the panel level - add this into your trigger handler:
this.up('panel').fireEvent('triggerclicked');