im trying to bind an entitySet from a oData-Service to a list.
My code looks like this:
var list = oView.byId("list");
var requestModel = new sap.ui.model.json.JSONModel()
.attachRequestCompleted(function(data) {
var model = new sap.ui.model.json.JSONModel();
model.setData(data.getSource());
list.setModel(model);
});
requestModel.loadData("/sap/opu/odata/sap/XXX_SRV/detailSet?$filter=XXX eq 'XXX'");
My service returns a array of detail-Objects as expected but i can't seem to find a way to bind them to the list.
Thanks
I finally found a solution:
At first i had to create a dummy Path in my list like this:
<Table class="sapUiResponsiveMargin" items="{/dummy}" id="table" width="auto">
When you can bind the url directly to the table:
var url = "/XXX?$filter=XXX eq '" + XXX + "'";
var table = oView.byId("table");
table.bindItems({
path: url,
template: table.getBindingInfo("items").template
});
To get started with the ODataModel try this guide. In general it is very easy.
Instantiate the model like described in the guide.
Set the model to the view.
Make use of the binding syntax in XML views to trigger a request to load your entities.
Related
I am developing a master detail Fiori app using SAP UI5. As the details contains more than 40 columns, I made separate OData services for master & detail.
In Master page, data are coming correctly. Now my task is that on any table line, when user clicks on Detail, next page will be open with details base on two key values of master table.
I'm getting two keys in variables in detail page as follows and it is working fine:
var spayid = jQuery.sap.getUriParameters().get("payid");
var spaydt = jQuery.sap.getUriParameters().get("paydt");
Next, I have created two filters as follows which is also working fine.
var filter1 = new Filter({
path: "Laufi",
operator: FilterOperator.EQ,
value1: spayid
});
var filter2 = new Filter({
path: "Laufd",
operator: FilterOperator.EQ,
value1: spaydt
});
Now I am calling OData service which is also working fine:
var oODataModel = new ODataModel("proxy/http/FIORI-DEV.abc.com:8000/sap/opu/odata/sap/ZASA_FI_pay_D_SRV?sap-client=100", {
json: true,
useBatch: false
});
this.getView().setModel(oODataModel);
I don't know now how to filter data. What should be included in above so that it will filter data according to my filters filer1 and filter2? I have tried following but it is not working.
filters : [ filter1, filter2 ],
json: true,
useBatch: false
I am very good in ABAP but not an expert in SAPUI5. I am in learning phase.
First of all, I was thinking to pass parameters on OData service so that only the required data are fetched. Means my OData call should be like this:
new ODataModel("proxy/http/FIORI-DEV.abc.com:8000/sap/opu/odata/sap/ZASA_FI_PAYMENT_D_SRV/PdetailSet(Laufi= spayid, Laufd = spaydt)?sap-client=100");
But this seems not like possible.
Second option is that I will fetch whole details in OData service and then during binding to table I will apply filter.
The purpose of the sap.ui.model.Filter class is usually to apply filters to lists on the UI. For example, if you have a list of items and you want to limit that list to a subset of items which fulfills certain criteria.
But what you have here appears to be a classic master-detail scenario where you have a list of items and then when the user selects one show more information about that one item.
The usual solution for such a scenario is to assign the full model to the detail-view and then use an element binding (also known as "context binding") on the view to tell it which item to display.
When the source of the item is a click on an element which already had an element binding, then you can actually retrieve the correct binding path from the click event and just apply it to your detail-view.
From one of the official demos:
onItemSelected: function(oEvent) {
var oSelectedItem = oEvent.getSource();
var oContext = oSelectedItem.getBindingContext("products");
var sPath = oContext.getPath();
var oProductDetailPanel = this.byId("productDetailsPanel");
oProductDetailPanel.bindElement({ path: sPath, model: "products" });
}
When you don't have any convenient way to get an element path from, then you have to construct one yourself:
var detailPanel = this.getView().byId("idOfDetailPanel");
detailPanel.bindElement("PdetailSet(Laufi = " + spayid +", Laufd = " + spaydt + ")");
The latter code snippet does of course assume that the oData-service actually supports access with a key consisting of laufi and laufd. This is decided by:
The definition of the key fields of the entity type in the SAP Gateway Service Builder (transaction SEGW)
The ABAP implementation of the method get_entity of the data provider class of that oData-service.
I'm working on a simple Master detail SAPUI5 app.
I use V2 Odata Model an TwoWay binding.
When I click on the submit button I want to get all the values entered by the user in the model.
The problem is that I get only header data but not items data.
I need both in order to use the create deep entity method in the backend.
Here is my code:
var sPath = evt.getSource().getBindingContext().getPath();
var myData = evt.getSource().getBindingContext().getObject(sPath);
In myData I get the header data and the navigation propoerty with no data in it.
How can I get the items data as well ?
I tried with expand but no success !
Have you tried to do it in the following way ?
var sPath = evt.getSource().getBindingContext().getPath(),
var myData = yourModel.getProperty(sPath);
If you model has a particular name you could do something like this -
var sPath = evt.getSource().getBindingContext("modelName").getPath(),
var myData = this.getView().getModel("modelName").getProperty(sPath);
You always need to get the path, and using it, you get the value in that path for the model
I would like to update some obsolete code from umbraco v4 in the updated to v6 solution.
I have
entitiesFolder = new umbraco.cms.businesslogic.web.Document(folderId);
entitiesFolder.ReorderChildren(
entitiesFolder.Children.OrderBy(fdoc => fdoc.Text),
refreshEntireCache);
Now the recomendation instead of obsolete Document is to use Umbraco.Core.Models.Content. How? Didn't find (as usual for Umbraco) any documentation about... (
// new version
var toto = new Umbraco.Core.Models.Content(??)
toto.SoirtChildren(???)
Are you doing this from a razor view? If so you can do:
var nodeId = 123;
var myNode = Umbraco.TypedContent(nodeId);
var property = myNode.GetPropertyValue<string>("myStringAlias");
If you're doing it from a class or something you'll have to use something like:
var helper = new UmbracoHelper(UmbracoContext.Current);
var nodeId = 123;
var myNode = helper.TypedContent(nodeId);
(This is untested but it should work..)
If you are just querying data and need to sort it, using the umbracoHelper is a great way to go. It only hits the xml cache in App_Data/umbraco.config, so you don't hit the database.
However, if you are attempting to programatically sort some of the nodes in the content tree, you will need to use the ContentService. You will need to use the ContentService whenever you actually want to programatically modify content nodes. You will also find a similar MediaService for media.
https://our.umbraco.org/Documentation/Reference/Management-v6/Services/ContentService
ApplicationContext.Current.Services.ContentService.Sort(...)
I've created my first custom Umbraco 5.1 solution. At this point I have a content item ("homepage") with a custom template which has a custom partial macro on it. Now how do I load an entity using the Umbraco helper? I've tried adding several HiveId constructions using a Uri, however I keep getting the same error:
Parameter 'other' must be of type Guid to convert to a Guid CLR type, but it is 'Uri', with value: xxx
Macro partial:
#inherits PartialViewMacroPage
#using Umbraco.Cms.Web
#using Umbraco.Cms.Web.Macros
#using Umbraco.Framework
#{
//All these fail with the same error message...
//Based on name:
var p = Umbraco.GetContentById(
new HiveId(
new Uri("content://Homepage")));
//Based on path
var p = Umbraco.GetContentById(
new HiveId(
new Uri("content://p__nhibernate/v__guid/5a4abe489a2e47858bd2a0580180b683")));
//With custom Hive provider (I've added this using a custom tree/section and products show up, so the hive provider works)
var p = Umbraco.GetContentById(
new HiveId(
new Uri("custom://products/1")));
}
Why are you creating a Uri?
The HiveId accepts a string parameter which you can use instead. So does Umbraco.GetContentById(string id)
I am Umbraco 5 certified and we never used the Uri overload of the HiveId constructor.
var p = Umbraco.GetContentById("yourStringHiveIdHere"); //(string overload) or
var p = Umbraco.GetContentById(new HiveId("yourSringHiveIdHere")); // (HiveId overload)
Also where are you getting your HiveId from?
Let's say I have two models: customers and orders.
Every order belongs to a customer.
I also set a orders (index) view with a Datatable showing all the orders.
If I want to see all the orders for a given customer all I have to do is to filter the results for that customer writing the concerning customer name in the "search" field or selecting that customer from its column filter field.
Now I'd like to implement a customer-orders link which automatically shows the orders Datatable with those settings.
In other words, I'd like that a link to /orders?isearch='customer_name+customer_surname' will show the Datatable with the customer full name already written in the search field (or the customer column filter set accordingly).
Of course I can fetch the #customer instance variable from the controller and pass it to the view, but then?
Using the oSearch variable in the initialization code I can define an initialization value for the search field, the isearch variable:
$(document).ready( function() {
var isearch = $('#isearch').val()
$('#example').dataTable( {
"oSearch": {"sSearch": isearch}
} );
} )
The isearch value is stored in a proper hidden field in the view:
<%= hidden_field_tag "isearch", #isearch.to_s, { :id => "isearch" } %>
(This is the best way I found so far to pass an instance variable to a .js file in Rails).
Last but not least, the #isearch instance variable is set from the order_controller:
#isearch = params[:isearch]
Of course its value should be passed to the url like:
.../orders?isearch='customer_name+customer_surname'
----ADDENDUM----
I figured out I don't need an instance variable, in fact I can pass as many url params as I want using this javascript function:
function getUrlParam( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1].replace("+", " ");
}
Then I can fetch them from my .js file like this:
// fetches url params
var isearch = getUrlParam('isearch');
var customer_name = getUrlParam('customer_name');
var order_status = getUrlParam('order_status');
Accordin to these values I not only can set the oSearch variable but also a column-specific using Datatables aoSearchCols initialization parameter ( http://www.datatables.net/ref#aoSearchCols )
The last problem to solve, given that I am using individual column filtering with select elements (http://www.datatables.net/release-datatables/examples/api/multi_filter_select.html), so set every select element according to the URL-passed params.
I did it with this jQuery instruction:
// sets all select filters according to url passed params
$('select').val([customer_name, preparation_kind, preparation_status]);
From the performance point of view this solution is improvable, but its easy and it works.