Hidden field in ListView, for my Guid, or just hidden field.

Their are many times developer bind their data from database to the user interface and we wants to know what the user has chosen.

But in the meantime, the user will never wants to see the Guid. So what we need is a hidden field or a branch of hidden fields.

If you try to do this by a label with Visible=”false”. You won’t get what you want. Because ASP will just skip rendering not visible controls. They don’t even exist in your user interface.

We should use HiddenField and assign the Guid to its value. I do this in my ListView template and get the Guid back by FindControl().

開發網頁系統時,很常把資料庫的資料跟介面結合,然後我們想知道使用者選了甚麼項目,勾了那一行裡的checkbox. 但同時我們不想使用者在介面上看到Guid. 所以我們需要隱藏欄位.

如果你把Guid放在一個Label並設定Visible為false,那並不能成為一個隱藏欄位,ASP會在繪制UI時就不會繪Visible為false的控制項,它不存在你也取不出Guid.所以我們應該產生一個HiddenField控制項,把Guid存進去它的value. 我在我的ListView裡的每一行加一個HiddenField,再用FindControl()把Guid取回來.

Advertisements

ListView with dynamic template in action

In the previous article “Keep it MVC. Use templated controls without injecting Eval() in your aspx” I write about how to implement dynamic template. Now let’s look at how to use them.

There are a few things we should know before using template and ListView.

1. There are build-in action you can use. What I mean build-in is, you can assign some pre-defined CommandName to your control inside your ListView, such as a LinkButton, then if you assign CommandName=”Edit” to it, the event you should be handling when that button is being click is ListView.Onitemediting. Here is the list of build-in CommandName I know and the event handler which handle them.

在前一篇怎樣避免在頁面加入Eval()同時設定資料要怎樣跟ListView綁定.也知道了怎樣實作模板.現在來看看要怎樣應用之前做出來的東西.

使用之前有些東西我們應該要知道,對使用上會有幫助.

1. ListView有一些內建的事件可以用,內建的意思是你只要在ListView裡的控制項設定適當的CommandName就能喚起對應該事件.例如一個LinkButton,如果你把它的CommandName設為Edit,當它被Click時,會喚起ListView的Onitemediting事件.下面是一部份常用的內建CommandName及其對應的事件.

CommandName Event Handler
Insert oniteminserting
Edit onitemediting
Update onitemupdating
Delete onitemdeleting
Cancel onitemcanceling

There should be more, but these are enough for us to discuss.

After we have the template and took care of LayoutTemplate. We have to assign the template to our ListView.

應該還有其他內建的CommandName,但暫時這些就夠了.

我們已經有模板和寫好的LayoutTemplate.現在我們把模板指定給ListView

protected void Page_Init(object sender, EventArgs e)
        {
            ltv_webpages.ItemTemplate = new WebpageListViewTemplate(ListViewTemplateType.ItemTemplate);
            ltv_webpages.AlternatingItemTemplate = new WebpageListViewTemplate(ListViewTemplateType.AlternatingItemTemplate);
            ltv_webpages.EditItemTemplate = new WebpageListViewTemplate(ListViewTemplateType.EditItemTemplate);
            ltv_webpages.InsertItemTemplate = new WebpageListViewTemplate(ListViewTemplateType.InsertItemTemplate);
        }

We have to do this in Page_Init(). If you do this in Page_Load(), you will get a template not define error. If you want to know why this happen, it is because .NET will create and initialize all controls object before Page_Load() is reach. Take a look at any ASP page life cycle tutorial if you want to know more about this.

Then we have to bind data to the ListView. You can bind it in Page_Load(), but doing this, when you add a DataPager to your ListView, it won’t work properly. So, we should do the binding in Page_PreRender().

我們要在Page_Init()做這個動作,如果你在Page_Load()裡做這個動作,你會得到一個缺少模板定義的錯誤.如果想知道為甚麼會這樣,可以去看一下.NET的Page life cycle.在Page_Load()前就會建立好所有控制項.

然後我們把資料綁到ListView.可以在Page_Load()做這個動作,但這樣就沒辦法用DataPager.所以我們應該在Page_PreRender()把資料綁定.

protected void Page_PreRender(object sender, EventArgs e)
        {
            ltv_webpages.DataSource = WebpageDA.GetAllPageInformation();
            ltv_webpages.DataBind();
        }

Then, the last thing, inserting, editing and deleting data in ListView.

接著就是最後一項,加入,修改,刪除ListView的資料

1. Insert, set the ListView.InsertItemPosition to InsertItemPosition.FirstItem or InsertItemPosition.LastItem. This will make the InsertItemTemplate appears as the first or last item in the ListView. Then after you read the user input and done the inserting. assign InsertItemPosition.None to ListView.InsertItemPosition. Then the insertItemTemplate will be gone.

