Telerik's TreeView control, although fancy and with a lot of functionality is proving to be a nightmare for me now. However I could not find a better TreeView control which supports collapsing/expanding etc. and has a little bit of documentation. Here's my problem.
This is the site master : _Layout.cshtml
<!DOCTYPE HTML>
<html>
<head>
<title>#ViewBag.Title</title>
<!--
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/custom.css")" rel="stylesheet" type="text/css" />-->
#(Html.Telerik().StyleSheetRegistrar()
.DefaultGroup(group =>
group.Add("telerik.common.css")
.Add("~/Content/Site.css")
.Add("~/Content/custom.css")
.Add("~/Content/themes/humanity/jquery-ui-1.8.18.custom.css")
.Combined(true)
.Compress(true)))
</head>
<body>
<div class="page">
<header>
<div id="header-logo">
<img alt="X" src="../../Content/Images/logo100.png"/>
</div>
<div id="title">
<h1>title</h1>
</div>
#(Html.Telerik().Menu()
.Name("menu")
.Items(menu =>
{
menu.Add().Text("Home").Action("Index", "Home");
menu.Add().Text("Products")
.Items(item =>
{
item.Add().Text("xxx").Action("xxx", "Products");
item.Add().Text("xxx").Action("xxx", "Products");
item.Add().Text("xxx").Action("xxx", "Products");
item.Add().Text("xxx").Action("xxx", "Products");
});
menu.Add().Text("Events").Action("Index", "Events");
menu.Add().Text("About Us").Action("About", "Home");
menu.Add().Text("Admin").Action("Index", "Admin");
})
.HtmlAttributes(new { style = "text-align:left;" }))
</header>
<section id="main">
#RenderBody()
</section>
<footer>
</footer>
</div>
#(Html.Telerik().ScriptRegistrar()
.Scripts(script=>script.Add("~/Scripts/custom.js"))
.Globalization(true)
.DefaultGroup(group => group.Combined(true)
.Compress(true)))
</body>
</html>
This is the base page view : Index.cshtml
#{
ViewBag.Title = "Admin";
}
<h2>
Admin Index</h2>
<div id="navAdminLeft">
#(Html.Telerik().TreeView()
.Name("AdminNavTree")
.Items(item =>
{
item.Add().Text("Products");
item.Add().Text("Categories");
item.Add().Text("Materials");
item.Add().Text("Finishes");
item.Add().Text("Packaging");
item.Add().Text("File Manager");
item.Add().Text("CategoryTree");
})
.ClientEvents(events => events.OnSelect("loadAdminContent"))
)
</div>
<div id="adminContent">
</div>
<script type="text/javascript">
function loadAdminContent(e) {
$.ajax({
type: "GET",
cache: false,
url: "Admin/" + e.item.innerText,
data: {},
success: function (data) {
$("#adminContent").html(data);
}
});
}
</script>
whenever the user selects a node on the #AdminNavTree the page fetches the content to be displayed and populates #adminContent. I am trying to build an edit page where there is a category tree listed in one div and when the user clicks on any of the category on that div, the details are ajax loaded into another div on the same page. Here is the partial view with the category tree that gets loaded into #adminContent: _CategoryTree.cshtml
#using xxx.Models.Navigation
#model IEnumerable<NavigationItem>
<div id="categoryTree">
#{Html.Telerik().TreeView()
.Name("ctree")
.BindTo(Model, mappings =>
mappings.For<NavigationItem>(binding => binding
.ItemDataBound((currentItem, navigationItem) =>
{
currentItem.Text = navigationItem.Text;
currentItem.Expanded = true;
})
.Children(child => child.Items)
))
.ClientEvents(events=>events.OnSelect("loadContent"))
.Render();
}
</div>
<div id="detail"></div>
<script type="text/javascript">
function loadCategoryDetail(e) {
$.ajax({
type: "POST",
url: "Admin/CategoryDetails",
data: { id: $("#ctree").data("tTreeView").getItemText(e.item) },
success: function (data) {
$("#detail").html(data);
}
});
}
</script>
the detail page that is ajax loaded does not contain any telerik controls so listing code for that is a non issue.
The PROBLEM : this will not render. As soon as it tries rendering #ctree treeview it starts throwing all kind of script errors, specifically it ignores loadCategories (says not found). So far I think what is happening is the ajax loaded partial page that contains the treeview is reloading the jquery lib destroying all old bindings and functions in the script. Is there a way to make this work, two treeviews on one page, one previously loaded, one in a ajax loaded partial view, both binding to separate data?
I've had good success with jsTree... doesn't help with your telerik question, but might be worth checking out.
http://www.jstree.com/
Related
Upon submission of a form, I want to push that data to my Firebase db and so I'm creating a function to do so (addMeeting). However, upon pressing the button to submit I get the error:
TypeError: undefined is not a function
at l.$scope.addMeeting (http://localhost:8000/js/controllers/meetings.js:10:12)
meetings.js:10:12 is right where my $push is if you'll look at my code below.
My HTML:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Angular Data</title>
<meta name="viewport" content="width=device-width, userscalable=no">
<link rel="stylesheet" href="css/style.css">
<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="js/lib/angular/angular-route.min.js"></script>
<script src="js/lib/angular/angular-animate.min.js"></script>
<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.2.2/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.0.0/angularfire.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/registration.js"></script>
<script src="js/controllers/meetings.js"></script>
</head>
<body>
<header>
<nav class="cf" ng-include="'views/nav.html'"></nav>
</header>
<div class="page">
<main class="cf" ng-view></main>
</div>
</body>
</html>
My apps.js:
var myApp = angular.module('myApp',
['ngRoute', 'firebase', 'appControllers']);
var appControllers = angular.module('appControllers', ['firebase']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/login', {
controller: 'RegistrationController',
templateUrl: 'views/login.html'
}).
when('/register', {
controller: 'RegistrationController',
templateUrl: 'views/register.html'
}).
when('/meetings', {
controller: 'MeetingsController',
templateUrl: 'views/meetings.html'
}).
otherwise({
redirectTo: '/login'
});
}])
meetings.js -the Controller containing the addMeeting function that is failing:
myApp.controller('MeetingsController',
function($scope, $firebaseObject) {
var ref = new Firebase('https://angulardataldc.firebaseio.com/meetings');
var meetings = $firebaseObject(ref);
$scope.meetings = meetings;
$scope.addMeeting = function() {
meetings.$push({
name: $scope.meetingname,
date: Firebase.ServerValue.TIMESTAMP
})
}
}); //MeetingsController
The view that is calling that function upon submission of a form:
<section class="meetings cf">
<h1>Add Meetings</h1>
<form class="formgroup addmeeting cf"
name="myform"
ng-submit="addMeeting()"
novalidate>
<div class="inputwrapper">
<input type="text" name="meetingname" placeholder="Meeting Name"
ng-model="meetingname" ng-required="true">
</div>
<button type="submit" class="btn"
ng-disabled="myform.$invalid">+</button>
</form>
<h2>Your Meetings</h2>
<div class="meeting" ng-repeat="meeting in meetings">
<p>{{meeting.name}}</p>
</div>
</section>
**Edit: ** It has something to do with the .push() method itself. I see that in the latest version of angularfire/firebase it should be .push, instead of .$push, ad have changed that but it does not solve my problem. I reverted AngularFire and Firebase to versions 0.8.2 and 1.0.21 respectively, re-introduced the .asObject() and $push, and everything works fine. I don't understand why .push() is failing with all the latest (Firebase 2.2.2, AngularFire 1.0).
Firebase's AngularFire library has two primary types: $firebaseObject and $firebaseArray (instantiated through $asObject and $asArray respectively in pre-1.0 versions of AngularFire).
You're using both the wrong type and the wrong method. To quote AngularFire's documentation on its array type:
Synchronized arrays should be used for any list of objects that will be sorted, iterated, and which have unique IDs. The synchronized array assumes that items are added using $add(), and that they will therefore be keyed using Firebase push IDs.
So:
var ref = new Firebase('https://angulardataldc.firebaseio.com/meetings');
var meetings = $firebaseArray(ref);
$scope.meetings = meetings;
$scope.addMeeting = function() {
meetings.$add({
name: $scope.meetingname,
date: Firebase.ServerValue.TIMESTAMP
})
}
You made a typo, it should be .push instead of $push
CODE
$scope.addMeeting = function() {
meetings.push({
name: $scope.meetingname,
date: Firebase.ServerValue.TIMESTAMP
})
}
Reference
I've just started out using backbone. I want to apply a view to a button, but when I open my file in the browser there is nothing there.
Why isn't the button being rendered?
HTML:
<!-- Scripts -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script type="text/javascript" src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<script type="text/javascript" src="views/BaseButtonView.js"></script>
</head>
<body>
<script type="text/template" id="button-test">
<div id="test-buttons">
<button class="cta-ajax">
<p>send message</p>
<div class="spinner-container"></div>
</button>
</div>
</script>
</body>
</html>
View:
$(document).ready(function(){
var ButtonView = Backbone.View.extend({
el: $(".cta-ajax"),
template: _.template($("#button-test").html()),
initialize: function(){
console.log("Started!");
},
render: function() {
this.$el.html(this.template());
console.log("rendered");
return this;
}
});
var TView = new ButtonView();
});
You have two issues with your code. Here is a working jsfiddle: http://jsfiddle.net/cj4zkyow/1/
Issue 1:
Aside from implementing the initialize function, you also need to call render within initialize. Otherwise you have to call render manually.
Issue 2:
Second issue is that you set the el attribute of your view to .cta-ajax, but the element does not exist. It is part of your template. The el attribute is the element that your view gets appended to. So you need to use something that exists in the DOM.
HTML:
// Need a element to append view to.
<div id="test"></div>
<script type="text/template" id="button-test">
<div id="test-buttons">
<button class="cta-ajax">
<p>send message</p>
<div class="spinner-container"></div>
</button>
</div>
</script>
Javascript:
$(document).ready(function(){
var ButtonView = Backbone.View.extend({
// If you specify, el, it should be an element in the DOM, not in your template.
el: $("#test"),
template: _.template($("#button-test").html()),
initialize: function(){
// Need to call render in initialize function to render view.
this.render();
},
render: function() {
this.$el.html(this.template());
return this;
}
});
var TView = new ButtonView();
});
I currently use button and trying to launch a new window passing parameter from mypage to the new page like this
<input type="button" name="launchpg" id="launchpg" value="LaunchPage" onclick="launch_page('<%=list_process_url%>',this.form.myform.options[this.form.myform.options.selectedIndex].value);"/>
Javascript is as below:
<script type="text/javascript">
//call servlet
function launch_new_window(list_process_url,smart_id)
{
popupWindow = window.open(list_process_url+"&id="+id,'List Process Page',
'scrollbars = yes');
}
I am trying to replace button with href link as in..
document.location='main.jsp?PAGE=myPage.jsp&id='+this.form.myform.options[this.form.myfom.options.selectedIndex].value;
I would like to use the same javascript for launching a new window passing the parameter to the script function.
The code however doesn't seem to work as it says Form is not valid for href.
Add this to wherever you want to launch a new page from:
window.location.href = "pageName.html";
<head>
<title></title>
<script src="Scripts/jquery-2.1.1.min.js"></script>
</head>
<body>
<div id="main">
<script>
$(function () {
<!--Some Logic-->
<!--window.location.href = "NewWindowName.html";-->
}
$("#btnSave").click(function () {
openNewWindow();
});
function openNewWindow()
{
window.location.href = "NewWindowName.html";
}
});
</script>
<article>
<button id="btnSave">Save Data</button>
</article>
</div>
</body>
I found a solution to my question:
Open New Window
Have a look at the following sample HTML. It is a simple KO foreach binding and a button to add a new item to the observableArray. The addition works fine and the new item shows up. However, the afterRender method is never called - not after the initial binding and not after a new item is added (and rendered). Why?
Fiddle: http://jsfiddle.net/CQNm6
HTML
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
</head>
<body>
<div data-bind="foreach: data.things, afterRender: afterRenderTest">
<h1 data-bind="text: name"></h1>
</div>
Add New Thing
<script type="text/javascript">
var Thing = (function ()
{
function Thing(p_name)
{
this.name = ko.observable(p_name);
}
return Thing;
})();
var data =
{
things: ko.observableArray(
[
new Thing("Thing One"),
new Thing("Thing Two"),
new Thing("Thing Three")
])
};
function afterRenderTest(elements)
{
alert("Rendered " + elements.length + " elements.");
}
ko.applyBindings();
</script>
</body>
</html>
Your syntax is wrong because foreach binding either take an array or an object where you specify the additional events, arguments.
From the documentaiton:
Pass the array that you wish to iterate over. The binding will output
a section of markup for each entry.
Alternatively, pass a JavaScript object literal with a property called
data which is the array you wish to iterate over. The object literal
may also have other properties, such as afterAdd or includeDestroyed...
So you need write:
<div data-bind="foreach: { data: data.things, afterRender: afterRenderTest }">
<h1 data-bind="text: name"></h1>
</div>
Demo JSFiddle.
After upgrading my project from ASP.NET MVC2 to MVC3, simply calendar partial view no longer renders. The code for this view is listed below.
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<AkwiMemorial.Models.CalendarModel>" %>
<link href="../../Content/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.ui.core.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.ui.datepicker.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#datepicker').datepicker({
inline: true,
onSelect: function(dateText, inst) {
$('#DateStr').val(dateText);
$('form').trigger('submit'); }});
});
</script>
<% using (Html.BeginForm()) { %>
<div>
<div id="datepicker"></div>
<%= Html.HiddenFor(x => x.DateStr)%>
</div>
<% } %>
Any ideas? TIA.
Edit 1:
To see if this is a problem with my original project, I modified Home/Index view on a new MVC3 project as shown below. When I execute, I get error "Microsoft JScript runtime error: Object doesn't support this property or method". This is using jquery-1.5.1.min.js.
#model DateTime
#{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript">
$(document).ready(function () {
$('.date').datepicker({ dateFormat: "dd/mm/yy" });
});
</script>
#using ( Html.BeginForm())
{
#Html.TextBox("datepicker", Model.ToString("dd/MM/yyyy"), new { #class = "date" });
<input id="submit" name="submit" type="submit" value="Save" />
}
Why is this not working?
** Edit 2: **
Got jquery calendar to display in MVC3 using the following partial view:
#model DateTime
#using (Html.BeginForm())
{
<div id="datepicker">
#Html.TextBox("date", Model.ToString("dd/MM/yyyy"), new { #class = "date" })
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$('#datepicker').datepicker({
inline: true,
onSelect: function (dateText, inst) {
$('#date').val(dateText);
$('form').trigger('submit');
}
});
});
</script>
Now back to the original problem.
I had the same problem and it fixed by upgrading to the latest version of jquery UI and jquery.
Without more info, my guess is that problem is with the nested div's. The default css of the browser could be playing a part here. Trying setting z-index of the datepicker div to a higher value.