Telerik Forums
UI for ASP.NET MVC Forum
7 answers
788 views
I am working on a UI where I am editing grid in an Ajax Popup Edit. The following data annotations do not work as expected in the popup edit:

 [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }

        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [StringLength(500, ErrorMessage = "Image path cannot be more than 500 characters.")]
        [Display(Name = "Image path")]
        [DataType(DataType.ImageUrl)]
        [RegularExpression(@"^http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$", ErrorMessage = "Image path format is incorrect.")]
        public string ImagePath { get; set; }

Currently for Add/Edit both, I am getting a minimum password length should be 6. Also both for Add and Edit I get "Image path format is incorrect" even when there is nothing typed in that field

In addition to the above
On Edit - I do not want the password to be required. On New I want password to be required.

Thanks
Daniel
Telerik team
 answered on 28 Feb 2014
1 answer
199 views
i have implemented Custom Binding.I get error like "object reference not set to an instance of an object" when Group a column which is complex Type(Order.Name).

public static IEnumerable<AggregateFunctionsGroup> BuildInnerGroup<T, TObject>(IEnumerable<TObject> group, Func<TObject, T> groupSelector, Func<IEnumerable<TObject>, IEnumerable> innerSelector)
{
return group.GroupBy(groupSelector)
.Select(i => new AggregateFunctionsGroup
{
Key = i.Key,
Items = innerSelector(i)
});
}

public static Func<IEnumerable<TObject>, IEnumerable<AggregateFunctionsGroup>> BuildGroup<T, TObject>(Func<TObject, T> groupSelector, Func<IEnumerable<TObject>, IEnumerable<AggregateFunctionsGroup>> selectorBuilder)
{
var tempSelector = selectorBuilder;
return g => g.GroupBy(groupSelector)
.Select(c => new AggregateFunctionsGroup
{
Key = c.Key,
HasSubgroups = true,
Items = tempSelector.Invoke(c).ToList()
});
}

public static IEnumerable<AggregateFunctionsGroup> ApplyGrouping<T>(this IQueryable<T> data, IList<GroupDescriptor> groupDescriptors)
{
Func<IEnumerable<T>, IEnumerable<AggregateFunctionsGroup>> selector = null;
foreach(var descriptor in groupDescriptors.Reverse())
{
var tempDescriptor = descriptor;
if(selector == null)
selector = g => BuildInnerGroup(g.Select(p => p), p => p.GetType().GetProperty(tempDescriptor.Member).GetValue(p, null), i => i.ToList());
else
selector = BuildGroup(p => p.GetType().GetProperty(tempDescriptor.Member).GetValue(p, null), selector);
}

return selector != null
? selector.Invoke(data).ToList()
: null;
}

For simple field it is working well.When I Group a field with complex type(Order.Name) i get the above error in ApplyGrouping function.In debug mode i see in ApplyGrouping function,the tempDescriptor.Member property value is Order.Name.I need to Split the property on dot(.) and make the grouping(like in the sorting which i already implemented for complex type). Please give a suggestion for grouping.i post the same issue in StackOverflow

http://stackoverflow.com/questions/22023649/telerik-grid-custom-bindinggrouping-on-complex-property

Sabbir
Daniel
Telerik team
 answered on 28 Feb 2014
4 answers
541 views
Hi guys, I have this grid:

@(Html.Kendo().Grid<Entity>(Model)
        .Name("valueGrid")
        .ToolBar(commands => commands.Create().Text("Add new value"))
        .Columns(columns =>
        {
            columns.Bound(c => c.DOMAINID).Visible(false);
            columns.Bound(c => c.CODE);
            columns.Bound(c => c.VALUE);
            columns.Command(command => { command.Edit().UpdateText("Save"); command.Destroy().Text("Delete"); });
        })
        //.Events(e => e.SaveChanges("OnSaveChanges"))
        .Sortable()
        .Scrollable()
        .DataSource(dataSource => dataSource       
        .Ajax()
        //.Events(e => e.Error("OnDatasourceError"))
        .ServerOperation(false)      
        .Model(m => m.Id(v => v.CODE))
        .Update(update => update.Action("UpdateValue", "DomainValue"))
        .Create(create => create.Action("CreateValue", "DomainValue"))
        .Destroy(delete => delete.Action("DeleteValue", "DomainValue"))
     )
    )

