SqlDataSource custom paging - sqldatasource

I need use sqldatasource(stored proc) to bind a gridview.
<asp:GridView ID="gvBC" runat="server" AutoGenerateColumns="False" ShowFooter="True" AllowSorting="True" AllowPaging="True" pageSize ="3" DataSourceID="dsBCSearch">
<Columns>
<asp:BoundField DataField="ContactID" HeaderText="ContactID" Visible="false"/>
<asp:BoundField DataField="BldgNum" HeaderText="Bldg#" SortExpression="BldgNum" />
</Columns>
<EmptyDataTemplate> No Building Coordinator Found. </EmptyDataTemplate>
<EmptyDataRowStyle HorizontalAlign="Center" />
</asp:GridView>
<asp:SqlDataSource ID="dsBCSearch" runat="server" ConnectionString="<%$ ConnectionStrings:DBConnStr %>" SelectCommand="GetBC" SelectCommandType="StoredProcedure"
SortParameterName="SortExpression" />
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
LoadBC();
}
protected void LoadBC()
{
dsBCSearch.SelectCommand = "GetBCwP";
dsBCSearch.SelectParameters.Clear();
dsBCSearch.SelectParameters.Add("LName", this.txtLNAme.Text.Trim());
dsBCSearch.SelectParameters.Add("Active", this.chkActive.Checked.ToString());
//dsBCSearch.SelectParameters.Add("sortExpression", this.gvBC.SortExpression);
dsBCSearch.SelectParameters.Add("startRowIndex", this.gvBC.PageIndex.ToString());
dsBCSearch.SelectParameters.Add("maximumRows", this.gvBC.PageSize.ToString());
this.gvBC.DataBind();
}
Now just render first page (3 records) and in footer no number showing up. HOw can I add paging to footer?
Thanks

sqldatasource is not good for custom paging. I have to add another pager part and like old asp page, to manually write the code.
But objectdatasource is much easy for this. It will have some parameter like StartRowIndexParameterName MaximumRowsParameterName SortParameterName SelectCountMethod. It will auto pass to data souce

Related

How to dynamically add listheaders and listcells in ZK

I am totally new in ZK. I need to create N listheaders and N listcells in my zul file. But I do not know how to do it from my java controller and I am not using MVVM.
The problem would be something like:
#Wire
private Window idWindow;
private Listheader header;
private Listcell item1;
#Override
public void onCreate(Event event) {
header.setLabel("laaaa");// It would set just one header but I can have many (N headers) and same for items
}
<zk>
<window id="idWindow" title="nameWindow" apply="controller.java" border="normal" closable="true" sizable="true" maximizable="true" maximized="true" height="85%" width="150%" style="overflow:auto;">
<!-- CONTINUES -->
<listbox id="mainList" hflex="1" vflex="1">
<listhead>
<listheader id="header" label="A" />
<listheader id="header1" label="B" />
<listheader id="header2" label="C" />
....
<listheader id="headerN" label="N" />
</listhead>
<listitem>
<listcell id="item1" label="A"/>
<listcell id="item2" label="B"/>
<listcell id="item3" label="C"/>
....
<listcell id="itemN" label="D"/>
</listitem>
</listbox>
<!-- CONTINUES -->
</window>
</zk>
You can leave the listhead empty in the zul, wire it into your controller and create the listheaders there. The important step is to ask the listbox for its listhead, and append the listheaders to it. For the cells, give your listbox a renderer that creates them for each item if you use a model to give your list data.
Your zul will be much shorter:
<zk>
<window ... >
<listbox id="mainList" hflex="1" vflex="1">
<listhead />
</listbox>
</window>
</zk>
Then in your controller, you create the header in doAfterCompose and attach the renderer:
#Wire
private Listbox mainList;
#Override // This method should be specified by a composer super class
public void doAfterCompose(Component comp)throws Exception
{
super.doAfterCompose(comp);
mainList.setModel(someModelWithYourData);
// create listheaders (manually/in for-loop/based on data...)
Listhead head = mainList.getListhead();
head.appendChild(new Listheader("A"));
...
// attach renderer
mainList.setItemRenderer(new ListitemRenderer<Object>() // use proper data type instead of Object
{
#Override
public void render(Listitem item, Object data, int index)
throws Exception
{
item.appendChild(new Listcell("a"));
...
}
});
}
There is also an example on zk's developer sites: https://www.zkoss.org/wiki/ZK_Developer%27s_Reference/MVC/View/Renderer/Listbox_Renderer
In case you cannot use a model, you could also append the listitems in the zul or in the controller, and then create the listcells:
for (Component child : mainList.getChildren())
{
if (child instanceof Listitem)
{
Listitem item = (Listitem) child;
// do the same as in the renderer
}
}

