How to get KendoUI Grid to work with custom cell renderer and selection - kendo-ui

It seems that the selection events are not being passed through custom cell renderers. My goal is I want to change the background color of every cell in my grid (based on the values), and also be able to handle selection events. I've modified the example in the docs here:
https://www.telerik.com/kendo-react-ui/components/grid/selection/
To include a background color on the Units on Order column. You'll notice that that column does not participate in selections. I created a stackblitz example here:
https://stackblitz.com/edit/react-o4ycqi?file=app/main.jsx
All I changed was I added a cellWithBackground function and assigned it to the column UnitsInStock. Here is that function
const cellWithBackGround = props => {
const examplePrice = true;
const style = {
backgroundColor: "rgb(243, 23, 0, 0.32)"
};
const field = props.field || '';
return <td style={style}>
{props.dataItem[field]}
</td>;
};
I did find an example that was close but it I couldn't get it to work with functional components. It just worked with classes which I don't use. So, please provide examples or references on that support Functional Components.

H Peter,
Thank you for sharing the code. By completely replacing the entire cell's infrastructure, it will no longer respond to anything from the Grid.
Specifically, I'm referring to this line in the function. It only returns a <td> with the field's name, it abandons the rest of the properties of the element.
//cell returned form the function
return <td style={style}>
{props.dataItem[field]}
</td>;
At that point, it's basically a dead cell. It will not respond to events, data actions, etc because it is missing all the parts that the Grid requires to interact with it.
Further Guidance
As I mentioned in my Twitter reply, you can get guidance for the Kendo Engineers to help you from here.
I think there's a better way to handle this by using styling instead of manually handling the DOM elements directly. At the very least, you need to return the complete infrastructure of the cell and they can assist with that.

Related

How to appendChild in the Wix Corvid/Code IDE

I've searched thru Corvid docs and Stack, not finding anything.
Is there a way to appendChild() in Wix Corvid(Code)?
EDIT: Wix does not allow DOM access directly. I assumed that people answering this would know i was looking for an alternative to appencChild and knew this method could not be used as is in Wix.
so to clarify: is there a way to add a child to a parent element using Wix's APIs?
It depends what you are trying to achieve,
the only thing off the top of my head is adding more items to a repeater
which you can do by first getting the initial data from the repeater, adding another item to array and reassign the data property of the repeater
const initialData = $w('#repeater').data
const newItem = {
_id: 'newItem1', // Must have an _id property
content: 'some content'
}
const newData = [...initialData, newItem]
$w('#repeater').data = newData
https://www.wix.com/corvid/reference/$w.Repeater.html#data
In Corvid, you cannot use any function which accesses the DOM.
Coming from one of the developers of Corvid:
Accessing document elements such as div, span, button, etc is off-limits. The way to access elements on the page is only through $w. One small exception is the $w.HtmlComponent (which is based on an iFrame). This element was designed to contain vanilla HTML and it works just fine. You just can't try to trick it by using parent, window, top, etc.
Javascript files can be added to your site's Public folder, but the same limitations apply - no access to the DOM.
Read more here: https://www.wix.com/corvid/forum/main/comment/5afd2dd4f89ea1001300319e

How to find the highest attribute in a dataset, then display the "name" associated with that

