I have both TreeView and Grid on the same page and I need to populate the TreeView from the grid data. So the flow is like this:
User selects a something from a dropdown and clicks on a button -> web service call -> populate the grid with data from web service -> populate TreeView with some massage of the grid data
The logic to populate TreeView is currently in the grid.dataSource.fetch() method like this:
// this function is called when user clicks on the button
function getData() {
grid.dataSource.read();
grid.dataSource.page(1);
grid.dataSource.fetch(function () {
var data = this.data();
... // logic to massage the data to populate TreeView
...
}
}
However, if the user selects another thing from the dropdown and clicks on the button again, this.data() seems to have the old data (fromt the 1st time), as a result, TreeView is populated with old data.
Which is the right event/method other than fetch() I should use to put my logic in?
I think you should use kendoGrid's dataBound event.
http://docs.kendoui.com/api/web/grid#events-dataBound.
Here is the sample code for kendoGrid dataBound event handler:
function Grid_DataBound(e) {
console.log("Grid_DataBound", e);
var grid = e.sender;
var dataItems = grid.dataSource.view();
console.log(dataItems);
var treeData = new Array();
for (var i = 0; i < dataItems.length; i++) {
treeData.push({
OrderId: dataItems[i].OrderID,
ShipName: dataItems[i].ShipName
});
}
var dataSource = new kendo.data.HierarchicalDataSource({
data: treeData,
schema: {
model: {
id: "OrderId"
}
}
});
$("#treeview").data("kendoTreeView").setDataSource(dataSource);
}
Let me know if you need full sample code.
Related
I am working with the latest Tianium Appcelerator and my project is using Alloy.
I have a TableView with the id: tblResults
In my controller, I populate this table view with rows like this:
// Dummy data
var results = [];
results.push({
title: 'Hello World',
value: '123456'
});
results.push({
title: 'Bye World',
value: '654321'
});
// Build result data
var resultData = [];
for (var i = 0; i < results.length; i++) {
resultData.push(createResultRow(
results[i].title,
results[i].value
));
}
// Method to create result row
function createResultRow(myTitle, myValue) {
var tableRow = Titanium.UI.createTableViewRow({
height: 160
id: 'row-'+ myValue
});
var tableRowView = Titanium.UI.createView({
layout: 'horizontal'
});
var myButton = Titanium.UI.createButton({
title: myTitle,
btnValue: myValue
});
myButton.addEventListener('click', function(e) {
handleButtonClick(e);
});
tableRowView.add(myButton);
tableRow.add(tableRowView);
return tableRow;
}
// Set table data
$.tblResults.setData(resultData);
// Method to handle button click
function handleButtonClick(e) {
if (e.source && e.source.btnValue) {
// how to select row having a id: 'row-'+ e.source.btnValue ???
}
}
What this will do is, generate a dummy array of objects. Then using that, populate the table view with row that has a view, within it there is a button.
What I am trying to achieve is, when the button is clicked, I want to select the table row having the id like this:
'row-'+ e.source.btnValue
in pure javascript/jquery DOM style, I would have done something like this:
$('#row-'+ e.source.btnValue)
How can I achieve this in Titanium Appcelerator? Is there a element selector functionality of some sort like in jQuery?
This is a very often requested feature that we don't currently support, but should. Right now, you'd have to keep a hash of id -> view reference and look it up that way. However, I opened a Feature Request here https://jira.appcelerator.org/browse/TIMOB-20286
If you have a select method on rows, you can do like this:
$.table.addEventListener('click',function(e) {
if(e.row.select) e.row.select();
//or
if(rows[e.index]) rows[e.index].select();
});
For tables and lists views always use the click and itemclick event on the table/list. These events provide you with both the selected row (e.row) as well as the actual view clicked upon (e.source). It is also more efficient then having a listener on the buttons of all rows.
Your code would look like:
$.tblResults.addEventListener('click', handleButtonClick); // or bind in XML
// Method to handle button click
function handleButtonClick(e) {
// user tapped on button
if (e.source.btnValue) {
var row = e.row;
}
}
I searched info on this topic but found only info about getting event element.
Yes, I can get an element of clicked div, but why it's fired all 19 times? (it's the number of views total). Info of clicked event is same - of the clicked div.
Here is what divs look like: http://d.pr/i/AbJP
Here is console.log: http://d.pr/i/zncs
Here is the code of index.js
$(function () {
var Table = new Backbone.Collection;
var TrModel = Backbone.Model.extend({
defaults: {
id: '0',
name: 'defaultName'
},
initialize: function () {
this.view = new Tr({model: this, collection: Table});
this.on('destroy', function () {
this.view.remove();
})
}
});
var Tr = Backbone.View.extend({
el: $('.pop-tags').find('.container'),
template: _.template($('#td_template').html()),
events: {
'click .tag': 'clicked'
},
clicked: function (event) {
event.preventDefault();
event.stopPropagation();
console.log(event.currentTarget);
},
initialize: function () {
this.render();
},
render: function () {
this.$el.append(this.template(this.model.attributes));
return this;
}
});
for (var i = 0, size = 19; i < size; i++) {
var trModel = new TrModel({id: i, name: 'name_' + i});
Table.add(trModel);
}
});
How can I avoid all elements from firing an event and fire only one that clicked and only 1 time?
el: $('.pop-tags').find('.container'),
Don't do that. You are attaching every view instance to the same DOM node. Each backbone view needs a distinct DOM node or, as you see, delegate events become complete chaos. In your view, set tagName: 'tr', then when creating your views, create them, call .render() and then append them to the DOM with something like $('.table-where-views-go').append(trView.el);.
You also may want to brush up on the basic MVC concept because Tables and Rows are view-related notions, not model-related, so a class called TrModel is a code smell that you aren't clear on Model vs View.
I would use a slightly different approach to solve your problem.
Instead for one view for every tr I would create one view for the entire table.
When I create the view I would pass the collection containing the 19 models to the view and in view.initialize use the collection to render the rows.
I created a jsbin with a working example.
I have a Kendo grid with a checkbox as a column along with other columns. I want to get all the rows where the checkbox is checked.
Please give me some idea.
Why not use the multi select feature of Kendo ui Grid
var checkDataSource = new kendo.data.DataSource({
data: checks
});
$("#CheckGrid").kendoGrid({
dataSource: checkDataSource,
change: CheckGridOnChange,
selectable:"multiple",
...
});
function CheckGridOnChange() {
var data = checkDataSource.view(),
selected = $.map(this.select(), function(item) {
return data[$(item).index()].CheckId;//CheckId is my unqiue id for my data, yours would probably be different
});
var ids = selected.join(",");
}
Ref url: Kendo ui grid Events Just hold control and select multiple rows
I have a kendo grid,and treeview with checkboxes in my application.I want to filter the grid based on treeview checkbox selection,i tried this one but its not working properly
my treeview code is
$("#treeview").on("change", function (e) {
var ds = $("#grid").data("kendoGrid").dataSource;
ds.filter([
{"logic":"or",
"filters":[
{
"field":"OrderId",
"operator":"eq",
}
]} ]);
});
my fiddle is http://jsfiddle.net/RHh67/66/
In treeview on change event you need to catch the checked nodes,and then filter the grid datasource based on your condition with field,operator and value of the treeview selected node.
$("#treeview").on("change", function (e) {
var selected = $('#treeview :checked').closest('li');
var ds = grid.dataSource;
var filter = {
logic : "or",
filters: []
};
This is the updated fiddle:
http://jsfiddle.net/RHh67/87/
Cheers,
Happy coding
I have a DDL, on its change I load a partial view _GetX. Right now I am using it like this
#Html.DropDownListFor(model => model.XId, Model.XList, "Select", new { GetUrl = Url.Action("GetX", "Route") })
I need to load this partial view on clicking a button. How do I do this?
Assuming your GetX controller action already returns the partial view:
$(function() {
$('#someButton').click(function() {
// get the DDL. It would be better to add an id to it
var ddl = $('#XId');
// get the url from the ddl
var url = ddl.attr('GetUrl');
// get the selected value of the ddl to send it to the action as well
var selectedValue = ddl.val();
// send an AJAX request to the controller action passing the currently
// selected value of the DDL and store the results into
// some content placeholder
$('#somePlaceholder').load(url, { value: selectedValue });
return false;
});
});