update component in another xhtml form from Custom layout p:selectOneRadio not working

My xhtml is split in to Menu area (defaultMenu.xhtml) and Content area (defaultContent.xhtml).
The code for defaultMenu.xhtml is:
<h:form id="defaultmenuform">
<p:outputPanel id="menupanel" class="contain auto-fixed-center">
<p:panel id="pmenu" visible="#{phController.user.menuVisible}">
<table id="stutable">
<tr>
<td width="15%">
<p:outputLabel id="stuname" value="#{phController.phBean.studentName}" />
</td>
<td>
<p:tabMenu activeIndex="#{param.selectedtab}">
<p:menuitem value="Home" outcome="phome" icon="ui-icon-star">
<f:param name="selectedtab" value="0" />
</p:menuitem>
<p:menuitem value="Bank" outcome="bhome" icon="ui-icon-person">
<f:param name="selectedtab" value="1" />
</p:menuitem>
</p:tabMenu>
</td>
</tr>
</table>
</p:panel>
</p:outputPanel>
</h:form>
The defaultContent.xhtml actually displays the ph.xhtml content (as part of functional navigation) and the code is:
<ui:define name="content">
<f:event listener="#{phController.readPeople}" type="preRenderView">
</f:event>
<h:form id="form">
<p:selectOneRadio id="selstud" value="#{phController.phBean.ssSeq}" layout="custom">
<p:ajax update=":defaultmenuform:parentmenupanel :defaultmenuform:stuname" listener="#{phController.onChangePerson}"/>
<f:selectItems value="#{phController.selectStudents}" />
</p:selectOneRadio>
<div style="width: 300px; float:left;">
<p:dataGrid var="studentlist" value="#{phController.listStudent}" columns="1" rowIndexVar="stuindex">
<p:panel header="" style="text-align:left">
<h:panelGrid columns="1" style="width:100%">
<h:outputText value="#{studentlist.studentName}" />
<p:radioButton for=":form:selstud" itemIndex="#{stuindex}"/> Select
</h:panelGrid>
</p:panel>
</p:dataGrid>
</div>
</h:form>
</ui:define>
The code for backing bean is:
Map<String, Object> studentparam = new HashMap<>();
studentparam.put("studentSeq", phBean.getSsSeq());
lS = getBaseDAOService().readStudent("readStudent", studentparam);
phBean.setStudentName(lS.get(0).getStudentFirstName() + " " + lS.get(0).getStudentLastName());
As you can see, I am calling the onChangeStu method to display the selected Student Name in defaultMenu.xhtml. I am using Custom Layout p:selectOneRadio in ph.xhtml and onClick trying to update a p:outputLabel in defaultMenu.xhtml.
The backing bean method gets invoked successfully and the value is also set in variable phController.phBean.studentName, but the update is not working. I also checked using view source and the id is “:defaultmenuform:stuname”, I also tried updating the menu panel ":defaultmenuform:menupanel”, but none of this works.
Not sure how to resolve this. Please suggest.
Including the structure of all .xhtmls
<h:body id="entirePageBody">
<div id="page">
<ui:insert name="header" >
<ui:include src="/template/defaultHeader.xhtml" />
</ui:insert>
<ui:insert name="menu" >
<ui:include src="/template/defaultMenu.xhtml" />
</ui:insert>
<div id="content_div" class="auto-fixed-center">
<div id="content_div_padding" class="content-block">
<ui:insert name="content" >
<ui:include src="/template/defaultContent.xhtml" />
<ui:debug hotkey="z" />
</ui:insert>
</div>
</div>
<ui:insert name="footer" >
<ui:include src="/template/defaultFooter.xhtml" />
</ui:insert>
</div>
</h:body>
PhController.java:
public class PhController extends BaseController implements Serializable {
private List<Stud> listStudent;
private List selectStudents;
SelectItem option;
private PhBean phBean;
private Boolean menuVisible;
int counter = 0;
public PhController() {
phBean = new PhBean();
}
public void readPeople() {
listStudent = new ArrayList<Stud>();
listStudent.add(new Stud(1, "John Miller"));
listStudent.add(new Stud(2, "Scott Jackson"));
selectStudents = new ArrayList();
option = new SelectItem(listStudent.get(0).getStudentSeq(), "Select");
selectStudents.add(option);
option = new SelectItem(listStudent.get(1).getStudentSeq(), "Select");
selectStudents.add(option);
phBean.setSsSeq(String.valueOf(1));
phBean.setSelectedName(listStudent.get(0).getStudentName());
menuVisible = true;
}
public void onChangePerson() {
phBean.setSelectedName(listStudent.get(1).getStudentName());
}
// Getters and Setters
}
PhBean.java:
public class PhBean implements Serializable {
private String ssSeq;
private String studName; // Used to display the name in the Menu bar.
private String selectedName;
public PhBean() {
}
// Getters and Setters
}
I'd say that in the p:ajax in defaultContent.xhtml the list of components to be updated should be separated with spaces only, no commas - so try changing this:
update=":defaultmenuform:menupanel, :defaultmenuform:stuname"
to this:
update=":defaultmenuform:menupanel :defaultmenuform:stuname"
UPDATE
I played with this a bit more and may have found a clue - please add the following code to defaultmenuform:
<p:messages autoUpdate="true" showDetail="true" />
This should help us tracking the reason for failed validation (in case failing validation is the root cause for you - as I said, I have rather limited possibility to reproduce this issue).
Anyway, when I selected some item in p:selectOneRadio, an error message like this appeared:
Conversion Error setting value 'test001.Student#4110c95c' for 'null Converter'.
And the root cause was on this row:
<p:selectOneRadio id="selstud" value="#{phController.phBean.ssSeq}" layout="custom">
p:selectOneRadio expects only String to be passed as a value - and ssSeq is very likely of a different type. Try to change the way value is populated to ensure it is always String - maybe a different attribute of the phBean or simply a brand new String one.
NOTE: if this doesn't help, maybe you could update your question with very simplified example of how phController and phBean could look like if we are to test it.
UPDATE #2
So you have explained there is a problem that you want to call phController.readPeople every time the page is loaded/refreshed, but instead it gets loaded with each and every Ajax request, thus overwriting the values.
In your PhController (it is a bean, right? session scoped?) you could add something like this (omitted null checks for the sake of readability):
public void readPeopleOnGet() {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
HttpServletRequest req = (HttpServletRequest) ec.getRequest();
String reqMethod = req.getMethod();
if ("GET".equals(reqMethod)) {
readPeople();
}
}
With the above method you could keep this part of your defaultContext.xhtml in place, provided it is actually called (I assume so), just with the listener method changed:
<f:event listener="#{phController.readPeopleOnGet}" type="preRenderView">
</f:event>
The method readPeopleOnGet will still be called with every request to the page, but since Ajax requests are POST, it will only call readPeople when the page is loaded or refreshed as whole.
This may not be a "perfectly clean" solution, but seemed to work properly when I tested it.
UPDATE #3
Well, since you use PrimeFaces, it would be possible to identify Ajax call also this way:
public void readPeopleOnGet() {
RequestContext rc = RequestContext.getCurrentInstance();
if (!rc.isAjaxRequest()) {
readPeople();
}
}
But if I got your point from latest comments, you want to only run readPeople when the page is loaded for the very first time - so the following part could be even better for that.
You didn't answer if PhController is actually a bean, but I assume it is (there were no annotations visible from the code you posted). You may try making it #SessionScoped:
#ManagedBean
#SessionScoped
public class PhController extends BaseController implements Serializable {
// the rest of the PhController goes here...
Then you could add something like this to the PhController:
#PostConstruct
private void init() {
readPeople();
}
The annotation #PostConstruct ensures the method init is called exactly once after the bean was created. You can continue calling the method readPeople from other places as necessary, while removing both the <f:event ... /> and readPeopleOnGet as these will no longer be needed.

MVC dropdown index change

I got a requirement can any one please suggest me ideas if possible with sample
I have a dropdown and beneath i have couple of checkboxes...
For each dropdown item user can select checkboxes.., if user change index of dropdown previous dropdown index and checkbox should maintain in session and new index item can select boxes....
All together we need to post to server...
for eg; dropdown list contains apple,samsung,motorola,htc
checkboxes contain 3G,LTE,Speed,Bandwdth..
once apple is selected he selected values 3g and LTE. and again user selected samsung in dropdown and he selected check boxes speed and lTE.
While posting to server i need to send both list like
apple 3G
apple LTE
Samsung Speed
Samsung LTE
Could any one please suggest some ideas and example
Rather than using Dropdown List you can use div with labels and checkboxes and use jQuery to post data.
You can use jQuery plugin in your case. Here is a good example http://www.erichynds.com/examples/jquery-ui-multiselect-widget/demos/
I am sure there will be many other way to do this, and i think this will help you.
In aspx page:
<form id="form1" runat="server">
<div>
<asp:DropDownList ID="DropDownList1" runat="server" >
<asp:ListItem Value="-1">Select a Device</asp:ListItem>
<asp:ListItem>Apple</asp:ListItem>
<asp:ListItem>Samsung</asp:ListItem>
<asp:ListItem>Nokia</asp:ListItem>
<asp:ListItem>HTC</asp:ListItem>
</asp:DropDownList>
<br />
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatDirection="Horizontal">
<asp:ListItem>3G</asp:ListItem>
<asp:ListItem>LTE</asp:ListItem>
<asp:ListItem>Speed</asp:ListItem>
<asp:ListItem>Bandwidth</asp:ListItem>
</asp:CheckBoxList>
<br />
<asp:Button ID="ButtonSubmit" runat="server" OnClick="ButtonSubmit_Click" Text="Submit" />
<asp:Button ID="ButtonSave" runat="server" OnClick="ButtonSave_Click" Text="Save Data" />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Clear First ListBox" />
<br />
<br />
<asp:ListBox ID="ListBox1" runat="server" Height="88px" SelectionMode="Multiple" Width="208px"></asp:ListBox>
<asp:ListBox ID="ListBox2" runat="server" Height="88px" SelectionMode="Multiple" Width="208px"></asp:ListBox>
</div>
</form>
and in code behind file paste this,
protected void Page_Load(object sender, EventArgs e)
{
}
public void LoadDataToListBox(string list1)
{
ListBox1.Items.Add(list1);
}
protected void ButtonSave_Click(object sender, EventArgs e)
{
if (ListBox1.Items.Count != 0)
{
for (int i = 0; i < ListBox1.Items.Count; i++)
{
ListBox2.Items.Add(ListBox1.Items[i]);
}
}
}
protected void ButtonSubmit_Click(object sender, EventArgs e)
{
if(DropDownList1.SelectedValue!="-1")
{
string item1 = "You'r device is " + DropDownList1.SelectedValue;
LoadDataToListBox(item1);
}
foreach (ListItem li in CheckBoxList1.Items)
{
if(li.Selected)
{
LoadDataToListBox("You Choose " + li.Text);
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
ListBox1.Items.Clear();
}

Load ASP-MVC View with Ext.Panel loader

I have following layout, related to the one i am describing in this question
<ext:Viewport runat="server">
<Items>
<ext:Panel Region="North" runat="server" ID="TopBar" />
<ext:Panel Region="West" runat="server" ID="Nav" >
<Items>
<ext:Button runat="server" ID="loaderComponentFooBar">
<DirectEvents>
<Click OnEvent="loadFooBar" />
</DirectEvents>
</ext:Button>
//Some more Buttons each with his own loader Function in Code-Behind
</Items>
</ext:Panel>
<ext:Panel runat="server" Region="center" ID="MainPanel" />
</Items>
</ext:Viewport>
on Button-Click i now want to load my View # "/Foo/Bar/" to the MainPanel
How can i achieve this in CodeBehind?
I already tried:
public void loadFooBar(object sender, DirectEventArgs e)
{
MainPanel.Loader.Url = "/Foo/Bar/"; //Throws null reference Exception
MainPanel.Loader.Url = "~/Foo/Bar/"; // same as above
MainPanel.Loader.GetUrlByRoute("Foo/Bar/"); //again the same
MainPanel.Loader.LoadContent("/Foo/Bar/");
//and after each of these attempts except the last went:
MainPanel.Loader.Mode = LoadMode.Frame;
MainPanel.Loader.LoadMask.ShowMask = false;
MainPanel.Loader.LoadContent();
}
Just by the way, i am using aspx-web-application views
I think you should not use a page's code behind for DirectEvents' handlers. It is going out of the MVC concept. You should refer a controller's actions.
Here is an example.
Example View
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<%# Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Ext.Net.MVC v2 Example</title>
</head>
<body>
<ext:ResourceManager runat="server" />
<ext:Viewport runat="server" Layout="BorderLayout">
<Items>
<ext:Panel runat="server" Region="West" Width="100">
<Items>
<ext:Button
runat="server"
Text="Load View 1"
DirectClickUrl=<%# Url.Action("LoadView1") %>
AutoDataBind="true" />
<ext:Button
runat="server"
Text="Load View 2"
DirectClickUrl=<%#Url.Action("LoadView2") %>
AutoDataBind="true" />
</Items>
</ext:Panel>
<ext:Panel ID="MainPanel" runat="server" Region="Center">
<Loader runat="server" Mode="Frame" AutoLoad="false">
<LoadMask ShowMask="true" />
</Loader>
</ext:Panel>
</Items>
</ext:Viewport>
</body>
</html>
Example Controller
using System.Web.Mvc;
using Ext.Net;
using Ext.Net.MVC;
namespace Work2MVC.Controllers
{
public class AspxController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult View1()
{
return View();
}
public ActionResult View2()
{
return View();
}
public ActionResult LoadView1()
{
Panel p = X.GetCmp<Panel>("MainPanel");
p.LoadContent(Url.Action("View1"));
return this.Direct();
}
public ActionResult LoadView2()
{
Panel p = X.GetCmp<Panel>("MainPanel");
p.LoadContent(Url.Action("View2"));
return this.Direct();
}
}
}
Also you can initiate a load request on client side via JavaScript. Then you avoid an additional request.

CalendarExtender loose his value on postback

Here is the code of my date selecting control.
When the page containing the control is submitted AFTER the Page_Load and link button click events passed, tb is reset to it is initial value (which is today)
<div class="ui-form-text">
<div>
<asp:TextBox ID="tb" runat="server" autocomplete="off"></asp:TextBox></div>
</div>
<ajaxToolkit:CalendarExtender ID="ce" runat="server" TargetControlID="tb" Format="dd/MM/yyyy"
CssClass="calendar" EnableViewState="true">
</ajaxToolkit:CalendarExtender>
<ajaxToolkit:MaskedEditExtender ID="mee" runat="server" TargetControlID="tb" Enabled="true"
Mask="99\/99\/9999" ClearMaskOnLostFocus="false" EnableViewState="true">
</ajaxToolkit:MaskedEditExtender>
<asp:CompareValidator ID="cv" runat="server" ControlToValidate="tb" Display="Dynamic"
ErrorMessage="Невалидна дата" Operator="DataTypeCheck" Type="Date" ForeColor="Red">
</asp:CompareValidator>
<asp:RangeValidator ID="rv" runat="server" ControlToValidate="tb" Type="Date">
</asp:RangeValidator>
I am having the same problem myself and the only solution (well, workaround) I could find was this:
ASP.NET Ajax CalendarExtender will not update SelectedDate value
I hope this can help you, this worked for me.
String tmp_;
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if (Request[txtCalendarExtender.UniqueID] != null)
{
if (Request[txtCalendarExtender.UniqueID].Length > 0)
{
this.tmp_ = Request[txtCalendarExtender.UniqueID];
}
}
}
}

Resources