I have a Navbar in my project (GWT, GWTBootstrap3, UiBinder), I would like to make vertical in UiBinder.
In HTML it is quite simple
<div class = "nav nav-pills nav-stacked col-sm-3">
<li> <a> Home </a> </li>
<li> <a> Settings</a> </li>
</div>
But it must be possible to do the same in UiBinder. As far as I understand it is only possible to set the position of the Navbar to FIXED_TOP, FIXED_BOTTON and one more.
My code looks like this
<g:HTMLPanel>
<g:ScrollPanel>
<b:Container >
<b:Navbar position="FIXED_TOP">
<b:Container>
<b:NavbarHeader>
<b:NavbarBrand targetHistoryToken="{nameTokens.getHome}" ui:field="brand" text="{resources.ProductName}" />
<b:NavbarCollapseButton dataTarget="#navbar-collapse" />
</b:NavbarHeader>
<b:NavbarCollapse b:id="navbar-collapse">
<b:NavbarNav>
<b:ListDropDown ui:field="admindropdown">
<b:AnchorButton dataToggle="DROPDOWN" text="{resources.CardHolder}" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.Employee}" targetHistoryToken="{nameTokens.getCardholderlist}" />
<b:AnchorListItem text="{resources.Guest}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Vendor}" targetHistoryToken="{nameTokens.getHome}" />
</b:DropDownMenu>
</b:ListDropDown>
<b:ListDropDown>
<b:AnchorButton dataToggle="DROPDOWN" text="{resources.User}" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.Customer}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Technician}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Portal}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Cloud}" targetHistoryToken="{nameTokens.getHome}" />
</b:DropDownMenu>
</b:ListDropDown>
<b:ListDropDown>
<b:AnchorButton dataToggle="DROPDOWN" text="{resources.Configuration}" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.Customer}" targetHistoryToken="{nameTokens.getCustomerlist}" />
<b:AnchorListItem text="{resources.Company}" targetHistoryToken="{nameTokens.getCompanylist}" />
<b:AnchorListItem text="{resources.Portal}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.ProductNameServer}" targetHistoryToken="{nameTokens.getCloudlist}" />
</b:DropDownMenu>
</b:ListDropDown>
</b:NavbarNav>
<b:NavbarNav pull="RIGHT">
<b:ListDropDown >
<b:AnchorButton text="{resources.SelectedLanguage}" dataToggle="DROPDOWN" />
<b:DropDownMenu >
<b:Image addStyleNames="btn {style.btnStyle}" ui:field="languageDK" url="/images/DK.png" />
<b:Image addStyleNames="btn {style.btnStyle}" ui:field="languageNO" url="/images/NO.png" />
<b:Image addStyleNames="btn {style.btnStyle}" ui:field="languageUK" url="/images/UK.png" />
</b:DropDownMenu>
</b:ListDropDown>
<b:ListDropDown ui:field="loginfield">
<b:AnchorButton dataToggle="DROPDOWN" ui:field="loginname" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.LogOut}" ui:field="logoutitem" />
</b:DropDownMenu>
</b:ListDropDown>
</b:NavbarNav>
</b:NavbarCollapse>
</b:Container>
</b:Navbar>
<b:Row>
<b:Column size="XS_12">
<g:SimplePanel ui:field="contentContainer" />
</b:Column>
</b:Row>
</b:Container>
</g:ScrollPanel>
</g:HTMLPanel>
It seems you are mistaking Navbar with Navs - your HTML example uses nav-pills, while the UiBinder one uses a Navbar (navbar, navbar-header, etc.). As far as I can tell (from the Bootstrap's and gwtbootstrap3's documentation) it is not possible to achieve a vertical ("stacked", as they call it in the docs) Navbar. But it is possible to get vertical/stacked NavPills:
<b:NavPills stacked="true">
<b:AnchorListItem active="true">Item 1</b:AnchorListItem>
<b:AnchorListItem>Item 2</b:AnchorListItem>
<b:AnchorListItem>Item 3</b:AnchorListItem>
</b:NavPills>
See the demo for more examples.
I took another approach to the problem, and made use of the grid system in bootstrap. So when we are at a desktop I show a side navigation bar, and when on a tablet/phone I show the Navbar. It needs to be tweaked a bit, but this is the essential part of the problem I had.
Here is my code for UiBinder
<b:Container>
<b:Row>
<b:Column size="XS_12,SM_12,MD_10,LG_10" visibleOn="XS_SM">
<b:Navbar position="FIXED_TOP">
<b:Container>
<b:NavbarHeader>
<b:NavbarBrand targetHistoryToken="{nameTokens.getHome}"
ui:field="brand" text="{resources.ProductName}" />
<b:NavbarCollapseButton dataTarget="#navbar-collapse" />
</b:NavbarHeader>
<b:NavbarCollapse b:id="navbar-collapse">
<b:NavbarNav>
<b:ListDropDown ui:field="admindropdown">
<b:AnchorButton dataToggle="DROPDOWN" text="{resources.CardHolder}" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.Employee}" targetHistoryToken="{nameTokens.getCardholderlist}" />
<b:AnchorListItem text="{resources.Guest}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Vendor}" targetHistoryToken="{nameTokens.getHome}" />
</b:DropDownMenu>
</b:ListDropDown>
<b:ListDropDown>
<b:AnchorButton dataToggle="DROPDOWN" text="{resources.User}" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.Customer}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Technician}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Portal}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Cloud}" targetHistoryToken="{nameTokens.getHome}" />
</b:DropDownMenu>
</b:ListDropDown>
<b:ListDropDown>
<b:AnchorButton dataToggle="DROPDOWN" text="{resources.Configuration}" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.Customer}" targetHistoryToken="{nameTokens.getCustomerlist}" />
<b:AnchorListItem text="{resources.Company}" targetHistoryToken="{nameTokens.getCompanylist}" />
<b:AnchorListItem text="{resources.Portal}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.ProductNameServer}" targetHistoryToken="{nameTokens.getCloudlist}" />
</b:DropDownMenu>
</b:ListDropDown>
</b:NavbarNav>
<b:NavbarNav pull="RIGHT">
<b:ListDropDown addStyleNames="{style.languageImageStyle}">
<b:Image url="{resources.SelectedLanguageURL}" />
</b:ListDropDown>
<b:ListDropDown>
<b:AnchorButton text="{resources.SelectedLanguage}" dataToggle="DROPDOWN" />
<b:DropDownMenu>
<b:Image addStyleNames="btn {style.btnStyle}" ui:field="languageDK" url="/images/DK.png" />
<b:Image addStyleNames="btn {style.btnStyle}" ui:field="languageNO" url="/images/NO.png" />
<b:Image addStyleNames="btn {style.btnStyle}" ui:field="languageUK" url="/images/UK.png" />
</b:DropDownMenu>
</b:ListDropDown>
<b:ListDropDown ui:field="loginfield">
<b:AnchorButton dataToggle="DROPDOWN" ui:field="loginname" />
<b:DropDownMenu>
<b:AnchorListItem text="{resources.LogOut}" ui:field="logoutitem" />
</b:DropDownMenu>
</b:ListDropDown>
</b:NavbarNav>
</b:NavbarCollapse>
</b:Container>
</b:Navbar>
</b:Column>
</b:Row>
<b:Row>
<b:Column size="MD_3,LG_3" visibleOn="MD_LG">
<b:Panel>
<b:PanelBody>
<b:PanelGroup b:id="accordion">
<b:Panel>
<b:PanelHeader>
<b:Heading size="H4">
<b:Anchor dataToggle="COLLAPSE" dataTarget="#collapseOne" text="{resources.CardHolder}"/>
</b:Heading>
</b:PanelHeader>
<b:PanelCollapse b:id="collapseOne" in="true" ui:field="collapseOne">
<b:PanelBody>
<b:AnchorListItem text="{resources.Employee}" targetHistoryToken="{nameTokens.getCardholderlist}" />
<b:AnchorListItem text="{resources.Guest}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Vendor}" targetHistoryToken="{nameTokens.getHome}" />
</b:PanelBody>
</b:PanelCollapse>
</b:Panel>
<b:Panel>
<b:PanelHeader>
<b:Heading size="H4">
<b:Anchor dataToggle="COLLAPSE" dataTarget="#collapseTwo" text="{resources.User}"/>
</b:Heading>
</b:PanelHeader>
<b:PanelCollapse b:id="collapseTwo" in="true">
<b:PanelBody>
<b:AnchorListItem text="{resources.Customer}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Technician}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Portal}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.Cloud}" targetHistoryToken="{nameTokens.getHome}" />
</b:PanelBody>
</b:PanelCollapse>
</b:Panel>
<b:Panel>
<b:PanelHeader>
<b:Heading size="H4">
<b:Anchor dataToggle="COLLAPSE" dataTarget="#collapseThree" text="{resources.Configuration}"/>
</b:Heading>
</b:PanelHeader>
<b:PanelCollapse b:id="collapseThree" in="true">
<b:PanelBody>
<b:AnchorListItem text="{resources.Customer}" targetHistoryToken="{nameTokens.getCustomerlist}" />
<b:AnchorListItem text="{resources.Company}" targetHistoryToken="{nameTokens.getCompanylist}" />
<b:AnchorListItem text="{resources.Portal}" targetHistoryToken="{nameTokens.getHome}" />
<b:AnchorListItem text="{resources.ProductNameServer}" targetHistoryToken="{nameTokens.getCloudlist}" />
</b:PanelBody>
</b:PanelCollapse>
</b:Panel>
<b:Panel>
<b:PanelHeader>
<b:Heading size="H4">
<b:Anchor dataToggle="COLLAPSE" dataTarget="#collapseFour" text="Sprog"/>
</b:Heading>
</b:PanelHeader>
<b:PanelCollapse b:id="collapseFour" in="true">
<b:PanelBody>
<b:Image addStyleNames="btn" ui:field="languageDK2" url="/images/DK.png" />
<b:Image addStyleNames="btn" ui:field="languageNO2" url="/images/NO.png" />
<b:Image addStyleNames="btn" ui:field="languageUK2" url="/images/UK.png" />
</b:PanelBody>
</b:PanelCollapse>
</b:Panel>
<b:Panel>
<b:PanelHeader>
<b:Heading size="H4">
<b:Anchor dataToggle="COLLAPSE" dataTarget="#collapseFive" text="Login"/>
</b:Heading>
</b:PanelHeader>
<b:PanelCollapse b:id="collapseFive" in="true">
<b:PanelBody>
<b:AnchorListItem text="{resources.LogOut}" ui:field="logoutitem2" />
</b:PanelBody>
</b:PanelCollapse>
</b:Panel>
</b:PanelGroup>
</b:PanelBody>
</b:Panel>
</b:Column>
<b:Column size="XS_12,SM_12,MD_9,LG_9">
<g:SimplePanel ui:field="contentContainer" />
</b:Column>
</b:Row>
</b:Container>
Related
Please note this pertains to Sharepoint Online Themes only, not older versions or on-premises.
Specifically, my manager wants a dark theme and we want to use the "Dark Blue" theme as a base for it. I can pull the colors for custom themes, but the built-in themes do not seem to be accessible with SPO Powershell get-spotheme or other methods i can find. Since it is a publically available theme, I did not expect it to be too difficult to get the information. I found this link https://learn.microsoft.com/en-us/sharepoint/dev/declarative-customization/site-theming/sharepoint-site-theming-json-schema which is supposed to show the default theme colors, but when i create my own from it and add/apply, it is not even close to the current "Dark Blue" theme. The theme.spcolor and theme.sptheme file created on application i can get, but they use a different color and format.
RANT: Microsoft really does not make this user friendly, which seems like a poor oversight on their part since users often think things are better when they LOOK better. Even the Theme Generator found here appears to be broken (along with lots of old broken links) and you cannot scroll to view and confirm without using dev tools to edit page. https://fluentuipr.z22.web.core.windows.net/heads/master/theming-designer/index.html
Theme files pulled directly from site /_catalogs/Theme after applied and files created by SP show base slot colors but they are in an odd format starting with ff? I think i can take the ff off and that should be the hex values but not entirely sure it will be accurate. Would prefer to get the actual theme as it currently exists like you would use for add-spotheme/get-spotheme - unsure it the additional colors are extrapolated colors from applying a theme or if i should/can include them in a theme i create for with add-spotheme. ANY ADVICE APPRECIATED
Theme.sptheme Dark Blue
<?xml version="1.0" encoding="utf-8"?>
<s:theme xmlns:s="http://schemas.microsoft.com/sharepoint/"
name="Dark Blue"
colorPaletteUrl="theme.spcolor" />
Theme.spcolor Dark Blue
<?xml version="1.0" encoding="utf-8"?>
<s:colorPalette isInverted="true" previewSlot1="BackgroundOverlay" previewSlot2="BodyText" previewSlot3="AccentText" xmlns:s="http://schemas.microsoft.com/sharepoint/">
<s:color name="themePrimary" value="ff3a96dd" />
<s:color name="themeLighterAlt" value="ff020609" />
<s:color name="themeLighter" value="ff091823" />
<s:color name="themeLight" value="ff112d43" />
<s:color name="themeTertiary" value="ff235a85" />
<s:color name="themeSecondary" value="ff3385c3" />
<s:color name="themeDarkAlt" value="ff4ba0e1" />
<s:color name="themeDark" value="ff65aee6" />
<s:color name="themeDarker" value="ff8ac2ec" />
<s:color name="accent" value="ff3a96dd" />
<s:color name="neutralLighterAlt" value="ff1d2b3c" />
<s:color name="neutralLighter" value="ff223244" />
<s:color name="neutralLight" value="ff2b3d51" />
<s:color name="neutralQuaternaryAlt" value="ff324459" />
<s:color name="neutralQuaternary" value="ff374a5f" />
<s:color name="neutralTertiaryAlt" value="ff4f637a" />
<s:color name="neutralTertiary" value="ffc8c8c8" />
<s:color name="neutralSecondary" value="ffd0d0d0" />
<s:color name="neutralPrimaryAlt" value="ffdadada" />
<s:color name="neutralPrimary" value="ffffffff" />
<s:color name="neutralDark" value="fff4f4f4" />
<s:color name="black" value="fff8f8f8" />
<s:color name="white" value="ff182534" />
<s:color name="primaryBackground" value="ff182534" />
<s:color name="primaryText" value="ffffffff" />
<s:color name="HyperlinkActive" value="ff8ac2ec" />
<s:color name="CommandLinksPressed" value="ff8ac2ec" />
<s:color name="NavigationPressed" value="ff8ac2ec" />
<s:color name="EmphasisHoverBorder" value="ff8ac2ec" />
<s:color name="TopBarPressedText" value="ff8ac2ec" />
<s:color name="HeaderNavigationPressedText" value="ff8ac2ec" />
<s:color name="Hyperlinkfollowed" value="ff8ac2ec" />
<s:color name="EmphasisHoverBackground" value="ff65aee6" />
<s:color name="EmphasisBorder" value="ff65aee6" />
<s:color name="AccentText" value="ff3a96dd" />
<s:color name="CommandLinksHover" value="ff3a96dd" />
<s:color name="RowAccent" value="ff3a96dd" />
<s:color name="NavigationAccent" value="ff3a96dd" />
<s:color name="NavigationHover" value="ff3a96dd" />
<s:color name="EmphasisBackground" value="ff3a96dd" />
<s:color name="HeaderNavigationHoverText" value="ff3a96dd" />
<s:color name="HeaderNavigationSelectedText" value="ff3a96dd" />
<s:color name="SuiteBarBackground" value="ff3a96dd" />
<s:color name="Hyperlink" value="ff3a96dd" />
<s:color name="ContentAccent1" value="ff3a96dd" />
<s:color name="AccentLines" value="ff3385c3" />
<s:color name="HeaderAccentLines" value="ff3385c3" />
<s:color name="ButtonPressedBorder" value="ff3385c3" />
<s:color name="SuiteBarHoverBackground" value="ff235a85" />
<s:color name="StrongLines" value="ff112d43" />
<s:color name="HeaderStrongLines" value="ff112d43" />
<s:color name="SuiteBarHoverText" value="ff112d43" />
<s:color name="ButtonPressedBackground" value="ff112d43" />
<s:color name="ButtonHoverBorder" value="ff112d43" />
<s:color name="ButtonHoverBackground" value="ff091823" />
<s:color name="SelectionBackground" value="7f112d43" />
<s:color name="HoverBackground" value="7f091823" />
<s:color name="NavigationHoverBackground" value="7f091823" />
<s:color name="PageBackground" value="ff182534" />
<s:color name="EmphasisText" value="ff182534" />
<s:color name="SuiteBarText" value="ff182534" />
<s:color name="TileText" value="ff182534" />
<s:color name="BackgroundOverlay" value="d8182534" />
<s:color name="HeaderBackground" value="d8182534" />
<s:color name="FooterBackground" value="d8182534" />
<s:color name="DisabledBackground" value="ff1d2b3c" />
<s:color name="HeaderDisabledBackground" value="ff1d2b3c" />
<s:color name="ButtonBackground" value="ff1d2b3c" />
<s:color name="ButtonDisabledBackground" value="ff1d2b3c" />
<s:color name="SubtleEmphasisBackground" value="ff223244" />
<s:color name="DialogBorder" value="ff223244" />
<s:color name="NavigationSelectedBackground" value="c62b3d51" />
<s:color name="TopBarBackground" value="c62b3d51" />
<s:color name="DisabledLines" value="ff2b3d51" />
<s:color name="HeaderDisabledLines" value="ff2b3d51" />
<s:color name="ButtonDisabledBorder" value="ff2b3d51" />
<s:color name="SuiteBarDisabledText" value="ff2b3d51" />
<s:color name="SubtleLines" value="ff4f637a" />
<s:color name="HeaderSubtleLines" value="ff4f637a" />
<s:color name="ButtonGlyphDisabled" value="ff4f637a" />
<s:color name="DisabledText" value="ffc8c8c8" />
<s:color name="CommandLinksDisabled" value="ffc8c8c8" />
<s:color name="HeaderDisableText" value="ffc8c8c8" />
<s:color name="ButtonDisabledText" value="ffc8c8c8" />
<s:color name="Lines" value="ffc8c8c8" />
<s:color name="HeaderLines" value="ffc8c8c8" />
<s:color name="ButtonBorder" value="ffc8c8c8" />
<s:color name="CommandLinks" value="ffd0d0d0" />
<s:color name="Navigation" value="ffd0d0d0" />
<s:color name="SubtleEmphasisText" value="ffd0d0d0" />
<s:color name="TopBarText" value="ffd0d0d0" />
<s:color name="HeaderNavigationText" value="ffd0d0d0" />
<s:color name="ButtonGlyph" value="ffd0d0d0" />
<s:color name="BodyText" value="ffffffff" />
<s:color name="WebPartHeading" value="ffffffff" />
<s:color name="HeaderText" value="ffffffff" />
<s:color name="ButtonText" value="ffffffff" />
<s:color name="ButtonGlyphActive" value="ffffffff" />
<s:color name="TopBarHoverText" value="ffffffff" />
<s:color name="StrongBodyText" value="fff4f4f4" />
<s:color name="SiteTitle" value="fff4f4f4" />
<s:color name="CommandLinksSecondary" value="fff4f4f4" />
<s:color name="SubtleEmphasisCommandLinks" value="fff4f4f4" />
<s:color name="HeaderSiteTitle" value="fff4f4f4" />
<s:color name="TileBackgroundOverlay" value="7ff8f8f8" />
<s:color name="ContentAccent2" value="ff00485b" />
<s:color name="ContentAccent3" value="ff288054" />
<s:color name="ContentAccent4" value="ff767956" />
<s:color name="ContentAccent5" value="ffed0033" />
<s:color name="ContentAccent6" value="ff682a7a" />
</s:colorPalette>
normal format for sp application via powershell is like the below:
#DARK BLUE BUILT IN – wrong/old
$themeDB1 = #{
“themePrimary: '#00bcf2',
themeLighterAlt: '#00090c',
themeLighter: '#001318',
themeLight: '#002630',
themeTertiary: '#005066',
themeSecondary: '#00abda',
themeDarkAlt: '#0ecbff',
themeDark: '#44d6ff',
themeDarker: '#6cdfff',
neutralLighterAlt: '#2e3340',
neutralLighter: '#353a49',
neutralLight: '#404759',
neutralQuaternaryAlt: '#474e62',
neutralQuaternary: '#4c546a',
neutralTertiaryAlt: '#646e8a',
neutralTertiary: '#c8c8c8',
neutralSecondaryAlt: '#d0d0d0',
neutralSecondary: '#dadada',
neutralPrimaryAlt: '#eaeaea',
neutralPrimary: '#ffffff',
neutralDark: '#f4f4f4',
black: '#f8f8f8',
white: '#262a35',
primaryBackground: '#262a35',
primaryText: '#ffffff',
error: '#ff5f5f',
accent: '#3a96dd'
}
Add-SPOTheme -Identity "FedPoint Dark Blue 1" -Palette $themeDB1 -IsInverted $true -Overwrite
#(from what i can tell -isinverted $true is for Dark background themes, but i have not had much luck `testing it as yet)
attempted to pull themes, only able to pull custom themes.
attempted to pull files created on theme application, not in same format and some info may be extrapolated at time of theme application with colors using different values than expected.
attempted to use disclosed MS Theme colors listed, but color values do not match actual current values when applied as a test theme.
UPDATE
Changed format to PowerShell accepted format
Removed first two letters of each color and replaced with #
replaced "themePrimary"="#3a96dd” with bright blue "themePrimary"="#2489ed”;
Replaced "themeLight"="#112d43"; with navy "themeLight"="#00308f"; This allows it to be selected as header and section background, may be too busy for our needs, considering creating two Dark Mode themes instead
It is likely most things after black/white are not in use as they are not in the FLUENT theme generator, but not sure since microsoft does not seem to want to document SharePoint Online Themes well
NOTE: May want to simply remove any with alpha not equal to FF (opaque)
Code I ended up using is:
$themeDB2 = #{
"themePrimary"="#2489ed";
"themeLighterAlt"="#020609";
"themeLighter"="#091823";
"themeLight"="#00308f";
"themeTertiary"="#235a85";
"themeSecondary"="#3385c3";
"themeDarkAlt"="#4ba0e1";
"themeDark"="#65aee6";
"themeDarker"="#8ac2ec";
"accent"="#2489ed";
"neutralLighterAlt"="#1d2b3c";
"neutralLighter"="#223244";
"neutralLight"="#2b3d51";
"neutralQuaternaryAlt"="#324459";
"neutralQuaternary"="#374a5f";
"neutralTertiaryAlt"="#4f637a";
"neutralTertiary"="#c8c8c8";
"neutralSecondary"="#d0d0d0";
"neutralPrimaryAlt"="#dadada";
"neutralPrimary"="#ffffff";
"neutralDark"="#f4f4f4";
"black"="#f8f8f8";
"white"="#182534";
"primaryBackground"="#182534";
"primaryText"="#ffffff";
"HyperlinkActive"="#8ac2ec";
"CommandLinksPressed"="#8ac2ec";
"NavigationPressed"="#8ac2ec";
"EmphasisHoverBorder"="#8ac2ec";
"TopBarPressedText"="#8ac2ec";
"HeaderNavigationPressedText"="#8ac2ec";
"Hyperlinkfollowed"="#8ac2ec";
"EmphasisHoverBackground"="#65aee6";
"EmphasisBorder"="#65aee6";
"AccentText"="#2489ed";
"CommandLinksHover"="#2489ed";
"RowAccent"="#2489ed";
"NavigationAccent"="#2489ed";
"NavigationHover"="#2489ed";
"EmphasisBackground"="#2489ed";
"HeaderNavigationHoverText"="#2489ed";
"HeaderNavigationSelectedText"="#2489ed";
"SuiteBarBackground"="#2489ed";
"Hyperlink"="#2489ed";
"ContentAccent1"="#2489ed";
"AccentLines"="#3385c3";
"HeaderAccentLines"="#3385c3";
"ButtonPressedBorder"="#3385c3";
"SuiteBarHoverBackground"="#235a85";
"StrongLines"="#112d43";
"HeaderStrongLines"="#112d43";
"SuiteBarHoverText"="#112d43";
"ButtonPressedBackground"="#112d43";
"ButtonHoverBorder"="#112d43";
"ButtonHoverBackground"="#091823";
"SelectionBackground"="#112d43";
"HoverBackground"="#091823";
"NavigationHoverBackground"="#091823";
"PageBackground"="#182534";
"EmphasisText"="#182534";
"SuiteBarText"="#182534";
"TileText"="#182534";
"BackgroundOverlay"="#182534";
"HeaderBackground"="#182534";
"FooterBackground"="#182534";
"DisabledBackground"="#1d2b3c";
"HeaderDisabledBackground"="#1d2b3c";
"ButtonBackground"="#1d2b3c";
"ButtonDisabledBackground"="#1d2b3c";
"SubtleEmphasisBackground"="#223244";
"DialogBorder"="#223244";
"NavigationSelectedBackground"="#2b3d51";
"TopBarBackground"="#2b3d51";
"DisabledLines"="#2b3d51";
"HeaderDisabledLines"="#2b3d51";
"ButtonDisabledBorder"="#2b3d51";
"SuiteBarDisabledText"="#2b3d51";
"SubtleLines"="#4f637a";
"HeaderSubtleLines"="#4f637a";
"ButtonGlyphDisabled"="#4f637a";
"DisabledText"="#c8c8c8";
"CommandLinksDisabled"="#c8c8c8";
"HeaderDisableText"="#c8c8c8";
"ButtonDisabledText"="#c8c8c8";
"Lines"="#c8c8c8";
"HeaderLines"="#c8c8c8";
"ButtonBorder"="#c8c8c8";
"CommandLinks"="#d0d0d0";
"Navigation"="#d0d0d0";
"SubtleEmphasisText"="#d0d0d0";
"TopBarText"="#d0d0d0";
"HeaderNavigationText"="#d0d0d0";
"ButtonGlyph"="#d0d0d0";
"BodyText"="#ffffff";
"WebPartHeading"="#ffffff";
"HeaderText"="#ffffff";
"ButtonText"="#ffffff";
"ButtonGlyphActive"="#ffffff";
"TopBarHoverText"="#ffffff";
"StrongBodyText"="#f4f4f4";
"SiteTitle"="#f4f4f4";
"CommandLinksSecondary"="#f4f4f4";
"SubtleEmphasisCommandLinks"="#f4f4f4";
"HeaderSiteTitle"="#f4f4f4";
"TileBackgroundOverlay"="#f8f8f8";
"ContentAccent2"="#00485b";
"ContentAccent3"="#288054";
"ContentAccent4"="#767956";
"ContentAccent5"="#ed0033";
"ContentAccent6"="#682a7a";
}
Add-SPOTheme -Identity "Dark Mode Blue 1" -Palette $themeDB2 -IsInverted $true -Overwrite
I am building Ionic React application, and the version of ionic is 5. In my application, I have bottom navigation. I have mentioned the logic of bottom navigation in App.tsx.
I have an add button on the Dashboard page on clicking that button I want a page to open which will not contain the bottom navigation. I got many answers over the internet which is for Ionic-Angular. I am specifically looking for an answer Ionic-React.
App.tsx
<IonContent>
<IonReactRouter>
<IonTabs>
<IonRouterOutlet>
<Route path="/profile" component={Profile} exact={true} />
<Route path="/dashboard" component={Dashboard} exact={true} />
<Route path="/dashboard/addInfo" component={Info} exact={true} />
<Route path="/" render={() => <Redirect to="/dashboard" />} exact={true} />
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="home" href="/home">
<IonIcon icon={home} />
<IonLabel>Home</IonLabel>
</IonTabButton>
<IonTabButton tab="profile" href="/profile">
<IonIcon icon={profile} />
<IonLabel>Profile</IonLabel>
</IonTabButton>
<IonTabButton tab="dashboard" href="/dashboard">
<IonIcon icon={grid} />
<IonLabel>Dashboard</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
</IonReactRouter>
</IonContent>
This might be what #MostafaHarb was trying to explain. You can have nested IonRouterOutlets, so place your tabs within a TabContainer component off your main App.tsx (shown here as a render prop on the /tabs Route). You will likely need to provide a fallback route, in this case there's a redirect to the tabs Route when the path is "/"
<IonReactRouter>
<IonRouterOutlet>
<Route path="/notabs" render={() => <div>a page no tabs</div>} />
<Route
path="/tabs"
render={() => (
<IonTabs>
<IonRouterOutlet>
<Route
path="/tabs/tab1"
component={Tab1}
exact={true}
/>
<Route
path="/tabs/tab2"
component={Tab2}
exact={true}
/>
<Route
path="/tabs/tab3"
component={Tab3}
exact={true}
/>
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="tab 1" href="/tabs/tab1">
<IonIcon icon={circle} />
<IonLabel>Tab1</IonLabel>
</IonTabButton>
<IonTabButton tab="tab 2" href="/tabs/tab2">
<IonIcon icon={square} />
<IonLabel>Tab2</IonLabel>
</IonTabButton>
<IonTabButton tab="tab 3" href="/tabs/tab3">
<IonIcon icon={triangle} />
<IonLabel>Tab3</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
)}
/>
<Route
path="/"
render={() => <Redirect to="/tabs" />}
exact={true}
/>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
Good luck!
I did something like this and that worked for me. I created an id for the tabs and then manipulated that to show or hide
function showTab() {
const tabBar = document.getElementById('appTabBar');
if (tabBar !== null) {
console.log("enabled")
tabBar.style.display = 'flex';
}
}
function hideTab() {
const tabBar = document.getElementById('appTabBar');
if (tabBar !== null) {
tabBar.style.display = 'none';
}
}
<IonTabBar slot="bottom" id="appTabBar" >
<IonTabButton tab="account" href="/account">
<IonIcon icon={personCircleOutline}/>
<IonLabel>Profile</IonLabel>
</IonTabButton>
</IonTabBar>
The datatable displays entries that I intend to be able to edit. In order to do so, I use a commandlink to open a dialog box. setPropertyActionListener sets the CostingType object that should be able to be modified from within the dialog box. However, the dialog box isn't able to get the object's variables or save them. Instead, it shows an empty object and clicking on the edit button(after keying in fields) shows the requiredMessage warnings instead. checkEdit() (which exists solely for debug purposes) isn't being called either.
HTML:
<h:form id="costingTypeForm" >
<p:tabView id="tabView">
<p:tab id="tab1" title="Costing Type">
<h:form id="costingTypeForm" >
<p:tabView id="tabView">
<p:tab id="tab1" title="Costing Type">
<p:dataTable
id="costingTypeTable"
value="#{costingTypeBean.costingTypeList}"
var="costingType"
rows="#{psmsProp['psms.dataTable.rows']}"
paginator="true"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} {CurrentPageReport}"
rowsPerPageTemplate="#{psmsProp['psms.dataTable.rowsPerPage']}"
currentPageReportTemplate="Displaying {startRecord}-{endRecord} out of {totalRecords}"
style="width:80%; text-align:center;"
sortBy="#{costingType.name}"
sortMode="single" >
<f:facet name="header">
Costing Type
<p:commandButton
value="Add"
oncomplete="PF('addCostingTypeDialog').show()"
update="costingTypeForm:tabView:addCostingTypeForm"
icon="ui-icon-plus"
style="float:right;" />
<div style="clear:both" />
</f:facet>
<p:column sortBy="#{costingType.name}"
filterBy="#{costingType.name}"
filterMatchMode="contains"
filterFunction="#{filterUtil.containsFilter}"
filterStyle="width:80%;"
headerText="Name">
<p:outputLabel id = "name" value="#{costingType.name}" />
</p:column>
<p:column headerText="Description">
<p:outputLabel id = "description" value="#{costingType.nameDesc}" />
</p:column>
<p:column headerText="Budgeted">
<p:outputLabel value="Yes" rendered="#{costingType.budget}" />
<p:outputLabel value="No" rendered="#{not costingType.budget}" />
</p:column>
<p:column headerText="Deleted">
<p:outputLabel value="Yes" rendered="#{costingType.del}" />
<p:outputLabel value="No" rendered="#{not costingType.del}" />
</p:column>
<p:column>
<p:commandLink
oncomplete="PF('editCostingTypeDialog').show()"
update=":costingTypeForm:tabView:editCostingTypeForm"
value="Edit" action="#{costingTypeBean.checkEdit}">
<f:setPropertyActionListener target="#{costingTypeBean.editCostingType}" value="#{costingType}"/>
</p:commandLink>
</p:column>
</p:dataTable>
<p:dialog
header="Edit Costing Type"
widgetVar="editCostingTypeDialog"
modal="true"
showEffect="slide"
hideEffect="fade"
resizable="false"
closable="false">
<p:outputPanel id="editCostingTypeForm">
<p:panelGrid columns="2" cellpadding="5" rendered="#{not empty costingTypeBean.editCostingType}">
<h:panelGroup>
<p:outputLabel value="Name:" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:inputText value="#{costingTypeBean.editCostingType.name}" required="true" requiredMessage="Name is required" />
<h:panelGroup>
<p:outputLabel value="Description:" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:inputText value="#{costingTypeBean.editCostingType.nameDesc}" required="true" requiredMessage="Description is required" />
<p:outputLabel value="Budgeted:" />
<p:selectOneMenu value="#{costingTypeBean.editCostingType.budget}">
<f:selectItem itemValue="true" itemLabel="Yes" />
<f:selectItem itemValue="false" itemLabel="No" />
</p:selectOneMenu>
<h:outputLabel value="Deleted:" />
<p:selectOneMenu value="#{costingTypeBean.editCostingType.del}">
<f:selectItem itemValue="true" itemLabel="Yes" />
<f:selectItem itemValue="false" itemLabel="No" />
</p:selectOneMenu>
</p:panelGrid>
<p:commandButton
value="Cancel"
actionListener="#{costingTypeBean.cancelChange}"
oncomplete="PF('editCostingTypeDialog').hide();"
icon="ui-icon-close"
style="float:right;margin-top:10px;margin-bottom:10px;" />
<p:commandButton
value="Edit"
actionListener="#{costingTypeBean.updateCostingType}"
oncomplete="if(args.update) PF('editCostingTypeDialog').hide();"
update=":costingTypeForm:messages #(.ui-datatable)"
icon="ui-icon-disk"
style="float:right;margin-top:10px;margin-right:10px;margin-bottom:10px;" />
</p:outputPanel>
</p:dialog>
<p:dialog
header="Add New CostingType"
widgetVar="addCostingTypeDialog"
modal="true"
showEffect="slide"
hideEffect="fade"
resizable="false"
closable="false">
<p:outputPanel id="addCostingTypeForm">
<p:panelGrid columns="2" cellpadding="5">
<h:panelGroup>
<p:outputLabel value="Name" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:inputText value="#{costingTypeBean.name}" required="true" requiredMessage="Enter name" />
<h:panelGroup>
<p:outputLabel value="Description:" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:inputText value="#{costingTypeBean.nameDesc}" required="true" requiredMessage="Enter Engine Type" />
<h:panelGroup>
<h:outputLabel value="Budgeted:" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:selectOneRadio value="#{costingTypeBean.budgeted}">
<f:selectItem itemValue="true" itemLabel="Yes" />
<f:selectItem itemValue="false" itemLabel="No" />
</p:selectOneRadio>
<h:panelGroup>
<h:outputLabel value="Deleted:" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:selectOneRadio value="#{costingTypeBean.deleted}">
<f:selectItem itemValue="true" itemLabel="Yes" />
<f:selectItem itemValue="false" itemLabel="No" />
</p:selectOneRadio>
</p:panelGrid>
<p:commandButton
value="Cancel"
actionListener="#{costingTypeBean.cancelChange}"
oncomplete="PF('addCostingTypeDialog').hide();"
icon="ui-icon-close"
style="float:right;margin-top:10px;margin-bottom:10px;" />
<p:commandButton
value="Save"
actionListener="#{costingTypeBean.addCostingType}"
oncomplete="if(args.add) PF('addCostingTypeDialog').hide(); else PF('addCostingTypeDialog').show();"
update="#form #(.ui-datatable)"
icon="ui-icon-disk"
style="float:right;margin-top:10px;margin-right:10px;margin-bottom:10px;" />
</p:outputPanel>
</p:dialog>
</p:tab>
</p:tabView>
</h:form>
Backing bean:
#Component
#Scope("view")
public class CostingTypeBean{
private static final Logger LOGGER = LoggerFactory.getLogger(CostingTypeBean.class);
private long costingTypeId;
private boolean budgeted, deleted;
private String name, nameDesc;
private CostingType costingType;
private CostingType editCostingType;
private List<CostingType> costingTypeList;
#Autowired
private CostingTypeService costingTypeService;
/*
getters and setters
*/
// dialog edit
public void updateCostingType(ActionEvent event) {
RequestContext context = RequestContext.getCurrentInstance();
if(editCostingType!=null) {
costingTypeService.saveOrUpdate(editCostingType);
context.addCallbackParam("update", true);
}
else
context.addCallbackParam("update", false);
}
//debug method
public void checkEdit() {
LOGGER.debug("Edit listener");
ViewUtil.showInfo("Edit dialog triggered");
System.out.println("Edit listener");
}
What should I do to get editCostingTypeDialog to reflect the fields of of the CostingType object and be able to read the values keyed in the input text areas?
Your code works just fine. All I had to do was to modify some of the update= attributes (as I was getting exceptions about destination components not being found). After populating with some random data and using your above code I get the following;
I tested with both PrimeFaces 6.1 and 6.2 on Mojarra 2.3.3.99. The backing bean callback for the edit button in the dialog is also being called properly.
So the next thing to check - which JSF implementation are you using? Is it Mojarra or MyFaces ? which version ? Maybe you are hitting upon some bug in your specific implementation. There is absolutely nothing wrong with your code.
While I'm at it, I might as well post the complete code (including my modifications);
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Costing type Test</title>
</h:head>
<h:body>
<h:form id="costingTypeForm" >
<p:tabView id="tabView">
<p:tab id="tab1" title="Costing Type">
<p:dataTable
id="costingTypeTable"
value="#{costingTypeBean.costingTypeList}"
var="costingType"
paginator="true"
style="width:80%; text-align:center;"
sortMode="single" >
<f:facet name="header">
Costing Type
<p:commandButton value="Add" oncomplete="PF('addCostingTypeDialog').show()" update="#form" icon="ui-icon-plus" style="float:right;" />
<div style="clear:both" />
</f:facet>
<p:column sortBy="#{costingType.name}"
filterBy="#{costingType.name}"
filterMatchMode="contains"
filterFunction="#{filterUtil.containsFilter}"
filterStyle="width:80%;"
headerText="Name">
<p:outputLabel id = "name" value="#{costingType.name}" />
</p:column>
<p:column headerText="Description">
<p:outputLabel id = "description" value="#{costingType.nameDesc}" />
</p:column>
<p:column headerText="Budgeted">
<p:outputLabel value="Yes" rendered="#{costingType.budget}" />
<p:outputLabel value="No" rendered="#{not costingType.budget}" />
</p:column>
<p:column headerText="Deleted">
<p:outputLabel value="Yes" rendered="#{costingType.del}" />
<p:outputLabel value="No" rendered="#{not costingType.del}" />
</p:column>
<p:column>
<p:commandLink
oncomplete="PF('editCostingTypeDialog').show()"
update=":costingTypeForm:tabView:editCostingTypeForm"
value="Edit" action="#{costingTypeBean.checkEdit}">
<f:setPropertyActionListener target="#{costingTypeBean.editCostingType}" value="#{costingType}"/>
</p:commandLink>
</p:column>
</p:dataTable>
<p:dialog
header="Edit Costing Type"
widgetVar="editCostingTypeDialog"
modal="true"
showEffect="slide"
hideEffect="fade"
resizable="false"
closable="false">
<p:outputPanel id="editCostingTypeForm">
<p:panelGrid columns="2" rendered="#{not empty costingTypeBean.editCostingType}">
<h:panelGroup>
<p:outputLabel value="Name:" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:inputText value="#{costingTypeBean.editCostingType.name}" required="true" requiredMessage="Name is required" />
<h:panelGroup>
<p:outputLabel value="Description:" />
<p:outputLabel value="*" style="color:red;" />
</h:panelGroup>
<p:inputText value="#{costingTypeBean.editCostingType.nameDesc}" required="true" requiredMessage="Description is required" />
<p:outputLabel value="Budgeted:" />
<p:selectOneMenu value="#{costingTypeBean.editCostingType.budget}">
<f:selectItem itemValue="true" itemLabel="Yes" />
<f:selectItem itemValue="false" itemLabel="No" />
</p:selectOneMenu>
<h:outputLabel value="Deleted:" />
<p:selectOneMenu value="#{costingTypeBean.editCostingType.del}">
<f:selectItem itemValue="true" itemLabel="Yes" />
<f:selectItem itemValue="false" itemLabel="No" />
</p:selectOneMenu>
</p:panelGrid>
<p:commandButton
value="Cancel"
actionListener="#{costingTypeBean.cancelChange}"
oncomplete="PF('editCostingTypeDialog').hide();"
icon="ui-icon-close"
style="float:right;margin-top:10px;margin-bottom:10px;" />
<p:commandButton
value="Edit"
actionListener="#{costingTypeBean.updateCostingType}"
oncomplete="if(args.update) PF('editCostingTypeDialog').hide();"
update="#form"
icon="ui-icon-disk"
style="float:right;margin-top:10px;margin-right:10px;margin-bottom:10px;" />
</p:outputPanel>
</p:dialog>
</p:tab>
</p:tabView>
</h:form>
</h:body>
</html>
And here is the backing bean (example uses Lombok and Apache Commons);
#Data
#Named
#ViewScoped
public class CostingTypeBean implements Serializable {
private CostingType costingType;
private CostingType editCostingType;
private List<CostingType> costingTypeList;
#PostConstruct
private void init() {
costingTypeList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
final String name = RandomStringUtils.randomAlphanumeric(10);
final String nameDesc = RandomStringUtils.randomAlphanumeric(10);
final boolean budget = RandomUtils.nextBoolean();
final boolean del = RandomUtils.nextBoolean();
costingTypeList.add(new CostingType(name, nameDesc, budget, del));
}
}
public void updateCostingType(ActionEvent event) {
System.out.println("update!");
}
public void checkEdit() {
System.out.println("Edit listener");
}
public void cancelChange() {
System.out.println("Cancel");
}
#Data
#AllArgsConstructor
public class CostingType {
private String name;
private String nameDesc;
private boolean budget;
private boolean del;
}
}
Hopefully this can be of some help.
It's a bug in PrimeFaces (I think).
I searched with many tests in a minimal test application. It's not possible to use following constellation:
<p:dataTable value="#{bean.list}" var="myVar".....
<p:ajax event="rowSelect" partialSubmit="true" process="#this" listener="#{bean.doWork(myVar)}"/>
bean.doWork() will always be called with a null pointer.
Glassfish 4.1.1
PrimeFaces 6.2
I think your problem is the same.
I'm getting an error on this (formatted for readability) OpenXML stylesheet at column 153, which seems to be the '.' in the 0.0% format identifier. Can anyone see what is wrong here? If I remove the numFmts then the issue goes away.
<?xml version="1.0" encoding="utf-16"?>
<x:styleSheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<x:numFmts count="2">
<x:numFmt />
<x:numFmt numFmtId="164" formatCode="0.0%" />
</x:numFmts>
<x:fonts count="2">
<x:font>
<x:sz val="11" />
<x:color rgb="000000" />
<x:name val="Calibri" />
</x:font>
<x:font>
<x:b />
<x:sz val="11" />
<x:color rgb="000000" />
<x:name val="Calibri" />
</x:font>
</x:fonts>
<x:fills count="1">
<x:fill>
<x:patternFill patternType="none" />
</x:fill>
</x:fills>
<x:borders count="1">
<x:border>
<x:left />
<x:right />
<x:top />
<x:bottom />
<x:diagonal />
</x:border>
</x:borders>
<x:cellXfs count="3">
<x:xf />
<x:xf fontId="1" applyFont="1" />
<x:xf numFmtId="164" applyNumberFormat="1" />
</x:cellXfs>
</x:styleSheet>
It's the empty <x:numFmt> element in the line above that's the cause of the issue. The numFmtId and formatCode are required elements within that element.
The schema from ECMA is:
<xsd:complexType name="CT_NumFmt">
<xsd:attribute name="numFmtId" type="ST_NumFmtId" use="required"/>
<xsd:attribute name="formatCode" type="s:ST_Xstring" use="required"/>
</xsd:complexType>
It's worth trying the OpenXml Productivity Tool in situations like these. It will validate files as well as backwards engineer code from a valid file. In your case you'd get something like this:
My secuirity-config
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd ">
<!-- #author Soeng kanel (soengkanel#gmail.com) -->
<!-- This is default url to get a token from OAuth -->
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/api/**" access="ROLE_ADMIN" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<!-- This is simple authentication manager, with a hardcoded user/password
combination. We can replace this with a user defined service to get few users
credentials from DB -->
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="mongoUserDetailsService">
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="120" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="restapp"
authorized-grant-types="authorization_code,client_credentials"
authorities="ROLE_ADMIN" scope="read,write,trust" secret="secret" />
<oauth:client client-id="restapp"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="restapp" authorities="ROLE_ADMIN" />
</oauth:client-details-service>
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>
above security-config works just fine, But when I added this above block of code
<global-method-security pre-post-annotations="enabled" />
<http pattern="/resources/**" security="none"/>
<!-- secure the application's urls with the specific Role -->
<http auto-config="false" use-expressions="true" access-denied-page="/accessdenied">
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/logout" access="permitAll" />
<intercept-url pattern="/accessdenied" access="permitAll" />
<intercept-url pattern="/campaigns" access="hasAnyRole('ROLE_ADMIN','ROLE_MASTER')" />
<intercept-url pattern="/users" access="hasAnyRole('ROLE_ADMIN')" />
<intercept-url pattern="/dashboard" access="hasAnyRole('ROLE_ADMIN','ROLE_MASTER')" />
<form-login login-page="/login" default-target-url="/dashboard" authentication-failure-url="/accessdenied" />
<logout logout-success-url="/logout" />
</http>
I get error in eclipse.
cvc-complex-type.2.4.a: Invalid content was found starting with element 'http'. One of '{"http://www.springframework.org/schema/beans":description,
"http://www.springframework.org/schema/beans":import, "http://www.springframework.org/schema/beans":alias, "http://www.springframework.org/schema/
beans":bean, WC[##other:"http://www.springframework.org/schema/beans"], "http://www.springframework.org/schema/beans":beans}' is expected.
[UPDATED] Finally, I can solve the problem, here good security-config,spring mvc,mongodb,
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd ">
<!-- #author Soeng kanel (soengkanel#gmail.com) -->
<!-- This is default url to get a token from OAuth -->
<sec:http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<sec:http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/api/**" access="ROLE_ADMIN" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</sec:http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<!-- This is simple authentication manager, with a hardcoded user/password
combination. We can replace this with a user defined service to get few users
credentials from DB -->
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="mongoUserDetailsService">
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="120" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails" token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<!-- client -->
<oauth:client client-id="restapp"
authorized-grant-types="authorization_code,client_credentials"
authorities="ROLE_ADMIN" scope="read,write,trust" secret="secret" />
<oauth:client client-id="restapp"
authorized-grant-types="password,authorization_code,refresh_token,implicit"
secret="restapp" authorities="ROLE_ADMIN" />
</oauth:client-details-service>
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<sec:http pattern="/resources/**" security="none"/>
<sec:http auto-config="false" use-expressions="true" access-denied-page="/accessdenied">
<sec:intercept-url pattern="/login" access="permitAll" />
<sec:intercept-url pattern="/logout" access="permitAll" />
<sec:intercept-url pattern="/accessdenied" access="permitAll" />
<sec:intercept-url pattern="/campaigns" access="hasAnyRole('ROLE_ADMIN','ROLE_MASTER')" />
<sec:intercept-url pattern="/users" access="hasAnyRole('ROLE_ADMIN')" />
<sec:intercept-url pattern="/dashboard" access="hasAnyRole('ROLE_ADMIN','ROLE_MASTER')" />
<sec:form-login login-page="/login" default-target-url="/dashboard" authentication-failure-url="/accessdenied" />
<sec:logout logout-success-url="/logout" />
</sec:http>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>