Problem with building dynamic BottomNavigation NS 6.5 - javascript

NS 6.5 has been released and there is a new feature: Dynamic Creation of Tabs and Bottom Navigation...
I followed their example but it seems not working, see my code below in a playground:
https://play.nativescript.org/?template=play-js&id=SoGnxo&v=6
Please help to fix if I am doing anything wrong.
Many thanks in advance.

There are multiple issues with your code. Here are all of them explained:
1.You have wrong imports. For example, there is a missing StackLayout import and also a wrong import for the BottomNavigation class.
const Color = require("tns-core-modules/color").Color;
const Label = require("tns-core-modules/ui/label").Label;
const StackLayout = require("tns-core-modules/ui/layouts/stack-layout").StackLayout;
const BottomNavigation = require("tns-core-modules/ui/bottom-navigation").BottomNavigation;
const TabStrip = require("tns-core-modules/ui/bottom-navigation").TabStrip;
const TabStripItem = require("tns-core-modules/ui/bottom-navigation").TabStripItem;
const TabContentItem = require("tns-core-modules/ui/bottom-navigation").TabContentItem;
2.You are creating an "empty" BottomNavigaiton within the XML. That is not needed and could cause trouble (as there are no tabStrip and content items initialized). Remove the BottomNavigation tag from the XML and create it dynamically via the code-behind logic.
3,You are creating bottom navigation via code-behind, but there is no code that actually adds this newly created component anywhere on the page. You could use the content property of the current page.
var bottomNavigaiton = new BottomNavigation();
/* TabStrip creating and adding to BottomNavigation.tabStrip */
let myTabStrip = new TabStrip();
let tabStripItem1 = new TabStripItem();
tabStripItem1.title = "Tab 1";
// To use icon font, you need to have a fonts folder with FontAwesome added in the project
// tabStripItem1.iconSource = `font://${String.fromCharCode(0xf053)}`;
// tabStripItem1.iconClass = "fas"; // e.g., Font Awesome
let tabStripItem2 = new TabStripItem();
tabStripItem2.title = "Tab 2";
// To use icon font, you need to have a fonts folder with FontAwesome added in the project
// tabStripItem2.iconSource = `font://${String.fromCharCode(0xf070)}`;
// tabStripItem2.iconClass = "fas"; // e.g., Font Awesome
myTabStrip.items = [tabStripItem1, tabStripItem2];
bottomNavigaiton.tabStrip = myTabStrip;
/* TabContent items creating and adding to BottomNavigation.items */
let tabContentItem1 = new TabContentItem();
tabContentItem1.content = createContent(1);
let tabContentItem2 = new TabContentItem();
tabContentItem2.content = createContent(2);
let contentItems = [tabContentItem1, tabContentItem2];
bottomNavigaiton.items = contentItems;
/*
Adding the created bottom navigation to the Page content
*/
page.content = bottomNavigaiton;
You don't have a fonts folder that contains the icon fonts (FontAwesome).
See the whole revised example here https://play.nativescript.org/?template=play-js&id=SoGnxo&v=16

Related

Remove Measure Toolbar Button from Autodesk Forge Viewer

