I am working on a requirement to highlight fields that have failed in red after JSF server side validation. No javascript can be used for validation. Is there a method to link server side validation with css style changes?
You could do this with a managed bean:
public class ValidBean {
private UIComponent myComponent;
public UIComponent getMyComponent() {
return myComponent;
}
public void setMyComponent(UIComponent myComponent) {
this.myComponent = myComponent;
}
public String getErrorStyle() {
FacesContext context = FacesContext
.getCurrentInstance();
String clientId = myComponent.getClientId(context);
Iterator<FacesMessage> messages = context
.getMessages(clientId);
while (messages.hasNext()) {
if (messages.next().getSeverity().compareTo(
FacesMessage.SEVERITY_ERROR) >= 0) {
return "background-color: red";
}
}
return null;
}
}
Request scope variable:
<managed-bean>
<managed-bean-name>validBean</managed-bean-name>
<managed-bean-class>stylevalid.ValidBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
Sample view:
<f:view>
<h:form>
<h:inputText binding="#{validBean.myComponent}" styleClass="foo"
style="#{validBean.errorStyle}">
<f:validateLength minimum="6" />
</h:inputText>
<h:commandButton />
<h:messages />
</h:form>
</f:view>
The component is bound to the backing bean. If error messages have been queued for the component, it overrides its CSS class settings with its style attribute.
The seam framework makes this very easy. Check this out: http://www.redhat.com/docs/manuals/jboss/jboss-eap-4.2/doc/seam/Seam_Reference_Guide/JSF_form_validation_in_Seam.html
Related
I'm trying to implement a JSF page in which the user should insert some data. In particular, when pressing a button a dialog box should appear asking for user input. The main problem is that the execution of the backing bean should be stopped waiting for a user response.
A toy example is the following.
JSF page:
<h:form id="label">
<p:dialog header="User input" widgetVar="dlg2"
visible="true" modal="false"
resizable="false" height="100" width="300">
<br />
<h:inputText value="#{userInputMB.userInput}"></h:inputText>
</p:dialog>
<p:commandButton action="#{userInputMB.pressButton}"></p:commandButton>
</h:form>
UserInputMB:
package jsfpackage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class UserInputMB {
private String userInput;
private boolean visualizeDialog = false;
public UserInputMB() {
}
public void pressButton() {
System.out.println("Executing the pressButton method..");
//here I need to visualize the dialog and wait for the user input
System.out.println(userInput);
}
public String getUserInput() {
return userInput;
}
public void setUserInput(String userInput) {
this.userInput = userInput;
}
public boolean isVisualizeDialog() {
return visualizeDialog;
}
public void setVisualizeDialog(boolean visualizeDialog) {
this.visualizeDialog = visualizeDialog;
}
}
In this example, when pressing the button, the pressButton method should visualize the dialog box and wait for the user input and then continue the execution.
I also found this similar question on stackoverflow:
Synchronous dialog invocation from managed bean
but my situation is quite different. I'm forced to implement this kind of behavior.
Thanks in advance!
The following sample contains a dialog and a button. The button prepares the input and opens the dialog. In the dialog the second button calls the action to process the input.
JSF:
<!-- dialog for input -->
<p:dialog id="inputDialog" widgetVar="inputDialog" header="Input here">
<p:inputText value="#{userInputMB.userInput}" />
<p:commandButton action="#{userInputMB.processInput}" />
</p:dialog>
<!-- Calls the action to prepare the input and updates and opens the dialog -->
<p:commandButton value="show dialog" action="#{userInputMB.prepareInput}"
oncomplete="PF('inputDialog').show()" process="#this" update=":inputDialog" />
Bean:
#ManagedBean
#SessionScoped
public class UserInputMB {
private String userInput;
public void prepareInput() {
userInput = "Please enter your input here";
}
public void processInput() {
if("inputYouWanted".equals(userInput)) {
System.out.println("hurray, correct input!");
}
}
public String getUserInput() {
return userInput;
}
public void setUserInput(String userInput) {
this.userInput = userInput;
}
}
i create a dependency property to close a view from view model,
dependencyProperty:
public static class WindowBehaviors
{
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.RegisterAttached("IsOpen"
, typeof(bool),
typeof(WindowBehaviors),
new UIPropertyMetadata(false, IsOpenChanged));
private static void IsOpenChanged(DependencyObject obj,DependencyPropertyChangedEventArgs args)
{
Window window = Window.GetWindow(obj);
if (window != null && ((bool)args.NewValue))
window.Close();
}
public static bool GetIsOpen(Window target)
{
return (bool)target.GetValue(IsOpenProperty);
}
public static void SetIsOpen(Window target, bool value)
{
target.SetValue(IsOpenProperty, value);
}
}
and use it in my xaml like this:
<window
...
Command:WindowBehaviors.IsOpen="True">
it work's fine,but when i want to bind it to a property in viewModel,it dosen't work,and i guess,it dosen't work because i define the resource later in xaml.
in xaml:
<Window.Resources>
<VVM:myVieModel x:Key="myVieModel"/>
</Window.Resources>
and i don't know what should i do,where should i put this:
Command:WindowBehaviors.IsOpen="{binding Isopen}"
public MainWindow()
{
InitializeComponent();
// DO THIS
this.DataContext = Resources["myVieModel"];
}
You need to bind the data context for the scope where your binding is in. Usually this is fairly high up in your XAML, usually the first element in your form or control.
In your case, the data context beeing a static resource the folllowing should work:
<grid DataContext="{StaticResource myVieModel}">
<!-- the code with the binding goß into here -->
</grid>
Actually this is the same as ebattulga suggests, just the XAML way (no code behind).
Thanks for your helps,i fixed it and here is my solution,
i used to use MVVMToolkit but now i'm useing MVVMlight and as you know in MVVMLight,we just define Application Resources Once in App.xaml.so we can bind all the window's properties simply,hope this can help some people who has the same problem!!
app.xaml
<Application.Resources>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True" />
</Application.Resources>
and in the window(view)
DataContext="{Binding DefaultSpecItemVM, Source={StaticResource Locator}}"
and it works perfect.:D
I have a WebControl and it has a property. However, value of this property should not be changed once the control has been constructed... in other words, the property can be set only in some code like:
<ct:Acontrol ID="xxx" Aproperty="xxx" runat="server"></ct:Acontrol>
but not:
xxx.Aproperty=...
so what is the normal way to do that? Thanks!
The properties that you are using in markup must be public properties with a public getter and setter. There is no special syntax for "only set this once".
What you can do is check in the setter whether it was already set and if so, not set to the new value.
private string _aProperty;
public string Aproperty
{
get { return _aProperty;}
set
{
if(_aProperty == null)
{
_aProperty = value;
}
}
}
You should be able to use
xxx.Attributes("Aproperty")
All ASP.NET markup attributes are set as properties after the constructor is executed. You can select specific read-only properties to be set only in the constructor by using sub-classes of the control.
<!-- Aproperty=xxx -->
<ct:Acontrolxxx ID="xxx" runat="server"></ct:Acontrolyyy>
<!-- Aproperty=yyy -->
<ct:Acontrolyyy ID="yyy" runat="server"></ct:Acontrolxxx>
public class Acontrolxxx : Acontrolbase
{
public Acontrolxxx () { base.Aproperty = xxx; }
}
The property is probably using a combination of the EditorBrowsable and DesignerSerializationVisibility attributes:
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string SomeProperty { get; set; }
The DesignerSerializationVisibility attribute shows the property in markup, and the EditorBrowsable attribute hides the property in code-behind.
I have the following code, and when I try to run it, I can see that the BrokerProvider is not being resolved. Here is my code:
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection) ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
new TestBroker().RunTestBroker();
}
class TestBroker
{
private IBrokerProvider brokerProvider;
public void RunTestBroker()
{
List<IPortfolio> portfolios = BrokerProvider.GetPortfolios();
}
[Dependency]
public IBrokerProvider BrokerProvider
{
get { return brokerProvider; }
set { brokerProvider = value; }
}
}
The related config
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
<typeAlias alias="IBrokerProvider" type="PA.Common.Interfaces.IBrokerProvider, PA.Common" />
<typeAlias alias="PManager" type="PA.BrokerProviders.PManager, PA.BrokerProviders" />
</typeAliases>
<containers>
<container>
<types>
<type type="IBrokerProvider" mapTo="PManager">
<lifetime type="singleton" />
</type>
</types>
</container>
</containers>
</unity>
Another question: Do I need to repeat the same 3 lines of code that I have under main in every other class that I would like to use unity or setting it up once is enough?
That's because are creating TestBroker directly by calling operator new on it:
new TestBroker().RunTestBroker();
In order for unity to resolve your dependencies you need to call the framework like so:
var broker = container.Resolve<TestBroker>();
IUnityContainer is the interface that is going to be doing all the work for you - i.e. resolving types to instances. You only need to create it once and then just pass it around the application where ever you need it.
I have a user control which accepts a title attribute. I would also like that input inner HTML (ASP Controls also) inside of that user control tag like so:
<uc:customPanel title="My panel">
<h1>Here we can add whatever HTML or ASP controls we would like.</h1>
<asp:TextBox></asp:TextBox>
</uc:customPanel>
How can I achieve this? I have the title attribute working correctly.
Thanks.
Implement a class that extends Panel and implements INamingContainer:
public class Container: Panel, INamingContainer
{
}
Then, your CustomPanel needs to expose a property of type Container and another property of type ITemplate:
public Container ContainerContent
{
get
{
EnsureChildControls();
return content;
}
}
[TemplateContainer(typeof(Container))]
[TemplateInstance(TemplateInstance.Single)]
public virtual ITemplate Content
{
get { return templateContent; }
set { templateContent = value; }
}
Then in method CreateChildControls(), add this:
if (templateContent != null)
{
templateContent.InstantiateIn(content);
}
And you will be using it like this:
<uc:customPanel title="My panel">
<Content>
<h1>Here we can add whatever HTML or ASP controls we would like.</h1>
<asp:TextBox></asp:TextBox>
</Content>
</uc:customPanel>
You need to make sure EnsureChildControls is called. There are number of ways of doing that such as through the CreateChildControls base method but you can simply do this to get the inner contents of a custom control to render. It gets more complicated when you need to remember state and trigger events but for plain HTML this should work.
protected override void Render(HtmlTextWriter writer) {
EnsureChildControls();
base.Render(writer);
}