I want to enable/disable a kendo combobox based on the user's selection from a checkbox, which I am storing in a variable.
I already tried setting the variable to the enable property, but this is useful only when the control is being built-in.
Does anybody know If I can do this while creating the control?
<div id="fund" class="col-xs-3">
input class="required" data-bind="title: $parent.selectedFund,
kendoComboBox: {
placeholder: 'Start typing to search...',
value: $parent.test,
widget: $parent.searchSource,
dataTextField: 'managerName',
dataValueField: 'managerId',
filter: 'contains',
autoBind: false,
minLength: 3,
enable: overrideGlobalMapping, //this does not work for me even though the variable holds the correct value
change: function(){ if(this.value() && this.selectedIndex == -1)
{
setTimeout(function () {$parent.selectedManagerId(null);}, 100);}},
dataSource: {
serverFiltering: true,
transport: {
read: $parent.retrieveManager
}
}
}" />
</div>
I ended up wrapping the kendo combox definition in a function, so it now looks likes this:
<input type="checkbox" id="overrideGlobalMappingCheck" onclick="SetFundsCombobox()" data-bind="checked: overrideGlobalMapping, enable: $root.canConfirmMapping" />
The kendo combobox is still wrapped and has an id, which I later use to manipulate it in javascript:
<div class="col-xs-3" id="funds">
<input class="required" data-bind="title: $parent.selectedFund,
kendoComboBox: {
placeholder: 'Start typing to search...',
value: $parent.selectedManagerId,
...
}" />
</div>
And this is the JavaScript function bound to the onclick checkbox's event:
function SetFundsCombobox() {
var fundsDiv = document.getElementById('funds');
var inputSelector = fundsDiv.getElementsByClassName('k-input');
var span = fundsDiv.getElementsByTagName('span');
if (document.getElementById('overrideGlobalMappingCheck').checked) {
document.getElementById('funds').disabled = false;
inputSelector[0].disabled = false;
span[1].classList.remove("k-state-disabled");
} else {
document.getElementById('funds').disabled = true;
inputSelector[0].disabled = true;
span[1].classList.add("k-state-disabled");
}
};
I'd have rather preferred to perform this via the view model, but it works for now.
EDIT:
I've been able to do this the right way (following the MVVM pattern), so now rather than wrapping the kendo combo box in a function, I added the following function in the view model:
$scope.overrideGlobalMappingChecker = ko.computed(function () {
if ($scope.entityMapping()) {
var checkboxChecked = $scope.entityMapping().overrideGlobalMapping();
$("#funds .k-input").prop('disabled', !checkboxChecked);
if (!checkboxChecked) {
$scope.selectedFundId(null);
}
}
});
So now, what the html only needs is the definition of the id in the div containing the combo box:
<div class="col-xs-3" id="funds">
<input data-bind="title: $parent.selectedFundName, kendoComboBox: {
autoBind: false,
...
}" />
</div>
And that's it, it's a much cleaner/correct way to handle this.
Related
I'm using selectize for my drop down menus and I'm trying to do form validation. Each of the menus has class .code_select, and I want to know if an option has been selected on all of them. My code should determine if something is selected, and if not add the ID of the dropdown to an array called empty_fields. However, my dropdowns are all ending up in the array whether they have a selected option or not. This is my code:
$(".code_select").each(function(){
if ($(this).find('option:selected').length === 0) {
empty_fields.push($(this).attr("id")+'-selectized');
submitForm=false;
}
});
An example of one of the inputs:
<div class='col-4'>
<input type='text' class='form-control code_select' id='5-tree-Betpap-stdCodeSelect' name='5-tree-Betpap-stdCode' aria-label='Tree Metric Field 5 Standard Code select'>
</div>
And my selectize initialization:
// initialize newCodes selectize control
newCodesSelect[index] = $(this).selectize({
valueField: 'id',
labelField: 'label',
create: false,
hideSelected: false,
options: listOptions[listType],
searchField: 'label',
placeholder: "Choose " + listType + " codes (type to search)",
maxItems: 1,
});
//This stores the selectize object to a variable
newCodesSelectize[index] = newCodesSelect[index][0].selectize;
How do I determine if the select is still on the "placeholder" when my placeholder has a variable?
Thank you!
OK, here is what worked for me. I had to use .selectize-control as the selector and find if any of the items have data-attribute=null.
$('#nextBtn').click(function() {
console.log("Next Button - adding hidden fields");
//remove any left over error formatting
$('.requiredField').removeClass('requiredField');
var fld_text="";
$('#error-messages').html(fld_text);
// validate form before submit
var empty_fields=[];
var submitForm=true;
$(".code_description").each(function(){
if ($(this).val()==="") {
empty_fields.push($(this).attr("id"));
submitForm=false;
}
});
$(".selectize-control").each(function(){
if ($(this).find(".item").attr('data-value') == null) {
empty_fields.push($(this).prev("input").attr("id")+'-selectized');
}
});
empty_fields.forEach(function(element) {
if (element!=="undefined-selectized") submitForm=false;
});
if (submitForm===true) {
$('#nextForm').submit();
}
else {
fld_text="<p>Review required fields</p>";
$('#error-messages').html(fld_text);
empty_fields.forEach(function(element) {
if (element!=="undefined-selectized") $("#"+element).addClass("requiredField");
});
}
});
I'm trying to get an instance of the current modal window (to save the data of the modal window to a file). But no success. I tried to do this via onActivate and then console.log($(this));
What is the correct method for doing this? Or I should have filled the data via template and then use content property of the kendoWindow ? THX!
Grid:
$("#grid")
.kendoGrid({
dataSource: {
transport: {
read: {
url: "/api/GridData/GetCustomers",
dataType: "json"
}
}
},
columns: [
{
command: { text: "View Details", click: viewDt },
title: "View DT",
width: "100px"
}
]
});
HTML:
<form id="formViewDetail">
Имя клиента:<br>
<input type="text" name="ClientName" id="ClientNameViewDetail" value="">
<br>
ОКПО:<br>
<input type="text" name="ClientOKPO" id="ClientOKPOViewDetail">
<br>
Дата регистрации:<br>
<input type="text" name="RegistrationDate" id="RegistrationDateViewDetail">
<br>
Дата закрытия:<br>
<input type="text" name="RemovalFromClientsDate" id="RemovalFromClientsDateViewDetail">
<br>
Комментарий:<br>
<input type="text" name="Comment" id="CommentViewDetail">
<br>
<button id="SubmitViewDetail">Сохранить</button> <button id="CloseViewDetail">Закрыть</button>
</form>
Modal window:
var myWindow = $("#window");
myWindow.kendoWindow({
width: "600px",
title: "Редактирование данных клиента:",
visible: false,
actions: [
"Pin",
"Minimize",
"Maximize",
"Close"
],
activate: onActivateWnd
//close: onClose
});
function onActivateWnd(e) {
console.log($(this));
}
Fill in data:
function viewDt(e) {
var dItem = this.dataItem($(e.currentTarget).closest("tr"));
console.log(dItem);
myWindow.data("kendoWindow").center().open();
//disabling input
$("#formViewDetail").find("#ClientNameViewDetail").prop('disabled', true);
$("#formViewDetail").find("#ClientOKPOViewDetail").prop('disabled', true);
$("#formViewDetail").find("#RegistrationDateViewDetail").prop('disabled', true);
$("#formViewDetail").find("#RemovalFromClientsDateViewDetail").prop('disabled', true);
//passing data to form input
$("#formViewDetail").find("#ClientNameViewDetail").val(dItem.ClientName);
$("#formViewDetail").find("#ClientOKPOViewDetail").val(dItem.ClientOKPO);
$("#formViewDetail").find("#RegistrationDateViewDetail").val(dItem.RegistrationDate);
$("#formViewDetail").find("#RemovalFromClientsDateViewDetail").val(dItem.RemovalFromClientsDate);
}
The provided information suggests that the Window holds one data item from the Grid, which is displayed when the user clicks on a button inside a Grid row. In this case, it will be a lot easier to retrieve the desired information from the Grid's data item, instead of the Window's content. The Grid data item is available in the dItem variable.
If you want to save the Customer information after the user has edited it, then consider using the Grid's built-in popup editing and the save event. In this way, the Grid data item will always hold the latest values.
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-save
http://demos.telerik.com/kendo-ui/grid/editing-popup
It is also possible to use popup editing with a custom popup edit form template:
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-editable.template
Finally, in order to get a data item with the Kendo UI-related stuff inside, use toJSON() to get a plain object:
http://docs.telerik.com/kendo-ui/api/javascript/data/model#methods-toJSON
I am trying to store value in attribute in input tag which would like as follows.
The following code will repeat several times and the value for different radio can be saved using index.
<div data-bind="attr : { name : 'ex['+$index()+']' }>
<input type="radio" name="value" data-target="#modal" data-bind="click:fun.fill($index())"/>
</div>
From the above text box i can get the index of that input.And it points to a common modal function from bootstrap which opens a popup.
<div class="modal fade">
<select data-bind="attr:{name:'assignedResources['+$index()+'][repeatedType]'},
options : $root.repeats,value : repeatedType"></select>
</div><!-- /.modal -->
This is a sample of modal target.I want to call this modal as common.(i.e)it will be called from several places.I want to show appropriate popup for appropriate click from radio button.
But what i get is value of last index.Thats my problem
I'm not 100% sure I understand your question, but something like this...
this.abc = ko.observable('');
this.fun = {
var that = this;
fill: function(index) {
console.log(that.abc());
}
}
As far as I understand your problem, you need an observable to store your value, and then you can access it by any other function on your viewModel.
This is a jsFiddle with my initial approach, let me know if is what you needed or clarify instead:
http://jsfiddle.net/rdarioduarte/X8Rc4/
With a model like this:
var viewModel = function() {
this.abc = ko.observable('Value to store');
this.fun = function() {
alert(this.abc());
}
}
ko.applyBindings(new viewModel());
Thanks,
Dario
I do not quite understand about your question. But, maybe this may help:
1) Obtains index of your input element automatically on page load to viewModel function maybe need custom binding to handle that:
e.g custom binding:
ko.bindingHandlers.saveIndex = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var index = ko.utils.unwrapObservable(valueAccessor());
viewModel.fun(index); // accessing fun function on viewModel
// You can also access that function using bindingContext.$root
// bindingContext.$root.fun(index);
}
};
e.g html:
<input type="text" data-bind="saveIndex: $index()"/>
2) Store index to input value attribute using attr binding:
<input type="text" data-bind="attr: { value: $index() }">
3) Send your input attr value to viewModel function onClick:
<input type="text" value="thisIsExampleValue" data-bind="click: function() { $root.fun($element.value); }">
You also can use event binding for this behavior, Knockout.Event-binding
UPDATE:
Try this:
<div data-bind="attr : { name : 'ex['+$index()+']' }>
<input type="radio" name="value" data-target="#modal" data-bind="click: function() { fun.fill($index()) }"/>
I have an input textbox and whenever it loses focus I want to get its value text in a function.
For example, if type "testimonials1", how could I get that text in an event handler for the blur event?
This is what I tried. I get ProjectTestimonial as an object, not user-typed text.
HMTL
<div class="ratingcontents" data-bind="foreach: ProjectTestimonial">
<!--ko if: !Testimonialstext-->
<input type="text" placeholder="Testimonials" class="txttestimonials"
data-bind="
text: Testimonialstext,
event: {
blur: $root.testimonialblurFunction.bind(SourceId, SourceText, Testimonialstext)
}
"
>
<!--/ko-->
</div>
JS
self.testimonialblurFunction = function (data, event, Testimonialstext) {
debugger;
alert(data.soid + Testimonialstext);
}
You can use event, that attaches to any JS event:
<input name="id" data-bind="value: id, event: { blur: blurFunction }">
And in your view model:
self.blurFuncion = function(){
// this attacks when blur event occurs in input
}
Simple as that.
The first mistake you made was using the 'text' binding on the input field, rather than the 'value' binding.
Regarding the event handler, I would not do this. I would use knockout's 'subscribe' functionality to listen for changes to the observable.
Here is a Jsfiddle version of your code. I have changed your markup to demonstrate more clearly.
HTML
<div class="ratingcontents" data-bind="foreach: ProjectTestimonial">
<input type="text" placeholder="Testimonials" class="txttestimonials"
data-bind="value: Testimonialstext" />
</div>
Javascript
function viewModel(jsModel){
var self = this;
self.ProjectTestimonial = ko.utils.arrayMap(jsModel, function(item) {
return new testimonial(item);
});
}
function testimonial(jsTestimonial){
var self = this;
ko.mapping.fromJS(jsTestimonial, {}, self);
self.Testimonialstext.subscribe(function(){
alert(self.SourceId() + self.Testimonialstext());
});
}
var rawModel = [
{
SourceId: '1',
SourceText: 'Foo',
Testimonialstext: 'Ahoy there.'
},
{
SourceId: '2',
SourceText: 'Bar',
Testimonialstext: 'Blah blah blah'
}];
ko.applyBindings(new viewModel(rawModel));
Use the has focus binding instead. From what I understand you want the data in the text box once the user stops editing. This is simple enough. Check out this example from the knockout js documentation page.
<p>
Hello <b data-bind="text:name"></b> </p>
<input data-bind="value: name, hasfocus: editing" />
<p><em>Click the name to edit it; click elsewhere to apply changes.</em></p>
View model
function PersonViewModel(name) {
// Data
this.name = ko.observable(name);
this.editing = ko.observable(false);
// Behaviors
this.edit = function() { this.editing(true) }
}
ko.applyBindings(new PersonViewModel("Bert Bertington"));
jsFiddle
I'm trying to get my head around Knockout.js and I'm quite stuck when it comes to checkboxes.
Server side I'm populating a set of checkboxes with their corresponding values. Now, when any of the unchecked checkboxes are checked, I need to store it's value in a comma-seperated string. When they're unchecked, the value needs to be deleted from the string.
Have anyone got a hint on how to achieve this with knockoutjs?
I have the following code so far:
ViewModel:
$().ready(function() {
function classPreValue(preValue)
{
return {
preValue : ko.observable(preValue)
}
}
var editOfferViewModel = {
maxNumOfVisitors : ko.observable(""),
goals : ko.observable(""),
description : ko.observable(""),
contact : ko.observable(""),
comments : ko.observable(""),
classPreValues : ko.observableArray([]),
addPreValue : function(element) {
alert($(element).val());
this.classPreValues.push(new classPreValue(element.val()));
}
};
ko.applyBindings(editOfferViewModel);
});
And my checkboxes are populated with a foreach loop:
<input data-bind="checked: function() { editOfferViewModel.addPreValue(this) }"
type="checkbox" checked="yes" value='#s'>
#s
</input>
I try to pass the checkbox element as the parameter to my addPreValue() function, but nothing seems to happen when I check the checkbox?
Any help/hints on this is greatly appreciated!
The checked binding expects to be passed a structure that it can read/write against. This could be a variable, an observable, or a writable dependentObservable.
When passed an array or observableArray, the checked binding does know how to add and remove simple values from the array.
Here is a sample that also includes a computed observable that contains the array as comma delimited values. http://jsfiddle.net/rniemeyer/Jm2Mh/
var viewModel = {
choices: ["one", "two", "three", "four", "five"],
selectedChoices: ko.observableArray(["two", "four"])
};
viewModel.selectedChoicesDelimited = ko.computed(function() {
return this.selectedChoices().join(",");
}, viewModel);
ko.applyBindings(viewModel);
HTML:
<ul data-bind="template: { name: 'choiceTmpl', foreach: choices, templateOptions: { selections: selectedChoices } }"></ul>
<script id="choiceTmpl" type="text/html">
<li>
<input type="checkbox" data-bind="attr: { value: $data }, checked: $item.selections" />
<span data-bind="text: $data"></span>
</li>
</script>
Why isn't there a Mutually exclusive checkboxes example Online somewhere
Since this link came up first whilst I was searching for mutually exclusive checkboxes I will share my answer here. I was banging my head against the wall with all my attempts. By the way, when you handle the click event in a binding in-line knockoutjs it seems to disconnect the bindings(maybe only because I tried to call my resetIllnesses function as defined below) even if you return true from the function. Maybe there is a better way but until then follow my lead.
Here is the type I needed to bind.
var IllnessType = function (name,title) {
this.Title = ko.observable(title);
this.Name = ko.observable(name);
this.IsSelected = ko.observable(false);
};
The array to bind with.
model.IllnessTypes = ko.observableArray(
[new IllnessType('IsSkinDisorder', 'Skin Disorder'),
new IllnessType('IsRespiratoryProblem', 'Respiratory Problem'),
new IllnessType('IsPoisoning', 'Poisoning'),
new IllnessType('IsHearingLoss', 'Hearing Loss'),
new IllnessType('IsOtherIllness', 'All Other Illness')]
);
The reset illness function to clear them all.
model.resetIllnesses = function () {
ko.utils.arrayForEach(model.IllnessTypes(), function (type) {
type.IsSelected(false);
});
};
The markup
<ul data-bind="foreach:IllnessTypes,visible: model.IsIllness()">
<li><label data-bind="html: Title"></label></li>
<li><input class="checkgroup2" type="checkbox"
data-bind="attr:{name: Name },checked:IsSelected" /></li>
</ul>
This just doesn't work
If you have been struggling with trying to call the resetIllness function as I below, you will feel my pain.
<input type='checkbox' data-bind="checked:IsSelected,
click: function() { model.resetIllnesses(); return true; }" />
you have been sharing my pain. Well, it works! when you call it from following example.
Notice that there is a class that I added above so that I can add the click function.
The script that makes all your problems go away.
<script type="text/javascript">
$(function() {
$(".checkgroup2").on('click', function() {
model.resetIllnesses();
var data = ko.dataFor(this);
data.IsSelected(true);
});
});
</script>
Send info to the server
Also, in my case I had to send the information up to the server differently than the default html format so I changed the inputs a little.
<input class="checkgroup2" type="checkbox" data-bind="checked:IsSelected" />
<input type="hidden" data-bind="attr:{name: Name },value:IsSelected" />