best practice when need to change grid options/datasource - kendo-ui

In an application I'm developing, i need to use the same space to display information from different sources with different formats in a grid according to what item was selected on a TreeView.
i found two ways to achieve this:
find the grid then destroy and recreate it.
find the grid then change datasoruce/options/
I'm very new to Kendo, so i'm not sure which approach would be wiser.
any advice?

The answer depends on your usage model.
How often are you going to change between datasources?
How long does it take getting the new data?
How much data is involved?
If it takes long time and you can switch quite often between DataSources I would go with a third approach that is having several grids and only one visible BUT if there is a lot of data involved then you should destroy the grid and recreate a new one avoiding having a lot of memory used but having to bring a lot of data back and forth.
You can go with the your second proposal (switching datasources) if you switch data and the structure of the grid is exactly the same (same columns and formatting).

If all your data had the same columns and options, then I would just call .setDataSource() on the grid widget to replace the data source with the new one.
However if you are changing options and columns, I think it would be better to just destroy the widget and re-create it, which would eliminate the possibility of the widget holding on to any of the old options. Something like:
function replaceGrid(selector, options) {
var $grid = $(selector);
var gridWidget = $grid.getKendoGrid();
if(gridWidget) {
gridWidget.destroy();
}
$grid.kendoGrid(options);
}

Related

Durandal and multiple views using the same vm

I have an ADD and an EDIT page for a customer entity. The data to support each function is similar, however there are business rules that differ between the 2, and slightly different UI, so my original thinking is that I make 2 separate views, but use a single vm. This is a different approach than the John Papa example I'm using as my guide, as he had a separate vm for each. (sessionadd.js, sessiondetail.js). The data is identical so it seems like a lot of duplication, but maybe that's the way to go.
Two questions: what is the best practice in this scenario where the data for an add/edit is the same, but the rules are different? I can already see myself doing "if (mode == 'add'){ // stuff } else {// its an edit }. That bothers me a little, but I also don't like the idea of having to change 2 vms if I add a new field to the views.
Second question, can I specify the view as part of the route definition? I didn't see anything in the docs but I'm still new to the framework. In the following routes, I would like the first one to be loaded with custedit.html and in the second one custadd.html. Both using the custmaint.js vm (never at the same time tho).
{ route: 'custedit', moduleId: 'viewmodels/custmaint', title: 'Edit' },
{ route: 'custadd', moduleId: 'viewmodels/custmaint', title: 'Add' },
thanks
You can customize the view you want to be used by defining getView() or viewUrl() on your viewmodel as described here:
http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks.html
As to your initial question, if they are very similar, I would definitely combine edit and add operations within a single viewmodel and single view. Sharing the same viewmodel but splitting the views will likely result in a ton of duplicated view code. You could always decompose the elements of your view into smaller views if you need to simplify.
If the edit and add experience are different enough to warrant a separate view, I would create a separate viewmodel as well (and potentially look into splitting view parts and viewmodel functionality into smaller components)

Need clarifications on adding regions dynamically in Marionette

I have an application where I need to display metrics. The application needs to display a separate vertical section for each metric. When I started this, there were only 5 metrics so I naively created a template with 5 regions, one for each metric I needed to display. Now, new metrics need to be added and I want to avoid adding "hardcoded" region divs in the template. I want to refactor this and create the required regions dynamically at startup time based on some configuration data.
So I have been looking at the latest Marionette release and in question "Dynamically add regions to Marionette layout", Derick Bailey mentions that Marionette v1.0 supports dynamic regions in Layouts through addRegion(), as in:
var layout = new MyLayout();
layout.render()
layout.addRegion("someRegion", "#some-element");
layout.someRegion.show(new MyView());
I have tried that in my code (using Marionette 1.0.2) and I am not getting it to work. I don't have a div with id="some-element" in my template and I suspect this could be the reason. I was hoping that Marionette would create that div itself.
Perhaps my expectation of what dynamically adding a region means is wrong. So my first question is: when adding regions dynamically to a layout, must the element id passed in the addRegion() function already exist in the layout?
If so, then I am back to the problem of having to "burn" in the template those divs for the regions to attach themselves too. My follow-up question is then: What is the best way of doing this in a data-driven fashion? Is it a matter of writing my own render() function so that the right set of divs get created? Or perhaps providing my Layout with a model object that will contain data which the template can then iterate through to create the necessary divs? How do we add regions dynamically to a Layout object if we don't know in advance how many regions we will actually need?
Aa #aaronfay specified, we need to use jQuery to create the element on the page. Here is some sample code:
var layout = new MyLayout();
layout.render()
var regionName = "dynamicRegion";
layout.$el.append('<div id="'+regionName+'"></div>');
layout.addRegion("someRegion", "#"+regionName);
layout.someRegion.show(new MyView());
I believe you would need to use jQuery (or similar) to create the element on the page. A Region expects the element to exist.
Otherwise, I believe your answer is here.

Orchard CMS pass data from View to Theme layout

