DatePicker Editor Template - asp.net-mvc

Below is an EditorTemplate that renders a Bootstrap datetimepicker with EditorFor helpers, the problem I am seeing is with the script section. It works OK for one DateTimePicker per view - but since I am using class selector, whenever I use 2 or more DateTimePickers per view it renders duplicate <script> sections, confusing the DOM as to on which TextBox to invoke the calendar. What am I missing here?
#model DateTime?
<div class='input-group date datePicker'>
<span class="input-group-sm">
#Html.TextBox("", Model.HasValue ? Model.Value.ToString("d") : String.Empty)
</span>
</div>
<script type="text/javascript">
$(function() {
$('.datePicker').datetimepicker({
pickTime: false
});
});
</script>

The problem you have as you have correctly deduced is that the script block defined in the editor template will run twice when you have two datepickers included in a view; When it is run twice, the plugin's behaviour is not as expected.
One solution to this would be to target only the datepicker input in the editor template in each script block. For example,
#model DateTime?
<div class='input-group date datePicker'>
<span class="input-group-sm">
#Html.TextBox("", Model.HasValue ? Model.Value.ToString("d") : String.Empty)
</span>
</div>
<script type="text/javascript">
$(function() {
// target only the input in this editor template
$('##Html.IdForModel()').datetimepicker({
pickTime: false
});
});
</script>