and I noticed that the delete action is called as soon as the user click on remove command, even if the confirmation popup is displayed.
I need to invoke the action only on the confirm from the user. I search a bit online but everyone is doing this with a custom popup.
I remember, however, that in another project I've done that automatically, but I wasn't using MVC back there.

Thanks
Fabio
Gaetano
Top achievements
Rank 1
 answered on 28 Feb 2014
3 answers
205 views
See gif,

There are 10 rows, but I can't scroll any further, I believe the JS isn't calculating the multi-line column height correctly.
Dimo
Telerik team
 answered on 28 Feb 2014
1 answer
316 views
So I have a kendo Grid and a datasource populated by an ajax call.

the grid has groupable set to true. 
when someone groups by a column I'd like to automatically select the first row in the first group.   I also have a button somewhere outside the group which needs to do the same this.

I am basically trying to make sure the first row in the grid is selected whatever the user is doing, group or not.

grid.table.find('tr:first'); this line correctly identifies the first row BEFORE any group is added but if I try that after the grouping is done it will simply return the first group's header and it's not what I need.

How can I achieve this?
Dimiter Madjarov
Telerik team
 answered on 27 Feb 2014
2 answers
73 views
I recently switched my grid from using the .Read() method to binding to local data.  My grid works fine when there are no items in my IEnumerable to start with.  When I have an item in my IEnumerable, I see two grid areas in IE9, and the submit buttons on my form don't work.  I don't see this behavior in Firefox 27.0.1 or in Chrome.  If I switch back to using the .Read() method the grid displays fine, but I would like to use the local option.  Do I have a configuration issue in my grid that only affects IE with local data, or is this an IE bug?  I have attached an image of how the grid is rendered in IE 9.

Here is my grid configuration:
@(Html.Kendo().Grid<AccountManagement.Business.ViewModels.Areas.DM.RehireDocumentSettingViewModel>(Model.RehireDocuments)
                    .Name("DocumentSettings")
                    .Columns(columns =>
                    {
                        columns.Bound(ds => ds.Form)
                            .ClientTemplate("#= data.Form.Description #" +
                                "<input type='hidden' name='DocumentSettings[#= index(data)#].Form.FormID' value='#= data.Form.FormID #' />"
                            );
                        columns.Bound(ds => ds.DocumentDateType)
                            .ClientTemplate("#= DocumentDateType.Description #" +
                                "<input type='hidden' name='DocumentSettings[#= index(data)#].DocumentDateType.RehireDocumentDateType' value='#= DocumentDateType.RehireDocumentDateType #' />"
                            );
                        columns.Bound(ds => ds.RemoveIfOlderThanDays)
                            .ClientTemplate("#= RemoveIfOlderThanDays #" +
                                "<input type='hidden' name='DocumentSettings[#= index(data)#].RemoveIfOlderThanDays' value='#= RemoveIfOlderThanDays #' />"
                            );
                        columns.Command(command => command.Destroy());
                    }
                    )
                    .ToolBar(toolbar =>
                    {
                        toolbar.Create().Text(AccountManagement.Resources.AccountManagementResources.AddRehireDocumentSettingButtonText);
                    })
                    .Navigatable()
                    .Sortable()
                    .Scrollable()
                    .Editable(editable => editable.Mode(GridEditMode.InCell))
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .Batch(true)
                        .ServerOperation(false)
                        .Events(events => events.Error("error_handler"))
                        .Model(model =>
                            {
                                model.Id(ds => ds.Form.FormID);
                                model.Field(ds => ds.Form).DefaultValue(
                                    ViewData["defaultForm"] as AccountManagement.Business.ViewModels.Areas.DM.FormViewModel);
                                model.Field(ds => ds.DocumentDateType).DefaultValue(
                                    new AccountManagement.Business.ViewModels.Areas.DM.RehireDocumentDateTypeViewModel() {
                                        RehireDocumentDateType = AccountManagement.Models.RehireDocumentDateType.DateTypeNotSpecified
                                    }
                                );
                            }
                        )
                    )
                )

