Kendo UI Gantt - Custom Task Edit Template - kendo-ui

I have created a custom template for a task using this example:
http://docs.telerik.com/kendo-ui/api/javascript/ui/gantt#configuration-editable.template
<script id="editor" type="text/x-kendo-template">
<h3>Edit meeting</h3>
<p><label>Title: <input name="title" /></label></p>
<p><label>Start: <input data-role="datetimepicker" name="start" /></label></p>
<p><label>End: <input data-role="datetimepicker" name="end" /></label></p>
</script>
Now I need to add a 'Resources - Assign' button, just like the one in this example (Edit Task Form):
http://demos.telerik.com/kendo-ui/gantt/resources
What do I need to do to create this button? I can't find any API documentation for this part of the Gantt control.

There are a few steps needed to accomplish this.
First, add something like this to your Kendo template:
<div>
<label for='resources'>Resources:</label>
<div class='k-gantt-resources' style='display: none;'>
</div>
<div class='k-edit-field' data-container-for='resources'>
<a class='k-button' href='\\#'>Assign</a>
</div>
</div>
Next, you'll want to add the following two event handlers to the options when you initialize the widget:
edit: editHandler,
save: saveHandler
Finally, you'll want to create the two handlers referenced above. You are basically intercepting the default functionality and opening the popup yourself, then saving the results when complete (if they were modified).
var resoucesdEdited = false;
function editHandler(e)
{
var gantt = e.sender;
resoucesdEdited = false;
if (e.task)
{
e.container.on('click', 'div[data-container-for="resources"] > a', function (event)
{
event.preventDefault();
resoucesdEdited = true;
gantt._createResourceEditor(e.container.find('div.k-gantt-resources'), e.task);
});
}
}
function saveHandler(e)
{
if (e.task && resoucesdEdited)
{
this._updateAssignments(e.task.get("id"), e.task.get(this.resources.field));
}
}
I'm glad you asked this question because it's something I needed to know too, and you're right, the Telerik/Kendo documentation doesn't mention anything on how to do this!

Related

Is it possible to exclude an element from kendo ui transformation?

I want to exclude an html-element from getting transformed to a kendo ui widget.
Is this possible? Maybe via css class or so?
Example:
https://jsfiddle.net/8L4zg92x/
<input type="file" class="first"> // => KendoUpload
<input type="file" class="second"> // => plain Html-File-Upload
--
i'm not able to change the jquery selector.
$(document).ready(function() {
$("input[type=file]").kendoUpload();
);
I realise this is a different approach which might not be practical in your situation, but using declarative initialization, instead of imperative (jQuery) initialization would give you what you want:
<body>
<div id="outer">
<input type="file" class="first" data-role="upload">
<input type="file" class="second">
</div>
<script>
kendo.init($("#outer"));
</script>
</body>
See Initializing with MVVM for more information on using this approach.
Example: https://dojo.telerik.com/eLOWaluL
just in case someone has the same problem, but can edit the selector. Here is an easy way to don't select the second input-field:
$(function() {
$("input[type=file]:not('.second')").kendoUpload();
});

if input (checkbox) is disabled -> hide it's label

I have the following code and would like to hide the label:
<div>
<input type="checkbox" data-filter-value="17_72" class="attrib filterselector unav_option" name="filter[17]" id="filter_17_72" value="72" disabled="">
<label class="optionvalue" for="filter_17_72"> Some Text</label> </div>
There are several of these in my code and I'd like to have all the labels hidden where their input has the state disabled=""
Any help would be fantastic.
You can use jQuery to achieve this. So it can be something like this
$(function () {
if ($('input[type=checkbox]').prop('disabled')) {
var hide = $('label').hide();
}
});
Jsfiddle
I didn't get managed via JS so I tried via CSS and it works:
#filterForm input.unav_option + label {display:none !important;}

Validating radio button list

I have a directive that sets a CSS class on a form element based on its $valid value. I want to use it with a radio button list. There a multiple radio buttons in the set but I only need to add the directive to one of them because a) they all control the same model and b) the CSS ultimately will reveal a single image tag which I only want once per radio button list.
Here's some HTML:
<div ng-app="myApp">
<input required type="radio" ng-model="type" name="typeGroup" value="type1">Type 1
<input add-validation-class required type="radio" ng-model="type" name="typeGroup" value="type2">Type 2
</div>
Script:
angular.module('myApp', []).directive('addValidationClass', function() {
return {
require: '^ngModel',
link: function($scope, $element, $attrs, $ngModel) {
if (!$ngModel) return;
var update = function () {
alert($ngModel.$dirty);
$element
.removeClass()
.addClass($ngModel.$dirty ? ($ngModel.$valid ? 'valid' : '') : '');
};
$scope.$watch($attrs.ngModel, function (newValue, oldValue) {
update();
});
}
};
});
Fiddle: http://jsfiddle.net/JqBgs/
You can see from the fiddle that the watch fires update regardless of the radio button clicked on. This is what I expected because both radio buttons control the same model. However you can also see that the left radio button isn't dirty. So the CSS class isn't applied.
Why isn't it dirty?
I put this in the HTML:
<div ng-app="myApp">
<input ng-change="myForm.validateRadio.$dirty = true" required type="radio" ng-model="type" name="typeGroup" value="type1">Type 1
<input name="validateRadio" add-validation-class required type="radio" ng-model="type" name="typeGroup" value="type2">Type 2
</div>
What a ridiculous bug in Angular.

KendoMobile ui template not rendering css How to make the template render with kendo stylng in view?

