how to add unique username in kendo ui and show alert or message after this insert duplicate username - model-view-controller

I want to use kendo ui for manage the users in asp.net mvc and i need that kendo ui don't create duplicate username and display the error message that "the user name is duplicate"
this is my action for create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddNewCountry([DataSourceRequest]DataSourceRequest request, CountryViewModel c,int countryId)
{
if (c != null && ModelState.IsValid)
{
countryService.Create(c);
}
return Json(new[] { c }.ToDataSourceResult(request, ModelState));
}
Thanks in advance for your help

I sent you a solution in your other post (see here). But here is how you handle SERVER side errors using the kendo CLIENT grid. Some of these steps could be changed. For example, you could popup an alert instead of displaying the error on the editor template.
1) Add a model state error to your action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddNewCountry([DataSourceRequest]DataSourceRequest request, CountryViewModel c,int countryId)
{
if (countryService.UserExists(c.UserName) // You need to code this
{
ModelState.AddModelError("UserName", "User name already exists.");
}
if (c != null && ModelState.IsValid)
{
countryService.Create(c);
}
return Json(new[] { c }.ToDataSourceResult(request, ModelState));
}
Handle the error event on your DataSource:
#(Html.Kendo().Grid<OrderDetailViewModel>()
.Name("orderDetailsGrid")
/* Not relevant grid setup code... */
.DataSource(dataSource => dataSource
.Ajax()
.Read(builder => builder.Url("/api/CustomerOrderDetails/GetOrderDetails/" + Model.OrderId).Type(HttpVerbs.Get))
.Create(builder => builder.Url("/api/CustomerOrderDetails/CreateOrderDetail/" + Model.OrderId).Type(HttpVerbs.Put))
.Update(builder => builder.Url("/api/CustomerOrderDetails/UpdateOrderDetail").Type(HttpVerbs.Post))
.Destroy(builder => builder.Url("/api/CustomerOrderDetails/DeleteOrderDetail").Type(HttpVerbs.Delete))
.Model(model => {
model.Id(x => x.OrderDetailId);
model.Field(m => m.OrderDetailId).DefaultValue(0);
})
.Events(events => events.Error("OrderDetails_Error"))
))
3) Add a placeholder for the errors to your editor template:
<ul class="errors"></ul>
4) Setup a kendo template to process the errors:
<script type="text/x-kendo-template" id="orderDetailsValidationMessageTemplate">
# if (messages.length) { #
<li>#=field#
<ul>
# for (var i = 0; i < messages.length; ++i) { #
<li>#= messages[i] #</li>
# } #
</ul>
</li>
# } #
</script>
Write the js error handler that will look at the server errors returned and format them into a template that can be displayed on the editor page:
OrderDetails_Error = function(args) {
if (args.errors) {
var grid = $("#orderDetailsGrid").data("kendoGrid");
var validationTemplate = kendo.template($("#orderDetailsValidationMessageTemplate").html());
grid.one("dataBinding", function(e) {
e.preventDefault();
$.each(args.errors, function(propertyName) {
// take the template and insert it into the placeholder
var renderedTemplate = validationTemplate({ field: propertyName, messages: this.errors });
grid.editable.element.find(".errors").append(renderedTemplate);
});
});
}
};

Related

Controller return incorrect data with ajax ActionLink in mvc

