Sidslog

Май 27, 2008

Поменялся яваскрипт к предыдущему посту

Filed under: Uncategorized — Метки: , , , , , — sidslog @ 2:39 пп

Были ошибки в JS, написанном в предыдущем посте. Те, что нашел, исправил. Также исправил яваскрипт для компоненты, срабатывающей по фокусу. Код самой компоненты появится через пару дней))

Вот исправленный JS:

var searchValue = “” ;

var onloadFunctions = new Array() ;
var onAfterLoad = new Array() ;

var FindHandler = new Object() ;

var searchElements = new Array() ;
var searchStrings = new Array() ;

FindHandler.testClass = function(tagClass, className) {
    var classN = new RegExp(“(^|\\s)” + className + “(\\s|$)”);
    return classN.test(tagClass) ;
}

FindHandler.getParentByClass = function(className, tag) {
    while (tag.parentNode) {
        if (tag.className && this.testClass(tag.className, className)) {
            return tag ;
        } else {
            tag = tag.parentNode ;
        }
    }
    return null ;
}

FindHandler.getElementsByClassName = function(className, tag) {
    var tag = tag || document ;

    var returnElements = new Array() ;
    for (var i = 0 ; i < tag.childNodes.length; i ++) {
        if (tag.childNodes[i].className && this.testClass(tag.childNodes[i].className, className)) {
            returnElements.push(tag.childNodes[i]) ;
        }
    }

    for (var i = 0 ; i < tag.childNodes.length; i ++) {
        var ret = this.getElementsByClassName(className, tag.childNodes[i]) ;
        if (ret) {
            for (var j = 0 ; j < ret.length; j ++) {
                returnElements.push(ret[j]) ;
            }
        }
    }

    return returnElements.length > 0 ? returnElements : null ;
}

var KeyCode = new Object() ;
KeyCode.VK_ENTER = 13 ;

var f1 =  function() {
    var form = document.forms[0] ;
    if (form) {
        form.onkeypress = function(e) {
            var key;
            if (window.event)
                 key = window.event.keyCode;     //IE
            else
                 key = e.which;     //firefox

            if (key == KeyCode.VK_ENTER) {

                var target ;
                if (window.event) {
                    target = window.event.srcElement ;
                } else {
                    target = e.target ;
                }
                var parent = FindHandler.getParentByClass(“useonenter-container”, target) ;
                if (parent) {
                    var controls = FindHandler.getElementsByClassName(“useonenter-control”, parent) ;
                    if (controls && controls[0]) {
                        if (controls[0].tagName == “INPUT” || controls[0].tagName == “BUTTON”) {
                            controls[0].click() ;
                        } else {
                            controls[0].onclick() ;
                        }
                    }
                }
                return false ;
            }

            return true ;
        }

    }
}

function focusSearch() {
    var target ;
    if (window.event) {
        target = window.event.srcElement ;
    } else {
        target = this ;
    }
    var index = searchElements.indexOf(target) ;
    if (target.value == searchStrings[index]) {
        target.value = “” ;
    }
}
function blurSearch() {
    var target ;
    if (window.event) {
        target = window.event.srcElement ;
    } else {
        target = this ;
    }
    var index = searchElements.indexOf(target) ;
    if (target.value == “”) {
        target.value = searchStrings[index] ;
    }
}
var f2 = function() {
    var allElements = FindHandler.getElementsByClassName(‘search-value-container’, null) ;

    var el = new Array() ;
    if (allElements) {
        for (var i = 0; i < allElements.length; i ++) {
            el[i] = allElements[i] ;
            if (el[i]) {
                el[i].onfocus = focusSearch ;
                el[i].onblur = blurSearch ;
            }
        }
    }
}

var setFocusEvents = function() {
    if (searchElements && searchStrings) {
        if (searchElements.length == searchStrings.length) {
            for (var i = 0; i < searchElements.length; i ++) {
//                alert(searchElements[i]) ;
                searchElements[i].onfocus = focusSearch ;
                searchElements[i].onblur = blurSearch ;
                searchElements[i].onfocus ;
                searchElements[i].onblur ;
                if (searchElements[i].value == null || searchElements[i].value == “”) {
                    searchElements[i].value = searchStrings[i] ;
                }
            }
        }
    }
}

var changeBeforeSubmit = function() {
    var form = document.forms[0] ;
    if (form) {
        form.onsubmit = function() {
            for (var i = 0; i < searchElements.length;  i ++) {
                if (searchElements[i].value == searchStrings[i]) {
                    searchElements[i].value = “” ;
                }
            }
        }
    }
}

