I am using Kendo UI DateTimePicker and i faced with binding issue. I am getting data from json then i creating new js date based on the json value and bind it. Actual result is that the date is converted to local timezone. Can i disable conversion to local timezone?
The DateTimePicker does not perform any conversion.
I expect that your date does not have time zone specificator and when you creating new js date this value considered as UTC and converted to local. To solve this problem you can simply bind date from json without creating new js date.
You can do this to add a useUtc option to your code that will always return the date in Utc:
kendo.ui.DatePicker.prototype.valueOld = kendo.ui.DatePicker.prototype.value;
kendo.ui.DatePicker.prototype.value = function (e) {
var val = this._value;
if (val != null && this.options != null && this.options.useUtc) {
this._value = new Date(Date.UTC(val.getFullYear(), val.getMonth(), val.getDate()));
}
return this.valueOld(e);
}
kendo.ui.DateTimePicker.prototype.valueOld = kendo.ui.DateTimePicker.prototype.value;
kendo.ui.DateTimePicker.prototype.value = function (e) {
var val = this._value;
if (val != null && this.options != null && this.options.useUtc) {
this._value = new Date(Date.UTC(val.getFullYear(), val.getMonth(), val.getDate(), val.getHours(), val.getMinutes(), val.getSeconds(), val.getMilliseconds()));
}
return this.valueOld(e);
}
Related
I have an entity which contains 2 forms, I want to prevent navagation between these 2 forms based on the value of two option field. In other words if the value of need prescoring is yes navigation is not possible and the inverse, how can I do this ?
Is it possible to simply hide the list ?
Thanks,
No, you cannot dynamically change the forms the user can select. This can only be done statically based on security roles.
Instead I suggest using a single form, where you hide and show the relevant fields/sections/tabs based on the value of your Need Processing field.
You can decide based on your project complexity wrt number of form controls/tabs/sections. We did something like this to maintain & forced navigation based on form control value.
var taskFormOptionSet = {
Form1: 1,
Form2: 2,
};
var FormNames = {
Form1: "Form1",
Form2: "Form2",
};
var myform = Xrm.Page.getAttribute("need_Prescoring").getValue();
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
if (myform == taskFormOptionSet.Form1 && formLabel != FormNames.Form1) {
var items = Xrm.Page.ui.formSelector.items.get();
for (var i in items) {
var form = items[i];
var formId = form.getId();
var formLabel = form.getLabel();
if (formLabel == FormNames.Form1) {
form.navigate();
return;
}
}
}
As it's not supported I used another solution which is to check if the boolean is true and the name of the, if the user tries to change the form he will be redirected to the right form until he changes the value of the boolean.
DiligenceSwitch: function(){
if (Xrm.Page.ui.formSelector.getCurrentItem() != null) {
var currentform = Xrm.Page.ui.formSelector.getCurrentItem();
}
if (currentform != null) {
var formId = currentform.getId();
var formLabel = currentform.getLabel();
}
var kycId = Xrm.Page.data.entity.getId();
SDK.REST.retrieveRecord(kycId, "kyc_Kycdiligence", "kyc_Needprescoring", null, //field for searching the targeted field, entity, targeted field, ...
function (kyc) {
if (kyc != null || kyc.kyc_Needprescoring != null) {
if (formLabel != "Pre-Scoring" && kyc.kyc_Needprescoring == true) {
var windowOptions = { openInNewWindow: false };
var parameters = {};
parameters["formid"] = "4B0C88A9-720C-4BFA-8F59-7C1D5DD84F02";
Xrm.Utility.openEntityForm("kyc_kycdiligence", kycId, parameters, windowOptions);
alert("Vous devez faire le pre-scoring");
}
}
},
function (error) {
Xrm.Utility.alertDialog(error.message);
});
},
I made a date validator. It validates existing dates. I need multiple date validator with other restrictions, for ex : a max date validator that won't let the user put in a future date or a date validator that only takes past dates. This is my current validator.
export function dateValidator(group) {
const {day, month, year} = group.value;
const fullDate = `${day}/${month}/${year}`;
const dobPattern = /^(\d{1,2})[-\/](\d{1,2})[-\/](\d{4})$/;
const isStringValid = dobPattern.test(fullDate);
let isValid = false;
if (isStringValid) {
const intDay = Number(day);
const intMonth = Number(month);
const intYear = Number(year);
const jsMonth = intMonth - 1;
const date = new Date(intYear, jsMonth, intDay);
isValid = (date.getFullYear() === intYear && date.getMonth() === jsMonth && date.getDate() === intDay ;
}
return isValid ? null : { invalid: 'Invalid date' };
};
How can I restrict the user from putting in future dates.
I used this code with the following line:
isValid = (date.getFullYear() === intYear && date.getMonth() === jsMonth && date.getDate() === intDay ;
But I wonder if there is an easier way without having to copy and past this code over and over again to make small restrictions to it.
Your dateValidator() function should be a function factory (i.e. a function that returns a function) instead of a function that returns the error directly:
export function dateValidator(maxDate: string): ValidatorFn {
// Return a validator function.
return (group: FormGroup): {[key: string]: any} => {
// Re-use your existing validation code here and return the error if any.
// Optionally, use the `maxDate` param to customize the validation:
// entered dates should not go beyond `maxDate`.
};
}
As you can see, you can customize the validator function by passing parameters to the function factory. In my example, I used a maxDate parameter to indicate the furthest date in time that the validator should allow.
In your form model, use this validator by calling the factory with the appropriate value, e.g. :
this.myForm = fb.group({
'date': ['', [Validators.required(), dateValidator('02/20/2017')]]
});
You can see another example of a function factory for a validator in the doc: https://angular.io/docs/ts/latest/cookbook/form-validation.html#custom-validation
I'm using a Kendo Grid / Custom validator editing to validate the a Column in the grid,Actually I'm trying the check the email already exists in the database or not ? to implement it I would like to get ID for the Row.
For example given in reference its products table, so in this case I would to get the ProductID inside the validation function ?
Reference:
http://demos.telerik.com/kendo-ui/grid/editing-custom-validation
You can get the id by retrieving the uid and then getting the data item from the dataSource via dataSource.getByUid(). Each row in the grid has a unique uid generated by the grid.
So for instance, referring to kendo's demo, the validation would now look like this:
productnamevalidation: function (input) {
//get row and uid
var row = input.closest('tr')[0];
var uid = $(row).attr('data-uid');
//get data item and then its ProductID
var dataitem = dataSource.getByUid(uid);
console.log(dataitem);
console.log(dataitem.ProductID);
//continue doing validation
if (input.is("[name='ProductName']") && input.val() != "") {
input.attr("data-productnamevalidation-msg", "Product Name should start with capital letter");
return /^[A-Z]/.test(input.val());
}
return true;
}
Here is their demo with this code included, you can open the console to see that each data row is being printed out with all its model properties.
You can get the record's ID with this:
input[0].kendoBindingTarget.source.ID
For example:
emailUnique: function (input) {
if (input.is("[name=Email]") && input.val() !== "") {
input.attr("data-emailUnique-msg", "Email already exists");
return isEmailUnique(input.val(), input[0].kendoBindingTarget.source.ID);
}
return true;
}
Bonus track, in case it's useful for someone:
function isEmailUnique(val, id) {
var data = YourGridDataSource; // If you don't have it, you may need something like $("#YourGrid").data().kendoGrid.dataSource
for (var i = 0; i < data.length; i++) {
if (data[i].ID != id && data[i].Email == val)
return false;
}
return true;
}
The following constraint is unreliable because new Date() will only be evaluated once, leaving you with a stale max date.
class Foo {
Date date
static constraints = {
date max: new Date()
}
}
So how do you reliably constrain a Date?
Assuming the date cannot be greater than the current date of validation:
static constraints = {
date(validator: { val, obj -> val <= new Date() })
}
Grails validator
I have the requiredFieldValidator configured for one of my columns and it works as expected for existing rows. When I tab thru, or click to begin editing a new row, the validator does not fire when moving off the column. When move off the new row (with no data in the column) so that it commits, and then move back to the row, now the validator works...but ONLY if I put some data in the editor, and then delete it.
In other words, for new rows, the requiredFieldValidator does not do anything until I actually type something in the column. If I leave a column blank it never fires, defeating the purpose of it. Interestingly, the example they provide (http://mleibman.github.com/SlickGrid/examples/example3-editing.html) exhibits the same problem.
This checks for both values being "". I believe this should return true since a validator could be a "required" validator.
this.isValueChanged = function () {
// this needs to validate if both are empty since a validator might be a "required" validator
if ($input.val() == "" && defaultValue == "")
return true;
else
return (!($input.val() == "" && defaultValue == "")) && ($input.val() != defaultValue);
};
Preferred method would be to create a custom editor so you aren't mucking with the core library.
I concur, just encountered this behavior myself.
Here is the solution.
Change this.isValueChanged function contents to the following.
if(($input.val().length > 0) && ($input.val() != defaultValue))
return true;
else if(($input.val() == defaultValue)&&($input.val().length > 0))
return true;
else if(($input.val().length == 0) && ((undefined === defaultValue )||(defaultValue == "")))
return true;
else
return false;
For some reason defaultValue is not set during the first interraction, my guess if you initialize it to "" you would not need to check for undefined.
At any rate defaultValue holds the previous value of the cell, so when it is empty and it is the first cell being edited it is undefined, after that it is set to "" for all other empty cells.
The problem is this function needs to tell the grid that the value has changed in order for the cell editor to validate the input. In the provided implementation the expression always returns false because
$input.val() == "" evaluates to true and then the expression
!($input.val() == "" && defaultValue == null)) evaluates to false
This means defaultValue is continuously undefined.
Hope that makes sense and my code helps you out.
Had the same problem and I believe that ideally defaultValue should be set to undefined or null, when it wasn't initialized. So I've modified TextEditor in a following way:
function TextEditor(args) {
var $input;
var defaultValue;
var scope = this;
this.loadValue = function (item) {
defaultValue = item[args.column.field] || null;
$input.val(defaultValue);
$input[0].defaultValue = defaultValue;
$input.select();
};
this.isValueChanged = function () {
return $input.val() != defaultValue;
};
....
setting default defaultValue to null and simplifying isValueChanged.
There is an error in the first else if of Roman, the return is false. Otherwise, any change in cell returns true even if the value has not been changed.
I tried this and it works.
this.isValueChanged = function () {
var attuale = $input.val();
if((attuale.length > 0) && (attuale != defaultValue))
return true;
else if((attuale == defaultValue)&&(attuale.length > 0))
return false;
else if((attuale.length == 0) && ((undefined === defaultValue )||(defaultValue == "")))
return true;
else
return false;
};