PDA

View Full Version : Change css style BEFORE layout



EdwinK
20 Aug 2009, 11:08 PM
I want to change the style of a TextField in a form (when read-only set background-color to grey).When I do this with:
textField.setStyleName("read-only");
textField.setReadOnly(true);
add(textField);

This does not work, it seems that a default style is added to the textField just
before it's layed-out and displayed. If after layout and display I use the same command:
textField.setStyleName("read-only");

Then the style is applied. How can I apply a style (that has higher priority then the default style) before it is displayed?

Arno.Nyhm
21 Aug 2009, 3:04 AM
and try it with addStyleName is it the same?

other way to make your css settings "!important"

EdwinK
21 Aug 2009, 4:46 AM
addStyleName does not help
and setting css to "!important" does not work either.

I have the following css:



.read-only{
background-color:#DFE8F6 !important;
}
.non-read-only{
background-color: #ffffff !important;
}



This moduleload:



public void onModuleLoad() {
.....
Viewport viewport = new Viewport();
viewport.setLayout(new RowLayout(Orientation.HORIZONTAL));
PaymentPanel p = new PaymentPanel();
viewport.add(p, new RowData(500, 800));
RootPanel.get().add(viewport);


// field only gets ready-only css directly when I do this AFTER display:
//p.setStyleForReadOnly();

}

And this class:



public class PaymentPanel extends ContentPanel {
private TextField<String> bankAccount;


private Button wijzigBewaar;



public PaymentPanel() {

this.setTitle("Paymentdata");

TableLayout tableLayout = new TableLayout(3);
tableLayout.setWidth("100%");
tableLayout.setBorder(0);
tableLayout.setCellSpacing(0);
tableLayout.setCellPadding(2);
setLayout(tableLayout);




TableData td = new TableData();

td.setMargin(0);



TableData td2 = new TableData();

td2.setMargin(0);

td2.setColspan(2);




bankAccount = new TextField<String>();

bankAccount.setFieldLabel("bankaccount:");

bankAccount.addStyleName("read-only");
bankAccount.setStyleName("read-only");
bankAccount.setReadOnly(true);
bankAccount.setValue("dummy");
FormPanel bankAccountPanel = new FormPanel();
FormData formLayout = new FormData(200, 20);
bankAccountPanel.add(bankAccount, formLayout);
add(bankAccountPanel, td2);




wijzigBewaar = new Button("Wijzigen");

wijzigBewaar.setEnabled(true);

SelectionListener<ButtonEvent> sl = new SelectionListener<ButtonEvent>() {
@Override
publicvoid componentSelected(ButtonEvent ce) {
if (wijzigBewaar.getText().equals("Wijzigen")) {
bankAccount.setReadOnly(false);
wijzigBewaar.setText("Bewaar");




} else {

bankAccount.setReadOnly(true);

wijzigBewaar.setText("Wijzigen");
}
setStyleForReadOnly();
}
};
wijzigBewaar.addSelectionListener(sl);
add(wijzigBewaar, td);
}




publicvoid setStyleForReadOnly() {

if (wijzigBewaar.getText().equals("Bewaar")) {

bankAccount.setStyleName("non-read-only");
} else {
bankAccount.setStyleName("read-only");
}
this.layout();
}


}


Only when I call setStyleName("read-only") AFTER the form is displayed.
(in this case when the button is pressed twice or when setStyleName is called
as last part in the moduleLoad) the style is applied.
How can I apply the style BEFORE the form is displayed?

Arno.Nyhm
21 Aug 2009, 6:02 AM
1. first note: pls use firebug to look into your ready rendered items!

2. second note: addStyleName vs. setStyleName

i dont tell to use addStyleName in addition to setStyleName but instead! on all places.

why never use setStyleName -> only addStyleName?

i think this confuse you more then it helps you, because then you not see that your css is wrong!

why only addStyleName? otherwise you overwrite the gxt css styles for a element (in this case the x-form-text).

addStyle and setStyle on startup the same. the set styles are only added after rendering - so it works like a addstyle name.



3. if you look at your styles with firefox you see that if you use setStyleName all other gxt styles are removed and your item is rendered as espected.


5. if you look into the first css you see that there is also a background for the stylign of the textfile. so the solution is: reset the image.



here are the solution:


css:


.read-only{
background-color:#DFE8F6;
background-image: none;
}


code:


package org.yournamehere.client.forum.code.snippets;

import com.extjs.gxt.ui.client.Style.Orientation;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.layout.TableData;
import com.extjs.gxt.ui.client.widget.layout.TableLayout;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.RootPanel;

