Dynamic number of tabs using ionic2-super-tabs tag - ionic-framework

I do not have fixed number of tabs in my app page, so that using *ngFor in ionic2-super-tabs tag to get dynamic tabs as mentioned in below ts and html.
typescript :
import { AustraliaPage } from './australia';
import {CanadaPage} from './canada';
export class CountryPage {
Australia = AustraliaPage;
Canada= CanadaPage;
tabsLoaded = false;
ionViewDidLoad() {
this.testservice.getCoutrynames().subscribe(countries => {
this.tabs = countries;
// below is the output data of getCoutrynames() method
// "countries": [
// {
// "country_id": 1,
// "countryName": "Canada"
// },
// {
// "country_id": 2,
// "countryName": "Australia"
// }
// ]
this.tabsLoaded = true;
})
}
}
HTML :
<super-tabs scrollTabs="true" *ngIf="tabsLoaded">
<super-tab *ngFor="let tab of tabs" [root]="tab.countryName" title="tab.countryName"></super-tab>
</super-tabs>
But getting a below error.
Runtime Error
Uncaught (in promise): invalid link: Australia
Any help would be greatly appreciated.

You are setting the root to the string 'Australia' not the Australia object/page. Do something like this:
pages = {
Australia: AustraliaPage,
Canada: CanadaPage,
...
};
<super-tabs scrollTabs="true" *ngIf="tabsLoaded">
<super-tab *ngFor="let tab of tabs" [root]="pages[tab.countryName]" title="tab.countryName"></super-tab>
</super-tabs>

Related

Set value in react-bootstrap-typeahead

First off, let me admit to being a React newbie...
I want to set the value displayed and selected in this component after the first render (eg from a button)
Here's my test code (with imports etc removed)
$(function () {
const data = [
{
DataID: 1,
DataType: 'Data1'
},
{
DataID: 2,
DataType: 'Data2'
},
{
DataID: 3,
DataType: 'Data3'
},
{
DataID: 4,
DataType: 'Data4'
}
]
ReactDOM.render(
<SelectionsExample
options={data}
preset={[data[1]]}
/>,
document.getElementById('divExampleSelector')
)
});
function SelectionsExample(props) {
const [options, setOptions] = useState(props.options);
const [preset, setPreset] = useState(props.preset);
function handleSelect(s) {
console.log((s ? s.DataType : 'Nothing') + ' selected');
}
function handlePreset() {
let s = options[2];
console.log('Preset', s);
setPreset([s]);
}
return (
<>
<Typeahead
id="selections-example"
options={options}
defaultSelected={preset ?? []}
onChange={(s) => handleSelect(s[0])}
labelKey="DataType"
clearButton
placeholder="Choose a value..."
/>
<Button
onClick={handlePreset}
variant="outline-secondary">Preset </Button>
</>
)
}
On first render, all works fine with as expected the second item in my options list shown.
But when I click the 'Preset' button, handlePreset runs but nothing changes in the control. I would have expected the selection to change to value of options[2].
If I change the Typeahead prop 'defaultSelected' to 'selected', then the only item I can select is the one I pass in in the 'preset' prop.
What am I doing wrong?
Using defaultSelected makes the typeahead uncontrolled, and will only display a preset selection when the component mounts. Since you want to be able to change the preset later, you should use selected to make the typeahead controlled:
function SelectionsExample(props) {
const [selected, setSelected] = useState(props.preset);
function handleSelect(s) {
console.log((s[0] ? s[0].DataType : 'Nothing') + ' selected');
setSelected(s);
}
function handlePreset() {
let s = props.options[2];
console.log('Preset', s);
setSelected([s]);
}
return (
<>
<Typeahead
clearButton
id="selections-example"
labelKey="DataType"
onChange={handleSelect}
options={props.options}
placeholder="Choose a value..."
selected={selected}
/>
<button onClick={handlePreset}>
Preset
</button>
</>
);
}
Working sandbox: https://codesandbox.io/s/heuristic-haze-3vugt

Angular PrimeNg Using autocomplete and passing REST object

