how to bind drop down in edit template of kendo scheduler? - kendo-ui

I am working on kendo scheduler and I need to add some extra text box and dropdowns to the create and edit of scheduler. I know extra dropdown can be added by adding the resource to scheduler, but in case of adding extra text box we have to add edit template. but in custom template I am not able to add the dropdown list for user appointment type with color specification. I have added a simple drop-down but with no color specification. I have this so far:
here is my .cshtml view code
#model List<FW.Model.UserColor>
#using Kendo.Mvc.UI;
#using Fairwater.UI.Filters
#using FW.Common.Helper
#using Fairwater.UI.Helper
<h5>Scheduler</h5>
<div class="row">
<div class="col-md-12">
#(Html.Kendo().Scheduler<FW.Model.Appointments>()
.Name("scheduler1")
.Date(new DateTime(2015, 11, 11))
.Editable(e => e.TemplateId("editor").Create(true).Confirmation(true))
.Height(600)
.Width(1000)
.EndTime(new DateTime(2025,11,11,7,00,00))
.Views(views =>
{
// views.DayView();
// views.WeekView(weekView => weekView.Selected(true));
views.MonthView(monthviw=>monthviw.Selected(true));
})
.Timezone("Etc/UTC")
//.Resources(resource =>
// {
// resource.Add(m => m.BackgroundId)
// .Title("Background")
// .DataTextField("BackgroundName")
// .DataValueField("BackgroundId")
// .Name("Background")
// .DataColorField("Color")
// .DataSource(x => x.Read(rs => rs.Action("GetBackgroundTypes", "Schedule", new { area = "Crew" })));
// })
.DataSource(d => d
.Model(m =>
{
m.Id(f => f.AppointmentId);
m.Field(f => f.Title).DefaultValue("No title");
// m.RecurrenceId(f => f.RecurrenceID);
m.Field(f => f.Title).DefaultValue("No title");
})
.Read("CrewSchedulerRead", "Schedule")
.Create("CreateAppointment", "Schedule")
.Destroy("Appointment_Destroy", "Schedule")
.Update("Appointment_Update", "Schedule")
.Events(x => x.Error("expError"))
)
)
</div>
</div>
<script id="editor" type="text/x-kendo-template">
<div class="k-edit-label">
<label for="title">Subject</label>
</div>
<div class="k-edit-field" data-container-for="title">
<input type="text" class="k-input k-textbox" name="title" data-bind="value: title">
</div>
<div class="k-edit-label">
<label for="title">Location</label>
</div>
<div class="k-edit-field" data-container-for="Location">
<input type="text" class="k-input k-textbox" name="Location" data-bind="value: Location" style="width:100%;">
</div>
<div class="k-edit-label">
<label for="BackgroundId">Background</label>
</div>
<div data-container-for="BackgroundId" class="k-edit-field">
<select id="BackgroundId" data-bind="value:BackgroundId" data-template="" data-role="dropdownlist" data-value-field="value" data-text-field="text">
#foreach (var item in Model)
{
<option style="background-color:red" value="#item.BackgroundId">#item.BackgroundName</option>
}
</select>
</div>
<div class="k-edit-label">
<label for="recurrenceRule">Repeat</label>
</div>
<div class="k-edit-field" data-container-for="recurrenceRule">
<div data-bind="value: recurrenceRule" name="recurrenceRule" data-role="recurrenceeditor"></div>
</div>
</script>
I don't now am I on the right path or not, but I think I am close of it.
Thats what I have till now
That's what I want more, the color dorpdown. Any help or suggestion would be appreciated. Thanks in advance. If anything not clear about my question please let me know in comments, I will happy to explain. Please help.

