We're working on a Kendo UI grid that is bound to REST endpoint. The messaging portion is working great.
Where we're having trouble is trying to mask a phone number input. We like the following behavior:
1) User clicks into phone number cell.
2) User enters 1234567890.
3) When leaving the cell, the format is changed to (123) 456-7890.
We looked already at custom formats. Those seem date/time and number specific. I haven't found a way to do a custom format for a string column.
We also looked at doing this with a formatPhoneNumber function that is called on each cell's change event. I'm not happy with that approach, though it does work.
Here is the base code for the grid. I'd like to just find a way to include a custom format, or bind to a function when defining the column or field properties.
EditGridConfig = function() {
var self = this;
self.gridConfig = {
columns: [
{ field: 'PhoneNumber', title: 'Phone Number', width: '150px' },
],
data: [],
toolbar: [
{ name: "save" },
{ name: "cancel" }
],
dataSource: {
type: "json",
transport: {
read: "/api/BusinessEntity",
update: {
url: function(parent) {
return "/api/BusinessEntity/" + parent.Id;
},
dataType: "json",
type: "PUT"
}
},
schema: {
model: {
id: "Id",
fields: {
PhoneNumber: { type: "string" },
}
}
}
},
editable: "incell"
};
self.selectedData = ko.observable();
};
Here is the change event and formatPhoneNumber function we are using to get the phone number to format when focus leaves the cell. I'm just not happy with this approach, and am looking for a "cleaner" way to do it.
change: function (e) {
if (e.field == "PhoneNumber") {
console.log('before' + e.items[0].PhoneNumber);
e.items[0].PhoneNumber = formatPhoneNumber(e.items[0].PhoneNumber);
console.log('after' + e.items[0].PhoneNumber);
}
}
function formatPhoneNumber(number) {
return number.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}
Thanks much for any suggestions!
Sorry for answering my own question. I thought I would add some more detail along the lines of #James McConnell's answer so other people won't struggle like I did trying to wire up the jQuery.on event with the .mask function.
Thanks to James' hint, I wound up using the Masked Input jQuery plugin and wiring up to dynamically created events using jQuery.on.
Here is the helper function I wrote (simplified for example):
applyDynamicInputMask = function(container, selector, event, mask) {
$(container).on(event, selector, function() {
var $this = $(this);
$this.mask(mask);
});
};
And to call it:
applyDynamicInputMask(document, "[name='PhoneNumber']", 'focusin', "(999) 999-9999");
edit: function (e) {
//if edit click
if (!e.model.isNew()) {
$('input[name=Time]').attr("data-role", "maskedtextbox").attr("data-mask", "00:00");
//init mask widget
kendo.init($('input[name=Time]'));
}
}
Have you tried a jQuery plugin? We use this one at work:
http://digitalbush.com/projects/masked-input-plugin/
You can bind the plugin to any jQuery selector, so just slap a custom class on the input that needs formatted, and use that to hook up the plugin. Not sure if this is a viable solution, but it's what I've used in the past. HTH! :)
Related
I have managed to get the community version of AgGrid (Javascript) to work
However, I cant get a button to work?
function drop( id) {
alert(id);
}
var columnDefs = [
{ headerName: "HELLO", field: "name", sortable: true, filter: true },
{ headerName: 'One', field: 'fieldName',
cellRenderer : function(params){
return '<div><button (click)="this.drop(params.id)">Click</button></div>'
}
}
];
I need the function to be called when the user clicks on the button
Nothing happens at all? No errors in the console even?
What am I doing wrong?
Is this functionality disabled for the community edition?
Please note that I need a Javascript solution not Angular or any other language/framework supported by the Ag Grid
Paul
While working with cellRenderer, you should not register the event like (click)="this.drop(params.id)".
Instead, register listener the javascript way. Have a look at below code.
colDef.cellRenderer = function(params) {
var eDiv = document.createElement('div');
eDiv.innerHTML = '<span class="my-css-class"><button class="btn-simple">Push Me</button></span>';
var eButton = eDiv.querySelectorAll('.btn-simple')[0];
eButton.addEventListener('click', function() {
console.log('button was clicked!!');
});
return eDiv;
}
Reference: ag-grid Cell Renderer
I have 10 to 12 select2 dropdowns in complex control, they need to be initialized as select2 dropdown.
On dropdown-open, I make ajax call to load data. The problem comes here, if there are specific data loaded from the server. the drop-down should became multiple select2.
Here is a part of the code:
$selectDropDown.select2({
ajax: {
url: '/GetValues',
dataType: 'json',
data: function (params) {
var query = {
title: name,
}
return query;
},
processResults: function (data) {
if (data.type === '10') {
// I need to make it multiple select here
return {results: data.results};
} else {
var values = getDefaultDataItems();
return {results: values };
}
}
},
allowClear: true,
placeholder: 'Select values'
width: '100%',
});
The data cannot be loaded before initialization of select2, because of optimization reasons.
Currently it works like:
processResults: function (data) {
if (data.type === '10') {
// The hacking way
$selectDropDown.select2({
multiple: 'multiple',
data: data.results
}).select2('open');
} else {
var values = getDefaultDataItems();
return {results: values };
}
}
I want to ask it it he best way to do it?
Is there a build-in functionality?
For me, the best way to do that is add attribute multiple to my select. And change attribute name become array. After that, call .select2(); on my select.
For example, I have select with sub-type class.
$('.sub-type').prop('multiple', true).attr('name', 'sub_type[]').select2();
If you want back to single select again, just write this:
$('.sub-type').prop('multiple', false).attr('name', 'sub_type').select2();
Sorry for the late reply, I just found your question today. I hope my answer can help others.
When I'm trying to paste into the empty area within the webix datatable, nothing happens and onPaste event doesn't occur.
Basically, I want to add a new item through onPaste even when existing data items aren't selected. But whether it's possible?
Something like the 'insert' operation in a list, but in my use-case the datatable can be empty after init (in the following sample I've added an item to make clipboard work). Here it is:
http://webix.com/snippet/9ae6635b
webix.ui({
id:'grid',
view:'datatable',
select:true,
clipboard:'custom',
editable:true,
columns:[
{ id:'id' },
{ id:'name', fillspace:true, editor:"text" },
{ id:'details' }
],
data: [
{ }
],
on:{
onPaste: function(text){
this.add({ id:webix.uid(), name:text })
}
}
});
Any suggestions are appreciated.
I found that 'clipbuffer' has focus only when datatable has the selection. Most probably it is required for data editing, detecting position or whatever. Anyway, the 'clipbuffer' can be focused manually:
var clipEvent = webix.event($$("grid").getNode(), "click", function(){
webix.clipbuffer.focus();
});
Sample: http://webix.com/snippet/aa441e70
I'm trying to use a Zebra_Dialog modal window as a small form for user input. However, when retrieving the textbox values, it returns a blank string every time. This is what I'm using to create the pop-up:
new $.Zebra_Dialog("<table><tr><td>Request ID:</td><td><input id='txtRequest' type='text' /></td></tr><tr><td>Request Title:</td><td><input id='txtTile' type='text' /></td></tr></table>", {
'type': 'information',
'title': 'Save Estimate',
'buttons':
[
{
caption: 'Submit', callback: function () {
UploadToDB();
return false;
}
},
{
caption: 'Cancel', callback: function () {
}
}
]
});
When the UploadToDB method fires it has this code to get the value from the dynamically created textboxes:
function UploadToDB() {
var param = {
requestID: document.getElementById("txtRequest").value,
requestTitle: document.getElementById("txtTitle").value
};
//Other code here.....
}
I've also tried different variations such as requestID: $("#txtRequest").val(),.
Every time though I get a blank string back. Any help appreciated.
I really like Zebra_Dialog, so I wrote these helper functions. zprompt() is the one you want, it turns out to be a little tricky to get Zebra to handle prompt, and I couldn't get zprompt or zconfirm to act like synchronous Javascript functions prompt or confirm which is why they have callbacks. The OP has the same problem I had, which is that the text input vanishes on closure and jquery cannot get its value, that's why I use the old-fashioned onchange handler below.
function zalert(msg,title,type) {
$.Zebra_Dialog(msg,"title":title||'Alert',"type":type||'error',"position":['center','top+50']});
}
function zconfirm(msg,title,okproc) {
$.Zebra_Dialog(msg,{
'type': 'question',
'title': title||'Confirm?',
'position': ['center','top+50'],
'buttons': ['OK','Cancel'],
'onClose': function(caption) {
if (caption=="OK")
okproc();
}
});
}
var zprompt_value='';
function zprompt(msg,deftxt,title,okproc) {
var len=deftxt.length;
var wd=len*10;
if (wd<220) wd=300;
var size=len || 24;
$.Zebra_Dialog(msg,{
'title': title||'Confirm?',
'message': msg+"<br><input type=text onchange='zprompt_value=this.value' value='"+deftxt+"' size="+size+">",
'width': wd,
'position': ['center','top+50'],
'buttons': ['OK','Cancel'],
'onClose': function(caption) {
if (caption=="OK")
okproc(zprompt_value);
}
});
Here are some examples how they might be called:
zalert("Big mistake!","Report","error");
zconfirm("Are you sure you want to format the drive?","Confirm?",function(){
format_drive(); // Ack!
});
zprompt("Enter a funny nickname:","(nickname)","Nickname",function(n){
set_nickname(n);
});
Hope that helps someone, it took most of an afternoon to figure it out! If there's a better way to do it, please tell me.
SSF
I want to remove a parameter from the store of a comboBox before it shows to the user, I know more or less how to do it but it´s not working properly, any one could give some solution? Maybe I need to select an specific event, but I tried with all the events that make sense and didn´t work, Here is the code:
var combo = fwk.ctrl.form.ComboBox({
storeConfig: {
url: app.bo.type.type_find
,fields: ['id', 'code']
}
,comboBoxConfig:{
triggerAction: 'all'
,allowBlank:false
}
});
combo.on('beforeshow', function() {
combo.store.removeAt(2);
});
Thank you very much!!!
Try removing it inside 'afterRender' event,
sample code:
listeners: {
'afterrender': function(comboRef) {
comboRef.store.removeAt(2);
}
}
Here you have the solution,
combo.getStore().load({
callback: function (r, options, success) {
if (success) {
combo.store.removeAt(2);
}
}
});
Is necessary to change it before the load of the store because first is painted the combobox and then is charged with the store data I was erasing data in a empty store.