I'm using LoadContentFrom method of Kendo TabStrip, it allows tabstrip to load content from another action method.
The content will be loaded only when user clicks the link, tab, therefore it causes a short delay that I'd like to avoid. I wasn't able to find any method to enable eager loading for this control and load all the tabs at once. Any suggestion or workaround is welcome.
This is a sample tabstrip:
#(Html.Kendo().TabStrip()
.Name("tabstrip")
.Animation(false)
.SelectedIndex(0)
.Items(i =>
{
i.Add()
.Text("Action1")
.LoadContentFrom("Action1", "Controller");
i.Add()
.Text("Action2")
.LoadContentFrom("Action2", "Controller");
i.Add()
.Text("Action3")
.LoadContentFrom("Action3", "Controller");
})
)
UPDATE
Thanks to #joaumg, this is the JS code that I'm using:
$('#tabstrip').data().kendoTabStrip.reload($('#tabstrip ul li'))
Reload method does the job and loads the tab, and $('#tabstrip ul li') selector return an array of all tabs.
There are 3 ways of doing it...
First, generating the HTML and calling $("#tabstrip").kendoTabStrip();
Second, generate a JSON, and pass it as dataSource
Both uses the client side and can be seen here: http://docs.telerik.com/kendo-ui/web/tabstrip/overview#initialize-the-tabstrip
A server side uses the TabStrip HtmlHelper, which doc's can be found here: http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/tabstrip/overview#tabstrip ( look at the .Items and .Content methods )
Related
I am getting the error:
Delegate 'System.Action' does not take 1 arguments
While creating a Splitter with Partial view rendered inside one of the panes of Splitter. The error is at Content property of the the pane. Please suggest me any changes to solve the problem
#(Html.Kendo().Splitter()
.Name("vertical")
.HtmlAttributes(new { style = "height:900px" })
.Orientation(SplitterOrientation.Horizontal)
.Panes(panes =>
{
panes.Add()
.HtmlAttributes(new { id = "pane1" })
.Resizable(true)
.Size("300px")
.Collapsible(false)
.Content((#<text><div>#Html.RenderPartial("GetUsers", Model)</div></text>));
})
)
with the information from the following link I am able solve my problem. When you have to nest container controls of kendo UI you need to create a helper method for nested content and call the helper method as cotent for container control.
Kendo widgets two level deep in Razor, inline markup blocks cannot be nested
I need to implement conditional TabStrip in Telerik MVC Grid. The parent grid row contains the cell value of Status. If the status is Active i dont suppose to show the tabstrip in the child grid. If the status is Pending, then i need to show the TabStrip to create new item.
I have to do something like this:
if ("<#= Status #>" == "Pending") // The condition is not working here. Always show this tab.
{
items.Add().Text("Create New Detail").Url("/Acq/PoDet/Create/<#=Id#>");
}
})
.ToHtmlString()
Since most probably you are using Ajax binding you will need to write a little bit of JavaScript to achieve your goal. Your writings are not correct because you are meshing JavaScript code (#= ...#) with C# code.
Here is what an idea what you can do in the detail template, (it is a little bit tricky because you need to escape the special symbols):
<script id="employeesTemplate" type="text/kendo-tmpl">
#(Html.Kendo().TabStrip()
.Name("test#=EmployeeID#")
.Items(it=>it.Add().Text("test").Content("content test"))
.ToClientTemplate()
)
<script>
if (#=EmployeeID # % 2) {
$('\#test' + #=EmployeeID#).data().kendoTabStrip.append({"text":"This is the TabTitle",content:"this is some content"})
}
<\/script>
</script>
The example above is using the client API method called append to append a node to the TabStrip on the client side when the DetailView is generated into the detail row if the EmployeeID%2 == 0 (a simple condition).
I hope you got the idea.
In my application, I want the program to redirect the user to a new page AND slide open the list of SUBITEMS when a panelBar ITEM is clicked/selected. However, I am unsure as how this should be implemented.
I have used ".Action" along with "item" of my panelBar but this is unfortunately throwing an error. A small portion of the code is displayed below for your convenience (mainly focus on the second last line). The error being thrown is:
HttpException was unhandled by user code
<% Html.Telerik().PanelBar()
.Name("PanelBar")
.SelectedIndex(0)
.Items(item =>
{
item.Add()
.Text("Home").Action("Index", "Home")
.Items(subItem =>
{
subItem.Add().Text("My Profile").Action("MyProfile", "Profile");
subItem.Add().Text("Test");
});
item.Add()
.Text("Orientation").Action("Index", "Orientation")
.Items(subItem =>
{
subItem.Add().Text("GridView");
subItem.Add().Text("Scheduler");
subItem.Add().Text("Docking");
subItem.Add().Text("Chart");
});
}).Render();
%>
It seems like ".Action" is not working in this case. So my question is, how should I make the item take in an event?
Here is a snippet of how I do this using javascript and it works just fine. I do not dispute that there are other ways of doing this as well. So you are aware, this snippet is from an MVC app that I am doing. I included styling code as well so that you are aware that you can do that. I realise that you were not asking for that functionality but just thought it may help better your understanding of the property.
Lets say I want the font bold, no border and we want to trap a mouse event to perform a redirect.
To handle the styling, I simply add my item and then set my styling with the HtmlAttributes property.
Here is the code for the styling...
**item.Add()
.Text("Surf Shop")
.HtmlAttributes(new { style = "font-weight: bold; border:none;" })**
As my site is a surfing site, I would like to open the Surf Shop homepage and drop the submenu
at the same time. To do this, I use the same HtmlAttributes attributes property and hook into the
onmousedown event event handler. I then call my handler passing in the controller name that I wish to load. I only need the controller as all pages are called index. You could however, pass in a complete string here and simply redirect to it. Whatever blows your hair back... :-)
Here is the code with hook into the event handler...
**item.Add()
.Text("Surf Shop")
.HtmlAttributes(new { onmousedown="onBaseNavItemClick('SurfShop');" })**
Finally, here is the complete code with both styling and hook into the event handler
**item.Add()
.Text("Surf Shop")
.HtmlAttributes(new { style = "font-weight: bold; border:none;",onmousedown="onBaseNavItemClick('SurfShop');" })**
Our event handler function
**function onBaseNavItemClick(itemText)
{
window.location = BASE_URL + itemText + "/index";
}**
ps. The MVC controller that is being called must pass a value back in ViewData in order to toggle the selectedIndex property of the PanelBar. This is so the correct Panel opens when the redirect is performed.
Hope this helps...
I have been trying to manipulate content that is loaded into jQuery UI tabs via AJAX.
As you can imagine, these elements are "future" DOM elements and aren't manipulated by normal $(".someClass")functions.
I've read using .live() for event handling is now deprecated using jQuery 1.7+ and is replaced by the new .on() method.
My issue is that the div I want to hide, when it loads in an AJAX tab, must be manipulated after the initial DOM load and is not bound to a click event at first.
My functions, which are currently wrapped in $() are below.
I think I have the syntax correct for links that use a click handler, but I'm not sure of the correct way to ".hide()" my "hiddenStory" div at load.
I also think that the functions themselves shouldn't be wrapped in an overall $()?
Any help or advice would be greatly appreciated.
$(function(){
// this .hiddenStory div below is what I want to hide on AJAX load
// need syntax and/or new methods for writing this function
$(".hiddenStory").hide();
// this is a function that allows me to toggle a "read more/read less" area
// on the "hiddenStory" div
$(".showMoreOrLess").on('click', (function() {
if (this.className.indexOf('clicked') != -1 ) {
$(this).removeClass('clicked');
$(this).prev().slideUp(500);
$(this).html("Read More" + "<span class='moreUiIcon'></span>");
}
else {
$(this).addClass('clicked');
$(this).prev().slideDown(500);
$(this).html("See Less" + "<span class='lessUiIcon'></span>");
}
}));
});
// prevents default link behavior
// on BBQ history stated tab panes with
// "showMoreOrLess" links
$('.showMoreOrLess').click(function (event)
{
event.preventDefault();
// here you can also do all sort of things
});
// /prevents default behavior on "showMoreOrLess" links
Could you set the display: none via CSS and override it when you wanted to show the element's content? Another option, if you have to do it this way would be to add the `$(".hiddenStory").hide() in the callback from the AJAX load that is populating the element. For example:
$(".hiddenStory").load("http://myurl.com", function(){
$(".hiddenStory").hide();
}
);
If you aren't using the .load method, you should have some sort of call back to tie into (e.g. success if using $.ajax...)
I designed a ASP.NET page named kk-container.aspx to be used as a control which will be loaded in Default.aspx with jQuery load function. The page kk-container.aspx has many HTML controls and javascript events bound as in the example.
<!--Sample code from kk-container.aspx-->
<div id="kk-container">
Action
<!--Many HTML controls here-->
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#kk-action").click(function () {
return false;
});
});
//Many javascript here.
</script>
I load this kk-container.aspx into Default.aspx with such code in the Default.aspx.
<div id="mycontainer"></div>
<script type="text/javascript">
$("#mycontainer").load("kk-container.aspx");
</script>
Everything works fine up to here. However, I have to load this kk-container.aspx in a few more divs in the Default.aspx. This causes conflict in the id's of HTML controls. $("#kk-action").click() doesn't work for all. How can I solve this problem and load kk-container.aspx multiple times in one Default.aspx page.
More to say: I considered giving random id's for HTML controls for each load of kk-container.aspx. However I had already designed my stylesheet mostly with id selector. And I use a packet javascript, valums uploader, working in kk-container.aspx. It will also require edit. If there is a simpler way, I don't want to code all over.
I expected too much from jQuery and asked this question desperately. I should have decided first whether I will use "kk-container" thing once or multiple times in a page. For loading "kk-container" thing multiple times, I had to consider these:
Designing CSS using class selectors instead of id selectors.
Producing random id for my HTML elements like in this question.
Writing my javascript functions so that they work compatible with those random id's.
Therefore loadind "kk-container.aspx" in a page with jQuery load wouldn't cause any id conflicts.
Anyway, I did a mistake and didn't want to rewrite my code. I found a solution to load content of "kk-container.aspx" in my Default.aspx page without a problem. Instead of jQuery load function I used iframes.
Since there is already an item with id "kk-action",
Action (like this one)
loading a content having an item with id "kk-action" will cause trouble.
$("#mycontainer").load("kk-container.aspx?id=" + recordID); //troublesome method.
Instead create an iframe without border and load that content into iframe.
function btnEdit_Click(recordID) {
$('#mycontainer').html("");
var kayitKutusuFrame = document.createElement("iframe");
kk-Frame.setAttribute("id", "kk-iframe");
kk-Frame.setAttribute("src", "kk-container.aspx?id=" + recordID);
kk-Frame.setAttribute("class", "kk-iframe"); //For border: none;
kk-Frame.setAttribute("frameBorder", "0");
kk-Frame.setAttribute("hspace", "0");
kk-Frame.setAttribute("onload", "heightAdapter();"); //For non-IE
document.getElementById("Mycontainer").appendChild(kk-Frame);
if (isIE = /*#cc_on!#*/false) { //For IE
setTimeout(function () { heightAdapter() }, 500);
}
}
I didn't gave random id to "kk-iframe" because I will not use it mulitple times. It now resides in FaceBox. To make the iframe flawless, it needs to be auto-resized. My heightAdapter() function will do it. Not only when a content is loaded into iframe but also content changes dynamically because of my clicks.
Here is the actual code for resizing iframe to fit content by Guy Malachi.
function calcHeight(content) {
//find the height of the internal page
var the_height = content.scrollHeight;
//change the height of the iframe
document.getElementById("kk-iframe").height = the_height;
}
Here is my heightAdapter() function which will work both when content is loaded and when I clicked something causing content to expand.
function boyutAyarlayici() {
var content=document.getElementById("kk-Frame").contentWindow.document.body;
calcHeight(content);
if (content.addEventListener) { //Forn non-IE
content.addEventListener('click', function () {
calcHeight(content);
}, false);
}
else if (content.attachEvent) { //For IE
content.attachEvent('onclick', function () {
calcHeight(content);
});
}
}
And the following is a link in a repeater. Since the link will be replicated, it should have unique id by asp server.
<a href="#mycontainer" rel="facebox" id='btnEdit-<%# Eval("ID") %>'
onclick='btnEdit_Click(<%# Eval("ID") %>); return false;'>Düzenle</a>
Now, whenever I click one of the replica links, the content having an item with id "kk-action" can be loaded into the my flawless iframe which will be created in "mycontainer".
<div id="mycontainer" class="kk-iframe" style="display:none"></div>
And the content will be shown in my fancy FaceBox.
You're going to have to use classes to style the elements. There can only be one unique ID per page, so you are going to have to generate different IDs or use class selectors in your JavaScript such as:
$('.kk-action').click()
The above is probably the best way to go as it will give every element with that class the binding