0

How to add or delete a Grid row (or register) without reseting all the Grid components values

asked 2011-10-10 16:25:47 +0800

carpolva gravatar image carpolva
155 4

updated 2011-10-10 16:49:31 +0800

Hello guys.

My issue is simple: I have a Grid composed of textboxes, comboboxes, etc., in my screen I have a button for adding new registers (or rows) to this grid but when I add a new register all the Grid components are reset and I lose previously entered values in the components. My question is similar to: http://www.zkoss.org/forum/listComment/9175/1/20/

Here's part of my code for better understanding:

page.zul grid (simplified)

<grid model="@{ejemploBean.allEvents, load-after='btnAdd.onClick'}" width="1600px">
    	<columns>
    		<column width="40px">Nro.</column>
    		<column width="180px">Actividades</column>
    		<column width="50px">Lunes</column>
    	</columns>
    	<rows>
    		<row self="@{each='data'}">
    			<!-- Nro. -->
    			<label value="@{data.counter}"/>
    			
    			<!-- Actividades -->
    			<combobox  model="@{data.actividades}" onAfterRender="self.setSelectedIndex(0)"/>
              	
              	<!-- Lunes -->
              	<intbox value="0" constraint="no negative,no empty">
              		<attribute name="onChange">
	                <![CDATA[
						lblLunes.setValue(ejemploBean.sumarValorColumna(self,"Lunes"));
						ejemploBean.sumaTotales();
	                ]]>
	                </attribute>
              	</intbox>
    		</row>
    	</rows>
    </grid>

Next is the class EjemploBean.java where the grid's model is the variable named "lista" composed with a normal bean (TablaBean) and is returned in the getAllEvents() method, "bandera" is a boolean (if it's false is because the page is loaded first time, so, don't create again the list when I add new registers, I put this 'cause getAllEvents() method is invoked every time I add a new register because of the load-after='btnAdd.onClick' in my .zul page). In the onClick$btnAdd I add the new records to the list, and the Grid is reloaded again by the load-after method with the new rows or registers.

public List<TablaBean> getAllEvents() {
		if(!bandera){
			for(int i=1; i<=4; i++){
				TablaBean myBean = new TablaBean();
				myBean.setCounter(i);
				lista.add(myBean);
				
				for(int j=0; j<7; j++){
					observaciones.add("");
				}
			}
		}
		bandera = true;

		return lista;
	}


This is onClick of the Add Button:

public void onClick$btnAdd() {
		int size = 0;
		Integer cantidad = iboxRegistros.getValue();
		
		for(int i=0; i<cantidad; i++){
			size = lista.size();
			
			TablaBean myBean = new TablaBean();
			myBean.setCounter(size+1);
			
			lista.add(myBean);
			for(int j=0; j<7; j++){
				observaciones.add("");
			}
		}
	}


I'll appreciate any help, maybe I'll bind each row component value in a TablaBean object and save each one in memory.

Is there a better way to do this?.

Best regards.

delete flag offensive retag edit

7 Replies

Sort by ยป oldest newest

answered 2011-10-10 20:19:26 +0800

RichardL gravatar image RichardL
768 4

I'm not sure if I fully understand but if you just want to add a new row to the grid you could you use ListModelList as your model and just add each row instead of loading the grid each time.

link publish delete flag offensive edit

answered 2011-10-11 07:45:47 +0800

carpolva gravatar image carpolva
155 4

Hi RichardL, thanks for your response. The fact is that actually I've developed some examples with <listbox> using listmodellist as its model, for example:

<listbox rows="5" model="@{win$composer.allEvents, load-after='add.onClick'}" 
		selectedItem="@{win$composer.current}">
		<listhead>
			<listheader label="Item" />
		</listhead>		
		<listitem self="@{each='event'}" value="@{event}">			
			<listcell label="@{event.name}" />
		</listitem>
	</listbox>

... and It works pretty well, but I see that a Listbox has child components like <listitem> and <listcell> ... how can I use a <combobox> , <textbox> or <intbox> inside a listbox?. For example, if I put:

<listitem self="@{each='event'}" value="@{event}">			
	<textbox value="@{event.name}"/>
</listitem>

It generates the following exception: org.zkoss.zk.ui.UiException: Unsupported child for listitem: <Textbox null>, I'll try the following in Javacode and tell you later if I succeeded:

ListItem item = new Listitem();
Listcell cell = new Listcell();
Textbox txt = new Textbox();
cell.appendChild(txt);
item.appendChild(cell);