I'm writing a custom Orchard module with a custom Theme. I would like to pass data from the View back to the Layout to change the layout based on data determined in the View.
In my example, I have a left-nav in my theme - certain views should be able to instruct the layout not to render this left-nav.
In standard mvc 3 I would just pass the value up through the ViewBag, but this doesn't seem to be working within Orchard - I'm guessing that the layout code is executed before the View is rendered?
I've looked into using a Shape to move this data around but looks like it might be a little heavyweight for what i'm trying to achieve.
What's the best practice for passing data around like this as an alternative to ViewBag?
Update: After playing around with it a bit more i've just noticed that TempData is being picked up in the Layout - can anyone explain why TempData is transmitted, but ViewData isn't? And is it safe to use from an Orchard POV?
It's easier than that... All templates have access to the Layout shape, which is a dynamic object. This means that you can modify it on the fly, add it properties, etc.
In your specific case, suppressing a zone, you may even be able to just set that to null: zones are just shapes, and in the case of top-level zones they are expandos on Layout. So if you have a zone named Foo, setting Layout.Foo to null should do the trick. As a matter of facts, I'm doing exactly that in one of my themes, to suppress the side bars from my error pages without having to create a specific widget layer:
Layout.AsideFirst = null;
Layout.AsideSecond = null;

How do you design a text-based view using Ember.js or some other MVC javascript framework?

I have an homemade javascript which, among other things, do some kind of text-formatting work in order to emulate a retro text-based game:
When developing it, i tried to stick close to an MVC model, and this is what i did:
The data model basically consists of a list of objects mapping strings to very specific locations in the display, like this
[{
"value":"Hello!",
"color":"blue",
"row":1,
"column":13
},
{
"value":"What is your quest ?",
"color":"red",
"row":5,
"column":10
},
/* ... some other data */]
Then my view consists of a simple <pre> tag. When my controller draws the model on the view, it iterates through each string-location pair and create a <span> for each one that is appended to the <pre> tag. To keep the formatting consistent, it also adds "blanck" span each time it is needed.
<pre>
<span> </span><span class="blue">Hello!</span><span> </span><br>
<!-- ... other lines of the scene-->
</pre>
It's pretty simple, but it worked great until i had to dynamically change a span text value, without redrawing the whole scene each time.
So i took a look on the internet and realized that Ember.js existed, it really seems to be exactly what i could use to improve my whole code.
Now, i tried to redesign it using Ember.js, but as i don't fully understand yet its features i ran into a problem:
How do you represent a 'text-based' view into an Ember.js handlebar template ?
What am i missing here?
My data model contains both the value and the position in the display, so i don't exactly see how handlebars template could fit my needs. Or perhaps dynamically generating the template is an option ?
What do you think ?
Am I choosing the wrong framework or misunderstanding its use? is it my original MVC design that is wrong ? Changing the data model for something completely different is not an option i can easily consider as it would impact everything.
Do you have any ideas on how this could be implemented using Ember or some other framework?
Any advice will be appreciated :)
I made a rudimentary example on jsfiddle on how you could use ember for this.
Each row is an object and we have an ArrayProxy holding such objects. Thus if we have 10 rows, we have 10 row objects.
The view is binding one output line per row object.
Enjoy the flying bird:
http://jsfiddle.net/algesten/YMrW3/2/
Edit: Better to {{#if}} away empty rows as pointed out by ud3323:
http://jsfiddle.net/ud3323/92b24/

AJAX Tabcontainer inside formview not inserting values

I have a TabContainer inside a data bound FormView (to present the information by category ex: Client Bio data, health history, financial details...). The Update and Insert of the formView doesn't work (posting NULL values to the database) - I guess the FormView cannot find the TextBoxes inside the tab container's tab panels.
Some of the forums say that it's because of the TabContainer's implementation (by design) of "INamingContainer", and a hack is to take control of the TabContainer's
source code (ajax ctl toolkit's source code) and remove the "INamingContainer" interface from it... Too complicated to my taste .. I'm kinda lost.
Well is there a straight forward and better way to fix this? I'm dazzled to see that the toolkit has failed to implement this basic functionnality as for most developper ordering info (tab control) with formview is a common need.
Thanks in advance,
Jeewai
Answering my own thread... I got some great inside from the asp.net forum and decided to post the solution here: Reproducing the explanation that helped me out:
Hope that will clear out some questions to other users who may encounter the same issue.
Best,
JY
Blockquote
Hi JY,
The short answer is that when a Bind statement is compiled, there are some limitations on extracting values for an insert/update. If the controls within the FormView are then within another Naming Container (TabContainer and TabPanel are both naming containers), then the compiler can't resolve how to extract the value from the TextBox. I have a more detailed discussion of this on my blog at http://www.aarongoldenthal.com/post/2009/03/15/ASPNET-Databinding-Bind()-Method-Dissected.aspx.
To get around this, you'll need to extract the values manually, something like:
protected void FormView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
// Get references to the controls
TextBox LastNameTextBox= FormView1.FindControl("TabContainer1").FindControl("TabPanel1").FindControl("LastNameTextBox") as TextBox;
// Set update parameters in datasource
ObjectDataSource1.UpdateParameters["LastName"].DefaultValue = LastNameTextBox.Text;
}
Since FindControl only searches the current naming container, you'll need to dig through each naming container (FormView, TabContainer, and TabPanel) to get to the TextBox.
Hope that helps.
Aaron
Blockquote

Resources