I have an issue with PrimeNg autocomplete :
When i type any research, I obtain [Object Object] in the input text.
First I have an API call for getting a data set :
ngOnInit(): void {
this.getCategories();
}
private getCategories(): void {
const response = this.apiService.getCategories().subscribe(
(data) => {
this.categories = data as CategoriesModel[];
}
);
console.log('Get categories');
console.log('response ', response);
}
It allows me to retrive my data correctly (here is a sample) :
[
{
"id": "1",
"categoryName": "Name1",
"docDescription": "Description1 ..."
},
{
"id": "2",
"categoryName": "Name2",
"docDescription": "Description2"
}..
]
Now I try to handle my array of javascript objects in order to filter them :
I defined member variables in my component :
categories: CategoriesModel[];
filteredCategories: CategoriesModel[];
category: CategoriesModel;
I add this code into the HTML template:
<p-autoComplete
[(ngModel)]="category"
[suggestions]="filteredCategories"
(completeMethod)="filterCategories($event)"
[size]="30"
[minLength]="1" placeholder="Hint: type a letter"
[dropdown]="true">
<ng-template let-category pTemplate="item.categoryName">
<div class="ui-helper-clearfix" style="border-bottom:1px solid #D5D5D5">
{{category.id}}
<div style="font-size:18px;float:right;margin:10px 10px 0 0">{{category.categoryName}}</div>
</div>
</ng-template>
</p-autoComplete>
<span style="margin-left:50px">Category: {{category?.categoryName||'none'}}</span>
Now I try to use a filter method that will show in list results :
filterCategories(event): void {
this.filteredCategories = [];
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < this.categories.length; i++) {
this.category = this.categories[i];
if (this.category.categoryName.toLowerCase().indexOf(event.query.toLowerCase()) === 0) {
console.log(this.category.categoryName);
this.filteredCategories.push(this.category);
}
}
}
I finally solved this by modifying the template :
<p-autoComplete
[(ngModel)]="category"
[suggestions]="filteredCategories"
field = "categoryName"
(completeMethod)="filterCategories($event)"
[size]="30"
[minLength]="1" placeholder="Hint: type a letter"
[dropdown]="true">
<ng-template let-category pTemplate="categoryName">
<div class="ui-helper-clearfix" style="border-bottom:1px solid #D5D5D5">
{{category.id}} {{category.categoryName}}
</div>
</ng-template>
</p-autoComplete>

Return a value with highlighted color

Requirement: I have a fragment.xml file which I am extending. The form element is currently being processed with a formatter.js where I am validating some values based on some condition:
In Fragment, the formatter function is getting called correctly
<Text text="{
parts: [
{path: 'ZName1'},
{path: 'ZStatus1'}
],
formatter: '.Formatter.delivery'
}" >
Formatter:
delivery: function(iName, iStatus) {
var sResult = "";
if(iStatus === "A" ) {
sResult = iName ;
} else if(iStatus === "P") {
sResult = iName ;
} else {
sResult = iName ;
}
return sResult ;
}
In the output, I should get sResult highlighted either in green, yellow, or red based on the condition.
Binding on text will not work for highlighting the text. refer the example for alternative solution.
<Text id="id" text="{ZName1}" class="{parts: [{path: 'ZName1'},{path: 'ZStatus1'} ],
formatter : '.Formatter.delivery'}">
In Format.js file:
delivery: function(iName, iStatus) {
var idText = this.byId("id");
if(iStatus === "A" ) {
idText.removeStyleClass("classForYellowColor");
idText.removeStyleClass("classForRedColor");
return "classForGreenColor";
} else if(iStatus === "P") {
idText.removeStyleClass("classForGreenColor");
idText.removeStyleClass("classForRedColor");
return "classForYellowColor";
} else {
idText.removeStyleClass("classForGreenColor");
idText.removeStyleClass("classForYellowColor");
return "classForRedColor";
}
}
Instead of plain sap.m.Text, take advantage of sap.m.ObjectStatus which works exactly like Text but supports semantic colors (via state) out-of-the-box.
Run the following snippet to see the results:
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/m/List",
"sap/m/CustomListItem",
"sap/m/ObjectStatus", // instead of Text
"sap/ui/core/ValueState",
"sap/ui/model/json/JSONModel",
], (List, Item, ObjectStatus, ValueState, JSONModel) => new List().bindItems({
path: "/myData",
template: new Item().addContent(new ObjectStatus({
text: "{ZName1}",
state: {
path: "ZStatus1",
formatter: status =>
status === "A" ? ValueState.Success : // Green
status === "P" ? ValueState.Warning : // Yellow
status === "Z" ? ValueState.Error : // Red
ValueState.None
},
}).addStyleClass("sapUiSmallMargin")),
}).setModel(new JSONModel({
myData: [
{
ZName1: "Success",
ZStatus1: "A"
},
{
ZName1: "Warning",
ZStatus1: "P"
},
{
ZName1: "Error",
ZStatus1: "Z"
},
{
ZName1: "None",
ZStatus1: ""
},
],
})).placeAt("content")));
<script>
window["sap-ui-config"] = {
libs: "sap.ui.core, sap.m",
preload: "async",
theme: "sap_belize",
compatVersion: "edge",
"xx-waitForTheme": true,
"xx-async": true
}
</script>
<script id="sap-ui-bootstrap" src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
We can see green, yellow, and red depending on the condition.
In Fragment file:
<Text text="{parts: [{path: 'ZName1'},{path: 'ZStatus1'}],
formatter : '.Formatter.delivery'}" >
In CSS file:
.greenTxtHlight {
color: green;
}
.yellowTxtHlight {
color: yellow;
}
.redTxtHlight {
color: red;
}
In Formatter file:
delivery: function(sName, sStatus) {
switch(sStatus){
case "A":
this.addStyleClass("greenTxtHlight");
this.removeStyleClass("yellowTxtHlight");
this.removeStyleClass("redTxtHlight");
break;
case "P":
this.removeStyleClass("greenTxtHlight");
this.addStyleClass("yellowTxtHlight");
this.removeStyleClass("redTxtHlight");
break;
case "G"://Update this
this.removeStyleClass("greenTxtHlight");
this.removeStyleClass("yellowTxtHlight");
this.addStyleClass("redTxtHlight");
break;
}
return sName;
}