1. 新增,設定ListView.InsertItemPosition為InsertItemPosition.FirstItem或InsertItemPosition.LastItem其中一個. 這樣InsertItemTemplate就會出現在你設定的位置. 在完成加入動作後,把InsertItemPosition設為InsertItemPosition.None. InsertITemTemplate就會消失.

2. Editing, assign the index of which you wants to edit to ListView.EditIndex.

2. 修改, 把你想要修改的行數指定給ListView.EditIndex.

protected void ltv_webpages_ItemEditing(object sender, ListViewEditEventArgs e)
        {
            ltv_webpages.EditIndex = e.NewEditIndex;
        }

3. Canceling, you have to handle two canceling, edit canceling and insert canceling. by setting EditIndex to -1 or InsertItemPosition to None.

3. 取消, 你要處理兩種取消,修改取消和新增取消,把EditIndex設成-1,把InsertItemPosition設為None.

protected void ltv_webpages_ItemCanceling(object sender, ListViewCancelEventArgs e)
        {
            if (e.CancelMode == ListViewCancelMode.CancelingEdit)
            {
                ltv_webpages.EditIndex = -1;
            }
            else if (e.CancelMode == ListViewCancelMode.CancelingInsert)
            {
                ltv_webpages.InsertItemPosition = InsertItemPosition.None;
            }
        }

If you want some custom command, CommandName = “YourCommand”, the use a switch in onitemcommand event handler to handle it.

This pretty much wrap everything common up. I will post sample code when I could.

See you next time.

如果你想用自訂的指令, CommandName=”YourCommand”, 然後你可以在Onitemcommand裡用一個Switch去處理不同的Command.

最常用的大概就這些了.

C++ template is clumsy

After knowing that C++ template is actually marco, feel kind of disappointed.

I implemented a generic double linked list to feel what it is like in C++, I have done that in Java.

C++ code is redundant, wherever your class or methods have something to do with the template, need template <class name>. And also C++ template is good for container class only. Your template methods should not touch anything inside your generic part, because this may get you into runtime error.

For example, you have a generic method that use generic class T, and then try to call T->print(), if T has define print(), everything is just fine, otherwise you will get runtime error. Whereas Java have interface to restrict the signature of a generic class. C++ may use inheritance to over come this but it won’t be type safe.

Not to mention C++ multiple inheritance may lead to diamond problem. That is exactly why I learned C, C#, Java before C++, because in my opinion C++ is difficult to use and clumsy. But even so, you will eventually need to use C++ someday if you are not obsessed to a paticular language. But learning C++ is still very funny, it will be easier if you have good memory, but sadly my memory is not so good.

Icefaces Facelets to get a template effect

I am planning to make it dynamic, but haven’t yet done the hands on.

Preparation:

include icefaces-facelets.jar

and put the following into web.xml

<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jspx</param-value>
</context-param>

This tells JSF to assume a prefix of jspx, which the Facelet’s rendered can interpret. Facelets can use many other parameters depending on your application.

put the following into faces-config.xml

<application>
<view-handler>com.icesoft.faces.facelets.D2DFaceletViewHandler

</view-handler>

</application>

tell JSF about the Facelets view handler. This is a plug-in that handles the Render Response and Restore View phases of the JSF request-processing life cycle.

Template Idea

And then comes the confusing part, I can’t understand this after reading the document twice. I have to jump into the source and do some hands on to figure this out. I think I have a better way to present it. This may be my wrong intepretation.

You need three things.

1. a jsp that load the template

2. a jspx which is the template

3. some jspx which are components you put inside the template.

1. load template

  • <ui:composition> – This is a templating tag that wraps content to be included in another facelet. Any content outside the composition tag will be ignored by the Facelets view handler.
  • <ui:define> – This tag is a templating tag that defines named content to be inserted into a template.

example:

            <ui:composition template="mainTemplate.jspx">
<ui:define name="faceletHeader">
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"></meta>
<title>
<ice:outputText value="Facelet Dynamic Include Tutorial"/>
</title>
<link href="./xmlhttp/css/xp/xp.css" rel="stylesheet" type="text/css"/>
</ui:define>
</ui:composition>

2. The template

  • <ui:insert>– A templating tag that declares a named content element to be defined by another Facelet. Used effectively with the ui:define tag.
  • <ui:include>– A server-side include tag for Facelets. It simply includes the document pointed to by the “src” attribute as part of the current JSF page.

example:

<ui:insert name="content">
<ui:include src="./content-facelet.jspx" />
</ui:insert>

3. Contents

just icefaces jspx that you normally write.

Conclusion:

The confusing part is when you load the template, you will have two way to actually put content inside <ui:insert>.

1. use <ui:define> inside “template load” to put content directly into it.

2. use <ui:include> inside “template” to reference a jspx.

And if I am not getting it wrong, any content inside <ui:insert> which is not <ui:include> will be replace by <ui:define> stuff.

I will update this post when I get the dynamic reference content work.

Have fun~