I'm trying to build main navigation with drop down subnavigation menu anchors. I got the HTML with CSS ready, but I don't know how to do it in the sublayout and its code behind.
I have done a lot of navigations, but those were all 1-dimensional menus using asp:repeaters or asp:ListViews.
Can anyone point me to the right direction?
Essentially you will want to have nested repeaters on the number of levels (or "dimensions") you want to display on your navigation. See an example below.
<asp:Repeater runat="server" ID="TopNavRepeater" OnItemDataBound="TopNavRepeater_OnItemDataBound">
<ItemTemplate>
<sc:Link runat="server" ID="sclTopLink" Field="__Display Name" />
<asp:Repeater runat="server" ID="SecondNavRepeater" OnItemDataBound="SecondNavRepeater_OnItemDataBound">
<ItemTemplate>
<sc:Link runat="server" ID="sclSecondLink" Field="__Display Name" />
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
You will want to get the children of each Item bound to the Top Repeater and bind it to the second Repeater. Use Sitecore Link Controls to render the links to the pages by settings the Items, and Fields, on the OnItemDataBound event.
See below for a rough example
protected void Page_Load(object sender, EventArgs e)
{
TopNavRepeater.DataSource = YourHomeItem.Children();
TopNavRepeater.DataBind();
}
protected void TopNavRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var item = e.Item.DataItem as Item;
if (item == null)
return;
var sclTopLink = e.Item.FindControl("sclTopLink") as Link;
var SecondNavRepeater = e.Item.FindControl("SecondNavRepeater") as Repeater;
if (sclTopLink != null)
{
sclTopLink.Item = item;
}
if (SecondNavRepeater != null)
{
SecondNavRepeater.DataSource = item.Children;
SecondNavRepeater.DataBind();
}
}
}
Related
I want to display a GI on one of the tab in any screen.
For example, there is a new custom GI for OrderMargin which I want to display on SO screen on a new tab that will show the Order Margin for a particular order only.
OrderMargin is simple GI with SOOrder, SOLine and InventoryItem table joins and few columns required columns with margin calculations.
Can anyone suggest?
Let's say you've created a GI called SalesOrderMargin with 2 hidden parameters:
To embed this GI into the Sales Orders page, you should follow the steps below:
Declare new unbound field for SOOrder to return absolute URL for the SalesOrderMargin GI:
public class SOOrderExt : PXCacheExtension<SOOrder>
{
public abstract class marginGiUrl : IBqlField { }
[PXString]
[PXUIField(Visible = false)]
public string MarginGiUrl
{
get
{
if (string.IsNullOrEmpty(Base.OrderType) ||
string.IsNullOrEmpty(Base.OrderNbr)) return string.Empty;
string inqName = "SalesOrderMargin";
var url = new StringBuilder(PXGenericInqGrph.INQUIRY_URL)
.Append("?name=").Append(inqName)
.Append("&SOOrderType=").Append(Base.OrderType);
.Append("&SOOrderNbr=").Append(Base.OrderNbr);
.Append("&hidePageTitle=true");
return PX.Common.PXUrl.SiteUrlWithPath().TrimEnd('/') +
url.ToString().Remove(0, 1);
}
}
}
On the Sales Orders screen, add new tab with a PXSmartPanel container set up to render as an iframe:
<px:PXTabItem Text="Margins" >
<Template>
<px:PXSmartPanel runat="server" ID="panelMarginGI" RenderIFrame="True"
AutoSize-Enabled="true" SkinID="Frame" LoadOnDemand="true"/>
</Template>
</px:PXTabItem>
Place input control for the custom SOOrder unbound field declared in step 1 somewhere in the Sales Orders' top level PXFormView container (input control will always be hidden from the users and is only required to assign source URL for the PXSmartPanel):
<px:PXFormView ID="form" runat="server" DataSourceID="ds" Width="100%"
DataMember="Document" Caption="Order Summary"...>
<Template>
...
<px:PXTextEdit ID="edMarginGiUrl" runat="server" DataField="MarginGiUrl" />
</Template>
</px:PXFormView>
In SO301000.aspx insert JavaScript code to assign source URL for the PXSmartPanel:
<script type="text/javascript" language="javascript">
function commandResult(ds, context) {
var commands = ["ReloadPage", "Save", "Cancel", "Insert", "First", "Previous", "Next", "Last"];
if (commands.indexOf(context.command) >= 0) {
var marginGiUrl = px_alls["edMarginGiUrl"];
var smartpanel = px_alls["panelMarginGI"];
if (marginGiUrl || smartpanel) {
var url = marginGiUrl.getValue();
smartpanel.setPageUrl(url);
smartpanel.repaint();
}
}
}
</script>
Subscribe to the CommandPerformed event of PXDataSource to invoke the commandResult JavaScript function:
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" TypeName="PX.Objects.SO.SOOrderEntry" PrimaryView="Document">
<ClientEvents CommandPerformed="commandResult" />
...
</px:PXDataSource>
And this is how your SalesOrderMargin GI should appear on the Sales Orders screen:
I have a web form in which i want to show label with time in decreasing fashion from 180 second to zero,i am using following code.
<div>
<asp:ScriptManager ID="SM1" runat="server"></asp:ScriptManager>
<asp:Timer ID="timer1" runat="server" Interval="1000"
OnTick="timer1_tick">
</asp:Timer>
</div>
<div>
<asp:UpdatePanel ID="updPnl" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblTimer" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="timer1" EventName="tick" />
</Triggers>
</asp:UpdatePanel>
</div>
and code behind
protected void timer1_tick(object sender, EventArgs e)
{
if (0 > DateTime.Compare(DateTime.Now,
DateTime.Parse(Session["TimeCount"].ToString())))
{
lblTimer.Text = "Number of Second Left: " +
((Int32)DateTime.Parse(Session["TimeCount"].
ToString()).Subtract(DateTime.Now).TotalSeconds).ToString();
}
else
{
}
}
and page load
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Page.Header.Title = "Test";
NewRecord();
}
if (!SM1.IsInAsyncPostBack)
Session["TimeCount"] = DateTime.Now.AddSeconds(180).ToString();
}
problem is that counter refresh each time to 180 when user click on button,and label is static value like 177,173 etc,i want to show changing in counting is shown to user?it is basically Q/A software.
I have a web form in which i want to show timing label for user,like 180 second,
i have done using following code,
<div>
<asp:ScriptManager ID="SM1" runat="server"></asp:ScriptManager>
<asp:Timer ID="timer1" runat="server" Interval="1000"
OnTick="timer1_tick">
</asp:Timer>
</div>
<div>
<asp:UpdatePanel ID="updPnl" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblTimer" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="timer1" EventName="tick" />
</Triggers>
</asp:UpdatePanel>
</div>
and code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Page.Header.Title = "Test";
}
if (!SM1.IsInAsyncPostBack)
Session["TimeCount"] = DateTime.Now.AddSeconds(180).ToString();
}
and
protected void timer1_tick(object sender, EventArgs e)
{
if (0 > DateTime.Compare(DateTime.Now,
DateTime.Parse(Session["TimeCount"].ToString())))
{
lblTimer.Text = "Number of Second Left: " +
((Int32)DateTime.Parse(Session["TimeCount"].
ToString()).Subtract(DateTime.Now).TotalSeconds).ToString();
}
else
{
}
}
problem i am facing that each time user click on button in page counter refresh to 180 again,Secondly this show fix value like 177,170,i want to show that label auto decreasing ?
Does anyone have any example on how to put a date time picker inside a sharepoint project?
more specifically to put a date time picker in the gridview..
I've been googling for hours and still couldn't find example that works..
most of the example is for normal web project and not for sharepoint project..
and btw I've tried putting the datetimecontrol inside the gridview, but it doesn't work as well.
Thanks in advance.
I love to use jQuery UI's Datepicker:
http://jqueryui.com/demos/datepicker/
To implement in a GridView, I normally make an editable text box and just apply the class to it, which would invoke the datepicker:
<asp:GridView ID="gvClientDetails" runat="server">
<Columns>
<asp:TemplateField HeaderText="Date">
<EditItemTemplate>
<asp:TextBox runat="server" ID="myTextBox" CssClass="dateTextBox" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="myLabel" runat="server" Text='<%# Eval("myDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and then make use of the below javascript (registered on your page or site wide):
$('.dateTextBox').each(function () {
$(this).datepicker(
{
changeMonth: true,
changeYear: true,
dateFormat: 'yy/mm/dd'
});
})
As for applying something like this to your sharepoint site, this should assist you:
http://blogs.lessthandot.com/index.php/WebDev/UIDevelopment/Javascript/adding-a-jquery-date-picker-to-sharepoint
Just use common standard SP DateTimeControl.
This is how we do it :
/// <summary>
/// Get common SP DateTimeControl with current DateOnly settings and MethodToProcessDateChanged
/// </summary>
public static DateTimeControl Cd(this bool DateOnly, bool AutoPostBack = false,
DateTime? SelectedDate = null, Func<bool> MethodToProcessDateChanged = null)
{
var d = new DateTimeControl();
d.DateOnly = DateOnly;
d.AutoPostBack = AutoPostBack;
if (SelectedDate != null)
d.SelectedDate = SelectedDate.Value;
if (MethodToProcessDateChanged != null)
d.DateChanged += (o, e) => { MethodToProcessDateChanged();};
return d;
}
See more details with some common usage samples here
i have one page and 2 user control in it and first user control have dropdownlist and second user control have another dropdown list , when we select dropdownlist of first user control than should be filled another dropdown list of second user control.... how can we achieve it ...please explaing in detain
thanks in advance...
I would expose the child DropDownList's OnSelectedItemChanged event AND the actual DropDownList at the top public level for the user control.
This would allow you to catch the OnSelectedItemChanged event in the Page and set the value of the second user control.
Let me know if you want some sample code.
Ok, so first the user control
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="SampleUserControl.ascx.cs" Inherits="WebApplication1.UserControls.SampleUserControl" %>
<asp:DropDownList runat="server" ID="DdlTest" AutoPostBack="true">
<asp:ListItem Text="Sampe 1" />
<asp:ListItem Text="Sampe 2" />
</asp:DropDownList>
now the file behind that
public partial class SampleUserControl : System.Web.UI.UserControl
{
public DropDownList InternalDropDownList
{
get { return DdlTest; }
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
okay, lets go to the actual .aspx
<form id="form1" runat="server">
<div>
<uc1:SampleUserControl ID="SampleUserControl1" runat="server" />
<uc1:SampleUserControl ID="SampleUserControl2" runat="server" />
</div>
</form>
and the code behind that
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SampleUserControl1.InternalDropDownList.SelectedIndexChanged += InternalDropDownList_SelectedIndexChanged;
}
void InternalDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
SampleUserControl2.InternalDropDownList.SelectedValue = SampleUserControl1.InternalDropDownList.SelectedValue;
}
}