When I click on the download link in the attached example, I want only the download event to be executed, but not the editor event.
Dojo Example: https://dojo.telerik.com/EcEDiGUB/27
HTML:
<div id="grid"></div>
JS:
var grid;
$(document).ready(function(){
grid = $("#grid").kendoGrid({
columns: [
{
field: "name",
},
{
field: "file",
template: function(e){
return '<div class="box">' + e.file + '</div>';
},
editor: function(e){
alert("open media editor");
return true;
}
}
],
dataSource: {
data: [
{ id: 1, name: "Jane Doe", file: "<div class='container'></div>" +
"<div class='file k-icon k-i-file-pdf'></div>" +
"<div class='download k-icon k-i-download'></div>" +
"</div>" },
{ id: 2, name: "John Doe", file: "<div class='container'></div>" +
"<div class='file k-icon k-i-file-pdf'></div>" +
"<div class='download k-icon k-i-download'></div>" +
"</div>" +
"<div class='container'></div>" +
"<div class='file k-icon k-i-file-xls'></div>" +
"<div class='download k-icon k-i-download'></div>" +
"</div>" }
],
schema:{
model: {
id: "id",
fields: {
file: { type: "string"}
}
}
}
},
editable: true,
}).data("grid");
$(".download").on("click", function(e){
e.preventDefault();
alert("download media");
});
It is now that the editable mode:
editable: true,
should be kept, because it is possible to edit as well as to start a download.
How can I start the download by clicking on the download icon without the editor event being fired?
you can use the columns.editable property:
{
field: "file",
template: function(e){
return '<div class="box">' + e.file + '</div>';
},
editable: function(){
return false;
},
editor: function(e){
alert("open media editor");
return true;
}
}
Dojo
Related
I currently have a normal ASPNETZERO index page, which renders a datatable grid with search fuctions. I want to change this view to render "tiles" for each row in the grid. I already have the CSS/HTML for rendering tiles working. I basically want to repurpose the below index.js code to render my tiles, instead of the datatable grid.
(function () {
$(function () {
var _$companyTable = $('#companyTable');
var _companyService = abp.services.app.company;
var _permissions = {
create: abp.auth.hasPermission('Pages.Tenant.Administration.Company.Create'),
edit: abp.auth.hasPermission('Pages.Tenant.Administration.Company.Edit'),
impersonation: abp.auth.hasPermission('Pages.Tenants.Impersonation'),
};
var _createModal = new app.ModalManager({
viewUrl: abp.appPath + 'Nursing/Company/CreateModal',
scriptUrl: abp.appPath + 'view-resources/Areas/Nursing/Views/Company/_CreateModal.js',
modalClass: 'CreateCompanyModal'
});
var _editModal = new app.ModalManager({
viewUrl: abp.appPath + 'Nursing/Company/EditModal',
scriptUrl: abp.appPath + 'view-resources/Areas/Nursing/Views/Company/_EditModal.js',
modalClass: 'EditCompanyModal'
});
var dataTable = _$companyTable.DataTable({
paging: true,
serverSide: true,
processing: true,
responsive: true,
listAction: {
ajaxFunction: _companyService.getCompanies,
inputFilter: function () {
return {
filter: $('#CompanyTableFilter').val()
};
}
},
columnDefs: [
{
targets: 0,
data: null,
orderable: false,
autoWidth: true,
defaultContent: '',
rowAction: {
cssClass: 'btn btn-xs btn-primary blue',
text: '<i class="fa fa-cog"></i> ' + app.localize('Actions') + ' <span class="caret"></span>',
items: [{
text: app.localize('Edit'),
visible: function () {
return _permissions.edit;
},
action: function (data) {
_editModal.open({ id: data.record.id });
}
}]
}
},
{
targets: 1,
orderable: true,
autoWidth: true,
data: "companyName"
},
{
targets: 2,
orderable: true,
autoWidth: true,
data: "companyLegalName"
},
{
targets: 3,
autoWidth: true,
data: "companyTaxID"
},
{
targets: 4,
orderable: true,
autoWidth: true,
data: "currency"
}
]
});
function getCompanies() {
dataTable.ajax.reload();
}
$('#CreateNewCompanyButton').click(function (e) {
_createModal.open();
});
$('#GetCompaniesButton').click(function (e) {
e.preventDefault();
getCompanies();
});
abp.event.on('app.editCompanyModalSaved', function () {
getCompanies(true);
});
abp.event.on('app.createCompanyModalSaved', function () {
getCompanies(true);
});
$('#CompanyTableFilter').focus();
});
How can I change the JS code above to render my tiles instead of the datatable? I also want to retain the search function for the tiles. The app service method GetCompanies used in the JS code above works for rendering my tiles. So that API call will remain the same.
Here is the output I want to achieve from the above JS code.
Here is the current standard ABP index page view. I want to replace this with above tiles.
I figured out a solution. I changed the index.js code by adding the method shown below. I'm using an AJAX call to the API method and then using the results to render my tiled output. This is working for me.
If anyone sees any issues with this approach, please do let me know.
function getCompanies() {
$.ajax({
type: 'GET',
url: '/api/services/app/Company/GetCompanies',
dataType: 'json',
success: function (companies) {
var _tileHtml = "";
//Iterate thru JSON list of values
$.each(companies.result.items, function (i, company) {
//Tile content start
_tileHtml = "<div class='SingleTileContent inline-block'>";
//Header
_tileHtml += "<div class='Tile-header'>";
_tileHtml += "<div class='pull-left inline-block'>";
_tileHtml += "<div class='badge badge-info'>" + company.id + "</div>";
_tileHtml += "</div>";
_tileHtml += "<div class='pull-left inline-block text-bold'> | " + company.companyName + "</div>";
_tileHtml += "</div>";
//Body start
_tileHtml += "<div class='Tile-body text-left'>";
//Body row
_tileHtml += "<div class='Tile-body-detail'>";
_tileHtml += "<label>Legal Name</label> " + company.companyLegalName + "</div>";
//Body row
_tileHtml += "<div class='Tile-body-detail'>";
_tileHtml += "<label>Tax Id</label> " + company.companyTaxID + "</div>";
//Body end
_tileHtml += "</div>";
//Buttons (footer)
_tileHtml += "<div class='Tile-buttons'>";
_tileHtml += "<a href='javascript:;' class='btn btn-xs blue btnEdit' id='EditCompanyButton'>Edit<i class='fa fa-edit'></i></a>";
_tileHtml += "</div>";
//Tile content end
_tileHtml += "</div>";
$("#TestJS2").append(_tileHtml);
});
Count = 0;
},
error: function (ex) {
abp.notify.error('Failed to retrieve companies' + ex);
}
});
}
I have a database of lots of info that build the table. What I want to be able to do is load the data through the ajax call and then be able to edit the data in the table. But I can't get the data to show up on the page. I'm using the DataTables in another interface and the loading, sorting, and other cool features work. I haven't used Editor before and I'm a little confused.
function drawDataTable(){
var len = allocationData.length;
html = "<div id='dataTableDiv'><table id='dataTable' class='table table-bordered table-striped dataTable' role='grid'><thead><tr role='row'><th>System Name</th><th>Gatherer</th><th>Operator</th><th>County</th><th>Sample Date</th><th>Daily Avg</th></tr></thead><tbody>";
for (i=0;i<len;i++){
html += "<tr><td>" + allocationData['SystemName'][i] + "</td><td>" + allocationData['Gatherer'][i] + "</td><td>" + allocationData['Operator'][i] + "</td><td>" + allocationData['County'][i] + "</td><td>" + allocationData['SampleDate'][i] + "</td><td>" + allocationData['DailyAvg'][i] + "</td></tr>";
}
html += "</tbody></table></div>";
$(".table-responsive").html(html);
}
$(function(){
editor = new $.fn.dataTable.Editor( {
"ajax": "qry/dataTable.php",
"table": "#dataTable",
"fields":[{
"name": "SystemName"
},{
"name": "Gatherer"
},{
"name": "Operator"
},{
"name": "County"
},{
"name": "SampleDate"
},{
"name": "DailyAvg"
}]
});
$('#dataTable').DataTable({
dom: "Bfrtip",
ajax: {
type: "POST",
url: "qry/dataTable.php",
success: function(){
drawDataTable();
}
},
serverSide: true,
columns: [
{data: "SystemName"},
{data: "Gatherer"},
{data: "Operator"},
{data: "County"},
{data: "SampleDate"},
{data: "DailyAvg"}
],
select: true,
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
]
});
});
Try editing your success: function. See if this helps.
success: function(result){
allocationData = JSON.parse(result);
drawDataTable();
}
I am trying to make expandable button on the header of grid. On click of that It will expand and then again click it will close.
I wrote a function for expanding with flag 1 and 0.
My question is how to place a switch button on header of grid column.
Here I tried.
By Design time just for reference.
columns: [{
id: 'Sd',
header: 'Study',
width: 130,
sortable: false,
hideable: false,
dataIndex: 'Stu'
}, {
width: 130,
header: '<u style="color:blue;cursor:pointer;" title="Click on to view by Days" onclick="Fn_dayclick(0)">' +
'<img alt="Click on to view by Days" style="vertical-align:bottom;" ' +
'src="Images/508Images/group-expand.gif"> ' + "Subject" + '</u>',
id: 'Sub',
itemId: "Sub",
dataIndex: 'Sub',
hidden: false,
}, {
width: 130,
id: 'Ext',
header: 'Exclude',
dataIndex: 'Excl',
hidden: false
}]
In Subject header i given that code with + button and on click it call Fn_dayclick(0). But where to give code for - button which I prepared. This is in the case where I am designing column in code.
What to do when my column is coming from xml.
My code for Ajax
Ext.Ajax.request({
url: 'XML/Cohart.xml',
scope: this,
timeout: global_constants.TIMEOUT,
method: "GET",
disableCaching: true,
failure: function(response) {
utils.showOKErrorMsg(sdisMsg.ajaxRequestFailed);
},
success: function(response) {
var datas = response.responseXML;
Ext.each(datas.getElementsByTagName("HEADER"), function(header) {
this.buildField(header);
this.buildColumn(header);
}, this);
Ext.each(datas.getElementsByTagName("G"), function(columnData) {
this.fieldLength = this.fields.length;
this.record = [];
for (i = 0; i < this.fieldLength; i++) {
//this.record.push(columnData);
var fieldName = this.fields[i].name
this.record[fieldName] = columnData.getAttribute(fieldName);
}
this.data.push(this.record);
}, this);
this.store = new Ext.data.ArrayStore({
fields: this.fields
});
this.store.loadData(this.data);
},
//this.store.loadData(this.data);});
buildField: function(header) {
this.fields.push({
name: header.getAttribute("DATAINDEX")
});
},
buildColumn: function(header) {
var hiddenflg = !(header.getAttribute("VISIBLE"));
if (header.getAttribute("VISIBLE") == "false")
hiddenflg = true;
var strHeaderName = '';
if ((Ext.isIE && !PC.common.isIE10()))
strHeaderName = header.text;
else
strHeaderName = header.textContent;
var strToolTip = "";
this.columns.push({
header: Ext.util.Format.htmlEncode(strHeaderName),
tooltip: strToolTip,
dataIndex: header.getAttribute("DATAINDEX"),
width: parseInt(header.getAttribute("LENGTH")),
metaID: header.getAttribute("M"),
enableHdMenu: false,
hidden: hiddenflg,
menuDisabled: true,
sortable: false,
scope: this,
fixed: false,
expanded: true
});
},
});
Shall I put in render or anywhere else. Thanks for help.
If you want particular column header to be button with expandable then try this.
declare a variable and store your header in that. In if statement set header for that perticular column and in else statement set header for other columns.
in coloumn.push in place of header call your variable where you storing your header.
here is a code for you.
var headerstu;
if(header.getAttribute("DATAINDEX") === "SUB"){
if(header.showPara){ // decelear a showPara as boolean in ur function
headerstu = '<u style="color:blue;cursor:pointer;" title="Click on to view across Subject" onclick="Fn_Dayclick(1)">' +
'<img alt="Click on to view across Subject" style="vertical-align:bottom;" ' +
' src="Images/508Images/group-expand.gif" />' +
' ' + Ext.util.Format.htmlEncode(strHeaderName) + '</u>';
}else{
headerstu = '<u style="color:blue;cursor:pointer;" title="Click on to view across Subject" onclick="Fn_Dayclick(0)">' +
'<img alt="Click on to view across Subject" style="vertical-align:bottom;" ' +
' src="Images/508Images/group-close.gif" />' +
' ' + Ext.util.Format.htmlEncode(strHeaderName) + '</u>';
}// take a groupclose image which is opposite to group-expand
}else{
headerstu = Ext.util.Format.htmlEncode(strHeaderName);
}
this.columns.push({
header: headerstu,
tooltip: strToolTip,
dataIndex: header.getAttribute("DATAINDEX"),
width: parseInt(header.getAttribute("LENGTH")),
metaID: header.getAttribute("M"),
enableHdMenu: false,
hidden: hiddenflg,
menuDisabled: true,
sortable: false,
scope: this,
fixed: false,
expanded: true
});
},
Also I am not tested your complete code like function which you given on onclick but I am sure you can get changeable button on expandable column.
I have a problem where i am trying to find out why do i have to press the "ok" button of the pop up button twice in order to make it disappear. I can see from my code that i just have only one alert statement and still it behaves as if i may have accidently called two alert statements
function intialiseKendoGrid(date) {
gridResult = $('#grid').kendoGrid({
scrollable: {
virtual: true
},
navigatable: true,
groupable: true,
sortable: true,
selectable: "row",
pageable: true,
pageable: {
input: true,
numeric: false
},
resizable: true,
reorderable: true,
filterable: {
extra: false
},
columns: [{
field: "DealNumber",
width: 150,
title: "DealNumber",
filterable: {
operators: {
string: {
startswith: "Starts With",
contains: "Contains"
}
}
},
},
{
field: "DealIssuer",
width: 150,
title: "Issuer",
filterable: {
operators: {
string: {
startswith: "Starts With",
contains: "Contains"
}
}
},
//template: "<a href='http://manager.dealogic.com/ManagerV3/CPCortex/Default/${DealNumber}'>${DealNumber}</a>"
template: "<a>${DealIssuer}</a>"
}, {
field: "Ticker",
width: 150,
title: "Ticker",
filterable: {
operators: {
string: {
startswith: "Starts With",
contains: "Contains"
}
}
}
}, {
field: "DealExchange",
width: 150,
title: "Exchange",
filterable: {
operators: {
string: {
startswith: "Starts With",
contains: "Contains"
}
}
}
}, {
field: "DealType",
width: 150,
title: "Type",
filterable: {
operators: {
string: {
startswith: "Starts With",
contains: "Contains"
}
}
}
}, {
field: "DealValue",
width: 150,
title: "Value ($m)",
filterable: {
operators: {
string: {
startswith: "Starts With",
contains: "Contains"
}
}
},
/* template: '#= kendo.culture("en-US");kendo.toString(${DealValue/1000000},"p")#' */
template: '#= kendo.toString(DealValue,"c2") #'
}, {
field: "DealStatus",
width: 150,
title: "Status",
filterable: {
operators: {
string: {
startswith: "Starts With",
contains: "Contains"
}
}
}
}, {
field: "DealPricingCompletionDate",
width: 230,
title: "DealPricingCompletionDate",
format: "{0:dd/MM/yyyy}",
filterable: {
ui: "datetimepicker",
operators: {
date: {
gt: "After",
lt: "Before",
eq: "Equals"
},
messages: {
filter: "Apply",
clear: "Clear"
}
}
}
},
],
change: function () {
var text = "";
var grid = this;
grid.select().each(function () {
var dataItem = grid.dataItem($(this));
text += "DealNumber: " + dataItem.DealNumber + "\n" + "Issuer: " + dataItem.DealIssuer + "\n" + "Ticker: " + dataItem.Ticker + "\n" + "Type: " + dataItem.DealType + "\n" + "Value: " + dataItem.DealValue + "\n" +
"Status " + dataItem.DealStatus + "\n" + "DealPricingCompletionDate: " + kendo.toString(dataItem.DealPricingCompletionDate, "dd/MM/yyyy");
});
alert(text);
},
height: 700
}).data("kendoGrid");
The change event is being triggered twice, and since the alert() is being bound to the change event, it will also pop up twice.
Take a look at the change event documentation. It is "Fired when the user selects a table row or cell in the grid."
Perhaps it is being fired twice, one for the row and one for the cell? Although I see you have selectable: "row" so it should only fire for the row.
Update your change event to change: function (e) { console.log(e); } and see what it outputs in your debug console. This will give you a hint as to what element it is being triggered on.
You can then try adding e.preventDefault(); to your change event to stop any other event from being triggered.
After a long delay its been cracked now.
All i had to do was use SetTimeOut Method by timeout as 0 meaning do not specify any time parameter.
So the fixed code is
function onRowSelected(e) {
e.preventDefault();
console.log(e.sender);
var text = "";
var grid = this;
grid.select().each(function () {
var dataItem = grid.dataItem($(this));
text += "DealNumber: " + dataItem.DealNumber + "\n" + "Issuer: " +
dataItem.DealIssuer + "\n" + "Ticker: " + dataItem.Ticker + "\n" + "Type: " + dataItem.DealType + "\n" + "Value: " + dataItem.DealValue + "\n" +
"Status " + dataItem.DealStatus + "\n" + "DealPricingCompletionDate: " + kendo.toString(dataItem.DealPricingCompletionDate, "dd/MM/yyyy");
});
setTimeout(function () { alert(text) },0);
}
I'm trying to populate a select2 element using geonames data. I have a formatSelection method defined but it will not fire when an item is selected.
Here's the HTML element:
<input id="location" size="30" type="text">
Select2 binding with format functions:
function locationFormatResult(location) {
var markup = "<table class='location-result'><tr>";
if (location.countryCode !== undefined) {
markup += "<td class='flag-image'><img src='http://www.geonames.org/flags/x/" + location.countryCode.toLowerCase() + ".gif' /></td>";
}
markup += "<td class='location-info'>";
markup += "<div class='location-name'>" + location.name + ", " + location.adminName1 + ", " + location.countryName + "</div>";
markup += "</td></tr></table>";
return markup;
}
function locationFormatSelection(location) {
return location.name + ", " + location.adminName1 + ", " + location.countryName;
}
$(function () {
$('#location').select2({
placeholder: 'Location',
allowClear: true,
width: '260px',
minimumInputLength: 2,
ajax: {
url: 'http://ws.geonames.org/searchJSON',
dataType: 'jsonp',
data: function (term) {
return {
featureClass: 'P',
q: term
};
},
results: function (data) {
return {
results: data.geonames
};
}
},
formatResult: locationFormatResult,
formatSelection: locationFormatSelection,
dropdownCssClass: "bigdrop"
});
});
You can see the full fiddle here: http://jsfiddle.net/6CVbw/1/
Why is selecting an item not working?
I figured it out. When you instantiate the select2 plugin on an element you have to specify an ID attribute. This worked:
$(function () {
$('#location').select2({
id: function(e) { return e.name + '|' + e.adminName1 + '|' + e.countryName },
placeholder: 'Location',
allowClear: true,
width: '260px',
minimumInputLength: 2,
ajax: {
url: 'http://ws.geonames.org/searchJSON',
dataType: 'jsonp',
data: function (term) {
return {
featureClass: 'P',
q: term
};
},
results: function (data) {
return {
results: data.geonames
};
}
},
formatResult: locationFormatResult,
formatSelection: locationFormatSelection,
dropdownCssClass: "bigdrop"
});
});
You can see the updated fiddle here: http://jsfiddle.net/6CVbw/2/