several days ago with searching i put an ajax button inside my page, but i didn't know the issue till now, the thing is happen, is that the result i receive is not the result from ajax redirection, but is result from first processing (though i was wonder why it do it twist)...
And what i wanna do is perform filtering through link button instead of button.
so i have two action, one is for my ajax button, and second for my index:
1.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ChooseCategoryAction(int? id)
{
Monitor.Enter(monitorObj);
// Save code here...
Session.Add("FilterCategory", id);
return RedirectToAction("Index");
}
2.
public override ActionResult Index()
{
.
.
.
int? id = (Session["FilterCategory"] != null) ? int.Parse(Session["FilterCategory"].ToString()) : (int?)null;
List<LinkEntity> filterList = null;
int catId = id ?? -1;
if (catId != -1)
{
filterList = new List<LinkEntity>();
foreach (LinkEntity linkEntity in linkList.Where(
where =>
(catId == 0 && #where.Category == null) ||
(#where.Category != null && #where.Category.Id == catId)).Select(
select =>
new LinkEntity(#select.Id, #select.Name, #select.Link, #select.Description,
#select.Category)))
{
filterList.Add(linkEntity);
}
}
else
{
filterList = linkList;
}
return View(filterList);
}
My View is like this:
<div class="split-left">
#if (ViewBag.CategoriesTags != null)
{
foreach (var cat in ViewBag.CategoriesTags)
{
<div class="link-item-category">
#using (Html.BeginForm())
{
#Ajax.ActionLink((string)cat.Name, "ChooseCategoryAction","Home", new { id = cat.Id }, new AjaxOptions { HttpMethod = "POST" }, new{#class = "category-link"})
}
</div>
}
}
</div>
When i click the link it should goes to Ajax method, then inbox, filter my data and return a view, but it first goes to inbox, then to Ajax, again to inbox, next it goes value seem to be true, but result which return is incorrect
i also before reaching to filtering step, tried following:
#Html.Hidden(((int)cat.Id).ToString())
#Html.ActionLink((string)cat.Name, "ChooseCategoryAction", "Home", null, new { #class = "category-link", onclick = "return false;" })
with following script:
<script type="text/javascript">
$(document).ready(function () {
$('.category-link').click(function () {
$(this).closest('form')[0].submit();
});
});
</script>
But it don't return to controller or don't refresh page

MVC 3 validation: want to turn my labels red that correspond to controls that failed validation

I am using MVC 3 validation. My Product Manager wants the label for each control that has an error to turn red.
So 'Student First Name' label should turn red. 'Email address' label should turn red.
I tried to wrap each error msg in a div and check the length of each div
<div id="divValStudentFirstName">#Html.ValidationMessageFor(m => m.studentFirstName)</div>
in a js file:
$(document).ready(function () {
if ($("#divValStudentFirstName").length > 1) {
("#divStudentFirstName").css("color", "red");
}
But I have no success. The validation check is done without a complete refresh and as a result, my $(document).ready isn't fired when validation hits.
Client side validation disabled :
public static IHtmlString ValidationLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText = null) {
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
var name = ExpressionHelper.GetExpressionText(expression);
string resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? name.Split('.').Last();
if (String.IsNullOrEmpty(resolvedLabelText)) {
return MvcHtmlString.Empty;
}
var tag = new TagBuilder("label");
tag.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name)));
tag.GenerateId(name);
tag.SetInnerText(resolvedLabelText);
ModelState modelState;
string fullName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (html.ViewData.ModelState.TryGetValue(fullName, out modelState)) {
if (modelState.Errors.Count > 0) {
tag.Attributes.Add("style", "color:red");
}
}
return new MvcHtmlString(tag.ToString());
}
EDIT
Client side validation enabled
I'm really not a king in js, but this seems to work (well on a simple case at least)
$('form').submit(function () {
var form = $(this);
$('label').removeClass('field-validation-error');
if (!form.valid()) {
$('.input-validation-error')
.each(function () {
$("label[for='" + $(this).attr("id") + "']").addClass('field-validation-error');
});
}
});
Below is a JQuery function that will color the containing div tag by adding (or removing) an error class when the submit button is clicked. It can easily be changed to add the class to the label.
$('form').submit(function () {
if ($(this).valid()) {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length == 0) {
$(this).removeClass('error-colored');
}
});
}
else {
$(this).find('div.form-group').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('error-colored');
}
});
}
});

Url passing in telerik asp.net mvc panel