I'm still relatively new to programming and I have a project I am working on. I am making a staff efficiency dashboard for a fictional pizza company. I want to find the quickest pizza making time and display the time and the staff members name to the user.
With the data charts it has been easy. Create a function, then use dc, e.g dc.barChart("#idOfDivInHtmlPage")
I suspect I might be trying to be too complicated, and that I've completely forgotten how to display any outputs of a js function to a html page.
I've been using d3.js, dc.js and crossfilter to represent most of the data visually in an interactive way.
Snippet of the .csv
Name,Rank,YearsService,Course,PizzaTime
Scott,Instore,3,BMC,96
Mark,Instore,4,Intro,94
Wendy,Instore,3,Intro,76
This is what I've tried so far:
var timeDim = ndx.dimension(function(d) {
return [d.PizzaTime, d.Name]
});
var minStaffPizzaTimeName = timeDim.bottom(1)[0].PizzaTime;
var maxStaffPizzaTimeName = timeDim.top(1)[0].PizzaTime;
}
then in the html
<p id="minStaffPizzaTimeName"></p>
<script type="text/javascript" src="static/js/graph.js">
document.write("minStaffPizzaTimeName");
</script>
You are surely on the right track, but in javascript you often have to consider the timing of when things will happen.
document.write() (or rather, anything at the top level of a script) will get executed while the page is getting loaded.
But I bet your data is loaded asynchronously (probably with d3.csv), so you won't have a crossfilter object until a bit later. You haven't shown these parts but that's the usual way to use crossfilter and dc.js.
So you will need to modify the page after it's loaded. D3 is great for this! (The straight javascript way to do this particular thing isn't much harder.)
You should be able to leave the <p> tag where it is, remove the extra <script> tag, and then, in the function which creates timeDim:
d3.select('#minStaffPizzaTimeName').text(minStaffPizzaTimeName);
This looks for the element with that ID and replaces its content with the value you have computed.
General problem solving tools
You can use the dev tools dom inspector to make sure that the p tag exists with id minStaffPizzaTimeName.
You can also use
console.log(minStaffPizzaTimeName)
to see if you are fetching the data correctly.
It's hard to tell without a running example but I think you will want to define your dimension using the PizzaTime only, and convert it from a string to a number:
var timeDim = ndx.dimension(function(d) {
return +d.PizzaTime;
});
Then timeDim.bottom(1)[0] should give you the row of your original data with the lowest value of PizzaTime. Adding .Name to that expression should retrieve the name field from the row object.
But you might have to poke around using console.log or the interactive debugger to find the exact expression that works. It's pretty much impossible to use dc.js or D3 without these tools, so a little investment in learning them will pay off big time.
Boom, finally figured it out.
function show_fastest_and_slowest_pizza_maker(ndx) {
var timeDim = ndx.dimension(dc.pluck("PizzaTime"));
var minPizzaTimeName = timeDim.bottom(1)[0].Name;
var maxPizzaTimeName = timeDim.top(1)[0].Name;
d3.select('#minPizzaTimeName')
.text(minPizzaTimeName);
d3.select('#maxPizzaTimeName')
.text(maxPizzaTimeName);
}
Thanks very much Gordon, you sent me down the right path!

Kendo UI Scheduler: Hide week-view Time Headers (MVC)