onloadFunctions.push(f1) ;
onloadFunctions.push(f2) ;
onloadFunctions.push(changeBeforeSubmit) ;
onAfterLoad.push(setFocusEvents) ;

window.onload = function() {
    for (var i = 0 ; i < onloadFunctions.length; i ++) {
        onloadFunctions[i]() ;
    }
    for (var i = 0 ; i < onAfterLoad.length; i ++) {
        onAfterLoad[i]() ;
    }
}

Май 25, 2008

Отслеживаем нажатие ENTER внутри формы

Filed under: Uncategorized — Метки: , , , , , , , — sidslog @ 12:21 пп

На форме jsf-страницы может быть расположено несколько UICommand компонент. Необходима возможность указать, какая компонента должна срабатывать при нажатии ENTER в одном из полей ввода.

Для этого будем обрабатывать onkeypressed внутри формы. То, какая компонента будет срабатывать и в каком контейнере, будем указывать с помощью классов “control” и “container”.

Также разработаем jsf-компоненту, которая будет показывать, внутри какого контейнера должен вызываться данный UICommand при нажатии ENTER в поле ввода.

<h:form id=”default”>
    <t:panelGrid id=”cont” >
        <t:inputText value=”#{testInfo.name}”/>
        <t:commandButton type=”button” action=”#{testInfo.act1}” value=”button” />
        <t:commandLink action=”#{testInfo.act2}” value=”link” >
            <jsfaces:test forId=”cont”/>
        </t:commandLink>
    </t:panelGrid>
    <t:panelGrid id=”cont2″>
        <t:inputText value=”#{testInfo.name}”/>
        <t:commandButton action=”#{testInfo.act1}” value=”button”>
            <jsfaces:test forId=”cont2″ />
        </t:commandButton>
        <t:commandLink action=”#{testInfo.act2}” value=”link” />
    </t:panelGrid>
</h:form>

Внутри сont все нажатия ENTER должны обрабатыватся с помощью CommandLink, внутри cont2 – CommandButton.

Код JS для обработки нажатия ENTER:

var onloadFunctions = new Array() ;

var FindHandler = new Object() ;

FindHandler.testClass = function(className) {
    var classN = new RegExp(“(^|\\s)” + className + “(\\s|$)”);
    return classN.test(className) ;
}

FindHandler.getParentByClass = function(className, tag) {
    while (tag.parentNode) {
        if (tag.className && this.testClass(tag.className)) {
            return tag ;
        } else {
            tag = tag.parentNode ;
        }
    }
    return null ;
}