/**
*
* @author anonym
*/
public class ForumThread377109 implements EntryPoint{

public void onModuleLoad() {
Viewport viewport = new Viewport();
viewport.setLayout(new RowLayout(Orientation.HORIZONTAL));
PaymentPanel p = new PaymentPanel();
viewport.add(p, new RowData(500, 800));
RootPanel.get().add(viewport);

// field only gets ready-only css directly when I do this AFTER display:
// p.setStyleForReadOnly();

}

public class PaymentPanel extends ContentPanel {

private TextField<String> bankAccount;
private Button wijzigBewaar;

public PaymentPanel() {
this.setTitle("Paymentdata");
TableLayout tableLayout = new TableLayout(3);
tableLayout.setWidth("100%");
tableLayout.setBorder(0);
tableLayout.setCellSpacing(0);
tableLayout.setCellPadding(2);
setLayout(tableLayout);


TableData td = new TableData();
td.setMargin(0);


TableData td2 = new TableData();
td2.setMargin(0);
td2.setColspan(2);


bankAccount = new TextField<String>(){

@Override
public void render(Element target) {
super.render(target);
}

@Override
public void render(Element target, int index) {
super.render(target, index);
}


};
bankAccount.setFieldLabel("bankaccount:");
bankAccount.addStyleName("read-only");
bankAccount.setReadOnly(true);
bankAccount.setValue("dummy");
FormPanel bankAccountPanel = new FormPanel();
FormData formLayout = new FormData(200, 20);
bankAccountPanel.add(bankAccount, formLayout);
add(bankAccountPanel, td2);


wijzigBewaar = new Button("Wijzigen");
wijzigBewaar.setEnabled(true);
SelectionListener<ButtonEvent> sl = new SelectionListener<ButtonEvent>() {

@Override
public void componentSelected(ButtonEvent ce) {
if (wijzigBewaar.getText().equals("Wijzigen")) {
bankAccount.setReadOnly(false);
wijzigBewaar.setText("Bewaar");


} else {
bankAccount.setReadOnly(true);
wijzigBewaar.setText("Wijzigen");
}
setStyleForReadOnly();
}
};
wijzigBewaar.addSelectionListener(sl);
add(wijzigBewaar, td);
}

public void setStyleForReadOnly() {
if (wijzigBewaar.getText().equals("Bewaar")) {
bankAccount.removeStyleName("read-only");
} else {
bankAccount.addStyleName("read-only");
}
this.layout();
}
}
}

Arno.Nyhm
21 Aug 2009, 6:11 AM
if the Internet Explorer would implement CSS2.1 selectors then it would be more easy.
http://www.w3.org/TR/CSS21/selector.html#attribute-selectors

just use the setReadOnly

and use this css


.x-form-text[readonly]{
background-color:#DFE8F6;
background-image: none;
}

but this works not in IE7

EdwinK
21 Aug 2009, 7:46 AM
Hi Arno,

Thanks for your answer. This was helpfull. When I ran the code you posted (ForumThread377109), it still did not work: the background of the field initially stayed white.

This is what I saw in FireBug:
HTML:
<input id="x-auto-9" class="x-form-field x-form-text read-only" type="text" readonly="" tabindex="0" style="width: 200px; height: 20px;"/>
Used CSS:
.x-form-text, textarea.x-form-field {
background-color:#FFFFFF;
background-image:url(../images/default/form/text-bg.gif);
border-color:#B5B8C8;
}
.x-form-text, textarea.x-form-field {
background:transparent none repeat-x scroll 0 0;
border:1px solid;
padding:1px 3px;
}
read-only{
-------
------
} (means striked out)
That's why I started using addStyle in the first place. I noticed in Firebug that x-form-text got priority over read-only. By using addStyle I was sure the properties for read-only where taken. But I agree that my solution was not the way to go.

I tried some other combinations, and combining all your answers, finally got me the solution: I changed the stylesheet to:

.read-only{
background-color:#DFE8F6 !important;
background-image: none !important;
}
And now it works perfectly.

Thank you for your extensive answer. I now do understand Ext-Gwt (and stylesheets) much better.

fother
21 Aug 2009, 7:55 AM
my suggest.. its more simple...

set read only equals true and disable the field.. :)

EdwinK
21 Aug 2009, 8:16 AM
Disabling the field works a little bit. Disabling makes the text vague in Internet Explorer, but that also makes the text less readable. I need the text to be very readable as this is a form for presenting information.
(I use a form field instead of a text field because the same panel can be used to modify when presented in another mode).

Arno.Nyhm
24 Aug 2009, 12:10 AM
Disabling the field works a little bit. Disabling makes the text vague in Internet Explorer, but that also makes the text less readable. I need the text to be very readable as this is a form for presenting information.
(I use a form field instead of a text field because the same panel can be used to modify when presented in another mode).

i also avoid this because the text is not readable.

EdwinK
25 Aug 2009, 3:49 AM
I now have it working by using a Helper-class with the following methods:



public static void setReadOnly(Field field){
field.setReadOnly(true);
field.addStyleName("read-only");
field.addInputStyleName("read-only");
}

public static void setReadWrite(Field field){
field.setReadOnly(false);
field.removeStyleName("read-only");
field.removeInputStyleName("read-only");
}


This works for all form-fields when using the following css:

.read-only{
background-color:#DFE8F6 !important;
background-image: none !important;
}

Arno.Nyhm
26 Aug 2009, 3:28 AM
please see also this thread with new css for readonly:

http://extjs.com/forum/showthread.php?p=378590#post378590

Arno.Nyhm
16 Sep 2009, 5:59 AM
1why never use setStyleName -> only addStyleName?

i think this confuse you more then it helps you, because then you not see that your css is wrong!

why only addStyleName? otherwise you overwrite the gxt css styles for a element (in this case the x-form-text).

addStyle and setStyle on startup the same. the set styles are only added after rendering - so it works like a addstyle name.

note also this problem of setStyleName which works different in before/after rendering:
http://www.extjs.com/forum/showthread.php?t=78510