I'm trying to find a way to remove the time headers from the kendo scheduler. I've come across a few ways to do it via css, but they tend to leave the scheduler looking a bit "off".
I found some answers in the kendo docs detailing how to do it out of the box with a javascript implementation, but I'm looking for MVC which I can't seem to find any mention of. I've tried and tried to figure out how to do this, but I can't seem to find the appropriate attributes to set.
The kendo MVC wrappers are effectively ASPX/Razor helper functions that generate a javascript implementation. So assuming the javascript solution in the link you provide contains the solution you need, it should be possible to replicate it using the MVC syntax.
Looking at telerik's solution, they manipulate the DOM with javascript in the dataBinding event for Ungrouped and in dataBound for Grouped. You can specify handlers for these events when declaring the scheduler with MVC syntax:
.Events(e => {
e.DataBound("scheduler_dataBound");
e.DataBinding("scheduler_dataBinding");
})
...and then include the implementation of these functions on the page separately (code lifted from the telerik solution):
<script>
function scheduler_dataBound(e) {
var tables = $(".k-scheduler-times .k-scheduler-table");
//Required: remove only last table in dataBound when grouped
tables = tables.last();
var rows = tables.find("tr");
rows.each(function() {
$(this).children("th:last").hide();
}
function scheduler_dataBinding(e) {
var view = this.view();
view.times.hide();
view.timesHeader.hide();
}
</script>
//for hiding time header
$('#schedulerID').find('.k-scheduler-header-wrap').closest('tr').hide()
//for hiding date header
$(".k-scheduler-layout tr:first .k-scheduler-table").find("tr:eq(0)").hide()

Trying to dynamically change width of hidden column leads to error "to many recursions"

unfortunately I can't find any help concerning to my specific problem.
I try to simplify it:
My grid consists of a shown column (A) and a hidden column (B) and other shown columns as well (C,D). With a custom button I can switch between these two columns, so that A is hidden and B is shown and vice versa.
My aim is as follows:
If the width of (shown) A has been changed, the width of (hidden) B should also be changed.
My current way to realize this this:
resizeStop: function () {
var $self = $(this);
shrinkToFit = $self.jqGrid("getGridParam", "shrinkToFit");
$self.jqGrid("setGridWidth", this.grid.newWidth, shrinkToFit);
var a = $self.jqGrid("getGridParam","colModel");
$self.jqGrid("setColWidth", "customers.name_short",a[2].width);
},
I works, but I have to wait for a wile and in addition to that I get the following log: "too much recursion". It seems that the function setColWidth is called more than 300 times.
I analyzed the code of setColWidth but I could not find any hint where it would call itself.
Can anybody help me?
Thanks in advance!
I suppose that you use my method setColWidth from here and the answer. It's wrong to use it inside of resizeStop callback.
You wrote: "With a custom button I can switch between these two columns, so that A is hidden and B is shown and vice versa." It seems to me that you need place one call of setColWidth method directly after you makes the column A or the column B visible (in the click event handle of your custom button). It should solve the problem.
UPDATED: The following demo http://jsfiddle.net/OlegKi/m7f9ghwq/18/ demonstrates the approach.

How to I add multiple distinct JSON objects into seperate lists in WinJS app?

I am trying to create a grid app with various sections and each section is being fetched to a specific listview however I have encountered a problem where you can only have one listview covering the entire page in order to properly horizontally scroll the objects inside the list which means there's no room for another one. This is the code I am using right now:
WinJS.xhr({ url: "http://search.twitter.com/search.json?q=%23windows8&rpp=100}).then(
function (response) {
var json = JSON.parse(response.responseText.toString());
var list = new WinJS.Binding.List(json.result);
gridView1.winControl.itemDataSource = list.dataSource;
//gridView1 is ID of listview
}
With the above code I can easily show grids of objects containing result array and then bind em to the list. However now I want multiple similar listviews for different URLs that are displayed like the one shown as default interface in WinJS grid app.
To be more clear, this is what I want - Twitter usernames in first section of grid by using Twitter API URL1 and then I want twitter search results in adjacent grid so I have to use another listview b using URL2.
How do I find a fix for this. Appreciate your help.
Yeah, coming up with what all of the disparate items from the different lists have in common and projecting your data up to a single grouped list is one option. You might not want to give up on what you were trying to do though. If you put multiple ListViews on a page wrapped in a flexbox, you shouldn't have any trouble with scrolling. If you look at my codeSHOW app at the ListView demo, you'll see that I have the rough equivalent. Windows is actually really smart about the way it handles the panning.
** EDIT **
Here's a rough example of what I'm talking about. Again, you can find a working example of this in the ListView demo of codeSHOW.
<!-- HTML snippet -->
<div class="hub">
<div>
<div id="list1" data-win-control="WinJS.UI.ListView"></div>
</div>
<div>
<div id="list2" data-win-control="WinJS.UI.ListView"></div>
</div>
<div>
<div id="list3" data-win-control="WinJS.UI.ListView"></div>
</div>
</div>
/* CSS snippet */
.hub {
display:-ms-flexbox; /* this will lay the lists out horizontally */
overflow-x:auto; /* set the flexbox to scroll its overflow */
}
/* select each of the sections */
.hub > div {
padding-right:80px; /* 80px of space between "sections" */
}
/* choose whatever sizes you want for your list views. You may want to make them wide
enough that they don't scroll because it can get a little awkward to have scrolling
within scrolling */
[data-win-control=WinJS.UI.ListView] {
width: 640px;
height: 480px;
}
You can solve this by aggregating the result set into a single data source.
You can either do this through splurging your data into a WinJS.Binding.List that's been set up with a grouping function, and attribute your data in such a way that you know how to group them. An example of the grouping of a WinJS.Binding.List can be found in the "Grid" Template that you find in Visual Studio when doing File/New/Project.
Or, you can build your own data VirtualizedDataSource - there is a great tutorial for this on MSDN here.

Resources