As far as rendering the script once, what about the following? It works for me so far. Any potential issues?
Editor Template - DateTime.cshtml
#model System.DateTime?
#Html.TextBox("", String.Format("{0:d}", Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { #class = "datepicker" })
_Layout.cshtml
<script type="text/javascript">
$().ready(function () {
$('.datepicker').datepicker({
changeMonth: true,
changeYear: true,
showOn: "button",
buttonImage: "/Images/calendar.gif",
buttonImageOnly: true
});
}
</script>

Related

How to use datetime picker as editortemplate

How can i use datetime picker in my mvc view .
EditorTemplate : Datetime.cshtml
#model DateTime?
#Html.TextBox("", Model.HasValue ? Model.Value.ToString("dd/MM/yyyy"):"", new { #class = "datefield" })
Model :
[Required]
public DateTime DateOfBirth { get; set; }.
Also jquery.ui.all.css is under my solution content>themes>base
Here is the partial view where the datepicker is needed .
#model PersonalDetails`
`
#Html.LabelFor(model => model.DateOfBirth)
#Html.EditorFor(model => model.DateOfBirth, new { #placeholder = "Date Of Birth", #class = "datefield" ,#type="text" })
#Html.ValidationMessageFor(model => model.DateOfBirth)
Here the date field is coming in the format specified in the Datetime editor template. But the calendor image is not coming.
Assume you have editor set up for jQuery datepicker:
#Html.EditorFor(model => model.DateOfBirth, new { #placeholder = "Date Of Birth", #class = "datefield", #type="text" })
Check if your JS code has working properly by browser debugging, your datepicker code should looks like this:
<script type="text/javascript">
$(document).ready(function () {
$(".datefield").datepicker({
changeMonth: true,
changeYear: true,
showButtonPanel: true,
showOtherMonths: true,
selectOtherMonths: true,
// other datepicker settings here as you want
});
});
</script>
Then make sure jQuery UI CSS file has included either inside Layout.cshtml or inside head tag on your page, at this step your calendar image should be shown besides date editor:
<link rel="stylesheet" href="~/Content/themes/base/jquery.ui.all.css" type="text/css">
<script src="~/Scripts/jQuery-[version].js" type="text/javascript">
<script src="~/Scripts/jQuery-ui-[version].js" type="text/javascript">
To simplify those script and style declarations, I suggest you learning MVC styles/scripts bundling.
Any suggestions welcome.

Kendo UI - Tooltip reads only once

Given the sample of the Kendo UI to load a tooltip with ajax data.
<ul id="products" class="dairy-photos">
<li><a href="#" data-id="11">
<img src="#Url.Content("~/content/12.jpg")" /></a> </li>
</ul>
#(Html.Kendo().Tooltip()
.For("#products")
.Filter("a")
.LoadContentFrom("Details", "Tooltip")
.Position(TooltipPosition.Top)
.Width(220)
.Height(280)
.Events(events => events.RequestStart("requestStart")))
<script type="text/javascript">
function requestStart(e) {
e.options.data = {
id: e.target.data("id")
}
}
</script>
This is working fine, but the call to the Tooltip controller is made only once !?
I'm unable to find a way to make sure the call is made -every- time the tooltip is hovered. Any help on this one ?
Seems like this is fixed in the latest release :
http://www.kendoui.com/forums/mvc/tooltip/load-tooltip-content-via-ajax-everytime-it-opens.aspx
#(Html.Kendo().Tooltip()
//...
.Events(e =>
{
//...
e.Show("show");
}))
<script type="text/javascript">
function show() {
this.refresh();
}

Disable jQuery Button with AngularJS and Form Validation

I would like to disable my jQuery button based on form validation. According to the docs this is fairly easy with regular buttons using syntax such as:
<button ng-click="save(user)" ng-disabled="form.$invalid">Save</button>
However, when changing to a jQuery UI button this no longer works. I assume that Angular has no real binding between jQuery UI and AngularJS and thus would require a directive to do the following:
$("button" ).button( "option", "disabled" );
Is that the case or are there other alternatives? A jsFiddle of what I'm trying to do is here: http://jsfiddle.net/blakewell/vbMnN/.
My code looks like this:
View
<div ng-app ng-controller="MyCtrl">
<form name="form" novalidate class="my-form">
Name: <input type="text" ng-model="user.name" required /><br/>
Email: <input type="text" ng-model="user.email" required/><br/>
<button ng-click="save(user)" ng-disabled="form.$invalid">Save</button>
</form>
</div>
Controller
function MyCtrl($scope) {
$scope.save = function (user) {
console.log(user.name);
};
$scope.user = {};
};
$(function () {
$("button").button();
});
Well the thing is with angular, you're supposed to be making directives to apply your JQuery plugins.
So here you could to this:
//NOTE: directives default to be attribute based.
app.directive('jqButton', {
link: function(scope, elem, attr) {
//set up your button.
elem.button();
//watch whatever is passed into the jq-button-disabled attribute
// and use that value to toggle the disabled status.
scope.$watch(attr.jqButtonDisabled, function(value) {
$("button" ).button( "option", "disabled", value );
});
}
});
and then in markup
<button jq-button jq-button-disabled="myForm.$invalid" ng-click="doWhatever()">My Button</button>
This worked for me:
app.directive('jqButton', function() {
return function(scope, element, attrs) {
element.button();
scope.$watch(attrs.jqButtonDisabled, function(value) {
element.button("option", "disabled", value);
});
};
});
With this markup:
<input type="button" value="Button" jq-button jq-button-disabled="myForm.$invalid" />

Date picker in mvc3 with razor view engine

I am using mvc3 and razor is my view engine how i get date picker with out using scripts in my
view.
You can create a script in the directory scripts of your project.
Basic example:
$(document).ready(function () { $("#datepicker").datepicker({ });});
in your view:
#model YourProjectName.Models.User
....
<div class="editor-field">
#Html.TextBoxFor(model => model.Dateadd, new { #Value = DateTime.Now, id = "datepicker" })
#Html.ValidationMessageFor(model => model.Dateadd)
</div>
I think you are going to have to use a script, check out jqueryui datepicker. Its a nice easy to use library and supports theming
I answered here, check it out: http://forums.asp.net/post/4647234.aspx
Basically you're using a template with a script in one location and calling it with EditorFor.
To advisers here: it's a bad practice to use scripts inside partial views (templates).
In my case it does not work at all. Because accessing jquery happens before it's included as js file.
Plus you cannot predict where exactly you would put this datepicker control.
Also, you will have this "ready" block for every editor on the page.
RenderSection would bring some order to all this, but it does not work for partialviews and templates.
So just move javascript code from a template (partialview) to a view.
#model Nullable<System.DateTime>
#if ( Model.HasValue ) {
#Html.TextBox( "" , String.Format( "{0:yyyy-MM-dd HH:mm}" , Model.Value ) , new {
#class = "textbox" , #style = "width:400px;" } )
}
else {
#Html.TextBox( "" , String.Format( "{0:yyyy-MM-dd HH:mm}" , DateTime.Now ) , new {
#class = "textbox" , #style = "width:400px;" } )
}
#{
string name = ViewData.TemplateInfo.HtmlFieldPrefix;
string id = name.Replace( ".", "_" );
}
<script type="text/javascript">
$(document).ready(function () {
$("##id").datepicker
({
dateFormat: 'dd/mm/yy',
showStatus: true,
showWeeks: true,
highlightWeek: true,
numberOfMonths: 1,
showAnim: "scale",
showOptions: {
origin: ["top", "left"]
}
});
});
</script>
If you use an Editor Template for the DateTime type, you can use an HTML5 date picker (i.e. <input type="date" />). Essentially you put a view called DateTime.cshtml in a folder called Views/Shared/EditorTemplates, then you can style the editor however you like. One example is in an answer here.

CKEditor and ASP.Net MVC 3 RequiredAttribute

I've integrated CKEditor 3 (formerly FCKEditor) into my asp.net MVC (v3 to be specific) application. I have a RequiredAttribute in my model for the field that needs the editor but the client side validation doesn't work correctly with CKEditor. When I try to submit and I've entered data into CKEditor the required validation doesn't see the data. If I try resubmitting again, then it works. I've looked around online and can't find a solution. I am also using Jquery and using the Jquery adapter
http://docs.cksource.com/CKEditor_3.x/Developers_Guide/jQuery_Adapter
If someone is looking for a more generic way to do this you can add this javascript :
$(document).ready(function () {
if ($('.text-editor')) {
$('.text-editor').ckeditor();
$('input[type=submit]').bind('click', function() {
$('.text-editor').ckeditorGet().updateElement();
});
}
});
And use .text-editor css class on a textarea and it works just fine.
#Html.TextAreaFor(model => model.Description, new { #class = "text-editor" })
I find this solution eazyer than the other one, hope it can helps!
It is even simpler if you don't use the jQuery adapter:
$(function () {
$('input[type="submit"]').click(function () {
CKEDITOR.instances.Body.updateElement();
});
});
Where Body is the ID of the textarea.
For me this code does the trick, it could probably be optimized a bit but it works:
$('#newsForm').submit(function (event) {
var editor = $('#Body').ckeditorGet();
editor.updateElement();
$(this).validate().form();
});
Because I don't know in which order the eventhandlers for submit runs I make sure to both update the value and refresh the validation result.
EDIT: Updated solution
<script type="text/javascript">
//<![CDATA[
$(document).ready(function () {
$('#Body').ckeditor();
$('#newsForm').bind('submit', onFirstSubmit);
});
function onFirstSubmit(event) {
var editor = $('#Body').ckeditorGet();
editor.updateElement();
$(this).validate().form();
$(this).unbind('submit', onFirstSubmit).submit();
}
//]]>
</script>
I couldn't get it fixed with the above solutions, but this worked for me;
<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>
<script src="#Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Content/ckeditor/ckeditor.js")" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
CKEDITOR.replace("activiteit_details", { toolbar: 'Basic' });
CKEDITOR.replace("activiteit_verslag", { toolbar: 'Full' });
// Bind CKeditor fields on submit (To avoid problems with the RequiredAttribute)
$('input[type=submit]').bind('click', function () {
var CKactiviteit_details = CKEDITOR.instances.activiteit_details.getData();
$("#activiteit_details").val(CKactiviteit_details);
var CKactiviteit_verslag = CKEDITOR.instances.activiteit_verslag.getData();
$("#activiteit_verslag").val(CKactiviteit_verslag);
});
});
</script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
...
<div class="editor-label">
#Html.LabelFor(model => model.activiteit_details)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.activiteit_details)
#Html.ValidationMessageFor(model => model.activiteit_details)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.activiteit_verslag)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.activiteit_verslag)
#Html.ValidationMessageFor(model => model.activiteit_verslag)
</div>
...
<p>
<input type="submit" value="Opslaan" />
</p>
</fieldset>
I also tried to use CKEditor but with no luck. I've been using CLEditor instead (along with the required attribute) and it works fine for me.
Ever thought of trying this instead?
Thanks for the answers.
Thanks to this post I've found my own solution which suits my case perfectly.
If you don't want to use click/mousedown event, but instead, want to trigger the validation on the right form-submit event you can use the following approach.
It doesn't use neither jQuery-Adapter CKEditor plugin nor click event.
And it's possible to apply it to all forms with ckeditor.
$('form').on('submit.ckeditorValidation', function () {
var $this = $(this);
var $ckeditor = $this.find('textarea.ckeditor');
// if no ckeditor for this form then do nothing
if (!$ckeditor || !$ckeditor.length) {
return true;
}
// update content from CKEditor to TextArea
var textAreaId = $ckeditor.attr('id');
CKEDITOR.instances[textAreaId].updateElement();
// trigger validation and check if the form is valid
if (!$this.valid()) {
return false;
}
// if form is valid then
// unsubscribe current event handler to avoid endless recursion
// and re-trigger form submit
$(this).off('submit.ckeditorValidation').submit();
return true;
});
i have been through the same issue and i was unable to resolve it because of one more issue that is related to it.
When ckeditor replaces the textarea, it makes it hidden and i found out that the default settings for jquery validator was to ignore the hidden elements with ":hidden" selector.
To resolve the issue, i have to update the hidden selector and update the element value. here is my code that does this in document ready event and is now working
$('#frmid').validate().settings.ignore = "input:hidden";
$('input[type="submit"]').click(function () {
$("#txtarea").val(CKEDITOR.instances["txtarea"].getData());
});

Resources