Thanks,
Brian
Brian
Top achievements
Rank 1
 answered on 26 Feb 2014
7 answers
250 views
Hi,
We are using a kendo treeview as our main menu in our MVC app.  It's in our default layout.
The question is, how do we keep the currently selected menu item selected and showing as they navigate from controller/view to controller/view? Should we use cookies? Session? Any sample code would be great!
We are trying to get up to speed on Kendo and want to do thing "right" from the get go.
Any help would be great.
Thanks ... Ed
Dimo
Telerik team
 answered on 26 Feb 2014
1 answer
87 views
Anyone know if this grid can have custom layouts that allow inline editing, but don't cause a popup?  I would like to just rearrange the rows to be stacked, but still be editable. Here is an simple layout example below:

LastName     Phone
FirstName     Email
Alexander Popov
Telerik team
 answered on 26 Feb 2014
1 answer
324 views
I am trying to implement a custom validator to require that a user enter a certain number of rows in my grid.  I am applying the validation attribute to the IEnumerable<T> that provides the rows for my grid.  The validation code gets called on the server side, but on the client side I don't see the data- properties anywhere in the page.  Is it possible to run a client-side validator for the grid as a whole?  If so, what do I need to do so that the client-side code is run?  I'm guessing that because there is no direct reference from the grid to the property, that the client-side validation is not being wired up.  Is there a way to work around this?  Could I bind the grid directly to the property somehow instead of going through the .Read() AJAX method to get the data?   

Here is my validation attribute:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class RequiredCountAttribute : ValidationAttribute, IClientValidatable
    {
        public const int NotRequiredCount = -1;
        private int minCount;
        private int maxCount;
 
        public string MinErrorMessage { get; set; }
        public string MaxErrorMessage { get; set; }
 
        public RequiredCountAttribute(int minCount, int maxCount = NotRequiredCount)
            : base()
        {
            this.minCount = minCount;
            this.maxCount = maxCount;
        }
 
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                IEnumerable list = (IEnumerable)value;
 
                int count = 0;
                foreach (object o in list)
                    count++;
 
                if (count < minCount)
                {
                    string errorMessage = FormatErrorMessage(validationContext.DisplayName);
                    return new ValidationResult(errorMessage);
                }
 
                if (maxCount != NotRequiredCount && count > maxCount)
                {
                    string errorMessage = FormatErrorMessage(validationContext.DisplayName);
                    return new ValidationResult(errorMessage);
                }
            }
            return ValidationResult.Success;
        }
 
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule();
            rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
            rule.ValidationType = "requiredcount";
            rule.ValidationParameters.Add("mincount", minCount);
            if (maxCount != NotRequiredCount) rule.ValidationParameters.Add("maxcount", maxCount);
            yield return rule;
        }
    }


Here is the JavaScript piece:
(function ($, kendo) {
    $.extend(true, kendo.ui.validator, {
        rules: { // custom rules
            requiredCount: function (input, params) {
                //check for the rule attribute
                if (input.filter("[data-val-requiredcount]").length && input.val()) {
                    var minCount = $(input).attr('data-val-requiredcount-mincount');
                    var maxCount = $(input).attr('data-val-requiredcount-maxcount');
 
                    if (input.val() < minCount)
                        return false;
 
                    if (maxCount !== undefined && input.val() > maxCount)
                        return false;
                }
                return true;
            }
        },
        messages: { //custom rules messages
            requiredCount: function (input) {
                // return the message text
                return input.attr("data-val-requiredcount");
            }
        }
    });
})(jQuery, kendo);

