I have a kendo UI Grid that has in-line editing on a single column. That column should be using a datepicker as the input when editing.
However, after setting the value on the datepicker, and then returning to the same row/column, the date does not then show in the datepicker input.
I have created a Dojo to show what I mean:
https://dojo.telerik.com/eJEmoVEv/4
And a quick gif to explain the issue better:
Dealing with bindings on kendo is always tricky. I have update your demo with a few changes:
Editor:
When you're using data-bind you're not suposed to handle the widget's state. Kendo should deal with it by itself, but you need to tell kendo to handle that using kendo.bind(element, model)(bind() docs). Hence, you don't need to set data-value attribute.
function commentEditor(container, options) {
var datePicker = $('<input data-role="datepicker" data-format="dd/MM/yyyy" type="date" name="Comment" data-bind="value:Comment">');
datePicker.appendTo(container);
kendo.bind(datePicker, options.model);
}
Comment field type:
In order to make kendo to know how to handle the Comment field value as a date and to set it properly to the widget, you need to set the right data type in it's model definition:
Comment: { type: "date", editable: true }
Template:
A small fix to the template:
template: function (dataItem) {
if (dataItem.Comment != "") {
let date = kendo.parseDate(dataItem.Comment);
if (date) {
return kendo.toString(date, "dd/MM/yyyy");
}
}
return (dataItem.Comment || "");
}
I'm making sure that the Comment content is a valid date by checking the parseDate result. If not valid, proceed to another condition where it verifies if Comment is not null, undefined, etc, if yes, prints an empty string.
I hope it helps.
Update
Not sure why, but it seems that kendo saves the selected value as string to the bound property. I have added this handler to the widget's change event that seems to work:
datePicker.data("kendoDatePicker").bind("change", function(e) {
let model = this,
widget = e.sender;
model.Comment = widget.value();
}.bind(options.model));
Updated demo
That forces Comment property to be of Date type.
After the help from #DontVoteMeDown I finally found an answer to this.
The datepicker is expecting the Comment field to be of date type, so adding in a kendo.parse and then resetting the comment field fixed this issue.
See updated kendo dojo: https://dojo.telerik.com/eJEmoVEv/4
var dateTimeComment = kendo.parseDate(options.model.Comment);
options.model.Comment = dateTimeComment;
Related
I am trying to to update/change the highlighted days in callendar view. But they are not updated on next event when calendar is shown.
There is working Plunker snippet: https://plnkr.co/edit/4HkCp5?p=preview
Part of code:
var element = $("#datetimepicker");
//element.datetimepicker('destroy');
element.datetimepicker({
'setOptions': {
highlightedDates: ["08/10/2016,,xdsoft_highlighted_mint", "10/10/2016,,xdsoft_highlighted_mint"]
}
});
How can I make that the highlights were updated after setting the new value to "highlightedDates"?
Some realated questions:
xdan/datetimepicker using knockout - can not update “highlihted days” dynamicaly
Note: I can not use "element.datetimepicker('destroy')" because it will destroy all data and I only need to update highlights.
Found solution...
So problem is that when new value of highlightedDays is empty array, then the "highlightedDays" value is not updated. So you need always some dummy value to update previous value.
This is like a hack, but works. I am passing dummy date from 1970`th, so no one cares about it...
I'm trying to make the materialize date picker editable. Here is the goal, the user can directly write the date in the input field or use the widget to pick a date.
I did something that is about to work on this jsfiddle. But there is a bug I'm trying to solve. When the user directly writes the date in the input, the picker needs to get the new value also (because I use a different format to submit the date and there is a an hidden input field to update). To accomplish that I tried to do
picker.set('select', $(this.val());
But it creates an infinite loop because the method set in materialize also triggers the event change on the input.
EDIT: oh i just found there is an issue open about that on github. Do you have any idea for a workaround?
Any specific reason you want to do it in the change method?
Why not something like this?
this.change(function(event) {
});
this.bind('blur keypress',function(e){
if (moment($(this).val(), "DD/MM/YYYY", true).isValid()) {
var inputFieldDate=getFmtDate($(this).val());
picker.set('select',inputFieldDate);
}
});
This is a utility function to parse the date in DD/MM/YYY format and get a javascript Date object
function getFmtDate(s){
var valx=new Array();
if(s!=null && s.length>0){
valx = s.split('/');
}
var d = new Date(valx[2],valx[1]-1,valx[0]);
return d;
}
This works for me.
Update:
Once you attach a widget to an html element, the usual event callback functions do not work the way you expect them to. Their functionality is overridden by the widget. You cannot use the functions the same way you are used to and have to find a workaround. In short you cannot use the change function to set or unset the date because set triggrers a change event.
In your case you want to address multiple issues which are very common problems. You should be able to get a lot of examples online to achieve each one of those. What I've done is just one way of doing it.
Populate the form in a non traditional way when the page loads.
Initialize various plugins with values from the form when the page loads
Initialize content from hidden fields when the form loads and update the hidden fields when submitting the form.
Fetch the values by name (of the hidden fields) and use them to initialize the widgets.
I've used blur keypress just to give you an idea that all your requirements can be handled without using change. You use the events that work for you. You can set the date by binding picker to calendar object with this keyword and access it from its instance as shown below.
(function($) {
$.fn.calendar = function(options) {
// Options du datepicker
var settings = $.extend({
editable: true,
format: 'dd/mm/yyyy',
formatSubmit: 'ddmmyyyy'
},
options
);
this.pickadate(settings);
//var picker = this.pickadate(''); will not work
this.picker = this.pickadate('picker');
this.change(function(event) {
});
this.bind('blur keypress',function(e){
if (moment($(this).val(), "DD/MM/YYYY", true).isValid()) {
var inputFieldDate=getFmtDate($(this).val());
picker.set('select',inputFieldDate);
}
});
var $triggerIcon = $('<div class="col s2 center-align"><a class="btn-floating btn-large waves-effect waves-light trigger-datepicker">Date</a></div>');
$triggerIcon.click(function(event) {
event.stopPropagation();
event.preventDefault();
picker.open();
});
this.parent().after($triggerIcon);
// Resolves picker opening for thing
this.next().unbind("focus.toOpen");
return this;
};
}(jQuery));
To set a date:
//This is how you set a date
var cal = $('.datepicker').calendar();
//You can access picker because we changed
//var picker to
//this.picker above in fn.calendar
cal.picker.set('select', getFmtDate($("[name=hiddenDate]").val()));
// The syntax is
//cal.picker.set('select', new Date());
$('#formulaireDate').validate();
You have to convert your date to Date(). The below function should give you an idea. You can also use plugins like jquery dateFormat plugin.
function getFmtDate(s){
var valx=new Array();
if(s!=null && s.length>0){
valx = s.split('/');
}
var d = new Date(valx[2],valx[1]-1,valx[0]);
return d;
}
This is your html.
<div class="row">
<div class="col s4">
<input type="text" class="datepicker" />
<input name="hiddenDate" type="hidden" value="12/12/2016">
</div>
</div>
Im trying to use the Angular Bootstrap Daterange Picker , But every instance overrides the ng model to be textual.
This is the very simple code:
<input class="input-filter form-control" type="daterange" ng-model="test" ranges="ranges" />
{{test}}
Exactly like the 4th example that they provide HERE.
By overriding, I mean that from an object:
{"startDate":"2015-11-28T22:00:00.000Z","endDate":"2015-11-28T22:00:00.000Z"}
It turns to text:
11/11/2015 - 12/14/2015
THIS is a 10 seconds video showing this problem. (hope this helps)
And these are the things I load:
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/2.1.11/daterangepicker.js
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/2.1.13/daterangepicker.min.css
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/2.1.13/moment.min.js
http://luisfarzati.github.io/ng-bs-daterangepicker/ng-bs-daterangepicker.js
I fall into the same issue. I think it caused by the mechanism of updating input value, it probably has been changed in the latest version of daterangepicker (i used v2.1.17 while demo is working with 1.3.17). New daterangepicker has an option autoUpdateInput, it might be helpful to set it to false in directive configuration code (https://github.com/luisfarzati/ng-bs-daterangepicker/blob/master/src/ng-bs-daterangepicker.js):
//...
options.locale = $attributes.locale && $parse($attributes.locale)($scope);
options.opens = $attributes.opens || $parse($attributes.opens)($scope);
options.autoUpdateInput = false; // Changed row
if ($attributes.enabletimepicker) {
options.timePicker = true;
angular.extend(options, $parse($attributes.enabletimepicker)($scope));
}
//...
It helps with incorrect model binding, but there is still a bug with rendering -- initial start/end dates do not rendered (input is blank). So in general it looks like someone just needs to move ng-bs-daterangepicker to the latest version of daterangepicker.
Try using this lightweight pure AngularJS DateRangePicker (no jQuery). https://github.com/tawani/taDateRangePicker
I have a question about the bootstrap-datepicker.
When I select a random Date and then open the Popup again and click the same Date, the Input-Field clears. Is there any way to prevent this from happening?
I need this because in my case the Input-Field is not allowed to be empty.
I use Angular, and have a directive defined that inserts this little snip of hacky javascript... you might be able to do something similar:
.on('changeDate', function (ev) {
if (ev.dates && !ev.date && selectedDate)
{
// Fixes bug in bootstrap calendar without multiselect, where picking the same day unselects it
$(this).datepicker('setDate',selectedDate);
}
else if (ev.date && ev.date!=selectedDate) selectedDate = ev.date;
});
By having a variable named "selectedDate" somewhere before the constructor for your datepicker, this additional event handler will store valid dates and strip the bogus deselection. You'll notice the event object passed includes the array "dates" when incorrectly deselected, and only "date" when correctly selected.
I have a kendo ui dropdownlist in my view:
$("#Instrument").kendoDropDownList({
dataTextField: "symbol",
dataValueField: "symbol",
dataSource: data,
index: 0
});
How can I change the selected value of it using jQuery?
I tried:
$("#Instrument").val(symbol);
But it doesn't work as expected.
You have to use Kendo UI DropDownList select method (documentation in here).
Basically you should:
// get a reference to the dropdown list
var dropdownlist = $("#Instrument").data("kendoDropDownList");
If you know the index you can use:
// selects by index
dropdownlist.select(1);
If not, use:
// selects item if its text is equal to "test" using predicate function
dropdownlist.select(function(dataItem) {
return dataItem.symbol === "test";
});
JSFiddle example here
The Simplest way to do this is:
$("#Instrument").data('kendoDropDownList').value("A value");
Here is the JSFiddle example.
Since this is one of the top search results for questions related to this I felt it was worth mentioning how you can make this work with Kendo().DropDownListFor() as well.
Everything is the same as with OnaBai's post except for how you select the item based off of its text and your selector.
To do that you would swap out dataItem.symbol for dataItem.[DataTextFieldName]. Whatever model field you used for .DataTextField() is what you will be comparing against.
#(Html.Kendo().DropDownListFor(model => model.Status.StatusId)
.Name("Status.StatusId")
.DataTextField("StatusName")
.DataValueField("StatusId")
.BindTo(...)
)
//So that your ViewModel gets bound properly on the post, naming is a bit
//different and as such you need to replace the periods with underscores
var ddl = $('#Status_StatusId').data('kendoDropDownList');
ddl.select(function(dataItem) {
return dataItem.StatusName === "Active";
});
Seems there's an easier way, at least in Kendo UI v2015.2.624:
$('#myDropDownSelector').data('kendoDropDownList').search('Text value to find');
If there's not a match in the dropdown, Kendo appears to set the dropdown to an unselected value, which makes sense.
I couldn't get #Gang's answer to work, but if you swap his value with search, as above, we're golden.
It's possible to "natively" select by value:
dropdownlist.select(1);