jqm-datebox 'setTheDate' option errs - jquery-mobile

In the jqm-datebox plugin for jquery-mobile, there is an option 'setTheDate', whose usage is described in the documentation like so:
$('element').datebox('setTheDate', <date>);
When I use it, I get an error:
$('#dateboxElement').datebox('setTheDate', new Date() );
TypeError: Object [object Date] has no method 'get'
The plugin seems to expect the date object to have a method get(). I know there's getDay(), getMonth(), etc, but certainly no get().
Does anyone know what I'm doing wrong here?

I managed to make it work like this:
$(element).trigger('datebox', {
"method": "set",
"value": "2013-09-18", //I think this needs to be in the format datebox uses
"date": new Date()
});
There's a lot of other events like this in the "Event Payload" section here:
http://dev.jtsage.com/jQM-DateBox2/demos/api/events.html

Related

Illegal sap.ui.model.odata.type.DateTimeOffset

Posting for prosperity. I had zero hits from google.
I'm writing a SAP Business One Web Client extension. I'm using the worklist template and have the b1s/v2/ Service Layer metadata (auto generated while setting up the template)
Running the sandbox version ("npm run start-local") it automatically generates fake data based on the metadata. My data included an edm.DateTimeOffset which is resolved by Fiori using the sap.ui.model.odata.type.DateTimeOffset model.
Here is an example response object from the test data proxy (all autogenerated)
{
DocEntry: 1,
U_CardCode: "U_CardCode_0",
U_CardName: "U_CardName_0",
U_DocCurrency: "U_DocCurrency_0",
U_DocTotal: "",
U_DueDate: "2017-04-13T14:50:39.000Z",
U_Status: "U_Status_0",
U_SupplierInvNo: "U_SupplierInvNo_0",
}
A perfectly normal U_DueDate value that, according to all the documentation I could find is an accepted format, doublely confirmed by the fact that it's a sap generated value.
This produces an error on screen
Illegal sap.ui.model.odata.type.DateTimeOffset
Adding a formatter doesn't work. If it's unable to parse the value then it won't pass it on to a formatter.
Turns out there is a way to override the expected type in the metadata. I couldn't find much documentation on it, but I changed the element from
text="{'U_DueDate'}" />
to
text="{
path: 'U_DueDate',
targetType: 'any',
formatter: '.formatter.date'
}" />
The date is now accepted as a string so I can use a custom formatter.
Here is the date function in the formetter:
date : function (sValue) {
if (!sValue) {
return "";
}
var date = new Date(sValue)
var asString = date.toLocaleDateString("en-GB")
return asString;
}
You don't have to hard code the localization, but my use case is that niche

How to refresh previously bound entity every time user visits the page

I just ran into a problem where I am not sure how to solve.
Background: I've got an App with two views:
1st one to input a number,
2nd one to see the details.
After the view switched to the detail view, I would call the bindElement() to get my data from the backend.
_onRoutePatternMatched: function(oEvent) {
// ...
this.getView().bindElement({
path: "/EntitySet('" + id+ "')"
});
},
Problem is that the ID is quite often the same, hence, the method will call the backend only if the ID is different from the last call.
So I tried to solve the problem by using the following:
this.getView().getModel().read("/EntitySet('" + id+ "')",{
success: function(oData, response) {
that.getView().setModel(oData, "");
}
});
By this, the data is always up to date. But now the binding is a bit different.
Binding with bindElement():
{
"id": "1234",
"propety1": "abc",
// ...
}
Binding with setModel() and id = 1234:
{
"EntitySet('1234')": {
"id": "1234",
"propety1": "abc",
// ...
}
}
For the first way, my binding looked like this:
<ObjectHeader title="{id}">
Now, it would have to look like this:
<ObjectHeader title="{/EntitySet('1234')/id}">
And here I have a problem, because the value of id (in this case 1234) will always be different and so the binding won't work. I can't bind directly to the ObjectHeader, because I will need some properties from the model later. That is the reason I am binding to the view so that all that remain available.
My idea was to edit the binding inside the success method of the read method. I would like to delete the surrounding element. Do you have an idea, how to do this? Or even a simpler/better idea to solve my pity?
Edit:
I forgot to mention the refresh method. This would be possible, but where do I have to put it? I don't want to call the backend twice.
Simply call the API myODataModel.invalidateEntry(<key>) before binding the context in order to retrieve the latest data.
// after $metadata loaded..
const model = this.getOwnerComponent().getModel("odata");
const key = model.createKey(/*...*/) //See https://stackoverflow.com/a/47016070/5846045
model.invalidateEntry(key); // <-- before binding
this.getView().bindElement({
path: "odata>/" + key,
// ...
});
From https://embed.plnkr.co/b0bXJK?show=controller/Detail.controller.js,preview
invalidateEntrydoc
Invalidate a single entry in the model data.
Mark the selected entry in the model cache as invalid. Next time a context binding or list binding is done, the entry will be detected as invalid and will be refreshed from the server.