you can add how many dropdowns or any other controls using resourses as
.Resources(resource =>
{
resource.Add(m => m.OwnerID)
.Title("Trainers")
.DataTextField("EMPNAME")
.DataValueField("EMPID")
.DataColorField("COLORCODE")
.BindTo(#ViewBag.trainers);
resource.Add(m => m.TypeID)
.Title("Type")
.Name("maintype")
.DataTextField("TYPENAME")
.DataValueField("TYPECODE")
.BindTo(#ViewBag.lsttypes);
})

Related

Aurelia validation nor working when data is pre-populated in the form

I have been unable to get the validation to work on an edit model-view that has data bound to it in the activate method of its view-model.
I have a created.ts which works on an object with the same fields. This file has almost the same code - the exception is that since this one is a create, no data needs to be loaded to it. In this case, the validation is working properly.
If I comment the code that loads the data for the edit model-view - in the activate method - the validation works properly.
Needless to say I am new to SPA, Aurelia and TypeScript and need some help!!
Below is the code in edit.ts
import { ContactRepository } from "./contactRepository";
import { autoinject } from "aurelia-framework";
import { ContactForEditDto } from "./contactForEditDto";
import { json } from "aurelia-fetch-client";
import { inject, NewInstance } from "aurelia-dependency-injection";
import { ValidationRules, ValidationControllerFactory, validateTrigger,
Validator } from "aurelia-validation";
#autoinject
export class Edit {
public saveStatusMessage: string;
public isSaved: number = -1;
private controller = null;
private validator = null;
public canSave: boolean = false;
constructor(public contactForEdit: ContactForEditDto, private repository:
ContactRepository, private controllerFactory: ValidationControllerFactory,
public contactFullName: string, validator: Validator) {
console.log("starting edit controller");
this.controller = controllerFactory.createForCurrentScope(validator);
this.controller.validateTrigger = validateTrigger.changeOrBlur;
this.validator = validator;
this.controller.subscribe(event => this.validateWhole());
ValidationRules
.ensure((c: ContactForEditDto) => c.contactFirstName)
.displayName("First Name")
.required().withMessage("\${$displayName} cannot be empty.")
.maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")
.ensure((c: ContactForEditDto) => c.contactLastName)
.displayName("Last Name")
.required().withMessage("\${$displayName} cannot be empty.")
.maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")
.ensure((c: ContactForEditDto) => c.contactEmailAddress)
.displayName("Email Address")
//.required().withMessage("\${$displayName} cannot be empty.")
.email().withMessage("\${$displayName} needs to be in a correct email address format.")
.maxLength(50).withMessage("\${$displayName} cannot have more than 50 characters.")
.ensure((c: ContactForEditDto) => c.contactPhoneNumber)
.displayName("Phone Number")
.required().withMessage("\${$displayName} cannot be empty.")
.maxLength(12).withMessage("\${$displayName} cannot have more than 12 characters.")
.matches(/\d{3}-\d{3}-\d{4}/).withMessage("'${$value}' is not a valid \${$displayName}. Please enter a phone in the format xxx-xxx-xxxx")
.on(ContactForEditDto);
}
// source https://www.jujens.eu/posts/en/2017/Jan/24/aurelia-validation/
workaround 3
validateWhole() {
this.validator.validateObject(this.contactForEdit)
.then(results => this.canSave = results.every(result => result.valid));
}
// Returning data from here because I can return a promise
// and let the router know when i have retrieved my initial data.
// Activate receives a params object as defined in the route.
activate(params) {
console.log("ACTIVATE ON EDIT PARAMS:" + params);
this.repository
.getById(params.id)
.then(data => {
console.log(data);
this.contactForEdit = data;
this.contactFullName = this.contactForEdit.contactLastName + ", " +
this.contactForEdit.contactFirstName; // This needs to come from a method
in
contact.
});
}
edit() {
this.saveStatusMessage = "";
this.isSaved = -1;
// This will be an edit
if (this.contactForEdit.contactId >= 1) {
this.repository
.update(this.contactForEdit)
.then(response => {
if (((response.status == 201) || (response.status == 204))
&& (response.ok == true)) {
this.isSaved = 1;
this.saveStatusMessage = "Successfully saved the contact";
}
else {
this.isSaved = 0;
//response.json().then(json => this.retVal = json);
//TODO: get more details about the error.
if (response.status == 400) {
this.saveStatusMessage = "Unable to save the contact. Please make sure that you entered correct values for every field and try again.";
}
else {
this.saveStatusMessage = "Unable to save the contact.";
}
}
});
}
}
clearContactFields() {
this.contactForEdit = new ContactForEditDto(-1, "", "", "", "");
}
}
Below is the code in edit.html
<template>
<form id="editContact" submit.delegate="edit()">
<!-- placeholder for status messages. If equal to 1 display it. If equals to
-1 or 1 hide this.-->
<div id="successStatusMessage" class.bind="isSaved == 1 ? 'visible' :
'hidden'">
<div id="divSuccessMessage" class="alert alert-success">
×
<!--<span class="glyphicon glyphicon glyphicon-ok" aria-hidden="true">
</span> TODO: How to get the glyphicon working? -->
<span class="sr-only"> Success:</span> ${saveStatusMessage}
</div>
</div>
<!-- placeholder for status messages. If equal to 0 is in error, so dislay error message. if equals to -1 or 1 hide this.-->
<div id="errorStatusMessage" class.bind="isSaved == 0 ? 'visible' : 'hidden'">
<!-- placeholder for status messages. -->
<div id="divErrorMessage" class="alert alert-danger">
×
<!-- <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> TODO: class="glyphicon glyphicon-exclamation-sign" how to get these in here for class? -->
<span class="sr-only"> Error:</span> ${saveStatusMessage}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
<!--<div if.bind="isCreate">
"Create a Contact"
</div>
<div if.bind="!isCreate">
Edit ${contactForEdit.contactFirstName}
</div>-->
${ "Edit " + contactFullName }
</div>
</div>
<div class="panel-body">
<div class="form-horizontal">
<div class="form-group" validation-errors.bind="editFirstNameErrors"
class.bind="editFirstNameErrors.length ? 'has-error' : ''">
<label class="control-label col-md-2">First Name: </label>
<div class="col-md-10">
<input type="text"
placeholder="First Name"
class="form-control"
value.bind="contactForEdit.contactFirstName & validate" required /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editFirstNameErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<div class="form-group" validation-errors.bind="editLastNameErrors"
class.bind="editLastNameErrors.length ? 'has-error' : ''">
<label class="control-label col-md-2">Last Name: </label>
<div class="col-md-10">
<input type="text"
placeholder="Last Name"
class="form-control"
value.bind="contactForEdit.contactLastName & validate" required /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editLastNameErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<div class="form-group" validation-errors.bind="emailErrors"
class.bind="editEmailErrors.length ? 'has-error' : ''">
<label for="emailAddress" class="control-label col-md-2">Email: </label>
<div class="col-md-10">
<input id="emailAddress"
type="text"
placeholder="Email Address (format: email#domain.com)"
class="form-control"
value.bind="contactForEdit.contactEmailAddress & validate" /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editEmailErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<div class="form-group" validation-errors.bind="editPhoneErrors"
class.bind="editPhoneErrors.length ? 'has-error' : ''">
<label class="control-label col-md-2">Phone: </label>
<div class="col-md-10">
<input type="text"
placeholder="Phone Number (format: xxx-xxx-xxxx)"
class="form-control"
value.bind="contactForEdit.contactPhoneNumber & validate" required /> <!-- NO ${} !!!-->
<span class="help-block" repeat.for="editErrorInfo of editPhoneErrors">
${editErrorInfo.error.message}
</span>
</div>
</div>
<button type="submit" class="btn btn-default ${canSave ? '' : 'disabled'}">
<!-- Look at click.dependent when there are child with buttons calling this.-->
Save
</button>
<!-- AA-10-17-17 - replaced with errors per input field. <ul for.bind="controller.errors">
<li repeat.for="error of controller.errors" style="color:red">
${error.message}
</li>
</ul>-->
</div>
</div>
</div>
</form>
<div>
<a route-href="route: home"
class="btn btn-default">
Back to list
</a>
</div>
</template>
I expect it's because of this code:
.getById(params.id)
.then(data => {
console.log(data);
this.contactForEdit = data;
your validation is against a ContactForEditDto object, but my guess is your repository is returning a JSON object cast to a ContactForEditDto, so it's not actually a class at all.
Try something like
console.log(data);
this.contactForEdit = new ContactForEditDto(data.id, data.firstname ..etc..);
or
console.log(data);
this.contactForEdit = Object.assign(new ContactForEditDto(), data);
We just had a similar problem and solved it by setting up our validations after assigning the remote data to our local field. In your code, you'd set up your validation rules after this.contactForEdit = data;

Kendo UI grid, search box in toolbar in mvc

Kendo-grid search box in toolbar in mvc with razor syntax,
I am facing i need toolbar in which searching box , this searching box search into grid data.
Just copy and paste this code bind with mvc model and custom button(CRUD) and search box in toolbar in kendo grid template
<div>
#(Html.Kendo().Grid(Model)
.Name("DiagnosisTestGrid")
.Columns(columns =>
{
columns.Bound(c => c.Description).Title("Description");
columns.Bound(c => c.Cost).Title("Cost");
columns.Bound(c => c.CostingRequired).Title("Cost Req.");
columns.Bound(c => c.DxTestId).ClientTemplate(#"
<a href='/DiagnosisTest/Details/#=DxTestId#' class = 'dialog-window'>Detail</a> |
<a href='/DiagnosisTest/Edit/#=DxTestId#' class = 'dialog-window' >Edit</a> |
<a href='/DiagnosisTest/Delete/#=DxTestId#' class = 'dialog-window'>Delete</a>
").Title("");
})
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
<div class="row">
<div class="col-md-4">
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></span>
<input type="text" class="form-control" id='FieldFilter' placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span></button>
</span>
</div>
</div>
</div>
</div>
</text>);
})
.Resizable(resizing => resizing.Columns(true))
.Sortable(sorting => sorting.Enabled(true))
.Reorderable(reorder => reorder.Columns(true))
.Pageable()
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.ServerOperation(false)
))
</div>
Script for search box. and filter grid items
<script>
$(document).ready(function () {
$("#FieldFilter").keyup(function () {
var value = $("#FieldFilter").val();
grid = $("#DiagnosisTestGrid").data("kendoGrid");
if (value) {
grid.dataSource.filter({ field: "Description", operator: "contains", value: value });
} else {
grid.dataSource.filter({});
}
});
});
I know this is a bit of an old question now but it seems like the accepted answer is quite limited. This is how I got my searchbox added into the toolbar.
.ToolBar(toolBar => toolBar.Template(#<text><input class='k-textbox' value="Search..." onfocus="if (this.value=='Search...') this.value='';" onblur="this.value = this.value==''?'Search...':this.value;" id='searchbox'/></text>))
Then the script
<script type="text/javascript">
function addSearch() {
return { searchbox: $('#searchbox').val() };
}
$('#searchbox').keyup(function () {
$('#gridWorkflows').data('kendoGrid').dataSource.read();
});
</script>
This seems a bit simpler that what you are using currently.
Hope it helps.

CheckedNodes posted is always null

I have followed the tutorial and the documentation of kendo treeview but I have an instance where in I added hidden values into the checkbox template. The problem is when the submit button was clicked, the posted values is always null.
Here is my view
#using (Ajax.BeginForm("Projects", "Maintenance", FormMethod.Post,null))
{
<div class="treeview-back">
#Html.TextBoxFor(c => c.UserAccountID)
#(Html.Kendo().TreeView()
.Name("treeviewSiteList")
.DataTextField("Name")
.Checkboxes(checkboxes => checkboxes
.CheckChildren(true)
.TemplateId("treeview-checkbox-template")
)
.DataSource(dataSource => dataSource
.Read(read => read
.Action("UserProjectFolderList", "Maintenance", new { useraccount_id = Model.UserAccountID }))
)
)
</div>
<button type="submit" class="k-button">Save</button>
}
<script id="treeview-checkbox-template" type="text/kendo-ui-template">
<input type="checkbox" name="treeviewNodes[#= item.id#]" value="#= item.id # "/>
<input type="hidden" name="treeviewNodes[#= item.id #]" value="#= item.SiteID #"/>
</script>
Here is my view:
public ActionResult GetChecked(int[] treeViewNodes)
{
}

Call ActionResult from Ajax.BeginForm

I using Ajax begin form and when I click submit button, post method doesn't call, here is code:
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "personListDivforReturnPerson"}))
{
<div class="ReturnPersonGeneralPageBody">
<div class="returnPersonHeader">
საზღვრის კვეთისას დაფიქსირებული მონაცემები
</div>
<div class="fieldNameForMIA">
<span>#Html.LabelFor(model => model.LastName, "გვარი")
<br />
#Html.EditorFor(model => model.LastName)
</span>
<div class="fieldNameInnerForMIA">
<span>#Html.LabelFor(model => model.FirstName, "სახელი")
<br />
#Html.EditorFor(model => model.FirstName)
</span>
</div>
</div>
<div class="fieldNameForMIA">
<span>#Html.LabelFor(model => model.PersonalNo, "პირადი ნომერი")
<br />
#Html.EditorFor(model => model.PersonalNo)
</span>
<div class="fieldNameInnerForMIA">
<span>#Html.LabelFor(model => model.DateOfBirth, "დაბადების თარიღი")
<br />
#Html.EditorFor(model => model.DateOfBirth)
</span>
</div>
</div>
<div class="fieldNameForReturnCheckBox">
#Html.LabelFor(model => model.IsIdentified, "სხვა სახელით დაბრუნდა")
#Html.CheckBoxFor(model => model.IsIdentified)
</div>
<div class="saveReturnPerson">
<input type="image" name="submit" id="submit" src="/Content/Resources/SaveGeo.gif" />
</div>
</div>
}
and here is post method which is never called:
[HttpPost]
public ActionResult EditReturnPerson(int id, FormCollection collection)
{ ....
but this method is called when first is loaded:
public ActionResult EditReturnPerson(long parentObjectId, int parentObjectTypeId, bool readOnly = false)
{
....
Mention the method as POST in AjaxOptions
new AjaxOptions { UpdateTargetId = "personListDivforReturnPerson",
HttpMethod ="POST"}
If you do not mention, It will take the Default which is GET.
EDIT : Also If you want to handle it with your own code, You can do it with handwritten JavaScript. Pretty clean and full control.
Get rid of the AjaxBeginForm and use a normal form in your view.
#using(Html.BeginForm())
{
#Html.EditorFor(model => model.FirstName)
#Html.EditorFor(model => model.PersonalNo)
<input type="submit" class="ajaxSubmit" />
}
Now have some javascript to handle the form submit
<script type="text/javascript">
$(function(){
$(".ajaxSubmit").click(function(e){
e.preventDefault();
var item=$(this);
$.post("#Url.Action("EditReturnPerson","YourControllerName")",
item.closest("form").serialize(), function(response){
$("#personListDivforReturnPerson").html(response);
});
});
});
</script>
ბიჭო აქ ვერ გეტყვიან ვერაფერს :D გეუბნები სერვერს მიმართავს და იქ უშლის რაღაცა ხელს. კლიენტის მხარეს ყველაფერი კარგადაა. ეს კიდე მაგარი კაცია, ფორმას უკეთებ სუბმით-ს და default მეთოდი არის პოსტი მაგ დროს.
I found my problem, the problem was [HttpPost] public ActionResult EditReturnPerson(int id, FormCollection collection) { .... in this part, id was int and my id in DB was bigint, so I changed int to long in controller and everything worked, thanks for advice.

autocomplete json

i have follow the following wave for autocomplete and datepicker but the auto complete can't work Secondly is there any razor syntax to show the datepicker and autocomplete
javascriptfile
/// <reference path="jquery-1.5.1-vsdoc.js" />
/// <reference path="jquery-ui-1.8.11.js" />
$(document).ready(function () {
$(":input[data-autocomplete]").each(function () {
$(this).autocomplete({ source: $(this).attr("data-autocomplete") });
});
$(":input[data-datepicker]").datepicker();
})
The View File
#model TestDateTimePicker.Models.TestClass
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>TestClass</legend>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<div class="editor-field">
<input data-autocomplete="#Url.Action("AutoComplete", "City","City")" class="text-box single-line" id="City" name="City" type="text" value="" />
#Html.ValidationMessageFor(model => model.City)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Date)
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-required="The Date field is required." id="Date" name="Date" type="text" value="" data-datepicker="true"/>
#Html.ValidationMessageFor(model => model.Date)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
The Json Controller
public ActionResult AutoComplete(String s)
{
var d = db.Cities
.Where(r => r.Name.Contains(s))
.Select(r => new { label = r.Name });
return Json(d, JsonRequestBehavior.AllowGet);
}
#Url.Action("AutoComplete", "City", "City")
should be
#Url.Action("AutoComplete", "City")
The third argument that you are using represents route values which must be an anonymous object and not a string. As far as the autocomplete plugin is concerned, it uses the term query string when performing the AJAX request to fetch the data. So you will have to rename your controller action parameter as well:
public ActionResult AutoComplete(string term)
{
var d = db.Cities
.Where(r => r.Name.Contains(term))
.Select(r => new { label = r.Name });
return Json(d, JsonRequestBehavior.AllowGet);
}
Also make sure that that jquery-ui-1.8.11.min.js script is referenced in your page (cannot see it in your code example).
If it still doesn't work make sure that the AutoComplete action doesn't throw an exception when performing the query. Also look with FireBug or Developer Tools if there aren't some javascript errors and if the AJAX request is correctly sent.
The key to this solution is: We need to use item.label name because the AJAX will return the value in list format so we need to extract the value as shown in the below example.
<html>
<head>
<title>Ajax</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function() {
$("#myname").autocomplete({
source: 'emp.php',
select: function (event, ui) {
$("#myname").val(ui.item.label);
$("#myid").val(ui.item.id);
},
minLength: 0,
autoFocus: true,
});
});
</script>
</head>
<body>
<h2>Ajax Testing</h2>
<input name="myname" id="myname" type="text">
<input name="myid" id="myid" type="text">
</body>
</html>
-------------- Below is the code of PHP for emp.php page --------------------------
<?php
require_once 'connection.php';
$query = "SELECT myname as label , myid as id FROM emp WHERE name LIKE ? ORDER BY name";
$rsTable = sqlsrv_query($conn, $query,array('%'.$_REQUEST['term'].'%'));
while ($row_rsTable = sqlsrv_fetch_array($rsTable, SQLSRV_FETCH_ASSOC)) {
$emparray[] = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $row_rsTable);
}
echo json_encode($emparray);
sqlsrv_close($conn);
?>

Resources