Here is my grid definition:
@(Html.Kendo().Grid<AccountManagement.Business.ViewModels.Areas.DM.RehireDocumentSettingViewModel>()
                    .Name("DocumentSettings")
                    .Columns(columns =>
                    {
                        columns.Bound(ds => ds.Form)
                            .ClientTemplate("#= data.Form.Description #" +
                                "<input type='hidden' name='DocumentSettings[#= index(data)#].Form.FormID' value='#= data.Form.FormID #' />"
                            );
                        columns.Bound(ds => ds.DocumentDateType)
                            .ClientTemplate("#= DocumentDateType.Description #" +
                                "<input type='hidden' name='DocumentSettings[#= index(data)#].DocumentDateType.RehireDocumentDateType' value='#= DocumentDateType.RehireDocumentDateType #' />"
                            );
                        columns.Bound(ds => ds.RemoveIfOlderThanDays)
                            .ClientTemplate("#= RemoveIfOlderThanDays #" +
                                "<input type='hidden' name='DocumentSettings[#= index(data)#].RemoveIfOlderThanDays' value='#= RemoveIfOlderThanDays #' />"
                            );
                        columns.Command(command => command.Destroy());
                    }
                    )
                    .ToolBar(toolbar =>
                    {
                        toolbar.Create().Text(AccountManagement.Resources.AccountManagementResources.AddRehireDocumentSettingButtonText);
                    })
                    .Navigatable()
                    .Sortable()
                    .Scrollable()
                    .Editable(editable => editable.Mode(GridEditMode.InCell))
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .Batch(true)
                        .ServerOperation(false)
                        .Events(events => events.Error("error_handler"))
                        .Model(model =>
                            {
                                model.Id(ds => ds.Form.FormID);
                                model.Field(ds => ds.Form).DefaultValue(
                                    ViewData["defaultForm"] as AccountManagement.Business.ViewModels.Areas.DM.FormViewModel);
                                model.Field(ds => ds.DocumentDateType).DefaultValue(
                                    new AccountManagement.Business.ViewModels.Areas.DM.RehireDocumentDateTypeViewModel() {
                                        RehireDocumentDateType = AccountManagement.Models.RehireDocumentDateType.DateTypeNotSpecified
                                    }
                                );
                            }
                        )
                        .Read("RehireDocumentSetting_Read", "RehireSetup")
                    )
                )


Any help would be appreciated.

Thanks,
Brian
Petur Subev
Telerik team
 answered on 24 Feb 2014
4 answers
193 views
Hi. New here.

Below is a ListView and a DropDownList, as simple as possible, calling the same Web API for their data. 

The DropDownList works well. The ListView does show anything. What am I doing wrong?

The ListView API call is: http://localhost/api/vehicles?sort=&group=&filter=
The DropDownList API call is : http://localhost/api/vehicles

I would have assumed the .ServerOperation(false) would have removed the sort&group&filter from the Get. In any case, the JSON returned by both Gets is exactly the same. 

Thanks

PS: in case this is relevant, the Web API controller was generated by the Telerik Data Access Wizard and unmodified

<script type="text/x-kendo-template" id="vehicletemplate">
    <div>
        <p>Dummy Placeholder</p>
    </div>
</script>
 
<div class="col-md-4">
    @(Html.Kendo().ListView<Object>().Name("VehicleList")
        .ClientTemplateId("vehicletemplate")
        .TagName("div")
        .DataSource(ds => ds
            .ServerOperation(false)
            .Read(read => read
                .Url("/api/vehicles").Type(HttpVerbs.Get)
            )
        )
    )
 
    @(Html.Kendo().DropDownList()
        .Name("ddList")
        .DataTextField("Registration")
        .DataSource(ds => ds
            .Read(read => read
            .Url("/api/vehicles").Type(HttpVerbs.Get)
            )
        )
    )
</div>
Daniel
Telerik team
 answered on 24 Feb 2014
Narrow your results
Selected tags
Tags
+? more
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Rob
Top achievements
Rank 3
Iron
Iron
Iron
Atul
Top achievements
Rank 1
Iron
Iron
Iron
Alexander
Top achievements
Rank 1
Veteran
Iron
Serkan
Top achievements
Rank 1
Iron
Shawn
Top achievements
Rank 1
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?