I m using Telerik Panel bar in mvc3, and i am facing a problem while passing Url??
can anyone please help me how can i pass Url in my view.
You need to bring controller/Action name dynamically in you model and create and pass the url
.Items(sub =>
{
for (int i = 0; i < Model.Count(); i++)
{
sub.Add().Text(Model.ElementAt(i).DisplayText)
.Url(Url.Action(Model.ElementAt(i).ActionName, Model.ElementAt(i).ControllerName, new { id = Model.ElementAt(i).IDParam }))
}});
If I understand your question correctly, I did something similiar to this using the PanelBar and Grid.In the panel bar, put a js function in the OnSelect event:
Html.Telerik().PanelBar()
.Name("PanelBar")
.ClientEvents(events =>
{
events.OnSelect("getEvent");
})
.Items(panelbar =>
{
panelbar.Add()
.Text("Header Text")
.Expanded(true)
.Items(item =>
{
item.Add()
.Text("Test1");
item.Add()
.Text("Test2");
});
}).Render();
In the getEvent function, assign a variable to each item and make an ajax post to an actionresult on your controller or something. In my case I just made the grid rebind.
function getEvent(e) {
panelItem = $(e.item).text();
if (panelItem == "Test1") {
var eventid1 = 1;
}
if (panelItem == "Test2") {
var eventid2 = 2;
}
//make ajax post here or something
$('#TheGrid').data('tGrid').rebind();
// $.ajax({
// url: '/Controller/Action',
// type: 'POST',
// data: {
// eventid1: eventid1,
// eventid2: eventid2,
// panelItem: panelItem
// }
// });
}
and in your controller make a conditional statement for the eventids and perform the action you want.
Hope this helps.

Save Grid Layout Data

I have this in grid settings:
var gridLayoutRepository = new GridLayoutRepository();
settings.ClientLayout = (s, e) =>
{
Debug.Write(e.LayoutData);
if (e.LayoutMode == ClientLayoutMode.Loading)
{
e.LayoutData = gridLayoutRepository.Load();
}
else
{
gridLayoutRepository.Save(e.LayoutData);
}
};
I want to have one button for saving gridstate in database and one button for resetting it. Can you help me?
This is possible this way. In grid settings must save grid state:
settings.ClientLayout = (s, e) =>
{
if (e.LayoutMode == ClientLayoutMode.Loading)
{
if (Session["myGridState"] != null)
e.LayoutData = (string)Session["myGridState"];
}
else
Session["myGridState"] = e.LayoutData;
};
Then on button click you should save grid state like this:
<script type="text/javascript">
function SaveLayoutData() {
$.getJSON("#Url.Action("SaveLayoutData", "MyController" })", null,
function (result) {
if(result == 'success') {
alert("Layout save success");
}
});
}
</script>
In Controller:
public JsonResult SaveLayoutData()
{
_gridStateRepository.Save(Session["myGridState"]);
return Json("success", JsonRequestBehavior.AllowGet);
}
When you are loading grid you should load grid state from database and write it in Session["myGridState"]

Telerik Mvc Grid and AntiForgeryToken

I'm trying to set things up with my grid such that every action that every ajax post will include an antiforgery token. My gird is set up like so:
#(Html.Telerik().Grid(Model)
.Name("Folks")
.Sortable(x => x.SortMode(GridSortMode.SingleColumn))
.PrefixUrlParameters(false)
.Footer(true)
.Pageable(x => x.PageSize(25).Total((int)ViewData["total"]))
.DataBinding(dataBinding => dataBinding.Ajax())
.Columns(columns =>
{
columns.Bound(o => o.FirstName).Width(120).Title("First Name");
columns.Bound(o => o.LastName).Width(120).Title("Last Name");
})
.Selectable()
.ClientEvents(events =>
{
events.OnDataBinding("Test");
})
)
The handler for OnDataBinding (Test) looks like so:
<script type="text/javascript">
function Test(e) {
var valTokenValue = $("input[name=__RequestVerificationToken]").val();
e.data = { __RequestVerificationToken: valTokenValue };
}
</script>
I thought the argument (e) had a property called data which accepted a dictionary of values. However, FireBug keeps complaining saying that "data is undefined". Any ideas how I can include the token with every request? I'm using version 2011.Q2.712. Thanks.
It can't attach your token if there is no object to attach to. Create a Json object and set it to data if data is null/length=0/undefined (I know, overkill on the checking). I did the checking in a separate function so I wouldn't have to repeat the check every time I made an ajax call.
(function (TelerikGrid, $, undefined) {
TelerikGrid.OnDataBinding = function (e) {
e.data = AntiForgery.AddToken(e.data);
};})(window.TelerikGrid = window.TelerikGrid || {}, jQuery);
(function (AntiForgery, undefined) {
AntiForgery.AddToken = function (data) {
data = ((data == null || data.length == 0 || data == undefined) ? { } : data);
data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
return data;
};
})(window.AntiForgery = window.AntiForgery || {});

Resources