Skip to Content
0

Alternative to MatrixLayout

Mar 14, 2017 at 02:43 PM

86

avatar image
Former Member

Hello experts!

I have created my first ui5 app via google app engine (hosted here: https://ustadhanif.appspot.com/). Its using the openUi5 ondemand ui5 resources with a Spring 4 MVC backend. However, when I created it, I used the ui5 desktop libraries as opposed to the mobile libraries. I would like to migrate this application into the proper MVC pattern and use only the mobile libraries.

Here is what the app looks like:

The individual cards are driven by css and html5 as opposed to using images. The above layout worked nicely with the use of the sap.ui.commons.layout.MatrixLayout. Here is a snippet of how it was constructed:

var pokerHandsArray = [];
var aCardValues = [ "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2" ];
var aSuitValues = [ "hearts", "diams", "clubs", "spades" ];
var cardIdArray = [ "firstCard", "secondCard", "thirdCard", "fourthCard" ];

var cardIndex = 0;
var oTextView3 = new sap.ui.commons.TextView({
	text : 'VS',
	semanticColor : sap.ui.commons.TextViewColor.Positive,
	design : sap.ui.commons.TextViewDesign.H1,
	enabled : false
});

/**
 * Create 2 rows of all 52 cards to choose from
 */
var oCardsMatrixLayout = new sap.ui.commons.layout.MatrixLayout({
	id : "cardsMatrix",
	layoutFixed : false,
}).addStyleClass("center");

var oCardsMatrixRow = new sap.ui.commons.layout.MatrixLayoutRow({});

var rowCount = 0;
jQuery.each(aSuitValues, function(index1, suit) {
	/**
	 * Make 2 rows in the matrix
	 */
	if (rowCount % 2 == 0) {
		oCardsMatrixRow = new sap.ui.commons.layout.MatrixLayoutRow({});
	}
	rowCount++;
	jQuery.each(aCardValues, function(index2, card) {
		var matrixCellId = suit + card + 'cell';
		var htmlId = suit + card + 'html';
		oCardsMatrixRow.addCell(new sap.ui.commons.layout.MatrixLayoutCell({
			id : matrixCellId,
			content : new sap.ui.core.HTML({
				id : htmlId,
				// the static content as a long string literal
				content : "<div class='smallCard'>" + card + " &" + suit + ";</div>",
				preferDOM : false,
			}).attachBrowserEvent('click', function() {
				// alert("selected " + card + suit);
				display(card, suit);
			})
		}));
	});
	oCardsMatrixLayout.addRow(oCardsMatrixRow);
});

As you can see, I used a combination of jquery nested loops and MatrixLayoutRow to get the desired result. I started creating an xml view with a Grid but I don't see how I can use binding relatively simply here. I tried but then the HTML control which helps resolve the card value and suite i.e) A hearts&; doesn't get interpreted correctly.

Could someone guide me as to how I can achieve the above UI the same way - 2 rows of 26 cards as shown above but abiding by the best practices of MVC, mobile libraries and clean separation?

thank you kindly!

Hanif

pokerhands.png (39.5 kB)
10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

3 Answers

Srikanth KV Mar 14, 2017 at 07:43 PM
0

grid layout can have a max of 12 columns....instead of grid may be you can use FlexBox which have two sub layouts HBox and VBox

Create XML view with root as VBox to hold two rows of 56 cards, below that have 2 HBox's each having 26 cards

<mvc:View
	xmlns="sap.m"
	xmlns:mvc="sap.ui.core.mvc"
	xmlns:core="sap.ui.core"
	displayBlock="true">
	
	<VBox>
		<!-- First row of 26 cards -->
		<HBox>
			<!--Each row refers to one card -->
			<core:HTML content="<div class='smallCard'>card & suit </div>" />
			<core:HTML content="<div class='smallCard'>card & suit </div>" />
			<core:HTML content="<div class='smallCard'>card & suit </div>" />
			....
			...
			...
		</HBox>
		
		<!-- Second row of 26 cards -->
		<HBox>
			<!--Each row refers to one card -->
			<core:HTML content="<div class='smallCard'>card & suit </div>" />
			<core:HTML content="<div class='smallCard'>card & suit </div>" />
			<core:HTML content="<div class='smallCard'>card & suit </div>" />
			.....
			....
			....
		</HBox>
	</VBox>
</mvc:View>
Share
10 |10000 characters needed characters left characters exceeded
avatar image
Former Member
Mar 22, 2017 at 03:22 PM
0

As responsive layout needs a bit different approach, and you'd like to have your app working on many devices, there is I guess a bit easier way to do so. Please check this code:

View

<mvc:View controllerName="test.cardscards.controller.View1" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
xmlns:l="sap.ui.layout" displayBlock="true" xmlns="sap.m">
<App>
<pages>
<Page title="{i18n>title}">
<content>
<l:Grid defaultSpan="L4 M6 S6" class="sapUiSmallMarginTop"  content="{cards>/results}">
<l:content>
<FlexBox class="panelBorder" id = "test">
<layoutData><l:GridData span="L6 M12 S12"/></layoutData>
<items>
<Panel content="{cards>colors}">
<content>
<CustomTile class="tileborder" >
<content>
<Label text="{cards>name} of {cards>color}" />
</content>
</CustomTile>
</content>
</Panel>
</items>
</FlexBox>
</l:content>
</l:Grid>
</content>
</Page>
</pages>
</App>
</mvc:View>

Controller:

sap.ui.define([
	"sap/ui/core/mvc/Controller"
], function(Controller) {
	"use strict";


	return Controller.extend("test.cardscards.controller.View1", {


		onInit: function() {
			var i, j;
			var oJson = {};
			var aColors = ["Hart", "Spade", "Diamond", "Club"];
			var aFigures = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "W", "Q", "K", "A"];
			oJson.results = [];
			
			for (i=0; i<4; i++){
				oJson.results.push({"colors": []});
				for (j=0; j<13; j++){
					oJson.results[i].colors.push({"name":aFigures[j], "color":aColors[i]});
				}
			}
			var oModel = new sap.ui.model.json.JSONModel(oJson);
			this.getView().setModel(oModel, "cards");
		}
	});
});

css:

.tileborder {
    border-radius: 10px 10px 10px 10px!important;
    -moz-border-radius: 10px 10px 10px 10px!important;
    -webkit-border-radius: 10px 10px 10px 10px!important;
    border: 2px solid #b8b6b8!important;
    width: 4em;
    height: 5em;
    text-align: center;
}

cards.png (21.8 kB)
Share
10 |10000 characters needed characters left characters exceeded
avatar image
Former Member
Mar 24, 2017 at 02:45 PM
0

Thank you Srikanth & Andrzej for the awesome responses! I noticed that in my approach, the cards themselves don't resize (scale up or down) depending upon device, they just wrap around as need be. In the approaches you guys have defined they do. I will try and incorporate your suggestions and report back the results. Hopefully the div content element within my html control will interpret correctly when binding to a model. What I mean is this:

content : new sap.ui.core.HTML({
	id : htmlId,
	// the static content as a long string literal
	content : "<div class='smallCard'>" + card + " &" + suit + ";</div>",
	preferDOM : false,

The content gets resolved to for example: "<div class='smallCard'>A ♥</div>" and the browser correctly interprets the HTML code for the heart symbol. However, when I tried to use binding like so: "<div class='smallCard'>{cards>rank} &{cards>suit};</div>" the binding is taken literally and not interpreted correctly. Any ideas on how I can address this?

Share
10 |10000 characters needed characters left characters exceeded