I am using the autodesk forge viewer and want to remove the 'measure' tool from the toolbar. I have tried the following but it will not remove the 'measure' button
const onToolbarCreated = (e) => {
const settingsTools = viewer.toolbar.getControl('settingsTools')
// settingsTools.removeControl('toolbar-modelStructureTool')
// settingsTools.removeControl('toolbar-propertiesTool')
settingsTools.removeControl('toolbar-settingsTool');
settingsTools.removeControl('toolbar-measureTool');
//settingsTools.removeControl('toolbar-fullscreenTool')
}
All of the other removeControl() functions work other than the one for the measure-tool. Any guidance on how I could remove this button from the viewer would be greatly appreciated!
Cheers!
EDIT: I have tried this without success
const onToolbarCreated = (e) => {
const settingsTools = viewer.toolbar.getControl('settingsTools');
const modelTools = viewer.toolbar.getControl('modelTools');
modelTools.removeControl('toolbar-measurementSubmenuTool');
// settingsTools.removeControl('toolbar-modelStructureTool')
// settingsTools.removeControl('toolbar-propertiesTool')
settingsTools.removeControl('toolbar-settingsTool');
//settingsTools.removeControl('toolbar-measurementSubmenuTool');
//settingsTools.removeControl('toolbar-fullscreenTool')
If you are not planning to use it anymore you can simply unload the extension from your project.
viewer.unloadExtension("Autodesk.Measure");
Measure tool is in modelTools group.
const modelTools = viewer.toolbar.getControl('modelTools')
modelTools.removeControl('toolbar-measurementSubmenuTool')

Need a javascript function to load new page

My site has English and Spanish versions of each page. The folder structure is identical for both, but all Spanish pages are under a /_spanish folder. For example:
/index.htm is English version
/_spanish/index.htm is Spanish version
I'd like to include a button on each page making it easy to swap languages.
The logic is:
onclick parse the full current page name
if it does not contain /_spanish/
insert /_spanish/ and go to that page e.g. go from http://example.com/index.htm to
http://example.com/_spanish/index.htm
else (it does contain /_spanish/)
remove /_spanish and go to that page e.g. go from http://example.com/_spanish/index.htm to http://example.com/index.htm
Thanks in advance for any help.
I've managed to get this working - not the most elegant, but functional.
<button style="width:100px;height:100px;" onclick="myFunction()"></button>
<script>
function myFunction() {
var host = location.hostname;
var path = location.pathname;
var n = path.indexOf('/_spanish');
var len = path.length;
if (n>-1) {
/* make the new page address without _spanish */
var newpath = path.substr(10,len-9);
var newpage = '/'.concat(newpath);
}
else {
/* make the new page address with _spanish inserted*/
var newpath = path.substr(10,len-9);
var spa = "/_spanish/";
var newpages= spa.concat(path);
/*Replace double // that will occur in sub-directories */
newpage = newpages.replace(/\/\//,"/");
}
window.location.href = newpage;
}
</script>

How to load data into modal?

I am trying to dynamically load data into the body of my modal but cannot seem to get it to work.
function legend(mb) {
var url = mb;
var location = document.getElementById("choice2");
var gwc = location.options[location.selectedIndex].value;
if (gwc == 15)
{
title = ['<strong>Geomorphology</strong>'];
var url = 'http://localhost/geoserver/apib/wms?REQUEST=GetLegendGraphic&VERSION=1.1.0&FORMAT=image/png&WIDTH=20&HEIGHT=25&LAYER=apib:chamapwathi_block_gm&legend_options=fontSize:14';
}
}
Considering you have only the javascript tag there, I am adding a basic javascript solution. In my example, content changes on button click, which you would have to do when you get the data from your API call.
I have also added an id attribute to the modal body.
document.getElementById('left-modal-body').innerHTML = 'Hello';
Updated Example

Any tools available for auto syncing the .js files

I'm working on themeing/skining of website using Absurd.js. I have theme data stored in data1.js, data2.js, data3.js and so on which passes data to the controller.js file. Changing the variable values affects the entire site with the values. Moreover we are using MultiTenant platform, where controller is one common file and data is dependent on instance of main branch. Each instance is for each client and have their own skinning (skin comes from data file).
Challenge I'm facing is, if I add a new parameter to one data file, I have to update/add all the data.js file with that parameter. Add it to the function call and as well update my contoller.js file to receive that new parameter. Its becoming tedious.
Question: Is there any tool out there to help with the file synchronization
To be more clear here is the sample file
data1.js
========
var primaryThemeColor = "#343344";
/* Primary Button Theme Colors*/
var primaryBtnBgColor = "#1A7483";
var primaryBtnBgHoverColor = "#0e233b";
var primaryBtnBorderColor = "#0093D2";
var primaryBtnFontColor = "#1A3567";
var primaryBtnFontHoverColor = "#D1ECF2";
skinComponent(primaryThemeColor,
primaryBtnBgColor,
primaryBtnBgHoverColor,
primaryBtnBorderColor,
primaryBtnFontColor,
primaryBtnFontHoverColor);
data2.js
var primaryThemeColor = "#413098";
/* Primary Button Theme Colors*/
var primaryBtnBgColor = "#38471A";
var primaryBtnBgHoverColor = "#b332e0";
var primaryBtnBorderColor = "#2d3300";
var primaryBtnFontColor = "#671A33";
var primaryBtnFontHoverColor = "#D3D3D3";
skinComponent(primaryThemeColor,
primaryBtnBgColor,
primaryBtnBgHoverColor,
primaryBtnBorderColor,
primaryBtnFontColor,
primaryBtnFontHoverColor);
data3.js, data4.js and so on... Here is my controller file
contoller.js
============
constructor: function(primaryThemeColor,
primaryBtnBgColor,
primaryBtnBgHoverColor,
primaryBtnBorderColor,
primaryBtnFontColor,
primaryBtnFontHoverColor){
this.primaryThemeColor = primaryThemeColor;
this.primaryBtnBgColor = primaryBtnBgColor;
this.primaryBtnBgHoverColor = primaryBtnBgHoverColor;
this.primaryBtnBorderColor = primaryBtnBorderColor;
this.primaryBtnFontColor = primaryBtnFontColor;
this.primaryBtnFontHoverColor = primaryBtnFontHoverColor;
});
You could do something like this. Although I feel like this is ill suited for a large amount of variations... I would imagine serving them with a persistant storage solution with a DB would be the best if these became too numerous.
var primaryThemeColor = ['#343344','#413098','#FFFFFF'];
/* Primary Button Theme Colors*/
var primaryBtnBgColor = ['#38471A','#38471A','#FFFFFF'];
var primaryBtnBgHoverColor = ['#0e233b','#b332e0','#FFFFFF'];
//...
var choice = 1; //or 0 or 2
//...
constructor: function(primaryThemeColor[choice],
primaryBtnBgColor[choice],
primaryBtnBgHoverColor[choice],
Merging the "controller" and "skinning" into one js object would enable you to implement that object across multiple js files where you could change the properties. This would provide a more reusable piece of code than what you have currently.
Since you're using jQuery, consider using a jQuery extension/widget so you can make use of the library's selectors. You could certainly do this with pure javascript as well.
Here's an example of a jQuery extension:
/// START PLUGIN:
(function($) {
$.fn.skinnify = function(options) {
// default settings
// data1
var defaults = {
primaryThemeColor: "#343344",
primaryBtnBgColor: "#1A7483",
primaryBtnBgHoverColor: "#0e233b",
primaryBtnBorderColor: "#0093D2",
primaryBtnFontColor: "#1A3567",
primaryBtnFontHoverColor: "#D1ECF2"
};
// extend the settings to include "options"
var settings = $.extend({}, defaults, options);
return this.each(function() {
// you'd need to do all of them...
$(this).css({
"background-color": settings.primaryBtnBgColor,
"border-color:": settings.primaryBtnBorderColor,
"color": settings.primaryBtnBorderColor
});
// hover is interesting...
$(this).on('hover', function() {
$(this).css({
"color": settings.primaryBtnFontHoverColor,
"cursor": "pointer",
});
});
});
};
}(jQuery));
/// END PLUGIN
// DATA.js
// can be called like this in any file and defaults apply:
$('#foo').skinnify();
// or you can set up your a settings object in a new file and then run the extension
// just make sure you load the skinning js file first!
var data2 = {
primaryThemeColor: "#413098",
primaryBtnBgColor: "#38471A",
primaryBtnBgHoverColor: "#b332e0",
primaryBtnBorderColor: "#2d3300",
primaryBtnFontColor: "#671A33",
primaryBtnFontHoverColor: "#D3D3D3",
}
// new settings
$('#bar').skinnify(data2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo">Button foo</div>
<div id="bar">Button bar</div>

Slide Out Panel that appends to a DIV

I'm attempting to create a slide out panel that appends to the container div within the header and footer of my page. I'm using Bootstrap for responsive, so the solution should ideally work with the media-queries contained within that package. I'm really at a loss on how to approach this because everything I've tried doesn't seem to work in some way or another.
This picture animates best what I'm trying to accomplish (sorry not a designer):
http://d.pr/i/DzQc+
What I've tried:
Pageslide - this is was the closest solution I've found so far. this appends the slide out panel to the body. As such it doesn't allow me to keep the slide out panel within the header/footer container of the page: http://srobbin.com/jquery-plugins/pageslide/
jQuery Mobile Panel Widget - I tried to hack and repurpose the jQuery mobile panel widget plugin to function as desired without any luck.
.append Function - I tried to animate the .append function but this didn't work with the responsive functions of bootstrap.
With that all said, do any of you have a suggestion on a plugin, function or implementation that may work? I'm not necessarily looking for a working piece of code, rather I'm looking for a direction that will work as I'm hoping.
Thanks!
Here is a popup container in a prototype pattern I built that you can create to any div. CSS it up to style to your liking
Useage:
InfoPopup.Create('YourDivID');
InfoPopup.Destroy();
InfoPopup.Bounce();
$(InfoPopup.YesBtn).fadeIn();
$(InfoPopup.NoBtn).fadeIn();
$(InfoPopup.ShowBtn).fadeIn();
Ect...
InfoPopup = {
YesBtn:'',
NoBtn:'',
ShowBtn:'',
IdlBtn:'',
HintText:'',
Create:function(target, contentId){
var infoImage = "";
var infoWrapperDiv = document.createElement('div');
infoWrapperDiv.id = 'infoWrapperDiv';
//min-max button
var minMax = document.createElement('img');
minMax.src = "images/minimize.png"
minMax.id = 'infoPopupMinMax';
minMax.setAttribute('onClick','InfoPopup.Shrink();');
infoWrapperDiv.appendChild(minMax);
//content
var contentDiv = document.createElement('div');
contentDiv.id = 'infoPopupContent';
contentDiv.innerHTML = '<span>Some Stuff Here</span>'
infoWrapperDiv.appendChild(contentDiv);
//YesNoButtons - append to infoWrapperDiv if needed in specific activity
//---- set custom onClick for the specific Activity in the switch
this.YesBtn = document.createElement('input');
this.YesBtn.id = 'infoBtnYes';
this.YesBtn.setAttribute('value','Yes');
this.YesBtn.setAttribute('type','button');
this.YesBtn.className = 'inputButton';
this.NoBtn = document.createElement('input');
this.NoBtn.id = 'infoBtnNo';
this.NoBtn.setAttribute('value','No');
this.NoBtn.setAttribute('type','button');
this.NoBtn.className = 'inputButton';
this.ShowBtn = document.createElement('input');
this.ShowBtn.id = 'infoBtnShow';
this.ShowBtn.setAttribute('type','button');
this.ShowBtn.setAttribute('value','Show');
this.IdlBtn = document.createElement('input');
this.IdlBtn.setAttribute('type','button');
this.HintText = document.createElement('div');
this.HintText.className = 'infoPopupHint';
switch(contentId){//Remove switch to just set up the content
case 1://on a 1 page web app the activity will dictate what content is presented
this.YesBtn.setAttribute('onClick','currentActivityObject.SaveVerification(1);');
this.NoBtn.setAttribute('onClick','currentActivityObject.SaveVerification(0);');
this.YesBtn.style.display = 'none';
this.NoBtn.style.display = 'none';
infoWrapperDiv.appendChild(this.YesBtn);
infoWrapperDiv.appendChild(this.NoBtn);
this.ShowBtn.setAttribute('onmousedown',"currentActivityObject.ShowAnswer(1);");
this.ShowBtn.setAttribute('onmouseup',"currentActivityObject.ShowAnswer(0);");
this.ShowBtn.className = 'inputButton infoBottomLeft';
this.ShowBtn.style.display = 'none';
infoWrapperDiv.appendChild(this.ShowBtn);
break;
case 2:
break;
}
infoWrapperDiv.appendChild(this.HintText);
$id(target).appendChild(infoWrapperDiv);
$('#infoWrapperDiv').animate({top:"78%"},'fast').animate({top:"80%"},'fast');
},
Shrink:function(){
$('#infoWrapperDiv').animate({top:"90%"},'fast').animate({top:"88%"},'fast');
var minMax = document.getElementById('infoPopupMinMax');
minMax.setAttribute('onClick','InfoPopup.Grow();')
},
Grow:function(){
$('#infoWrapperDiv').animate({top:"78%"},'fast').animate({top:"80%"},'fast');
var minMax = document.getElementById('infoPopupMinMax');
minMax.setAttribute('onClick','InfoPopup.Shrink();')
},
Bounce:function(){
$('#infoWrapperDiv')
.animate({top:"90%"},'fast')
.animate({top:"80%"},'fast');
},
Destroy:function(){
var infoWrapperDiv = $id('infoWrapperDiv');
if(infoWrapperDiv){
infoWrapperDiv.parentNode.removeChild($id('infoWrapperDiv'));
}
}
};

Categories