FindHandler.getElementsByClassName = function(className, tag) {
    var returnElements = new Array() ;
    for (var i = 0 ; i < tag.childNodes.length; i ++) {
        if (tag.childNodes[i].className && this.testClass(tag.childNodes[i].className)) {
            returnElements.push(tag.childNodes[i]) ;
        }
    }

    for (var i = 0 ; i < tag.childNodes.length; i ++) {
        var ret = this.getElementsByClassName(className, tag.childNodes[i]) ;
        if (ret) {
            for (var j = 0 ; j 0 ? returnElements : null ;
}

var KeyCode = new Object() ;
KeyCode.VK_ENTER = 13 ;

var f1 = function() {
    var form = document.forms[0] ;
    if (form) {
        form.onkeypress = function(e) {
            var key;
            if (window.event)
                key = window.event.keyCode; //IE
            else
                key = e.which; //firefox

            if (key == KeyCode.VK_ENTER) {

                var target ;
                if (window.event) {
                    target = window.event.srcElement ;
                } else {
                    target = e.target ;
                }
                var parent = FindHandler.getParentByClass(“container”, target) ;
// alert(parent) ;
                if (parent) {
                    var controls = FindHandler.getElementsByClassName(“control”, parent) ;
                    if (controls && controls[0]) {
// alert(controls[0].tagName) ;
                        if (controls[0].tagName == “INPUT” || controls[0].tagName == “BUTTON”) {
                            controls[0].click() ;
                        } else {
                            controls[0].onclick() ;
                        }
                    }
                }
            }

            return false ;
        }
    }
}

onloadFunctions.push(f1) ;

window.onload = function() {
    for (var i = 0 ; i < onloadFunctions.length; i ++) {
        onloadFunctions[i]() ;
    }
}

Классы компоненты:

UITest.java:

public class UITest extends UIComponentBase implements NamingContainer {

    public void restoreState(FacesContext facesContext, Object object) {
        if (object instanceof Object[]) {
            Object[] state = (Object[]) object ;
            super.restoreState(facesContext, state[0]);
            forId = (String) state[1] ;
        } else {
            super.restoreState(facesContext, object); //To change body of overridden methods use File | Settings | File Templates.
        }
    }

    public Object saveState(FacesContext facesContext) {
        Object[] state = new Object[2] ;
        state[0] = super.saveState(facesContext) ;
        state[1] = forId ;
        return state ; //To change body of overridden methods use File | Settings | File Templates.
    }

    public static final String COMPONENT_TYPE = “ru.js.faces.component.test.Test” ;
    public static final String COMPONENT_FAMILY = “ru.js.faces.component.test.Test” ;
    public static final String RENDERER_TYPE = “ru.js.faces.component.test.TestRenderer” ;

    public UITest() {
        super() ;
        setRendererType(RENDERER_TYPE) ;
    }

    public String getFamily() {
        return COMPONENT_FAMILY ; //To change body of implemented methods use File | Settings | File Templates.
    }

    private String forId ;

    public String getForId() {
        return forId;
    }

    public void setForId(String forId) {
        this.forId = forId;
    }
}

TestTag.java:

public class TestTag extends UIComponentTag {

    public String getComponentType() {
        return UITest.COMPONENT_TYPE; //To change body of implemented methods use File | Settings | File Templates.
    }

    public String getRendererType() {
        return UITest.RENDERER_TYPE; //To change body of implemented methods use File | Settings | File Templates.
    }

    public String forId;

    public String getForId() {
        return forId;
    }

    public void setForId(String forId) {
        this.forId = forId;
    }

    protected void setProperties(UIComponent uiComponent) {
        super.setProperties(uiComponent); //To change body of overridden methods use File | Settings | File Templates.
        if (null != getForId()) {
            ((UITest)uiComponent).setForId(getForId());
        }
    }
}

TestRenderer.java:

public class TestRenderer extends Renderer {

    @Override
    public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
        super.encodeBegin(facesContext, uiComponent); //To change body of overridden methods use File | Settings | File Templates.
        UITest testComponent = (UITest) uiComponent ;
        ResponseWriter writer = facesContext.getResponseWriter();

        writer.startElement(“script”, testComponent);
        writer.writeAttribute(“type”, “text/javascript”, null);

        String containerId = ((UITest)uiComponent).getForId() ;
        UIComponent parent = uiComponent.getParent() ;
        String controlId = parent.getId() ;

//JavaScript в данном случае добавляет к фунциям, которые выполнятся при загрузке еще одну. В ней элементам контейнера и контрола будут присваиваться соответствующие классы
        writer.writeText(“var “+ controlId +”UseOnEnter = function () { var container = document.getElementById(document.forms[0].id + ‘:’ + ‘”+ containerId + “‘) ;\n” +
        ”var control = document.getElementById(document.forms[0].id + ‘:’ + ‘” + controlId + “‘); \n” +
        ”container.className = container.className + ‘ container’ ;\n” +
        ”control.className = control.className + ‘ control’; }\n” +
        ”onloadFunctions.push(“+ controlId +”UseOnEnter)”, null) ;

        writer.endElement(“script”);
    }

}

Описание компоненты и рендерера в faces-config.xml:

<component>
    <component-type>ru.js.faces.component.test.Test</component-type>
    <component-class>ru.js.faces.component.test.UITest</component-class>

    <property>
        <property-name>value</property-name>
        <property-class>java.lang.String</property-class>
    </property>

</component>

<render-kit>
    <renderer>
        <component-family>ru.js.faces.component.test.Test</component-family>
        <renderer-type>ru.js.faces.component.test.TestRenderer</renderer-type>
        <renderer-class>ru.js.faces.component.test.TestRenderer</renderer-class>
    </renderer>
</render-kit>

Описание тега в components.tld:

<tag>
    <name>test</name>
    <tag-class>ru.js.faces.component.test.TestTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
        <name>forId</name>
        <type>java.lang.String</type>
        <required>true</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <name>id</name>
        <type>java.lang.String</type>
        <required>false</required>
        <rtexprvalue>false</rtexprvalue>
    </attribute>
</tag>

Подключение components.tld в web.xml:

<jsp-config>
    <taglib>
        <taglib-uri>http://jsfaces</taglib-uri>
        <taglib-location>/WEB-INF/components.tld</taglib-location>
    </taglib>
</jsp-config>

Май 23, 2008

Myfaces Tomahawk и Javascript изменение надписи при наведении фокуса

Filed under: Uncategorized — Метки: , , , , — sidslog @ 12:09 пп

На странице расположена таблица с некоторыми данными. Над ней фильтр с полем ввода и кнопкой найти. Изначально в поле ввода значение “Поиск…”, при наведении фокуса значение пропадает. На то, какое поле ввода будет обрабатываться, будет указывать с помощью класса.

Код jsf:

<h:inputText value=”#{searchInfo.searchName}” styleClass=”search-value-container” />

<h:commandLink value=” #{resources['command.FIND']} ” action=”#{searchInfo.find}” />

Класс search-value-container указывает на то, что наведение и уход фокуса будут обрабатываться у inputText.

В бине :

public String getSearchName() {
    if (getName() == null || getName().equals(“”)) {
        return Util.getResource(Messages.SEARCH_CODE) ;
    }
        return getName();
}

public void setSearchName(String name) {
    if (name == null || name.equals(Util.getResource(Messages.SEARCH_CODE)) || name.equals(“”)) {
        setName(null);
    } else {
        setName(name.trim()) ;
    }
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

Код JS для обработки фокуса:

var el = new Array() ;
var searchValue = “” ;

function getElementsByClassName(className, tag, elm){
     var testClass = new RegExp(“(^|\\s)” + className + “(\\s|$)”);
     var tag = tag || “*” ;
     var elm = elm || document ;
     var elements = (tag == “*” && elm.all) ? elm.all : elm.getElementsByTagName(tag) ;
     var returnElements = [] ;
     var current ;
     var length = elements.length ;
     for ( var i = 0; i < length; i ++) {
         current = elements[i] ;
         if (testClass.test(current.className)) {
             returnElements.push(current) ;
         }
     }
     return returnElements ;
}

function focusSearch() {
     if (this.value == searchValue) {
         this.value = “” ;
     }
}

function blurSearch() {
     if (this.value == “”) {
         this.value = searchValue ;
     }
}

function load() {

     var allElements = getElementsByClassName(‘search-value-container’, null, null) ;

     for (var i = 0; i < allElements.length; i ++) {
         el[i] = allElements[i] ;
         if (el[i]) {
             el[i].onfocus = focusSearch ;
             el[i].onblur = blurSearch ;
         }
     }

}

window.onload = load ;

Для того, чтобы указать, какое значение должно быть в поле ввода, необходимо перед inputText’ом поместить

<t:jsValueSet name=”searchValue” value=”#{resources['message.SEARCH_CODE']}” />

Май 17, 2008

Решение PermGen OutOfMemoryError

Filed under: Uncategorized — Метки: , , , — sidslog @ 6:01 пп

Теория про поколеняи и сборщики мусора

Ошибка PermGen происходит при переполнении памяти в постоянном (permanent) поколении.

Решение:

Использовать синхронизованый сборщик мусора

-XX:+UseConcMarkSweepGC

Указать, что сборщик мусора должен вызываться для объектов постоянного поколения

-XX:+CMSPermGenSweepingEnabled

Указать сборщику на выгрузку классов

-XX:+CMSClassUnloadingEnabled

Задать количество памяти, выделяемой под постоянное поколение, чтобы сборщик мусора не выгружал классы, необходимые для работы сервера приложений

-XX:MaxPermSize=128m

Ссылка на оригинал

Май 16, 2008

JBOSSQL ManyToOne OUTER JOIN

Filed under: Uncategorized — Метки: , , — sidslog @ 2:30 пп

Класс карточки

public class Card implements Serializable {
private List contributors;
@OneToMany(mappedBy = “card”)
public List getContributors() {
return contributors != null ? contributors : (contributors = new ArrayList());
}
}

Класс контрибутора:

public class Contributor implements Serializable {
private Card card ;
@ManyToOne(targetEntity = Card.class)
@JoinColumn(name = “CARDID”)
public Card getCard() {
return card;
}
}

При выборке карточек для поиска по контрибуторам можно использовать запрос:

getEntityManager().createQuery(“SELECT DISTINCT card FROM catalog.Card card LEFT OUTER JOIN card.contributors contributor WHERE contributor….”) ;

Theme: Silver is the New Black. Блог на WordPress.com.

Follow

Get every new post delivered to your Inbox.