Regards.

link publish delete flag offensive edit

answered 2011-10-11 08:59:28 +0800

carpolva gravatar image carpolva
155 4

Hi. I was able to append any component (intbox, textbox, etc) in my listcell... but when I add a new row, all the previous entered data still dissapears, so, I'm still in trouble jeje :(

What do you mean with "use ListModelList as your model and just add each row instead of loading the grid each time"?, because if I use a listmodelList as my listbox's model I need to specify the "load-after='add.onClick" sentence to see the added row, or is there another way?.

Thanks for the help.

link publish delete flag offensive edit

answered 2011-10-12 03:30:30 +0800

matthewgo gravatar image matthewgo
375

Hi

You can use "ListModelList" to render the row automatically instead of using "List" and triggering load-after.
(because load-after is registered to model, it will re-render all grid rows)

ListModelList is alive list. Registered with onChange event, it will detect the change on itself and then notify the grid to render the change.

ListModelLit lista;
public ListModelLit  getAllEvents() {

link publish delete flag offensive edit

answered 2011-10-12 08:47:06 +0800

carpolva gravatar image carpolva
155 4

Hi Matthewgo, RichardL, thank you very much for your responses. Actually I made it! jeje. I can add a new row without reseting the previous entered data in any grid row (intbox, datebox in my example). I only have a question, I'm still using the load-after='btnAdd.onClick' sentence in my grid's model but now the entered values are not reset, any idea?.

The following is my working example (maybe it'll be useful for someone):

todo.zul

<?page title="Todo Example"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>

<window id="win" width="360px" apply="${sessionScope.myController}">
	<grid model="@{win$composer.myList, load-after='btnAdd.onClick'}" width="360px">
		<columns>
    		<column width="100px">Item</column>
    		<column width="100px">Priority</column>
    		<column width="150px">Date</column>
    	</columns>
    	<rows>
    		<row self="@{each='event'}">
    			<label value="@{event.id}"/>
    			<intbox value="@{event.priority}" constraint="no negative,no empty"/>
    			<datebox value="@{event.date}"/>
    		</row>
    	</rows>
	</grid>
	<label value="New Registers"/><intbox id="myIntBox" value="0"/><button id="btnAdd" label="Add"/>
</window>

EventController.java

public class EventController extends GenericForwardComposer {

	ListModelList myList;
	
	Intbox myIntBox;
	
	public EventController(){
		myList = new ListModelList();
		for(int i=1; i<6; i++){
			TodoEvent evento = new TodoEvent(""+i, "Nombre"+i, i, new Date());
			myList.add(evento);
		}
	}
	
	public void onClick$btnAdd() {
		Integer size = myList.size()+1;
		Integer cantidad = myIntBox.getValue();

		for(int i=0; i<cantidad; i++){
			TodoEvent myBean = new TodoEvent(""+size, "Nombre"+size, size, new Date());
			myList.add(myBean);
			size++;
		}
	}

	public ListModelList getMyList() {
		return myList;
	}

	public void setMyList(ListModelList myList) {
		this.myList = myList;
	}
}

Regards.

link publish delete flag offensive edit

answered 2011-10-12 09:00:56 +0800

RichardL gravatar image RichardL
768 4

Nice job, now the load-after is registered to ListModelList

link publish delete flag offensive edit

answered 2011-10-12 14:18:40 +0800

carpolva gravatar image carpolva
155 4

Thanks guys for your help, now it works pretty well. Now I've a last issue related to this thread (sorry, I'm a beginner in ZK jeje):

I add rows to my grid and it doesn't reset the previous entered values in grid row components like textboxes, intboxes or dateboxes (just like code shown above)... but if I use comboboxes is different, all the previous comboboxes selected options are reset.

This is where I define the combobox in my .zul page:

        <rows>
    		<row self="@{each='event'}">
    			<label value="@{event.id}"/>
    			<intbox value="@{event.priority}" constraint="no negative,no empty"/>
    			<datebox value="@{event.date}"/>
    			<combobox model="@{event.myCombo}" onAfterRender="self.setSelectedIndex(0)"/>
    		</row>
    	</rows>

In the Java class, myCombo is a ListModelList, for example:

myCombo = new ListModelList();
myCombo.add("Please select...");
myCombo.add("Option1");
myCombo.add("Option2");
myCombo.add("Option3");

I'll appreciate any related help, you're my last hope! :D

Best regards.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2011-10-10 16:25:47 +0800

Seen: 475 times

Last updated: Oct 12 '11

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More