i make simple application on titanium using table view. I have some custom row with checkbox on the left side. Here's my code :
var pickingData = [];
for (var i = 0; i<25; i++){
var row = Ti.UI.createTableViewRow({
className:'forumEvent', // used to improve table performance
backgroundSelectedColor:'cyan',
layout:'vertical'
});
if (Titanium.Platform.osname === 'android'){
var checkbox = Ti.UI.createSwitch({
style:Ti.UI.Android.SWITCH_STYLE_CHECKBOX,
value:false,
left:10
});
row.add(checkbox);
}
var rndMatNo = (randomInt(50000)+10000) //randomInt is my random number function
var lblMatNo = Ti.UI.createLabel({
realValue:rndMatNo,
text:'Mat No : ' + rndMatNo,
font:{fontFamily:'Arial', fontSize:DefaultFontSize, fontWeight:'bold'},
left:10,
color:'#222'
});
row.add(lblMatNo);
pickingData.push(row);
}
var tempPickingTable = Titanium.UI.createTableView({
data:pickingData,
editable: Titanium.Platform.osname === 'iphone' ? true : false,
name:'Picking table'
});
tempPickingTable.addEventListener('longclick',function(e){
for (var i=0, length=tempPickingTable.data[0].rows.length;i<length;i++){
if (tempPickingTable.data[0].rows[i].children[0].value === true){
tempPickingTable.deleteRow(i); //Still error when i'm using delete row because index out of bound
}
}
});
all i want is delete the row based on checkbox when it checked. i've tried looping for every row and check the checkbox and then delete the row, but it still give me error index out of bound.
has anyone know how to do that? thanks in advance..
There are some bugs in deleting rows from TableView in Android. You can try to create a new data array with all the rows except the ones that have been checked and then set the data for the tableview again.
You're iterating forward through the array, and deleting the rows, which modifies the array, so it makes sense that you'd go out of bounds. Have you tried iterating backwards?
tempPickingTable.addEventListener('longclick',function(e){
for (var i=tempPickingTable.data[0].rows.length;i>=0;i--){
if (tempPickingTable.data[0].rows[i].children[0].value === true){
tempPickingTable.deleteRow(i);
}
}
});
Related
I am trying to delete an array record based on what table row is clicked.
This function adds a button to a row and appends it to the end of the table
function addButtons(table, tr){
var delBtn = document.createElement("button");
delBtn.innerHTML = "×"
delBtn.onclick = deleteBu(tr)
tr.appendChild(delBtn);
table.children[1].appendChild(tr)
}
The function below is meant to delete an array record based on the row clicked. For example, in row 1, the first cell is "45". Based on this, the record is deleted if it is found in the array storageProblem.
Here is what I have so far. The issue is because I am using tr as the action listener, so simply clicking on the row will delete the row, it is not localized to the button. But using tr is the only way I have found to get the first td of a row.
function deleteBu(tr){
$(tr).click(function(){
var value=$(this).find('td:first').html();
for(i = 0; i < storageProblem.length; i++){
if(value == storageProblem[i][0]){
storageProblem.splice(i, 14)
loadCallProblemTable()
}
}
})
}
I'm not sure if I've understood your question right but maybe try this solution:
function deleteBu(x) {
var Index = $(x).closest('tr').index();
console.log("Row index: " + Index);
}
I have a kendo grid(with pagination Enabled) with some entries. Say, I have 5 pages and I have selected(clicked on checkbox) one row from each page and then clicked on top level action DELETE. I am not able to figure out how to delete the entries from the grid and the data source?
I tried below code, which deletes the entries from the page which is visible in the grid (on screen)
var grid = $("#grid").data("kendoGrid");
var userSelectionInfo = usersService.getUserSelectionInfo();
for(var userName in userSelectionInfo) {
if(userSelectionInfo[userName]) {
var selector = '#' + userName+ '_actions';
grid.removeRow($(selector).closest('tr'));
}
}
I tried one more approach:
I created an array of objects which will remain after deletion operation from the original array of objects and then added into the grid data source.
var newData = [];
var userSelectionInfo = usersService.getUserSelectionInfo();
for(var i = 0; i < users.length; i++) {
if(users[i].userName&& !userSelectionInfo[users[i].userName]) {
newData.push(users[i]);
}
}
loadUsersIntoGrid(newData);
Is there any better approach or kendo API which I am missing?
Thanks in advance.
You can delete from the dataSource instead of grid.First push the id of each selected item to an array, say DeleteList. Then you can delete from the datasource on clicking the top DELETE.
for(i=0; i<= DeleteList.length; i++)
{
grid.dataSource.remove(grid.dataSource.get(DeleteList[i]));
}
I am using jsTree. Its working fine but I want to get first node's data value in group of tree.
What I want to do?
When I click on any checkbox, then it will click automaticaly first checkbox
I am getting node id for first element but not getting original checkbox.
I have mention my code below.
.on("changed.jstree", function (event, data) {
if(data.action == 'deselect_node' || data.action == 'select_node'){
var parentId = $('#'+data.node.id).parent().parent().attr('id');
var childId = $('#'+parentId+' li:first-child').attr('id');
var i, j, r = [];
for (i = 0, j = data.selected.length; i < j; i++) {
if(data.instance.get_node(data.selected[i]).original.permID){
r.push(data.instance.get_node(data.selected[i]).original.permID);
}
}
A checkbox in a jsTree node is not a checkbox control really, it is an image.
You can get it of course. Based on your script it would go like:
var checkBoxImageElement = $('#'+childId).find('.jstree-checkbox')[0];
Please check out demo: JS Fiddle
I have a Kendo UI Grid and I am populating and maintaining the data it displays using Knockout JS (with knockout-kendo.min.js and knockout.mapping-latest.js). When the underlying data updates, the grid also updates to reflect this change. It's working well apart from the problem outlined below.
Code presented in the following Fiddle: http://jsfiddle.net/rTtS9/
The problem is that when the grid updates, it 'forgets' the selected cell that the user has chosen, such that if they are trying to keep an eye on a certain cell value, they can't. If this data is updating sub second (which it could), this gets very silly. The are many other use-case problems too (this is a contrived one).
Is there a way to have the Kendo UI Grid avoid a complete redraw when new data arrives such that the user's selection does not get forgotten?
I thought that this issue might be because KO thought that the whole object had changed, so rather than updating an existing object, it removed and added new ones. To make sure that this isn't the case, I uniquely identify objects using “keys” via the Mapping plugin. In addition, the array remain the same length.
I think that the mapping plugin is working OK as I seem to get desired behavior with the foreach binding, whereby you can select and highlight the ID part of the list item and it won't drop your selection when the data updates. See the Fiddle to see what I mean.
In case this is helpful for anyone else, I have included my solution below which remembers which grid cells were selected before the grid is re-drawn/bound.
I have attached the following code to the Kendo Grid change and dataBound events, respectively. Note, naming conversions for my grid variables always lead with "grid" followed by "name", such as "gridName".
So for the change event:
function saveGridSelection (gridID) {
try {
var shortName = gridID.substring(4,gridID.length)
var idxGrid = ns.grids.map(function(e) {return e.name}).indexOf(shortName);
var gridID = "#grid" + shortName;
var pair=[];
var columnHeader=[];
ns.grids[idxGrid].selectedCells = [];
// Loop over selected realized volsz
$(gridID + " > .k-grid-content .k-state-selected").each(function (index, elem) {
var grid = $(gridID).data("kendoGrid");
var row = $(this).closest("tr");
var colIdx = $("td", row).index(this);
pair[index] = $('td:first', row).text();
columnHeader[index] = $(gridID).find('th').eq(colIdx).text();
if (colIdx != 0 && ns.grids[idxGrid].dataGrid.length > 0 ) { // Check if cell is permitted and has data
pairID = ns.grids[idxGrid].dataGrid.map(function(e) { return e.pair; }).indexOf(pair[index]); // Get the index for the appropriate Pair
ns.grids[idxGrid].selectedCells.push({pair: pairID, container: (colIdx - 1), pairTitle: pair[index], columnHeader: columnHeader[index] });
}
});
} catch (err) {
console.log(err);
}
}
And for the dataBound event:
function loadGridSelection (gridID) {
try {
var shortName = gridID.substring(4,gridID.length)
var idxGrid = ns.grids.map(function(e) {return e.name}).indexOf(shortName);
var gridID = "#grid" + shortName;
var grid = ns.grids[idxGrid];
var gridSelectedCells = grid.selectedCells;
var tempSelectedCells = gridSelectedCells.slice(0); // Create a temp. array to work with
$(gridID + " > div.k-grid-content > table > tbody > tr").each(function (i,e) {
var pair = $("td:nth-child(1)", this).text();
if (tempSelectedCells && typeof tempSelectedCells !== "undefined") {
var ii = tempSelectedCells.length;
while(ii--) { // Loop backwards through teh array so we can slice out the bits we're finished with.
if (pair == tempSelectedCells[ii].pairTitle) {
var row = i;
var column = tempSelectedCells[ii].container;
var noColumns = $(gridID + " > div.k-grid-content > table").find("tr:first td").length;
var cell = (row * noColumns) + 1 + column;
$(gridID).data("kendoGrid").select(gridID + " td:eq("+cell+")");
tempSelectedCells.splice(ii, 1)
}
}
}
});
} catch (err) {
console.log(err);
}
}
Improvements to code always welcome.
I am pushing items to a data array and then adding these to a rowData array in order to create custom rows for a table. I need to know how to access these when a user clicks a specific row. I was previously using e.rowData, title etc. for accessing these elements when I had a basic table but now that it is a custom table, this isn't working. Don't worry about the parsing bit, that all works fine. All help appreciated!
data.push({
title: items.item(i).getElementsByTagName("title").item(0).text,
leftImage: str.match(patt1) !== null ? str.match(patt1)[0] : 'image_news.png',
dataToPass: items.item(i).getElementsByTagName("description").item(0).text,
hasChild: true,
js:"external.js"
});
}
var rowData=[];
for(i=0;i<data.length;i++){
var img= Titanium.UI.createImageView({
image:data[i].leftImage,
left:0,
bottom:5,
height: 100,
width: 100
});
var bgBar=Titanium.UI.createView({
height:110,
width: "100%",
bottom:0,
left:0,
backgroundColour: "#000",
opacity: 0.6
});
var title=Titanium.UI.createLabel({
text:data[i].title,
color: 'black',
left: 105
});
var row=Titanium.UI.createTableViewRow({
height: "auto",
hasChild: "true",
js:"external.js",
dataToPass: data[i].dataToPass
});
row.add(img);
row.add(bgBar);
row.add(title);
rowData.push(row);
console.log("row shiznick" + rowData);
}
tableView.setData(rowData);
tableView.addEventListener("click", function (e){
console.log("HERE SOURCE.TITLE ------------------"+e.row.title);
console.log("YOYOOYOYO------------"+e.source.title);
console.log("IS THIS IT---------------"+e.children[0]);
console.log("HERE IS THE SOURCE -----------------------------"+ e.source);
console.log("HERE SOURCE.LEFTIMAGE REG EXP3 ------------------"+e.row.leftImage);
console.log("HERE SOURCE.ClassName ------------------"+e.source.className);
console.log("HERE HASCHILD ------------------"+e.rowData.hasChild);
console.log("HERE DATATOPASS ------------------"+e.row.dataToPass);
});
There are two ways to set the rows of a table, you can create custom rows, or create JSON objects that have the attributes of the row object. Both cases have different ways of accessing the row, either the row object or the rowData object, from the docs:
When the row is created implicitly using a JavaScript dictionary object, use [the rowData property] rather than row to access any custom row properties.
Here's an example of creating a row implicitly, which is not the recommended way.
In your example, since you did not create the row objects implicitly, but explicitly, you can access the clicked row from the row attribute of the event like this:
tableView.addEventListener("click", function(e){
// Get the [TableViewRow](http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.TableViewRow) object
var theRow = e.row;
// Get the children
var rowChildren = theRow.children;
// Here are your objects in the row
var imgInRow = rowChildren[0];
var bgBarInRow = rowChildren[1];
var titleInRow = rowChildren[2];
// Here is the title
var rowTitle = titleInRow.text;
});
Alternatively, in both cases, you could always use the index to look up the row object like this:
tableView.addEventListener("click", function(e){
// Get the index of the row
var ndx = e.index;
// Get the row, this only works if you have not added sections
var row = tableView.data[ndx];
});
For accessing row's datas when user click on (even those which are not displayed in case of custom row for example), you can create an array, push your data in it during the loop and have an access to it with e.index.
A simple code example :
var allDataArray = [];
// loop through each item
for ( var i = 0; i < items.length; i++ )
{
// Your source datas (custom row : id is not displayed in the rows)
var sourceData = {
id: items.item(i).getAttribute('id'),
title: items.item(i).getElementsByTagName("title").item(0).textContent,
};
// Saving data for each loop
allDataArray.push(sourceData);
}
Then accessing the data
itemsTable.addEventListener('click', function(e)
{
// Target the array with e.index offset
var rowContent = allDataArray[e.index];
Ti.API.info(rowContent); // will display every single data of the current row clicked
alert(rowContent.id) // will display the "hidden" id which was not displayed in the UI
}
Try using the event.taget function, something like:
$(".row").click(function(event) {
var element = event.target;
// Accessing element
});