Basically the template wont render to a ScrollView using kendo.render(template, response) but WILL work with content = template(response) - BUT this has no styling in view -- see comment below
How to make the template render with kendo stylign in view?
BTW response from api call is JSON:
{"event_id":"5","stamp":"2013-01-24 06:00:00","type":"Event Type","loc":"Location","status":"1"}
<!-- eventDetail view -------------------------------------------------------------------------------------------------->
<div data-role="view" id="view-eventDetail" data-show="getEventDetailData" data-title="eventDetail">
<header data-role="header">
<div data-role="navbar">
<span data-role="view-title"></span>
<a data-align="right" data-role="button" class="nav-button" href="#view-myEvents">Back</a>
</div>
</header>
<div id="eventDetail" data-role="page"></div>
</div>
<script id="eventDetail-template" type="text/x-kendo-template">
--><form id="addEventForm"><p>
<input name="event_type" id="event_type" data-min="true" type="text" value="#= type #" />
</p>
<p>
<input name="event_loc" id="event_loc" data-min="true" type="text" value="#= loc #" />
</p>
<p>
<input name="event_date_time" id="event_date_time" data-min="true" type="datetime" value="#= stamp#" />
</p>
<p>
Share this
<input data-role="switch" id="event_share" data-min="true" checked="checked" value="1"/></p>
<p>
<input type="button" id="eventCancelButton" style="width:30%" data-role="button" data-min="true" value="Cancel" />
<input type="submit" id="eventDoneButton" style="width:30%" data-role="button" data-min="true" value="Done" />
</p></form><!--
</script>
<script>
//eventDetail engine
function getEventDetailData(e) {
$.ajax({
url: 'http://localhost/mpt/website/api/event_details.php?',
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: { userID: 2, eventID: e.view.params.id },
success: function(response) {
console.log(response);
var template = kendo.template($("#eventDetail-template").html()),
content = template(response);//works but no kendo css
//content = kendo.render(template, response);not working
$("#eventDetail")
.kendoMobileScrollView()
.data("kendoMobileScrollView")
.content("<!--" + content + "-->");
}
});
}</script>
The widget classes (like km-button) are not added until the widget is initialized.
The template() and render() functions just return the template as a string with the data replaced (replaces #=foo# with the value of the foo property) but does not init all the widgets. In fact, it coldn't initialize the widgets if it wanted to singe it just returns a text string, not DOM elements. The initialization of the widgets is usually done by the parent widget that is using the template.
render() is not working in your case because its 2nd argument is supposed to be an array. All it does is call the given template function once per item in the array and concatenate the results. If you instead did:
var content = kendo.render(template, [response]); // wrap response in an array
it would return the same text string as template(response). It just provides a way to apply the same template to many items at once.
Normally when you create a widget, in your case calling .kendoMobileScrollView() you would expect it to turn any HTML contents of that element into widgets too, but it looks like the ScrollView widget doesn't do this. I think its intent may have been to just display pages of static content, not other widgets.
There is a Kendo method that isn't listed in the docs, kendo.mobile.init(contents); that you might be able to use to turn your template string into widgets. When I tried it in a jsFiddle it threw some error for me, but you could try something like:
var content = template(response); // apply response to template
var contentElements = $(content); // turn the string into DOM elements
kendo.mobile.init(contentElements); // turn elements into widgets (this throws error for me)
$("#eventDetail").html(contentElements); // add contents to the desired element
$("#eventDetail").kendoMobileScrollView(); // create the scroll view
Also, what is with the end and begin comment bits hanging off the ends of the template? I don't see why those are needed. Might be better to remove them.
The ScrollView widget is supposed to take a series of <div> elements as its children. It then pages between them as you swipe left/right across the control. I don't see you adding a series of <div>s anywhere.

Can you call ko.applyBindings to bind a partial view?

I'm using KnockoutJS and have a main view and view model. I want a dialog (the jQuery UI one) to popup with another view which a separate child view model to be bound to.
The HTML for the dialog content is retrieved using AJAX so I want to be able to call ko.applyBindings once the request has completed, and I want to bind the child view model to just the portion of the HTML loaded via ajax inside the dialog div.
Is this actually possible or do I need to load ALL my views and view models when the page initially loads and then call ko.applyBindings once?
ko.applyBindings accepts a second parameter that is a DOM element to use as the root.
This would let you do something like:
<div id="one">
<input data-bind="value: name" />
</div>
<div id="two">
<input data-bind="value: name" />
</div>
<script type="text/javascript">
var viewModelA = {
name: ko.observable("Bob")
};
var viewModelB = {
name: ko.observable("Ted")
};
ko.applyBindings(viewModelA, document.getElementById("one"));
ko.applyBindings(viewModelB, document.getElementById("two"));
</script>
So, you can use this technique to bind a viewModel to the dynamic content that you load into your dialog. Overall, you just want to be careful not to call applyBindings multiple times on the same elements, as you will get multiple event handlers attached.
While Niemeyer's answer is a more correct answer to the question, you could also do the following:
<div>
<input data-bind="value: VMA.name" />
</div>
<div>
<input data-bind="value: VMB.name" />
</div>
<script type="text/javascript">
var viewModels = {
VMA: {name: ko.observable("Bob")},
VMB: {name: ko.observable("Ted")}
};
ko.applyBindings(viewModels);
</script>
This means you don't have to specify the DOM element, and you can even bind multiple models to the same element, like this:
<div>
<input data-bind="value: VMA.name() + ' and ' + VMB.name()" />
</div>
I've managed to bind a custom model to an element at runtime. The code is here: http://jsfiddle.net/ZiglioNZ/tzD4T/457/
The interesting bit is that I apply the data-bind attribute to an element I didn't define:
var handle = slider.slider().find(".ui-slider-handle").first();
$(handle).attr("data-bind", "tooltip: viewModel.value");
ko.applyBindings(viewModel.value, $(handle)[0]);
You should look at the with binding, as well as controlsDescendantBindings http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html

Resources