How to Access the ID from Kendo Model in KendoGrid / Custom validator editing? - 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;
}

Related

hide forms tab in a form head crm dynamics 365

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);
});
},

Refresh a single Kendo grid row

Is there a way to refresh a single Kendo grid row without refreshing the whole datasource or using jQuery to set the value for each cell?
How do you define the row that you want to update? I'm going to assume that is the row that you have selected, and the name of the column being updated is symbol.
// Get a reference to the grid
var grid = $("#my_grid").data("kendoGrid");
// Access the row that is selected
var select = grid.select();
// and now the data
var data = grid.dataItem(select);
// update the column `symbol` and set its value to `HPQ`
data.set("symbol", "HPQ");
Remember that the content of the DataSource is an observable object, meaning that you can update it using set and the change should be reflected magically in the grid.
data.set will actually refresh the entire grid and send a databound event in some cases. This is very slow and unnecessary. It will also collapse any expanded detail templates which is not ideal.
I would recommend you to use this function that I wrote to update a single row in a kendo grid.
// Updates a single row in a kendo grid without firing a databound event.
// This is needed since otherwise the entire grid will be redrawn.
function kendoFastRedrawRow(grid, row) {
var dataItem = grid.dataItem(row);
var rowChildren = $(row).children('td[role="gridcell"]');
for (var i = 0; i < grid.columns.length; i++) {
var column = grid.columns[i];
var template = column.template;
var cell = rowChildren.eq(i);
if (template !== undefined) {
var kendoTemplate = kendo.template(template);
// Render using template
cell.html(kendoTemplate(dataItem));
} else {
var fieldValue = dataItem[column.field];
var format = column.format;
var values = column.values;
if (values !== undefined && values != null) {
// use the text value mappings (for enums)
for (var j = 0; j < values.length; j++) {
var value = values[j];
if (value.value == fieldValue) {
cell.html(value.text);
break;
}
}
} else if (format !== undefined) {
// use the format
cell.html(kendo.format(format, fieldValue));
} else {
// Just dump the plain old value
cell.html(fieldValue);
}
}
}
}
Example:
// Get a reference to the grid
var grid = $("#my_grid").data("kendoGrid");
// Access the row that is selected
var select = grid.select();
// and now the data
var data = grid.dataItem(select);
// Update any values that you want to
data.symbol = newValue;
data.symbol2 = newValue2;
...
// Redraw only the single row in question which needs updating
kendoFastRedrawRow(grid, select);
// Then if you want to call your own databound event to do any funky post processing:
myDataBoundEvent.apply(grid);
I found a way to update the grid dataSource and show in the grid without refreshing all the grid.
For example you have a selected row and you want to change column "name" value.
//the grid
var grid = $('#myGrid').data('kendoGrid');
// Access the row that is selected
var row = grid.select();
//gets the dataItem
var dataItem = grid.dataItem(row);
//sets the dataItem
dataItem.name = 'Joe';
//generate a new row html
var rowHtml = grid.rowTemplate(dataItem);
//replace your old row html with the updated one
row.replaceWith(rowHtml);
updateRecord(record) {
const grid = $(this.el.nativeElement).data('kendoGrid');
const row = grid.select();
const dataItem = grid.dataItem(row);
for (const property in record) {
if (record.hasOwnProperty(property)) {
dataItem.set(property, record[property]);
}
}
}

How do I Get Full Html Field Name for an item in a list on my model at controller level?

