I'm trying to assign a class to a row in my sap.m.Table dynamically using my view model SearchResults.
Unfortunately it's ignoring my class properties (see below).
How do I do this in my XML view ?
<ColumnListItem class="{SearchResults>typeClass}">
To apply CSS properties to row, you will also need take predefined CSS class of table .sapMListTbl along with your custom CSS class like I have done here.
I would suggest you to use formatter to apply these classes along with class from your model.
Unfortunately the class attribute is not bindable since it is not a property.
As a workaround you could do sth. like this:
<ColumnListItem visible="{
path: 'SearchResults>typeClass',
formatter: 'my.formatter.formatClass'
}" />
my.formatter.formatClass = function(typeClass) {
// in a static formatter this refers to the control, here your ColumnListItem
this.addStyleClass(typeClass);
// just always return true for the visible property
return true;
}
Note: The formatter can't be a member of your controller since then you won't be able to refer to the control (this will be the controller itself). Hence the formatter needs to be a static function.
Solution found!!!!
http://scn.sap.com/community/developer-center/front-end/blog/2016/05/17/coloring-table-rows-conditionally-in-sap-ui5-xml-views-based-on-odata-service
Hopefully this help anyone who's had the same problem...
Related
I have the following XMLView:
<mvc:View
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:data="sap.chart.data"
xmlns:viz="sap.viz.ui5.controls"
xmlns:con="sap.suite.ui.commons"
controllerName="MY_NAMESPACE.controller.ChartView"
xmlns:html="http://www.w3.org/1999/xhtml"
>
<!-- Panel here -->
</mvc:View>
Now, in my controller, I want to dynamically add a sap.m.Panel to the view.
In my onInit function, I pass the object of the current view to the method that creates the Panel and adds it to the view.
onInit: function() {
var sUrl = "/sap/opu/odata/sap/MY_ODATA_SERVICE/",
oModel = new ODataModel(sUrl), // v2
oCurrentView = this.getView();
this.getView().setModel(oModel);
this._createPanel(oCurrentView);
this._createChartContainer();
this._initializeCharts();
this._showCharts();
},
_createPanel: function(currentView) {
var sId = this._globals.panelId;
var oViewPanel = new Panel(sId, {
width: "auto"
}).addStyleClass("sapUiSmallMarginBeginEnd");
this._globals.panelState = oViewPanel;
currentView.addContent(oViewPanel);
return currentView;
},
However, the Panel is never rendered:
But when I call the getContent function of the view, the panel is listed as an entry.
Clarification:
Creating a sap.m.Panel in the XMLView isn't a problem. Placing this bit of XML into the XMLView works.
<Panel id="chartPanel"
class="sapUiSmallMarginBeginEnd"
width="auto"
></Panel>
But, I need to create and append the sap.m.Panel object to the XMLView at runtime (in the controller), not in the XMLView.
Now, the problem:
With above posted controller code, the panel objects gets created. In fact, it even gets registered as a content aggregation of the XMLView, but it simply doesn't get rendered (see picture above).
Any suggestion on why and how this behaviour occurs are greatly appreciated.
Issue
this.getView().addContent(/*...*/) doesn't work.
Why
Currently, XMLView won't allow manipulating its content via APIs as the documentation warns:
Be aware that modifications of the content aggregation of this control are not supported due to technical reasons. This includes calls to all content modifying methods like addContent etc., but also the implicit removal of controls contained by the content aggregation. For example the destruction of a Control via the destroy method. All functions can be called but may not work properly or lead to unexpected side effects.
This is, at the time of writing (v1.64), still the case.
PS: The above limit applies only to XMLView. Other view types, such as JSView*, are not affected.
* sap.ui.core.mvc.JSView and sap.ui.jsview are deprecated. Use Typed Views instead (Applicable since v1.90).
try to put the Panel inside the XML view and give it a property visible="false".
<Panel id="panelId" visible="false">
</Panel>
In your function you could do something like this:
_createPanel: function(){
var oPanel = this.getView().byId("panelId");
oPanel.setVisible(true);
// Other Methods for Panel
}
With the oPanel instance you can execute all methods listed in the API:
https://sapui5.hana.ondemand.com/#/api/sap.m.Panel
Hope this helps :-)
Best regards
I am trying to convert a string value to Boolean while binding it from a JSONModel. Ideally the value in my model is "true"/"false" and I want to bind it to the visible property of an item. The model is defined to be TwoWay binding but I guess that does not matter in this case
I have declared "complex binding" in the index.html.
data-sap-ui-xx-bindingSyntax="complex"
Then I create my XML view and bind the property from the model as below:
<P13nColumnsItem>
columnKey="{tableVariantAFModel>Fieldname}"
visible="{path:'tableVariantAFModel>Visible', type: 'sap.ui.model.type.Boolean', mode: 'sap.ui.model.BindingMode.TwoWay'}"
index="{tableVariantAFModel>DisplayOrder}">
<P13nColumnsItem>
When I run my app,it throws the below error:
Is there any step I am missing?
Also, I need to add this app to the Fiori Launchpad, so I need to define the complex binding in manifest.json file rather than in index.html . Where can I define it in the manifest file.
For simple use cases like this you can use an expression binding instead of implementing additional logic somewhere.
<P13nColumnsItem>
columnKey="{tableVariantAFModel>Fieldname}"
visible="{= ${tableVariantAFModel>Visible} === 'true'}"
index="{tableVariantAFModel>DisplayOrder}">
<P13nColumnsItem>
i would advise to use a formatter. See here. In the formatter you could write:
visible="{path:'tableVariantAFModel>Visible', formatter: '.formatter.stringToBoolean'}"
in the formatter you could create the function like:
stringToBoolean: function(_stringBoolean){
(_stringBoolean === "true") ? return true : return false;
}
You have to make sure that you instantiate the formatter in your controller, or optionally you could choose a function in your controller itself.
Using the infos in this link:
https://docs.typo3.org/typo3cms/ExtbaseFluidBook/8-Fluid/9-using-php-based-views.html
I try to create an action to output a JSON.
I have a normal controller with the list action:
public function listAction()
{
$storelocators = $this->storelocatorRepository->findAll();
$this->view->assign('storelocators', $storelocators);
}
And in ext/my_storelocator/Classes/View/Storelocator I have a class List.php:
<?
class Tx_MyStorelocator_View_Storelocator_List extends Tx_Extbase_MVC_View_AbstractView {
public function render() {
return 'Hello World';
}
}
All I get is:
Sorry, the requested view was not found.
The technical reason is: No template was found. View could not be resolved for action "list" in class "My\MyStorelocator\Controller\StorelocatorController".
So I guess there is something wrong with the paths. Or where is the Problem?
Edit: Extensioninfos
Vendor: My
key: my_storelocator
controller: NOT SURE (I created it with the extension_builder so I guess my controllers name is Storelocator)
action: list
From my understanding a classname like Tx_MyStorelocator_View_Storelocator_List should be correct. But its not working
You will need to create an empty file for the HTML view for your controller, e.g. Resources/Private/Template/Storelocator/List.html, even if you do not plan to use the HTML view or if you just return the content yourself (which is perfectly fine).
The reason for this is simply technical limitation.
First of all, TYPO3 now has a built-in JSON view, described thoroughly here: https://usetypo3.com/json-view.html. It lets you easily define which properties you'd like to render.
The error message means that your Controller is still pointing to the TemplateView - because thats the error the TemplateView throws if it can't find the defined template file.
You can specify which view to use to render within your controller. You can either set a default view via the $defaultViewObjectName property, like so:
/**
* #var string
*/
protected $defaultViewObjectName = '\TYPO3\CMS\Fluid\View\TemplateView';
You can also set it from within the Controller inside initialization actions like so:
public function initializeExportPDFAction(){
$this->defaultViewObjectName = 'Vendor\Extension\View\FileTransferView';
}
(I have, however, not yet found a way to define the template from within actions, any tips in the comments would be appreciated)
Your path syntax is probably out of date. Instead of writing a render() function in Classes/View/Storelocator/List.php, try writing a listAction() function in a Classes/Controller/StorelocatorController.php file. Extension Builder should have created this file for you, if you made an aggregate model with the usual "list, create, edit ..." and such actions.
Review A journey through the Blog Example and the following chapter, Creating a first extension, for tips.
Keep in mind that there is a mismatch between the documentation and the Extension Builder generated PHP code files. Developing TYPO3 Extensions with Extbase and Fluid has some parts up to date, and other parts still using old syntax.
I have a list view containing basic info about a set of tasks and I want to bind a detail view to the model object for an item when an item from the list is selected ...
http://jsfiddle.net/g2wYX/
I've been trying to use the change event of the grid ...
change: function (arg) {
var grid = $("#taskGrid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
kendo.bind("#taskDetail", selectedItem);
}
For some reason I can't seem to figure out the model binding on the detail view.
Does anyone have any ideas on how I can do this?
The binding is just simple as binding to any of the View, the only difference is that you have to place the Detail template inside a < scripts /> tag with type set as text/x-kendo-template. I have updated your fiddle example to what I have understood you require.
<script id="javascriptTemplate" type="text/x-kendo-template">
and provide the detail template link to the Grid as below:
detailTemplate: kendo.template($("#javascriptTemplate").html()),
Let me know if the solution is not what you desired or you are confused in any code statement.
Question Fiddle Solution
EDIT:
Updated the fiddle Solution as per your requirement,have a look and let me if that is as per your requirement.
The only change that is required in your code is just change the data-bind from value to html
Updated Solution
I am attempting to have multiple data grids in a single project. They have some different behavior and therefore different styling. The first grid is a fully custom grid, building the rows with an AbstractCellTableBuilder with a fully custom CSS file (using the DataGrid.Resources override).
The issue I am having is that my second grid's custom CSS is being applied to my first grid. I don't see any coding overlap. It just seems like the CSS classes are being anonymized the same, so they show up on the elements both grids.
Any thoughts?
Please let me know if there is anything I can provide to clarify the situation.
UPDATE:
ReportSelectorGrid.css has every class required by the DataGrid.Style defined. All of them are empty.
private SelectorDataGridResources gridResource = GWT.create(SelectorDataGridResources.class);
public interface SelectorDataGridResources extends DataGrid.Resources {
#Source({ "ReportSelectorGrid.css" })
DataGrid.Style dataGridStyle();
};
And then this is in my UiFactory method:
DataGrid<ReportSelectorItem> grid = new DataGrid<ReportSelectorItem>(-1, gridResource, KEY_PROVIDER);
You have to declare a DataGrid.Style sub-interface or they'll all share the same obfuscated class names. See also: https://code.google.com/p/google-web-toolkit/issues/detail?id=6144