Hi, I'm using a wizard with form component integration, using taghelpers.
The second page will have a dynamic list of phones:
class Phone {
[Required] public string number {get;set;}
[Required] public string country {get;set;} }
I can't find a way to accomplish the following:
How do I declare a loop to display all the phones?
How can I dynamically add more phones to the list, given that most non-form-related tags are invalid inside the form?
I have a custom validator to check the list length, but I don't see how to wire it up, since I haven't figured out how to render the list.
I'd appreciate it if you could point me in the right direction.
Regards,
<div class="form-group">
Let's say I have a Telerik Wizard With Three Steps and I am passing a View Model to each step. In Step 1, A Telerik Form component would suffice. But, In Step 2, I need to have more specific control over the layout and function than what the Form Component provides. I would like to use custom MVC Razor View syntax for Step 2, for example:
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Rating" class="control-label"></label>
<input asp-for="Rating" class="form-control" />
<span asp-validation-for="Rating" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ReleaseDate" class="control-label"></label>
<input asp-for="ReleaseDate" class="form-control" />
<span asp-validation-for="ReleaseDate" class="text-danger"></span>
</div>Is this something that is possible and would I preserve the View Models state between steps? I'm not exactly finding a clear solution in the documentation. Any help or an example of how this could be done would be appreciated!
Hi All
Right now Kendo Wizard only allows to move 1 step up or down. Do we have any way to make it all steps clickable. If I am on step 1 I can click on step 4 to see the content or click anyway to go to any step instead of only 1 +-
https://demos.telerik.com/aspnet-core/wizard/ajax
First time using the Wizard control and I am running into a serious problem. Here is the console error I receive when I try to run:
Uncaught DOMException: Failed to execute 'setAttribute' on 'Element': '$id' is not a valid attribute name.
at attr (https://kendo.cdn.telerik.com/2023.1.314/js/jquery.min.js:4:11364)
at Y (https://kendo.cdn.telerik.com/2023.1.314/js/jquery.min.js:3:4598)
at Y (https://kendo.cdn.telerik.com/2023.1.314/js/jquery.min.js:3:4436)
at Te.fn.init.attr (https://kendo.cdn.telerik.com/2023.1.314/js/jquery.min.js:4:10935)
at string (https://kendo.cdn.telerik.com/2023.1.314/js/kendo.all.min.js:10:1312585)
at init.editor (https://kendo.cdn.telerik.com/2023.1.314/js/kendo.all.min.js:10:1315704)
at init.refresh (https://kendo.cdn.telerik.com/2023.1.314/js/kendo.all.min.js:10:1317046)
at new init (https://kendo.cdn.telerik.com/2023.1.314/js/kendo.all.min.js:10:1314677)
at HTMLDivElement.<anonymous> (https://kendo.cdn.telerik.com/2023.1.314/js/kendo.all.min.js:9:40719)
at Function.each (https://kendo.cdn.telerik.com/2023.1.314/js/jquery.min.js:2:2898)
This happens in any time I try to add anything more than just Content items. Here is my page using the sample code I found in Telerik's Github repo:
@page
@model WilliamsKastner.Pages.CreateCarrierInvoiceModel
@{
ViewData["Title"] = "Create Carrier Invoice";
}
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@{
var token = Xsrf.GetAndStoreTokens(HttpContext).RequestToken;
}
<h2 style="text-align: center;">Create Carrier Invoice</h2>
<p style="text-align: center;">Please select whether you want to create an end of month or end of quarter invoice. Verify the dates and click the Next button to continue.</p>
<hr class="dividerBar"/>
@(Html.Kendo().Wizard()
.Name("wizard")
.Tag("form")
.Events(ev => ev.Done("wizardDone"))
.HtmlAttributes(new { url = @Url.Page("CreateCarrierInvoice"), method = "POST" })
.Steps(s =>
{
s.Add<CreateCarrierInvoiceModel.UserModel>()
.Title("Account Details")
.Form(f => f
.Validatable(v =>
{
v.ValidateOnBlur(true);
v.ValidationSummary(vs => vs.Enable(false));
})
.FormData(Model.UserViewModel)
.Items(items =>
{
items.Add().Field(p => p.AccountDetails.Username).Label(l => l.Text("Username:")).InputHtmlAttributes(new { required = "required", validationMessage = "Username is required !" });
items.Add().Field(p => p.AccountDetails.Email).Label(l => l.Text("Email:")).InputHtmlAttributes(new { type = "email", required = "required", validationMessage = "Email is not valid !" });
items.Add().Field(p => p.AccountDetails.Password).Label(l => l.Text("Password:")).InputHtmlAttributes(new { @type = "password", required = "required", validationMessage = "Password is required !" }).Hint("Hint: enter alphanumeric characters only.");
})
)
.Buttons(b =>
{
b.Next();
});
s.Add<CreateCarrierInvoiceModel.UserModel>()
.Title("Personal details")
.Form(f => f
.Validatable(v =>
{
v.ValidateOnBlur(true);
v.ValidationSummary(vs => vs.Enable(false));
})
.FormData(Model.UserViewModel)
.Items(items =>
{
items.Add().Field(p => p.PersonalDetails.FullName).Label(l => l.Text("Full Name:")).InputHtmlAttributes(new { required = "required", validationMessage = "Full Name is required !" });
items.Add()
.Field(p => p.PersonalDetails.Country)
.Label(label => label.Text("Country:"))
.Editor(e =>
{
e.AutoComplete()
.DataTextField("Text")
.BindTo(new List<SelectListItem>() {
new SelectListItem() {
Text = "France",
},
new SelectListItem() {
Text = "Germany",
},
new SelectListItem() {
Text = "Italy",
},
new SelectListItem() {
Text = "Netherlands",
},
new SelectListItem() {
Text = "Norway",
},
new SelectListItem() {
Text = "Spain",
}
});
});
items.Add()
.Field(p => p.PersonalDetails.About)
.Label(l => l.Text("About:").Optional(true));
})
)
.Buttons(b =>
{
b.Previous();
b.Next();
});
s.Add().Content("<h3>Click on the \"Done\" button to complete your registration.</h3>");
})
)
<script>
function wizardDone(e) {
$("#wizard").append($("<input type='hidden' name='__RequestVerificationToken' value='@token' data-stop='true' />"))
}
</script>
And finally, the code behind for the page:
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using WilliamsKastner.Data;
namespace WilliamsKastner.Pages
{
public class CreateCarrierInvoiceModel : PageModel
{
[BindProperty]
public CarrierInvoiceModel InvoiceViewModel { get; set; }
[BindProperty]
public UserModel UserViewModel { get; set; }
//[BindProperty(SupportsGet = true)]
//public string InvoiceTypeID { get; set; }
private readonly ExtranetDbContext _context;
private readonly UserManager<ExtranetUser> _userManager;
public CreateCarrierInvoiceModel(ExtranetDbContext context, UserManager<ExtranetUser> InjectedUser)
{
_context = context;
_userManager = InjectedUser;
}
public void OnGet()
{
UserViewModel = new UserModel()
{
AccountDetails = new Account()
{
Username = "kev123",
Email = "kevin@mymail.com"
},
PersonalDetails = new Person()
{
FullName = "Kevin Carter",
Country = "Norway"
}
};
//InvoiceViewModel = new CarrierInvoiceModel
//{
// EndDate = "This is a test",
// Period = "0",
// StartDate = "This is another test",
// UserID = ""
//};
}
public IActionResult OnPost()
{
var model = Request.Form;
if (!ModelState.IsValid)
{
return Page();
}
return RedirectToPage("Success");
}
public class CarrierInvoiceModel
{
[Required]
public string Period { get; set; }
[Required]
public string StartDate { get; set; }
[Required]
public string EndDate { get; set; }
public string? UserID { get; set; }
}
public class UserModel
{
public Account AccountDetails { get; set; }
public Person PersonalDetails { get; set; }
}
public class Account
{
[Required]
public string Username { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
}
public class Person
{
[Required]
public string FullName { get; set; }
[Required]
public string Country { get; set; }
public string About { get; set; }
}
}
}
This is the Head tag in the _Layout file:
@{
var kendoVersion = "2023.1.314";
}
<script src="https://kendo.cdn.telerik.com/@kendoVersion/js/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link href="https://kendo.cdn.telerik.com/themes/6.2.0/bootstrap/bootstrap-main.css" rel="stylesheet" type="text/css" />
<script src="https://kendo.cdn.telerik.com/@kendoVersion/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/@kendoVersion/js/kendo.all.min.js"></script>
<script src="~/kendo-ui-license.js"></script>
<script src="https://kendo.cdn.telerik.com/@kendoVersion/js/kendo.aspnetmvc.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
FYI, I have tried every v5 version of Bootstrap. If I download and run the sample solution from Github, all of the steps are rendered together on the page - in other words, all steps are shown and none hidden. And if I just put 3 Content items here, the Wizard shows all 3 as steps and everything just works.
What in the world am I doing wrong? All of the other Telerik UI controls that I am using (Grid and Chart) work as expected. Just not the Wizard.
Good afternoon,
I'm trying to find a way to programmatically set the content id for the next step in a wizard based on a radiogroup choice on the previous step.
I'm basing it on the Accepted answer from Mihaela on this post:
https://www.telerik.com/forums/skipping-diabled-steps-in-wizard-doasn-t-work
Incidentally, the required validation on the radiogroup in the example doesn't seem to work - you can click next to step 2 without choosing an option.
Rather than disable steps and jump to a different next step, I'd like to set the content for the next step based on the selected option.
On the select event for the wizard form I've tried the following:
var wizard = e.sender;
var radioValue = $("input[name='uploadType']:checked").val();
if (radioValue == "1") {
//e.sender.insertAt(3, { title: "Upload File(s)", contentId: "uploadFile" });
wizard.steps()[3].contentId = "uploadFile";
}
else {
//e.sender.insertAt(3, { title: "Choose File(s)", contentId: "chooseFile" });
wizard.steps()[3].contentId = "chooseFile";
}
e.preventDefault();
wizard.select(3);
I've used the syntax from this question:
https://www.telerik.com/forums/programmatically-enable-or-disable-wizard-buttons
$("#wizard").data("kendoWizard").steps()[1].buttons()[1].enable(true);
This assumes that e.sender on the wizard select event is the equivalent of $("#wizard").data("kendoWizard").
I have two templates with partial views which are used dependent on the radiogroup selected value:
<script type="text/x-kendo-template" id="uploadFile">
@await Html.PartialAsync("_UploadFile")
</script>
<script type="text/x-kendo-template" id="chooseFile">
@await Html.PartialAsync("_UploadChoose")
</script>
The insertAt method works by inserting a step with the desired content, but I don't want to insert multiple new steps.
Can what I want to do be achieved? Can the content be set programmatically?
I did also wonder if it was possible to have the conditional logic (e.g. if (radiogroup value == 1) in the kendo template, but this also didn't seem to work.
Kind regards,
Richard
Good afternoon,
I am using the wizard component with a partial view on step 1, and a form on step 2.
@(Html.Kendo().Wizard()
.Name("uploadWizard")
.Events(events => {
events.Select("onFormSelect");
events.FormValidateFailed("onFormValidateFailed");
})
.ValidateForms(v => v.ValidateOnPrevious(false))
.LoadOnDemand(true)
.ReloadOnSelect(false)
.Steps(s => {
s.Add()
.Title("Choose Route")
.ContentId("chooseRoute")
.Buttons(b =>
{
b.Next();
});
s.Add<TransactionViewModel>()
.Title("File Details")
.Form(form =>
{
form.FormData(Model);
form.Items(items =>
{
items.Add()
.Field(f => f.FileVersion)
.Label(label => label.Text("Version of file (if applicable) e.g. 1.00:")
.Optional(true))
.InputHtmlAttributes(new { @maxlength = "50" });
items.Add()
.Field(f => f.FileDescription)
.Label(label => label.Text("Description of file use/content:"))
.Editor(e => e.TextArea()
.MaxLength(256)
.Rows(2)
);
items.Add()
.Field(f => f.BusinessReason)
.Label(label => label.Text("Business reason for the transfer:"))
.Editor(e => e.TextArea()
.MaxLength(256)
.Rows(2)
);
items.Add().Field(f => f.SourceUri).Label(label => label.Text("Source URI (if from an identifiable source):").Optional(true));
});
})
.Buttons(b =>
{
b.Previous();
b.Next();
});
s.Add().Title("Upload File").Content("Upload file");
})
)
The partial view content contains a Kendo dropdownlist and a Kendo grid. I need the user to have selected a value from the dropdownlist and the grid before the step 1 wizard button allows the navigation to step 2.
I have added required text inputs to the partial view to capture the required value of the dropdownlist and id of the selected row in the grid. I'm going to hide the inputs but I want the "this field is required" error messages to appear in a validation summary, as they do on the step 2 form.
I've tried adding @Html.ValidationSummary() to the partial view but the error messages still appear next to the text inputs (which are due to be hidden). The partial view isn't based on a model.
The wizard's select event checks if the two inputs are valid and prevents the user from moving on:
// Get the current step's container element
var container = e.sender.currentStep.element;
// Instantiate a validator for the container element
$(container).kendoValidator();
// Get the validator's reference
var validator = $(container).kendoValidator().data("kendoValidator");
// Validate a given input elements
if (!validator.validateInput($("#SourceEnvironmentId")) || !validator.validateInput($("#RouteId"))) {
// Prevent the wizard's navigation
e.preventDefault();
}
How do I get the validation error messages for the hidden inputs to appear in the validation summary on step 1?
Kind regards,
Richard
Hi
I have a wizard that loads partials as steps. Whenever I add more than one kendo component (for example a gauge and a slider) onto the same partial the second component renders outside of the wizards' container.
Please assist with this.
Kind Regards
This question is two-fold, and I can't seem to find the answers in the documentation. For background info, I'm using the latest version of Wizard (the Tag version) :
TIA!
I wanted to rule out if this is some kind of issue with Telerik - I've implemented this in CodePen and it works there, but not with what I'm using in Visual Studio w/ the entire code.
I have a series of buttons like so:
<wizard-step title="Step 2">
<wizard-step-content><span class="nowrap d-flex flex-row"><div class="reasons">
@Html.RadioButtonFor(c => c.category, item.Value, new { id = item.Value, name = "Lists", @value = item.Value, @text = item.Text, @class = "reasons-input"})
<label for="@(item.Value)"
class="reasons-label">@item.Text</label></div><button type="button"
id="@item.Value"
class="inputBtn btn btn-secondary"
data-toggle="modal"
datatarget="#@item.Value"
style="background-color: transparent; border-color: transparent; color: #007bff; font-size: 21px;"><i class="fa fa-question-circle"></i></button></span>
</wizard-step-content>
</wizard-step>
And here's my attempt at setting up event listeners
var inputButtons = document.querySelectorAll(".inputBtn"); console.log(inputButtons); console.log(inputButtons.length); var buttonsCount = inputButtons.length; for (var i = 0; i <= buttonsCount; i += 1) { inputButtons[i].addEventListener("click", function(e) { console.log("HI"); }); }