The codes below returns Uncaught TypeError: Cannot set property 'checked' of null.
what is the correct way to programmatic set checkbox as checked?
array.forEach(this._getAllCheckBoxIDs(), function(item){
dom.byId(item).checked = true;
}, this);
The following example shows a programmatic example on how to set property checked for a widget checkbox.
The script gets references of your checkboxes using dijit/registry opposite to querying the DOM.
Instead of setting a property directly for your widget like this:
dom.byId(item).checked = true;
I would suggest using a setter like:
widgetReference.set('checked', true);
This will allow the widget life-cycle to work properly.
Live example here:
https://jsfiddle.net/femtf4uh/
require(["dijit/form/CheckBox", "dijit/registry", "dijit/form/Button", "dojo/domReady!"], function(CheckBox, registry, Button) {
new CheckBox({
id: "checkBox0",
name: "checkBox0",
value: "option0",
checked: false,
onChange: function(event) {
}
}, "checkBox0").startup();
new CheckBox({
id: "checkBox1",
name: "checkBox1",
value: "option1",
checked: false,
onChange: function(event) {
}
}, "checkBox1").startup();
var markCheckAll = function() {
registry.toArray().forEach(function(widget) {
if (widget.type === 'checkbox'){
widget.set('checked', true);
}
});
};
markCheckAll();
});
<input id="checkBox0" />
<label for="checkBox">Option 0</label>
<br>
<input id="checkBox1" />
<label for="checkBox">Option 1</label>
<br>
Well, If you you have the collections of dojo checkboxes then I would suggest you to use registry.byId instead of dojo.byId because you need checkbox dojo widget along with it's domNode to update its attribute.
dojo class name:-
dijit/registry
Ex:-
// require registry class first
array.forEach(this._getAllCheckBoxIDs(), function(item){
registry.byId(item).set("checked", true);
}, this);
for more details please click here...
Hoping this will help you :)
Related
I have functionality where developers can add custom Angular views where they can bind properties to the $scope.settings object. When clicking on the save button the $scope.settings object will be converted to JSON and saved to the database. Something like this will be the result:
{
"name": "bob",
"age": "25"
}
As long as I add elements like <input type="text" ng-model="settings.name" /> everything goes as expected.
But, now I want to add directives like this:
<umb-property property="property in properties">
<umb-editor model="property"></umb-editor>
</umb-property>
With the following code:
$scope.properties = [
{
label: 'Name',
alias: 'name',
view: 'textbox',
value: $scope.settings.name
},
{
label: 'Age',
alias: 'age',
view: 'number',
value: $scope.settings.age
}
];
The 'editor' directive loads views in place based on the 'view' property. The views are third party. The editors are loaded in a dialog. After submission of the settings dialog, the following line of code will convert the settings to JSON:
$scope.dialog = {
submit: function (model) {
var settingsJson = JSON.stringify(model.settings);
},
close: function (oldModel) {
//
}
};
In this case I cannot parse the $scope.settings to JSON, because the $scope.settings.name is not updated anymore. The $scope.editorModel.value was updated instead.
How can I bind the $scope.editorModel.value to $scope.settings.name?
I don't want to end up with a solution where I must update all $scope.settings values with the corresponding values from the editor models, because I want to support the dynamic way to convert the $scope.settings to a JSON value in the database.
For example I dont want to do: $scope.settings.name = $scope.properties[0].value
Use property accessors:
for (var i=0; i<$scope.properties.length; i++) {
$scope.settings[$scope.properties[i].alias] = $scope.properties[i].value;
};
HTML
<div ng-repeat="prop in properties">
<input ng-model="prop.value">
</div>
I trying Select item in dx-tree-view, my treeview config:
$scope.treeViewOptions = {
bindingOptions: {
dataSource: 'localArray',
searchValue: "searchValue",
},
keyExpr: 'id',
displayExpr: 'caption',
parentIdExpr: 'parentId',
dataStructure: 'plain',
selectedExpr: 'isSelected',
onItemClick: function (e) {...
I added selectExpr:'isSelected' option, and trying select my item use it:
$scope.localArray[0].isSelected = true;
$scope.localArray = $scope.localArray;
but it don't works, may be somebody have ideas how i can do it ?
Thanks for Your answers!
In DevExtreme v.15.2 tree view selection works only with the showCheckBoxesMode: 'normal' option.
$scope.treeViewOptions = {
// tree view config...
showCheckBoxesMode: 'normal'
};
The sample is here.
But, if you want to apply a custom style to the item with the isSelected field, you can do it manually. Just use the onItemRendered event and check if item is selected:
onItemRendered: function(args){
if(args.itemData.isSelected) {
args.itemElement.css("color", "green");
}
}
Sample.
I have an order line grid where I need to be able to open the popup editor form programmatically with the edit form fields pre-populated (using AngularJs).
In the HTML, I have a lineGrid and an addButton, which calls addRow() on the ticketEntryController:
<div id="wrapper" class="container-fluid" ng-controller="ticketEntryController">
<div ng-controller="ticketLineController">
<div kendo-grid="ticketLineGrid" k-options="getTicketLineGridOptions()"></div>
</div>
<button id="addButton" ng-click="addRow()" class="btn btn-primary btn-sm">Add Row</button>
</div>
Here is the ticketEntryController:
(function () {
'use strict';
angular.module('app').controller('ticketEntryController', ticketEntryController);
function ticketEntryController($scope) {
$scope.lineGrid = {};
$scope.addRow = function () {
var item = { itemNo: 'TEST123', itemDescr: 'Some description' };
$scope.$broadcast('AddRow', item);
}
}
})();
Here is part of the ticketLineController:
function ticketLineController($scope) {
$scope.$on('AddRow', function(event, item) {
console.log("ticketLineController, AddRow: " + item.itemNo);
$scope.itemNo = item.itemNo;
$scope.itemDescr = item.itemDescr;
$scope.ticketLineGrid.addRow();
});
Plunker: http://plnkr.co/edit/VG39UlTpyjeTThpTi4Gf?p=preview
When the Add Row button is clicked, the editor popup form opens up, but all fields are empty. How can I populate the fields (like they are when you click the Edit button for an existing row)?
I figured out how to get a row to be pre-populated for you, although I'm not sure if this is necessarily the best way to do it, but it does accomplish the job - I'm more familiar with AngularJs, not so much with Kendo UI.
The only place that the Kendo API allows you to change/set the new item that you are adding is in the edit event but I couldn't see a way to send your own object along to the event when you call addRow so you need to have a reference to a shared object in your controller with I called itemForAdd. Before calling addRow() in your controller, you need to set the itemForAdd object with the actual object that you want to pre-populate the form with.
var itemForAdd = {};
$scope.$on('AddRow', function(event, item) {
// save reference to item to use for pre-population
itemForAdd = item;
$scope.ticketLineGrid.addRow();
});
Now in the edit event that the Kendo API sends out, you can populate the items from your selected item in the model item. It's not really required, but I also like to clear out objects that I use like this so in the save and cancel events, I clear out the shared itemForAdd object.
edit: function (e) {
if (e.model.isNew()) {
e.model.set("itemNo", itemForAdd.itemNo);
e.model.set("itemDescr", itemForAdd.itemDescr);
}
var popupWindow = e.container.getKendoWindow();
e.container.find(".k-edit-form-container").width("auto");
popupWindow.setOptions({
width: 640
});
},
save: function(e) {
if (e.model.isNew()) {
// clear out the shared object
itemForAdd = {};
}
},
cancel: function(e) {
if (e.model.isNew()) {
// clear out the shared object
itemForAdd = {};
}
}
With the previous changes, the functionality that you want is mostly working but the data in the table in the edit popup doesn't show the updated values. This is because the Kendo data bindings apparently didn't know they had to update. I couldn't figure out how to make that work, so I just used the AngularJs style bindings for that table (where you had +=itemNo=+), so that the values in the table would update based on the changes in the model object:
<tbody>
<tr>
<td>{{dataItem.itemNo}}</td>
<td>{{dataItem.itemDescr}}</td>
<td>{{dataItem.cat}}</td>
<td>{{dataItem.mfg}}</td>
<td>{{dataItem.mfgPartNo}}</td>
</tr>
</tbody>
But there was one more issue at this point, only the itemNo was being updated, not the itemDescr and that was because itemDescr was set as editable: false in your grid configuration, so I had to changed it to editable: true
fields: {
id: { type: "string", editable: false },
itemDescr: { type: "string", editable: true },
...
},
And finally, here is an updated plunker with my changes: http://plnkr.co/edit/rWavvMh4dRFAsJjuygQX?p=preview
In my AngularJS application, I am displaying contacts data in a grid. My typical contacts JSON looks like as below ...
[
{ type: "IM", value: "mavaze123", default: true },
{ type: "IM", value: "mvaze2014", default: false },
{ type: "IM", value: "mavaze923", default: false },
{ type: "IM", value: "mvaze8927", default: false },
{ type: "Email", value: "mavaze123#abc.com", default: true },
{ type: "Email", value: "mvaze2014#xyz.net", default: false }
]
The last property 'default' is actually a radio button, selection of which should alter the original default value of the corresponding contact type in above JSON. There can be one default from each type of contact i.e. we can group radio buttons based on the contact type.
<div ng-repeat="contact in contacts">
<div>{{contact.type}}</div>
<div>{{contact.value}}</div>
<div><input type="radio" name="{{contact.type}}" ng-model="contact.default" ng-value="true"/></div>
</div>
Note: The above code is not the exact one, but approximately same, as
it will appear inside a custom grid component.
Now when I load my view/edit form page with above JSON, it correctly shows the radio state of all contacts. The problem comes, after page load, when user selects another contact as default. This actually changes the model value of default to true for newly selected contact however the model value of original default contact still remains true, even though its radio state changes to uncheck/blur (because they are having same 'name' value).
I thought to write a directive, but I am unable get it triggered on radio on-blur/uncheck event.
There are various posts on binding boolean values to radio buttons, but I am unable to get it work in my scenario, as I want to update model values for individual radio button in a radio group. See there is no single model representing a radio group.
I think you should change your design to separate the contacts from contactTypes and store the key to the default contact in contact type.
In your current design, there are duplicated values for default and that's not the desired way to work with radio.
$scope.contacts = [
{ type: "IM", value: "mavaze123" },
{ type: "IM", value: "mvaze2014" },
{ type: "IM", value: "mavaze923" },
{ type: "IM", value: "mvaze8927" },
{ type: "Email", value: "mavaze123#abc.com" },
{ type: "Email", value: "mvaze2014#xyz.net" }
];
$scope.contactTypes = {
"IM": { default:"mavaze123"}, //the default is contact with value = mavaze123
"Email": { default:"mavaze123#abc.com"}
};
You Html:
<div ng-repeat="contact in contacts">
<div>{{contact.type}}</div>
<div>{{contact.value}}</div>
<div><input type="radio" name="{{contact.type}}" ng-model="contactTypes[contact.type].default" ng-value="contact.value"/></div>
</div>
DEMO
I assume that the key of contact is value, you could use an Id for your contact.
I added an attribute directive in my input statement ...
<div ng-repeat="contact in contacts">
<div>{{contact.type}}</div>
<div>{{contact.value}}</div>
<div><input type="radio" name="{{contact.type}}" ng-model="contact.default" ng-value="true" boolean-grid-model /></div>
</div>
And my custom directive ...
myModule.directive('booleanGridModel') {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attrs, controller) {
var radioSelected = scope.$eval(attrs.ngModel);
if(radioSelected) {
var selectedContact = scope.contact;
_.each(scope.contacts, function(contact) {
if(contact.type === selectedContact.type) {
_.isEqual(contact, selectedContact) ? contact.default = true : contact.default = false;
}
});
}
}
};
}
WHy you declare ng-value="true" please remove that
<div><input type="radio" name="{{contact.type}}" ng-model="contact.default" ng-value="{{contact.default}}"/></div>
Please use $scope.$apply() in your value changing code
Like something below
$scope.$apply(function ChangeType()
{
/Code
});
And you need to change name="{{contact.type}}" to name="contact.type{{$index}}" Because some types are same name.
The following screenshot shows a combined form for sign-in and sign-up:
The following module is used to render the AuthView:
MyApp.module("User", function(User, App, Backbone, Marionette, $, _) {
User.AuthView = Marionette.ItemView.extend({
className: "reveal-modal",
template: "user/auth",
ui: {
signInForm: "#signin-form",
signUpForm: "#signup-form"
},
events: {
"focus input": "onFocus"
},
onFocus: function() {
console.log("Some input field has received focus.");
},
onRender: function() {
this.signInForm = new Backbone.Form({
schema: {
signInEmail: {
type: "Text",
title: "E-Mail address"
},
signInPassword: {
type: "Password",
title: "Password"
}
}
}).render();
this.ui.signInForm.prepend(this.signInForm.el);
this.signUpForm = new Backbone.Form({
schema: {
signUpEmail: {
type: "Text",
title: "E-Mail address"
},
signUpPassword: {
type: "Password",
title: "Password"
},
signUpPasswordConfirmation: {
type: "Password",
title: "Password confirmation"
}
}
}).render();
this.ui.signUpForm.prepend(this.signUpForm.el);
}
});
});
How can I automatically focus the first field in each sub-form whenever it is rendered? The first fields would be signInEmail for the signInForm and signUpEmail for the signUpForm.
I tried to listen to focus input events. Such an event is triggered when I click into one of the input fields, not before.
Meanwhile, inspired by the current answers I came up with the following helper function:
focusFirstFormField: function(form) {
if (_.isUndefined(form)) {
throw "IllegalStateException: Form is undefined."
}
// TODO: AuthView does not focus first sign-in field.
var firstInput = form.find(':input:first');
if (_.isObject(firstInput)) {
if (firstInput.length > 0) {
firstInput = firstInput[0];
}
else {
throw "IllegalStateException: Form find returns an empty jQuery object."
}
}
_.defer(function() {
firstInput.focus();
});
}
There is still need for improvement, though.
The events object are DOM events which are generally triggered by the user so that's not what you'll likely want to use in this case.
If I'm understanding you correctly you would like to put the focus in the first input of each of the forms but since you can only have focus on one thing at a time and they are rendering together you'll have to choose one or the other.
The simplest option is to add another line at the end of onRender focusing on the input. If your input is generating an input something like this:
<input type="text" name="signInEmail">
Then you can add:
this.$('[name=signInEmail]').focus();
If not you'll have to change the selector this.$(xxxx).focus() to suit.
You can use onDomRefresh event of the view. It will be triggered after view rendered and Dom refreshed.
onDomRefresh: function() {
this.focusFirstInput();
};
focusFirstInput: function() {
this.$(':input:visible:enabled:first').focus();
};
This solution applies to general cases. However, pay attention if you are using Bootstrap. I can't get this work there. Instead, I set autofocus: 'autofocus' in the field and it works.
You can add it to onRender method.
this.ui.signInForm.find('input[type=text]:first').focus();
this.ui.signUpForm.find('input[type=text]:first').focus();
On the onRender method I do :
$(this.el).find(':input[autofocus]').focus();
And I add the autofocus="" flag onto my HTML node. This works for refresh.