How to in-place edit boolean value with x-editable - javascript

I want to display a boolean value on a page (actually it'll be cells in a table), and it has to be editable. Furthermore, it's not a checkbox, but I spell out "false" and "true". We use bootstrap 3, and latest knockout. I decided to use x-editable Bootstrap 3 build. I also use a knockout custom binding: https://github.com/brianchance/knockout-x-editable.
I figured that to implement this I need to configure x-editable to be in popup mode, and select type. I also supply the selections ("true" and "false" only in this case) in a parameter. Almost everything is fine and dandy, except that the in-place dialog doesn't display the current value when it pops up. How can I fix that? I tried 'defaultValue' parameter, but it didn't help.
Here is the fiddle:
http://jsfiddle.net/csabatoth/7ybVh/4/
<span data-bind="editable: value,
editableOptions: { mode: 'popup', type: 'select',
source: '[{ value: 0, text: "false" },
{ value: 1, text: "true" }]' }">
</span>
simple model:
function ViewModel() {
var self = this;
self.value = ko.observable(false);
}

The problem is that you have true and false Boolean values in your observable but x-editable uses the 0 and 1 values to represent the "true" and "false" selection.
This causes two problems:
when initialized x-editable does not know that "false" means 0 so no default value selected
if you select anything in your pop-up editor your value observable will contain the "0" and "1" strings and not the false and true Boolean values...
You can solve both problems with intoroducing a computed property which translates between the Boolean and numerical values:
self.computed = ko.computed({
read: function() { return self.value() ? 1 : 0 },
write: function(newValue) { self.value(newValue == '1') }
});
And you need to use this property in your editable binding:
<span data-bind="editable: computed,
editableOptions: { mode: 'popup', type: 'select',
source: '[{ value: 0, text: "false" },
{ value: 1, text: "true" }]' }">
</span>
Demo JSFiddle.

Related

Knockout: Alert based on property of list of objects on select option

I know this is a simple change but I have not been able to achieve it despite researching and trying many things. And I am new to Knockout.
I have this select option of a list of objects Payors which has IsValueChecked boolean property.
<select name="InsuranceId" data-bind="options:Payors ,
optionsValue: 'Id',
optionsText: 'Text',
value:InsuranceId">
</select>
I want to create an alert if IsValueChecked is true, however the value that I am updating is InsuranceId. I am trying to achieve this by subscribing to InsuranceId.
vm.InsuranceId.subscribe(function (newValue) {
//doing something here
}
How do I write this logic?
Payors has to be an array or observableArray, with the options that you want to choose from.
When you subscribe to InsuranceId you will get the selected Id. Use this to filter through Payors.
vm.Payors = ko.observableArray([
{IsValueChecked : false, Id : 1, Text: 'False'},
{IsValueChecked : true, Id: 2, Text: 'True'}
]);
vm.InsuranceId.subscribe(function (newValue) {
var boolean = vm.Payors().find(function(payorObject){
if (newValue === payorObject.Id) {
return payorObject.IsValueChecked;
}
});
if (boolean) alert ("IsValueChecked is true");
}

Select2 dropdown allow new values by user when user types

The select2 component can be configured to accept new values, as ask in Select2 dropdown but allow new values by user?
And you can see it at: http://jsfiddle.net/pHSdP/646/ the code is as below:
$("#tags").select2({
createSearchChoice: function (term, data) {
if ($(data).filter(function () {
return this.text.localeCompare(term) === 0;
}).length === 0) {
return {
id: term,
text: term
};
}
},
multiple: false,
data: [{
id: 0,
text: 'story'
}, {
id: 1,
text: 'bug'
}, {
id: 2,
text: 'task'
}]
});
The problem is that the new value is only added to the list if you enter new value and press enter, or press tab.
Is it possible to set the select2 component to accept this new value when use types and leave the select2. (Just as normal html input tag which keeps the value which you are typing when you leave it by clicking some where on the screen)
I found that the select2 has select2-blur event but I don't find a way to get this new value and add it to list?!
Adding attribute selectOnBlur: true, seems to work for me.
Edit: glad it worked for you as well!
I am using Select2 4.0.3 and had to add two options:
tags: true,
selectOnBlur: true,
This worked for me
And to be able to submit multiple new choices together with the existing ones:
select2({tags: true, selectOnBlur: true, multiple: true})

JS Object being logged as HTML Element

I am working on a javascript control for work, and integrating it into a grails plugin. All the plugin simply does is populate the options based on a taglib, which looks like this:
$(document).ready(function() {
var ${name} = $("#${name}").tagInput({
$inputListener: $("#${inputListenerName}"),
$errorHandler: $("#${errorHandler}"),
$domainListener: $("#${domainListenerName}"),
errorClass: "${errorClass}",
validClass: "${validClass}",
caseSensitive: ${caseSensitive},
constraints: {
minSize: ${minSize},
maxSize: ${maxSize},
maxTags: ${maxTags},
validationRegex: "${tagRegex}"
},
errorMessages: {
size: "${sizeErrorMessage}",
regex: "${regexErrorMessage}",
maxTags: "${maxTagsError}"
},
responsive: {
length: ${maxTagLength},
lengthxs: ${maxTagLengthxs},
xsMode: ${xsWidth}
}
});
debugger;
});
Which looks like this when evaluated:
var emailTags = $("#emailTags").tagInput({
$inputListener: $("#invitesInput"),
$errorHandler: $("#inviteErrors"),
$domainListener: $("#null"),
errorClass: "label-danger",
validClass: "label-primary",
caseSensitive: false,
constraints: {
minSize: 1,
maxSize: 255,
maxTags: 100,
validationRegex: "[^#]+#[^#]+\.[^#]+"
},
errorMessages: {
size: "",
regex: "Must be a valid email string.",
maxTags: "You have entered too many recipients. Please send out invites before adding more recipients."
},
responsive: {
length: 50,
lengthxs: 20,
xsMode: 768
}
});
When Chrome hits the debugger statement, I have the correct object. Which is:
tagInput {parseTags: function, clear: function, serialize: function}
If I step out of this, I immediately entry jQuery and my object is instantly turned into
div#emailTags.turningTags
which eventually turns into
<div id=​"emailTags" name=​"emailTags" class=​"turningTags ">​…​</div>​
If it helps, here is the current code for the tagInput object.
https://gist.github.com/anonymous/e785ec24e0c1388cd599
Why is this happening? Why is my object being turned into this HTML element? I have tried changing the name of the variable to no avail, no matter what I change the name of this variable to, it happens every time. I have tried making it a standalone object and not a jQuery function and the same thing STILL keeps happening.

Using Kendo Grid with knockoutjs row template make filtering impossible

I'm currently building an application using knockoutjs for the MVVM pattern, and Kendo Web for the controls.
I have somme issues with filtering/grouping the data in the kendo grid.
I need to have highly customizable rows, and so I choose to use row template according to this sample :
http://rniemeyer.github.io/knockout-kendo/web/Grid.html
I also need to have a two way binding with the grid, cause I need to add/remove/update items.
The grid :
<div data-bind="kendoGrid: {
data: LienActionIndicateurPourFicheCollection,
widget: indicateurWidget,
rowTemplate: 'indicateurRowTmpl',
useKOTemplates: true,
dataSource : {
schema: {
model: {
fields: {
Code: { type: 'string' },
Titre: { type: 'string' },
Note: { type: 'number' }
}
}
},
},
columns: [
{ title: '#', width: 30 },
{ field: 'Code', title: 'Code', width: 80 },
{ field: 'Titre', title: 'Titre', width: 150 },
{ field: 'Note', title: 'Note', width: 80 }]
}">
</div>
The row template :
<script id="indicateurRowTmpl" type="text/html">
<tr">
<td>
<button data-bind="visible: $root.isInEditMode, click: removeIndicateur"
class="common-button delete-button"></button>
</td>
<td data-bind='text: Code'></td>
<td data-bind='text: Titre'></td>
<td data-bind='text: Note'></td>
</tr>
</script>
When I'm using the grid, it works fine, expect when I use grouping/filtering : it's like the grid is using the observable objet instead of the value to perform the operations.
Example : When I'm grouping on 'Note' integer value :
To prevent that, I have replaced in columns definition "field: 'Note'" by "field: 'Note()'" : the grouping works fine now, since grid use the integer value instead of a function.
But the filtering remain impossible : the column filter menu has changed from number filter to string filter when I have make the 'Note()' change.
I suppose it's because the fields entry key 'Note' does not match the columns entry key 'Note()' anymore !
I've tried to replace 'Note' by 'Note()' in fields definition : does not work.
I've replace Note observable by a non observable variable in my item model : all is working fine, but i'm not enable to edit those values anymore, and I want to.
Thanks for your help !
EDIT : here a jsfiddle reproducting the bug : http://jsfiddle.net/camlaborde/htq45/1/
EDIT#2 here's the final solution, thanks to sroes : http://jsfiddle.net/camlaborde/htq45/7/
EDIT#3 final solution plus inline grid edition : http://jsfiddle.net/camlaborde/8aR8T/4/
It works if you create a computed which returns the items as a plain JS object:
this.items.asJS = ko.computed(function() {
return ko.toJS(this.items());
}, this);
http://jsfiddle.net/htq45/2/
The reason why putting ko.toJS(this.items) directly in the binding doesn't work is because the way kendo tracks individual options in the bindings. Knockout.js man RP Niemeyer taught me this: Dynamically enable/disable kendo datepicker with Knockout-Kendo.js
I solved this issue by using Knockout ES5. Then, when assigning my data to my model, I used knockout-mapping with a mapping object like this:
var dataMapper = {
create: function(o) {
return ko.track(o.data), o.data;
}
};
ko.mapping.fromJS(json, dataMapper, self.data);
This makes the filtering and sorting work out of the box for the knockout kendo grid.

Dojo Dgrid row selection not working and retrieving the values of dgrid selectors?

Currently i am using the Dojo dgrid with select box,textbox and two checkboxes but i am not able to disable the whole row selection and also when i click the second checkbox the dgrid select and deselect not working and its reflecting the first checkbox.
1.How to disable the whole row selection in dojo Dgrid?
2.How to get the values of Dgrid selectbox and Dgrid textbox when i click on save?
3.If i use selectors(Checkbox) i am not able to render the label for that column?
var columns = {
person :{
sortable: false,
renderCell: lang.hitch(this, function(object,value,node) {
if(value == true){
myTextBox = new dijit.form.TextBox({
name: "Amount",
value: "" ,
placeHolder: "Enter Amount"
}).placeAt(node);
}
})
},
description:{
label:"description",
field:"description",
sortable: false,
renderCell : lang.hitch(this, function(object,
value, node, options) {
new Select({
name : "select",
options : [ {
label : "Daily",
value : "daily"
}, {
label : "Weekly",
value : "weekly",
}]
}).placeAt(node);
}),
},
email : selector({
sortable:false,
field:"email"
})
/*i tried this instead of using selectors inserting a checkbox so that i can remove complete row selection but not working*/
email: {
sortable:false,
field:"email",
renderHeaderCell : function(node) {
var cellDiv = domConstruct.create("label", {
innerHTML : "Email"
}, node);
var checkBox = new CheckBox({
name: "checkBox",
id:"emailAddress",
checked: false,
}, cellDiv);
},
renderCell:createMessageLabel
}
};
function createMessageLabel(object,value, node,options){
console.log("node option",node);
var checkbox = new CheckBox({
name: "checkBox",
id:"emailAddress",
checked: false,
}).placeAt(node);
};
var grid = new GridView().show(gridData, columns, "",
"dgridAutoHeight", true);
function addSelection(self, event) {
console.log("Row selected: ", event.rows[0].data);
}
function removeSelection(self, event) {
console.log("Row deselected: ", event.rows[0].data);
}
grid.startup();
grid.on("dgrid-select", lang.hitch(grid, addSelection, this), true);
grid.on("dgrid-deselect", lang.hitch(grid, removeSelection, this), true);
Hope i can get some valuable answers....
To disable direct selection, set selectionMode: "none" in the properties passed to the constructor. This does not affect selection via a selector column.
You should still be able to set the label in the header cell of a selector column by setting the label property in the object passed to the selector column plugin.
If you want to use Dijit form widgets for the purpose of changing values of fields in items, you should probably not be defining renderCell functions yourself, but instead use the editor column plugin, which does the work of maintaining the state of data and putting it back in the store when you call save.
Thank you so much Ken for your valuable answer and as you said editor suits perfect for the above situation....but i have an another doubt like can't we user editor inside a renderCell like below as i needed the value of textbox on datachange so i thought of using editor inside rendercell....below code is working fine but the TextBox is not getting placed inside a particular node(Textbox view is not getting rendered) whereever the value is "True"....
dollarThresholdAvailable :{
field: "dollarThresholdAvailable",
label : "Threshold Limit",
sortable: false,
"class":"dollarThresholdAvailableValue",
renderCell: lang.hitch(this, function(object,value,node) {
if(value === true){
editor({
field: "dollarThresholdAvailable",
sortable: false
},TextBox).placeAt(node);
}
}),
}

Categories