Get javascript array first element - javascript

How can I get the first element of an array in javascript by a means other than array[0]?
I do not know why, but for some reason the array that gets passed into the method has its first, and only, element at index 5, not 0.
Edit - Here is my attempt at providing a minimal reproducible example.
// Initialize database connection string datatable editor
editor = new $.fn.dataTable.Editor({
table: "#remoteSqlDatabaseTable",
ajax: $("#UpdateIntegrationRemoteSqlDatabaseAction").val(),
fields: [
{ label: 'Reference Name', name: 'Name' },
{ label: 'IP Address or Host', name: 'IpAddress' },
{ label: 'Port', name: 'Port' },
{ label: 'Username', name: 'UserCredential' },
{ label: 'Password', name: 'PasswordCredential', def: '' },
{ name: 'button' }
]
});
editor
.on('open', function (e, type) {
if (type === 'inline') {
// Listen for a tab key event when inline editing
$(document).on('keydown.editor', function (e) {
if (e.keyCode === 9 || e.keyCode === 13) {
editor.blur();
}
});
}
if (editor.s.includeFields[0] === 'PasswordCredential') {
editor.field(editor.s.includeFields[0]).val('');
}
})
.on('close', function () {
$(document).off('keydown.editor');
})
.on('preSubmit', function (e, edit) {
if (edit.data[1].PasswordCredential !== undefined) {
var value = edit.data[1].PasswordCredential;
// check for null or whitespace
if (typeof value === 'undefined' || value == null || value.replace(/\s/g, '').length < 1) {
editor.close();
return false;
}
}
});
// Configure inline editing columns
$('#remoteSqlDatabaseTable').on('click', 'tbody td:not(:last-child)', function (e) {
editor.inline(this, {
submitOnBlur: true
});
});
// Reload data on edit to handle reordering
//editor.on("submitSuccess", function () {
// var table = $('#databaseConnectionTable').DataTable();
// console.log('submitSuccess');
// table.ajax.reload(function () {
// initTableStyling();
// });
//})
// Initialize datatable
var table = $('#remoteSqlDatabaseTable').DataTable({
paging: false,
searching: false,
info: false,
ordering: false,
ajax: $("#GetIntegrationRemoteSqlDatabasesAction").val(),
dom: 'Bfrtip',
columns: [
{ data: 'Name' },
{ data: 'IpAddress' },
{ data: 'Port' },
{ data: 'UserCredential' },
{ data: 'PasswordCredential' },
{ data: null }
],
select: false,
responsive: false,
buttons: [],
columnDefs: [
{
targets: -1,
data: null,
render: function (data, type, row, meta) {
return '<button class="btn red" type="button">Delete</button>';
}
}
],
initComplete: function (settings, json) {
//initTableStyling();
}
});
Like i said, i am not sure exactly where the problem is coming from. The method that is breaking is the editor.on('presubmit'), where it check if(edit.data[1] . edit.data[1] is the object that only has a 5th element.
this is everything relating to the table whos editing is the problem.

Updated answer, this works with objects. It isn't a pretty as find filter answers but it simply works.
Loop through the object and set a value.
Since there is only one element, it will set the variable without overwriting anything.
testArray = {"5" : "test"};
var val = "";
for(key in testArray){val = testArray[key];}
console.log(val);

You can do this:
let [first_element] = your_array

Related

How to set cutom template for kendo grid columns

I need to set Kendo grid action button Icon based on value. My code as follows,
function InitProductServicesGrid() {
var prodServiceDataSource = new kendo.data.DataSource({
transport: {
type: "json",
read:
{
url: SERVER_PATH + "/LTSService/ProductsService.asmx/GetProductServiceDetailsList",
type: "POST",
contentType: 'application/json',
data: GetAdditonalData,
datatype: "json"
},
update:
{
url: SERVER_PATH + "/LTSService/ProductsService.asmx/SaveProductService",
type: "POST",
contentType: 'application/json',
datatype: "json"
}
},
schema: {
data: function (result) {
return JSON.parse(result.d);
},
model: {
id: "Id",
fields: {
Id: { type: "int" },
ServiceTime: { type: "string" },
IsActive: { type: "boolean"}
}
}
},
requestEnd: function (e) {
if (e.type === "destroy") {
var grid = $("#productServicesGrid").data("kendoGrid");
grid.dataSource.read();
}
},
error: function (e) {
e.preventDefault();
if (e.xhr !== undefined && e.xhr !== null) {
var messageBody = e.xhr.responseJSON.Message;
ShowGritterMessage("Errors", messageBody, false, '../App_Themes/Default/LtsImages/errorMessageIcon_large.png');
var grid = $("#productServicesGrid").data("kendoGrid");
grid.cancelChanges();
}
},
pageSize: 20,
});
$("#productServicesGrid").kendoGrid({
dataSource: prodServiceDataSource,
sortable: true,
filterable: false,
pageable: true,
dataBound: gridDataBound,
editable: {
mode: "inline",
confirmation: false
},
columns: [
{ field: "Id", title: "", hidden: true },
{
field: "ServiceTime",
title: "Time Standard",
sortable: false,
editor: function (container, options) {
var serviceTimeTxtBox = RenderServiceTime();
$(serviceTimeTxtBox).appendTo(container);
},
headerTemplate: '<a class="k-link" href="#" title="Time Standard">Time Standard</a>'
},
{
title: "Action", command: [
{
name: "hideRow",
click: hideRow,
template: comandTemplate
}
],
width: "150px"
}
]
});
}
I wrote a custom template function as follows,
function comandTemplate(model) {
if (model.IsActive == true) {
return '<a title="Hide" class="k-grid-hideRow k-button"><span class="k-icon k-i-lock"></span></a><a title="Hide"></a>';
}
else {
return '<a title="Show" class="k-grid-hideRow k-button"><span class="k-icon k-i-unlock"></span></a><a title="Show"></a>';
}
}
But when I debug the I saw the following value for model value.
I followed this sample code as well. here you can see, I also set the custom template like the sample code. Please help me to solve this. Why I can't access model IsActive value from comandTemplate function.
Updated
When clicking hideRow action, I access the dataItem as follows.
function hideRow(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
if (dataItem.IsActive == true) {
dataItem.IsActive = false;
}
else {
dataItem.IsActive = true;
}
}
Is there any possible way to access data from template function as above or any other way?
I would suggest a different approach because you can't access grid data while rendering and populating grid.
My suggestion is to use two actions and hide it based on the flag (in your case IsActive).
Something like this: Custom command
NOTE: in visible function you can access item!
EDIT: you can access it and change it on dataBound traversing through all data.
Check this example: Data bound
I don't see the advantage of relying on the grid commands. You can render any button you want yourself and and use the dataBound event to bind a click handler:
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{
template: function(dataItem) {
const isActive = dataItem.isActive;
return `<a title=${isActive ? "Hide": "Show"} class="k-grid-hideRow k-button"><span class="k-icon k-i-${isActive ? 'lock' : 'unlock'}"></span></a>`
}
}
],
dataBound: function(e) {
e.sender.tbody.find(".k-grid-hideRow").click(evt => {
const row = evt.target.closest("tr")
const dataItem = e.sender.dataItem(row)
dataItem.set("isActive", !dataItem.isActive)
})
},
dataSource: [{ name: "Jane Doe", isActive: false }, { name: "Jane Doe", isActive: true }]
});
Runnable Dojo: https://dojo.telerik.com/#GaloisGirl/eTiyeCiJ

