I have a datepicker that was created with the following code snippet:
return new sap.m.DatePicker(sId, {
dateValue: `{${sPath}}`,
valueFormat: "dd-MM-yyyy",
displayFormat: "dd-MM-yyyy"
});
Typing wrong weird stuff into the field:
It does not recognize the invalid format.
But when I tried to write in this example, it does recognize.
What am I doing wrong?
const oDatePicker = new DatePicker(sId).bindValue({
path: sPath,
type: new DateType({ // "sap/ui/model/type/Date"
pattern: "dd-MM-yyyy",
})
});
const messageManager = sap.ui.getCore().getMessageManager();
messageManager.registerObject(oDatePicker, true);
return oDataPicker;
If working with data binding, you'll need to bind the value property instead of dateValue.
API reference: sap.m.DatePicker
Use the value property if you want to bind the DatePicker to a model using the sap.ui.model.type.Date.
Use the dateValue property if the date is already provided as a JavaScript Date object or you want to work with a JavaScript Date object. (...) Although possible to bind it, the recommendation is not to do it. When binding is needed, use value property instead.
And finally, register the control to the MessageManager or enable handleValidation. UI5 will then take care of displaying the error message if the input could not be parsed or violates given constraints.
https://sapui5.hana.ondemand.com/#/sample/sap.m.sample.DatePicker/code/Group.controller.js
handleChange: function (oEvent) {
var oText = this.byId("T1");
var oDP = oEvent.oSource;
var sValue = oEvent.getParameter("value");
var bValid = oEvent.getParameter("valid");
this._iEvent++;
oText.setText("Change - Event " + this._iEvent + ": DatePicker " + oDP.getId() + ":" + sValue);
if (bValid) {
oDP.setValueState(sap.ui.core.ValueState.None);
} else {
oDP.setValueState(sap.ui.core.ValueState.Error);
}
}
this is the change handler used in the sample you have to implement the error handling by yourself
Related
I am using the alternative JSON format along with AJAX to load data in tree. Now there is a new ask, I am required to add a new element at the end of <li> tag.
I have created sample URL to display what I am currently doing.
Tree crated using alternative JSON format along with AJAX
And how the new LI should appear
Tree created using hard coded HTML but shows how the LI should look like
I think I should be able to do this if I use HTML Data but since the project is already live with JSON format this would require me to change a lot so before I start making this major change I just wanted to check if this is possible using JSON and AJAX format or not.
So I got answer from Ivan - Answer
In short there is misc.js in the src folder which has question mark plugin, this is the best example of what I wanted to do.
I tweaked its code for my needs and here is the new code.
(function ($, undefined) {
"use strict";
var span = document.createElement('span');
span.className = 'glyphicons glyphicons-comments flip jstree-comment'
$.jstree.defaults.commenticon = $.noop;
$.jstree.plugins.commenticon = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
};
this.teardown = function () {
if (this.settings.commenticon) {
this.element.find(".jstree-comment").remove();
}
parent.teardown.call(this);
};
this.redraw_node = function (obj, deep, callback, force_draw) {
var addCommentIcon = true;
var data = this.get_node(obj).data;
//....Code for deciding whether comment icon is needed or not based on "data"
var li = parent.redraw_node.call(this, obj, deep, callback, force_draw);
if (li && addCommentIcon) {
var tmp = span.cloneNode(true);
tmp.id = li.id + "_commenticon";
var $a = $("a", li);
$a.append(tmp);
}
return li;
};
};
})(jQuery);
I am learning sapui5. I want pass my model data vitw parameter. I tried this but I think this is very bad a choice. How can I fix this?
var view = this.getView();
var model = new sap.ui.model.json.JSONModel();
var variable="testVariable";
model.loadData("......format=json&key=selectbyname&Name=" +variable+ ");
view.setModel(model);
You simply need to build the URL as string
var variable = "testVariable";
var url = "http://www.example.org/models?type=json&name=" + variable;
model.loadData(url);
view.setModel(model);
in your case it should be enough if you delete the bold part, so that you receive valid javascript:
model.loadData("......format=json&key=selectbyname&Name=" +variable + ");
to
model.loadData("......format=json&key=selectbyname&Name=" + variable );
Ok, so this is not a first, but I'm having a hard time getting a date. ;-)
I'm using Breeze, Knockout. Have a form where I wish to show short date.
<input name="start" data-bind="value: start" class="date required" required="required" placeholder="mm/dd/yyyy" style=" width:142px">
yields a long dateTime: Wed Aug 31 2011 20:00:00 GMT-0400 (Eastern Daylight Time).
Creating a method to format the desired short date accomplishes the goal of creating a short date, but my modelContext is unaware of any change notifications. So my object won't notify the screen of changes. I can possibly kludge this by trying to notify the dataContext on click, etc, but I'm hoping to not have that lost during the conversion.
function positionInitializer(posit) {
var shortDate = function (date) {
return date && moment.utc(date).isValid() ? moment.utc(date).format('L') : "";
};
posit.start = ko.observable(shortDate(posit.start()));
}
Are there any decent examples on how to do this?
I don't think I can convert when I make my call for the query b/c I am expanding the number of tables in my call & you can't do both.
var query = EntityQuery.from('Positions')
.where('id', '==', id)
.expand('Company, Projects')
.orderBy(orderBy.positions);
Thought I'd see what the hive-mind thinks...
There are a couple good options for handling date formatting using Knockout.
Writable Computed
You could create a writable computed for your date value and do all your formatting and parsing there. For example:
var myViewModel = function(){
var self=this;
self.trueDate = ko.observable(new Date());
self.formattedDate = ko.computed({
read: function(){
return moment(self.trueDate()).format('L');
},
write: function(value){
self.trueDate(moment(value).toDate());
}
});
}
<input type="text" data-bind="value: formattedDate" />
Any time the backing observable "trueDate" is updated its observers will be alerted.
Custom Binding
Another approach would be to build a custom data binding to format your data during binding and leave your view model simple.
var myViewModel = function(){
var self=this;
self.trueDate = ko.observable(new Date());
}
ko.bindingHandlers.dateString = {
init : function(element, valueAccessor) {
//attach an event handler to our dom element to handle user input
element.onchange = function(){
var value = valueAccessor();//get our observable
//set our observable to the parsed date from the input
value(moment(element.value).toDate());
};
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
if (valueUnwrapped) {
element.value = moment(valueUnwrapped).format('L');
}
}
};
(Please keep in mind that the binding code above is untested, and doesn't check for invalid input, etc.)
And then your binding would be
<input type="text" data-bind="dateString : trueDate" />
I prefer the custom binding approach, since it can be easily reused for other dates and view models. A custom binding can also read other bindings on that element, so you could make the date format string configurable as a binding rather than hard-coding it to "L".
I hope this helps!
#RyanRahlf Your answer gave me some inspiration so offering up configurable formatting and date validation add-ons to your solution.
My situation was a tad different. My date is coming in as JSON string (Ex. 2013-08-02T00:00:00) so I needed two formats, one from JSON, the other to what will be displayed (user friendly)
ko.bindingHandlers.date = {
init: function (element, valueAccessor, allBindingsAccessor) {
var formats = allBindingsAccessor().dateFormats || { from: "", to: "" };
element.onchange = function () {
var observable = valueAccessor();
var value = moment(element.value)
if (value && value.isValid()) {
//if format is not set then assume observed is a js date
if (formats.from) {
observable(value.format(formats.from));
}
else {
observable(value.toDate());
}
}
else {
observable("");
//ensures element is blank when invalid input is attempted
if (element.value) element.value = "";
}
};
},
update: function (element, valueAccessor, allBindingsAccessor) {
var formats = allBindingsAccessor().dateFormats || { from: "", to: "MM/DD/YYYY" };
var observable = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(observable);
if (valueUnwrapped) {
element.value = moment(valueUnwrapped).format(formats.to);
}
else {
element.value = "";
}
}
};
use (dateFormats optional with defaults)
<input type="text" data-bind="date: trueDate, dateFormats: { from: 'YYYY-MM-DDTHH:mm:ss', to: 'YYYY/MM/DD' }" />
If you're already using jQuery datepicker and you don't want to add another javascript library you could use:
ko.bindingHandlers.textDate = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor(),
allBindings = allBindingsAccessor(),
valueUnwrapped = ko.utils.unwrapObservable(value),
pattern = allBindings.datePattern || $.datepicker._defaults.dateFormat,
valueFormatted = $.datepicker.formatDate(pattern, valueUnwrapped);
$(element).text(valueFormatted);
}
};
However, it will only work with Date types.
I've tried to populate a dropdownlist with values from my database. I've got the following code in my .js file:
function getDropdowndata() {
var sHTML;
var filter;
var url = "dropdown.json";
jQuery.getJSON(url, function (dddata) {
if (dddata.rows.length > 0) {
sHTML = "";
for (x = 0; x < dddata.rows.length; x++) {
sHTML += (dddata.rows[x].Type + ":" + dddata.rows[x].Type + ";");
}
filter = sHTML.substring(0, sHTML.length - 1);
}
});
return filter;
}
And in my Jqgrid list I've got the following:
editoptions: { value: ":All;" + getDropdowndata() }
The problem I've got with this code is that it seems that the function is being executed too early and because of that the dropdownlist contains nothing.
The reason for my assumption is that if I put an alert inside of the javascript function before the return, the dropdownlist is filled with the values and everything seems to work.
Any suggestions?
Instead of getting the data with a custom function using JSON, you might want to try using the built-in functionality for dynamic select fields (see documentation: select edittype ). All you do is specify a url where the code for the select element is generated.
colModel:[
{name:'colName',
editable:true,
edittype:'select',
formatter:'select',
editoptions:{dataUrl:'/path/to/generated/html/select'}
]
Then you just need to make sure that /path/to/generated/html/select returns all the right HTML code for a select element.
The question I have is how I would be able to change the value that is set in the text box that the autocomplete is linked to. The task I am attempting to do is to convert from YUI 2 to YUI 3. Please don't say that I shouldn't do that... because It isn't my choice. I am aware... The code below is what was used before. I already have the autocomplete functionality doing most of what it needs to do. It's just when it gets to the field.itemSelectEvent.subscribe(myHandler) part that I can no longer get anything else to work. The list comes up with the persons information but when selected it just puts [object Object] in the text box instead of their name that automatically forwards to another page. Thank you for your help!!!
var field = new YAHOO.widget.AutoComplete("webUserSearch",
"webUserSearchContainer", oDS);
field.highlightClassName = "autoCompleteHighlight";
field.useShadow = true;
field.queryMatchContains = true;
field.maxResultsDisplayed = 20;
field.resultTypeList = false;
field.formatResult = function(oResultData, sQuery) {
return "<div class=\"result\"><u style=\"cursor:pointer\">"
+ oResultData['Last Name'] + ", " + oResultData['First Name']
+ "</u> (" + oResultData['User Name'] + ")</div>";
};
var myHandler = function(sType, aArgs) {
var theField = aArgs[0];
var selectedElement = aArgs[1];
var repObject = aArgs[2];
theField.getInputEl().value = repObject['Last Name'] + ", "
+ repObject['First Name'];
var newTabURL = <URL Removed for Stack Overflow>;
window.location.href = newTabURL;
};
field.itemSelectEvent.subscribe(myHandler);
Listen for the select event, then in the handler for that you'll get a result object. The structure of that is described in the docs for the result event (a little up from the select event).
I usually take a value out of the raw property on the result object to stick into the field.
resultTextLocator was the ticket. All I had to do was to return the value I wanted to display in the box.
resultTextLocator : function (result) {
return result["Last Name"] +
', ' +
result["First Name"];
}