How to dynamically set binding type's "formatOptions" and "constraints" in XML with binding?

I have a list of elements (OData set) and use a binding to show this list.
One field is for a quantity value and this value could sometimes need some decimal places.
The requirement is: only show that amount of decimal numbers that is also available in the OData service.
Annotation techniques can't be used.
I 'hacked' something that is misusing a formatter to update the type of a binding. But this is 'a hack' and it is not possible to convert it to XML views. (The reason is a different handling of the scope the formatter will be called).
So I am searching for a working solution for XML views.
The following code would not work but shows the issue:
new sap.m.Input({ // looking for an XML solution with bindings
value: {
path: "Quantity",
type: new sap.ui.model.type.Float({
// formatOptions
maxFractionDigits: "{QuantityDecimals}",
// ...
}, {
// constraints
minimum: 0
}),
// ...
}
});
The maxFractionDigits : "{QuantityDecimals}" should be "dynamic" and not a constant value.
Setting formatOptions and constraints dynamically in XML (via bindings or a declared function) is unfortunately not (yet) supported. But IMHO this is a valid enhancement request that app developers would greatly benefit from, since it encourages declarative programming.
I already asked for the same feature some years ago but in a comment at https://github.com/SAP/openui5/issues/2449#issuecomment-474304965 (See my answer to Frank's question "If XMLViews would allow a way to specify the dynamic constraints as well (e.g. enhanced syntax), would that fix the problem?").
Please create a new issue via https://github.com/SAP/openui5/issues/new with a clear description of what kind of problems the feature would resolve and possibly other use cases (You can add a link to my comment). I'll add my 👍 to your GitHub issue, and hopefully others too.
I'll update this answer as soon as the feature is available.
Get your dynamic number from your model and store it in a JS variable.
var nQuantityDecimals = this.getModel().getProperty("/QuantityDecimals");
new sap.m.Input({
value : {
path : "Quantity",
type : new sap.ui.model.type.Float({
maxFractionDigits : nQuantityDecimals,
source : {
groupingSeparator: ",",
decimalSeparator: ".",
groupingEnabled: false
}
}, {
minimum:0
})
}
}),

Dart List within a Map

I have a Map in Dart (originally loaded from JSON) that looks something like this:
somevar = {
'Title': 'Some object',
'items': [{'title': 'Item 1 Title'}, {'title': 'Item 2 Title'}]
}
For some reason somevar['items'] doesn't behave quite like a list.
I get Exception: NoSuchMethodError : method not found: 'iterator' if I attempt to iterate over the list.
I also get a similar error if I try somevar['items'].length
If I manually load this "list" like this: someList = new List(somevar['items']); then it works as expected.
Any idea why this is that case, and what I'm doing wrong? For me the natural expectation would be that a "list" parsed from JSON will behave exactly like the List() object.
Never mind, seems that I had a deeper issue in my code that cause my somevar variable to be null (even though it should have the map.
Anyway, I'm marking this as solved for now so not to waste anyone's time.

Dojox Grid pass two fields to formatter

I created a dojox.Grid successfully, but in one case I need to pass two fields to a formatter function instead of just one.
For instance:
{
field: 'id',
name: 'Id',
formatter: formatterFunction,
},
I need to pass to formatterFunction() both 'id' and 'name' for instance. How can I do this?
Thank you.
I know this was already mentioned in the IRC channel, but I'm answering here so others are aware, and also to address your further question that I'm not sure anyone answered.
New in 1.4 If you set the value of the field to "_item", then your formatter will be called with the entire item from the store - instead of just one field value
This makes it possible to do what you want using a formatter as well.
http://www.dojotoolkit.org/reference-guide/dojox/grid/DataGrid.html#usage
In the simplest case, without setting the grid's formatterScope, the grid's store can be accessed from within formatters via this.grid.store, e.g.:
function fmtItem(value) {
var store = this.grid.store;
return store.getValue(value, 'id') + ': ' + store.getValue(value, 'name');
}
Here's a really simple example of the above formatter in action:
http://jsbin.com/upico4/edit
There's also an example of this in one of the test pages, which creates an object to hold and scope the formatters:
http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/grid/tests/test_grid_formatters.html
As from dojo 1.4 you can also get multiple fields from a store. Should look something like:
var layout = [{
rows: [
{name: 'Title', fields:['Title', 'url'], formatter:formatLink}
]}]
function formatLink(value){
return ''+value[0]+'';
}
That uses the value from the field "url" to point your link at and the displayed title is filled with the data from "Title" field in your store.
Are you sure that you want to format and maybe not use get instead?
When you use a formatter the only value that is passed to the function is the value that field represents.
However, if you were to use get instead, you could use the item to access the other values. (However then you will lose sorting).
So for your column have
{
field: 'id',
name: 'Id',
get: getFunction
},
Then have
getFunction: function(index,row) {
return row.id + row.name;
}
function formatterFunction(val, rowIdx, cell){
var name=this.name,
field=this.field;
}

Resources