Updating Div with Total Records Outside of table

I’m working with datatables and trying to figure out what I’m doing wrong. I am trying to display the total number of rows when the table hits the draw event on the table. Right now with the code, I’m showing below I am not getting any console errors. The element where the number is supposed to be updated is correct. I am just not getting it to render with the correct count.
("use strict");
const renderStatusCell = (data, type, full, meta) => {
const status = {
0: { title: "Inactive" },
1: { title: "Active" }
};
if (typeof status[data] === "undefined") {
return data;
}
return status[data].title;
};
var table = $('[data-table="users.index"]');
// begin first table
table.DataTable({
// Order settings
order: [[1, "desc"]],
ajax: "/titles",
columns: [
{ data: "id", title: "User ID" },
{ data: "name", title: "Name" },
{ data: "slug", title: "Slug" },
{ data: "introduced_at", title: "Date Introduced" },
{ data: "is_active", title: "Status", render: renderStatusCell },
{
data: "action",
title: "Actions",
orderable: false,
responsivePriority: -1
}
]
});
var updateTotal = function() {
table.on("draw", function() {
$("#kt_subheader_total").html(table.fnSettings().fnRecordsTotal());
});
};
I expected when the table was rendered to update the dom with the correct number of rows however the div does not get updated.
I don't understand your problem, but I think you need something like that.
table
.row($(this).parents('tr'))
.remove()
.draw();
or
table.ajax.reload();
I believe you need to wait until the HTML loads before running all your javascript code. Also, if you are storing the total, you not make it a function but rather just store the value.
'use strict';
// this will make sure all the HTML loads before the JavaScript runs.
$(function() {
var table = $('[data-table="users.index"]');
var updateTotal = null; // store in a variable
const renderStatusCell = (data, type, full, meta) => {
const status = {
0: { title: "Inactive" },
1: { title: "Active" }
};
if (typeof status[data] === "undefined")
return data;
return status[data].title;
};
// begin first table
table.DataTable({
// Order settings
order: [[1, "desc"]],
ajax: "/titles",
columns: [
{ data: "id", title: "User ID" },
{ data: "name", title: "Name" },
{ data: "slug", title: "Slug" },
{ data: "introduced_at", title: "Date Introduced" },
{ data: "is_active", title: "Status", render: renderStatusCell },
{
data: "action",
title: "Actions",
orderable: false,
responsivePriority: -1
}
]
});
table.on("draw", function() {
updateTotal = table.fnSettings().fnRecordsTotal();
$("#kt_subheader_total").html(table.fnSettings().fnRecordsTotal());
});
});