Unable to send data to Sitecatalyst with function CQ_Analytics.record

I am working on a POC involving AEM and site catalyst integration .
I am using AEM’s out of box Geomatrixx outdoors website which already implements site catalyst features.
Data is being populated to report suite via
• Data tracking (on page load)
data-tracking="{'event': ['eventName'], 'values': {'key': 'value', 'nextKey': 'nextValue'}, componentPath: 'myapp/component/mycomponent'}"
• CQ_Analytics.record(after page load, activates on a page).
CQ_Analytics.record({event: 'eventName', values: { valueName: 'VALUE' }, collect: false, options: { obj: this, defaultLinkType: 'X' }, componentPath: '<%=resource.getResourceType()%>'})
UseCase: When, I am adding a product to cart below function gets executed CQ_Analytics.record But unable to send cart addition data to site catalyst .
I have verified same using adobe digital debugger.
Code snippet from /libs/commerce/components/product/product.jsp
function trackCartAdd(form) {
if (CQ_Analytics.Sitecatalyst) {
var productQuantity = Number($("input[name='product-quantity']", form).val() || '1');
var productPrice = Number($("input[name='product-size']:checked", form).data('price').replace(/[^0-9\\.]/g, ''));
var productChildSku = $("input[name='product-size']:checked", form).data('sku')
CQ_Analytics.record({
"event": ["cartAdd"<%= (session.getCartEntryCount() == 0) ? ", 'cartOpen'" : "" %>],
"values": {
"product": [{
"category": "",
"sku": "<%= xssAPI.encodeForJSString(baseProduct.getSKU()) %>",
"price": productPrice * productQuantity,
"quantity": productQuantity,
"evars": {
"childSku": CQ.shared.Util.htmlEncode(productChildSku)
}
}]
},
"componentPath": "<%= xssAPI.encodeForJSString(resource.getResourceType()) %>"
});
}
return true;
}
Note: I have done the product variable mapping for report suite in AEM.
Please guide me .

jquery ui autocomplete js error on keydown

i've included the jquery ui automcomplete plugin into the following structure:
<li class="search">
<input type="text" class="searchfield" name="searchfield" value="Search for Products" />
</li>
my javascript for this input field looks like:
<script type="text/javascript">
function addSearchFieldFunctionality() {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$('.searchfield').each(function () {
$(this).autocomplete({
source: availableTags,
minLength: 1
}).data("autocomplete")._renderItem = function(ul, item) {
//console.log(item);
var a = $('<a>', {
href: item.value,
text: item.label,
"class" : "mySearchClass"
});
var b = $('<a>', {
href: item.value,
text: "Add", style: "float:right"});
var $li = $('<li></li>', {style:"width:100%"});
return $li.add(a).appendTo(ul);
};
});
}
</script>
I'm loading that function on document ready. for some reason, if a start typing e.g. the first three letters of a item, i get a resultlist. as soon as i push the keydown push button on the keyword, i get the following error in the chrome (latest version) console:
Uncaught TypeError: Cannot read property 'top' of null
a.widget.activate jquery-ui.min.js:12
a.widget.move jquery-ui.min.js:12
a.widget.next jquery-ui.min.js:12
a.widget._move jquery-ui.min.js:12
a.widget._create.element.addClass.attr.attr.bind.bind.d jquery-ui.min.js:12
f.event.dispatch jquery-1.7.1.min.js:3
f.event.add.h.handle.i
i'm using version 1.7.1 of jQuery and Version 1.8.12 of jquery UI
On the demo page of jquery ui autocomplete the keydown works well.
Any ideas what's going wrong with my constellation?
It doesn't make a difference to use remote or local data.
Best regards,
Ramo
I really can make your code working. So I tried to rewrote it in a more simplier way. The problem is render functions only accept strings, not html element. So I add a listener to render the list after its generation (fired on keydown() event).
My thought is you are doing it the wrong way.
why adding another class on those items ? they have already one, so they can be styled.
why transforming them into a nodes ? just add a click() event on them
Could you explain your functional goal ?
// Your list of links
var redirectLinks = {'Ruby': '1234.com', 'Asp': '1235.com'};
function redirect(url) {
// TODO implement window.location=url or whatever you like
if(redirectLinks[url] != undefined) {
alert('redirecting to '+url+' => '+redirectLinks[url]);
}
}
$('.searchfield').each(function () {
$(this).autocomplete(availableTags, {
minLength: 1,
change: function(event, ui) {
console.log('this change event doesnt seem to be fired');
},
select: function(event, ui) {
console.log('this select event doesnt seem to be fired');
}
});
// After the list construction
$(this).keyup(function(e){
if (e.which == 13) { // typing enter validates the input => autocompletechange
console.log('validating input '+$(this).val());
redirect($(this).val());
}
var $list = $('.ac_results:first ul').find('li');
$list.click(function() { // adding an event on suggestion => autocompleteselect
console.log('clicking on suggestion '+$(this).text());
redirect($(this).text());
});
});
});