*First Post
I have a JQuery error handler for my Ajax posts that I must use, it appends an error to the html based on the field name for that element like this
$(document).ready(function () {
function myHandler(e, error) {
var tag = "";
if (error.Success == true) { $('.field-validation-error').remove(); return; } // if success remove old validation and don't continue
if (error.Success == false) { $('.field-validation-error').remove(); } // if success remove old validation and continue
for (i = 0; i < error.Errors.length; i++) {
var t = error.Errors[i];
//get error key and assign it to id
tag = t.Key;
//clear down any existing json-validation
for (j = 0; j < t.Value.length; j++) {
//this part assumes that our error key is the same as our inputs name
$('<span class="field-validation-error">' + t.Value[j].ErrorMessage + '</span>').insertAfter('input[name="' + tag + '"], textarea[name="' + tag + '"], select[name="' + tag + '"], span[name="' + tag + '"]');
}
}
}
$.subscribe("/******/errors", myHandler);
});
This works perfectly out of the box with our fluent validation setup until I try to add a custom modelstate error at controller level like so:
foreach (var item in model.Locations)
{
var cityRepos = new CityRepository(NhSession);
var cityItem = cityRepos.GetAll().FirstOrDefault(o => o.Country.Id == item.CountryID && o.Name == item.City);
if (cityItem == null)
item.City
ModelState.AddModelError("City", string.Format(#"The city ""{0}"" was not found, please ensure you have spelt it correctly. TODO: add a mail to link here with city not found subject", item.City));
}
the problem is that the modelstate error needs to be attached to the html field name not my magic string "City". The html name property is MVC Generated and looks something like this:
name="Locations[0].City"
I have encountered this problem in a html helper before and used the method:
.GetFullHtmlFieldName(
ExpressionHelper.GetExpressionText(propertySelector)
);
which resolved my problem in that case.
My question is can I use this method on my model property in an MVC post action to obtain the html name property it has come from?
Thanks in advance
ok so it's not ideal but I have implemented this Helper method until I can find a better solution that doesn't involve magic strings:
public static class ModelStateErrorHelper
{
public static string CreateNameValidationAttribute(string collectionName, int index, string propertyName)
{
string template = "{0}[{1}].{2}";
return string.Format(template, collectionName, index.ToString(), propertyName);
}
}

Obtaining a hidden column value from the selected row in a Telerik RadGridView

How do I obtain the selected row value for a hidden column in a Telerik RadGridView? The column is hidden on the aspx page and I would like to retrieve the value on the client side (JavaScript).
Essentially, I want to display a name in the grid view and be able to retrieve a value from the hidden field "ID" to bring up an edit form.
Here is an example of how I'm hiding the RadGridView column.
code sample:
onKeyPressEvent(sender, args) {
var variable = function (e) {
e = e || window.event;
if (e.keyCode == 13) {
var PartyID = args.getDataKeyValue("PARTY_ID");
var oManager = '<%=winMgr.ClientID %>';
var oManager = window.radopen("AttorneyEdit.aspx?PARTY_ID=" + PartyID, null);
oManager.setSize(1000, 530);
//Width, Height oManager.center();
} else { return true;
}
}
theForm.onkeypress = variable
}
Thanks for your help...
maybe you're going the wrong way. There is a property called "ClientDataKeyNames" on the mastertableview. You can add several key separated by a comma in this property. Then you'll be able to get your value without adding an extra column.
You should do something like this:
function onKeyPressEvent(sender, args) {
if (args.get_keyCode() == 13) {
var dataItem=sender.get_selectedItems()[0];
var PartyID = dataItem.getDataKeyValue("PARTY_ID");
var oManager = '<%=winMgr.ClientID %>';
var oManager = window.radopen("AttorneyEdit.aspx?PARTY_ID=" + PartyID, null);
oManager.setSize(1000, 530);
//Width, Height oManager.center();
}
else {
return true;
}
}
good luck

How can I find the checked rows in a YUI DataTable?

I'm using a YUI DataTable with a checkbox column like this:
var myColumnDefs = [
{key:"check", label:'', formatter:"checkbox"},
{other columns...}
];
How can I iterate over all the rows that have been checked?
UPDATE:
Here is my current work-around:
function getCheckedIds() {
var records = yuiDataTable.getRecordSet().getRecords();
var ids = '';
for (i=0; i < records.length; i++) {
var checked = false;
if (records[i] != undefined)
{
checked = $('#' + records[i].getId() + ' td div.yui-dt-liner input.yui-dt-checkbox').attr('checked');
if (checked) {
if (ids != '') {
ids += ',';
}
ids += records[i].getData("item.id");
}
}
}
return ids;
}
A better approach might be to subscribe to the checkboxClickEvent of the Datatable, then when a check box is selected (or unselected) programmatically mark the row as selected using the selectRow/unselectRow method of the Datatable. If you do this, it looks better in the UI (the rows are highlighted) and it is easy to get the selected rows using the getSelectedRows method of the Datatable.

Resources