How do I select kendo grid items by Id passed in by an array?

I have a Kendo Grid with checkbox selection in my MVC web application. I am trying to set some initial selections that trigger on databind. Here is my grid code:
#(Html.Kendo().Grid<MyProject.ViewModels.MyViewModel>()
.Name("MyGrid")
.Columns(columns => {
columns.Select().Width(50);
columns.Bound(c => c.Id);
columns.Bound(c => c.Name).Title("Name")
})
.Pageable()
.Sortable()
.Events(ev => ev.DataBound("onChange"))
.PersistSelection()
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(p => p.Id))
.Read(read => read.Action("GetData", "Test"))
))
You'll notice that under the events parameter I've set a function to trigger on DataBound called onChange. This function is where I want to make my initial selections. I started writing a function to achieve this and Telerik assisted with some code:
function onChange(e) {
//Sample array
var arr = [206, 210];
for (var i = 0; i < e.sender.items().length; i++) {
//206 is a test value, I want to pass an array in.
if (e.sender.dataItem(e.sender.items()[i]).Id == 206) {
e.sender.select(e.sender.items()[i]);
}
}
}
This code only takes me part of the way. What I want to do and where I need help is, adjusting this code to accept an array of Ids and select those items. For testing purposes, I have made a very basic array called arr but I'm not sure how to pass this into the loop.
I attempted to get it working using a jquery each loop to iterate over every value in the array and select the row but it didn't work. The code was something like:
function onChange(e) {
//Sample array
var arr = [206, 210];
$.each(arr, function(i, v) {
if (e.sender.dataItem(e.sender.items()[i]).Id == v) {
e.sender.select(e.sender.items()[i]);
}
})
}
Any help is appreciated.
Use indexOf() to check if each Id exists in the array:
function onChange(e) {
//Sample array
var arr = [206, 210],
grid = e.sender;
for (var i = 0; i < grid.items().length; i++) {
if (arr.indexOf(grid.dataItem(grid.items()[i]).Id) > -1) {
grid.select(grid.items()[i]);
}
}
}
Working example:
let arr = [1,3,5,7],
data = [1,2,3,4,5,6,7,8,9,10];
for (let i = 0, len = data.length; i < len; i++) {
if (arr.indexOf(data[i]) > -1) {
console.log(`item ${data[i]} exists in the array`);
}
}
Here I have a namespaced myApp with functions where I added a klookup function to return the first match in an array, then select using that. Note I used the dataBound event using a kendo data sample.
// create a namespace for my functions
var myApp = myApp || {};
myApp.funcs = {
klookup: function(myArray, searchTerm, property, firstOnly) {
var found = [];
var i = myArray.items().length;
while (i--) {
if (myArray.dataItem(myArray.items()[i])[property] == searchTerm) {
found.push(myArray.items()[i]);
if (firstOnly) break; //if only the first
}
}
return found;
},
onDataBound: function(e) {
// console.log("onDataBound");
myApp.data.Sender = e.sender;
let s = myApp.data.Sender
// console.dir(myApp.data.arr);
let rows = s.items();
//console.log(rows);
myApp.data.arr.forEach(function(entry) {
let found = myApp.funcs.klookup(s, entry, "OrderID", true);
s.select(found[0]);
});
}
};
// add data to my namespace
myApp.data = {
arr: [10248, 10250]
};
$(function() {
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
schema: {
model: {
fields: {
OrderID: {
type: "number"
},
Freight: {
type: "number"
},
ShipName: {
type: "string"
},
OrderDate: {
type: "date"
},
ShipCity: {
type: "string"
}
}
}
},
pageSize: 5,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
persistSelection: true,
dataBound: myApp.funcs.onDataBound,
height: 550,
filterable: true,
sortable: true,
pageable: true,
columns: [{
selectable: true,
width: "50px"
}, {
field: "OrderID",
filterable: false
},
"Freight",
{
field: "OrderDate",
title: "Order Date",
format: "{0:MM/dd/yyyy}"
}, {
field: "ShipName",
title: "Ship Name"
}, {
field: "ShipCity",
title: "Ship City"
}
]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.blueopal.min.css" />
<script src="https://kendo.cdn.telerik.com/2018.2.620/js/kendo.all.min.js"></script>
<div id="grid"></div>

How to declare closeCell() method for a particular row-item in Angular-JS

I have a grid which is editable, but at a particular column of a row I want to make it stable(non-editable) if it meets certain requirements,
This is the code for my grid
$scope.Grid = {
dataSource : new kendo.data.DataSource({
schema: {
model: {
id: 'Id',
fields: {
Id:{type:'number'},
Name: { type: "string" },
Description: { type: "string" },
Remarks: { type: "string" },
ApprovalStatus: { type: "string" }
}
}
}
}),
selectable: true,
sortable: true,
resizable: true,
scrollable: false,
edit: edit,
save: update,
These are my edit and update functions
function edit(e) {
e.model.Id = e.model.Id == "" ? 0 : e.model.Id;
if(e.model.ApprovalStatus === 'Waiting')
{
$('#Grid').data("kendoGrid").closeCell();
}
}
function update(e) {
var Data = {
Id: e.model.Id != "" && e.model.Id > 0 ? e.model.Id : 0,
Name: e.model.Name,
Description: e.model.Description,
Remarks: e.model.Remarks,
ApprovalStatus: e.model.ApprovalStatus
}
ciSetUp.setPayLoad({ Info: Data });
ciSetUp.postdata(e.model.Id).then(function () {
console.log(ciSetUp.postcreatedata);
});
}
So if ApprovalStatus is equal to Waiting, Approval Status field should become non-editable, which I'm not able to get.
It works fine till the if condition, but the thing inside the loop doesn't execute
Instead of using $('#Grid').data("kendoGrid").closeCell();, use e.sender.closeCell();
EDIT:
The above answer is for incell editing mode. When using inline editing mode, use e.sender.cancelRow(); instead.
See this Plunker demo.

Format multiple columns depending on the value of one

Can I use a custom formatter on a cell A to modify a cell B ?
Your original demo http://jsfiddle.net/fo3wb58w/12/ shows what you want. In general, you use already one formatter function shared by multiple columns. If you would click on the column header of the column PLA, MCO, SUP or REX you will see nothing happens. The problem is: you use datatype: "local", which holds the internal data of the grid in the data and _index parameters. The data will be used during sorting and filtering/searching of the local data. Formatting is just the form to display the corresponding data. Thus I would recommend you to fill the column data for every column first and only then format the data. It will saves correct data in the data parameter and will allows to sort and filter the data.
The simplest modification of the demo will consist from including localReader
localReader: {
repeatitems: true,
cell: function (item) {
var rowData = $.parseJSON(item.data);
rowData.data = item.data; // include the original data too
return rowData;
}
}
and modification of your custom formatter to the following, for example,
function format (cellvalue) {
if (cellvalue !== undefined) {
return '<div class="led-box"><div class="' +
(cellvalue !== null ? 'led-green' : 'led-red') +
'"></div></div>';
} else {
return '';
}
}
See http://jsfiddle.net/OlegKi/fo3wb58w/14/. Now we will fill the data, which allows us to sort there. I use in the demo the latest version of free jqGrid because jqGrid 4.6, which you used in the original demo has the bug with processing of localReader which has repeatitems: true.
More deep modification will be http://jsfiddle.net/OlegKi/fo3wb58w/15/
var mydata = [
{ data: "{\"pla\":1,\"mco\":null,\"sup\":null}" },
{ data: "{\"pla\":null,\"mco\":1,\"sup\":1}" },
{ data: "{\"pla\":1,\"rex\":null}" }
],
sortRedGreen = function (value) {
switch (value) {
case 1:
return 2;
case null:
return 1;
default:
return 0;
}
},
formatRedGreen = function (cellvalue) {
if (cellvalue !== undefined) {
return '<div class="led-box"><div class="' +
(cellvalue !== null ? 'led-green' : 'led-red') +
'"></div></div>';
} else {
return '';
}
},
templateRedOrGreen = {
width: 48,
sorttype: sortRedGreen,
stype: "select",
searchoptions: { value: "undefined:Undef;null:Null;1:1", noFilterText: "Any"},
formatter: formatRedGreen
};
$("#grid").jqGrid({
data: mydata,
autoencode: true,
colModel: [
{ name: 'data', width: 250, search: false },
{ label: 'PLA', name: 'pla', template: templateRedOrGreen },
{ label: 'MCO', name: 'mco', template: templateRedOrGreen },
{ label: 'SUP', name: 'sup', template: templateRedOrGreen },
{ label: 'REX', name: 'rex', template: templateRedOrGreen }
],
localReader: {
repeatitems: true,
cell: function (item) {
var rowData = $.parseJSON(item.data);
rowData.data = item.data; // include the original data too
return rowData;
}
},
iconSet: "fontAwesome",
caption: "Stack Overflow Example"
}).jqGrid("filterToolbar");
It uses custom sorttype function which allow to reorder the possible value undefined, null and 1 during sorting. It uses filterToolbar with
stype: "select",
searchoptions: { value: "undefined:Undef;null:Null;1:1", noFilterText: "Any"}
to simplify filtering of the data.

Categories