Как я могу предотвратить исчезновение jQuery UI look'n'feel после отправки формы/обратной передачи?

У меня есть JSF (Mojarra) v2.1.11, Primefaces v3.4.2, веб-приложение Java 6 с использованием jQuery datepicker. Я использую селектор, который выглядит примерно так:

$('#form1\\:dp').datepicker({showOn: 'button', buttonText: "Choose"});

Это позволяет пользователю щелкнуть кнопку, чтобы вызвать datepicker. Проблема, с которой я сталкиваюсь, заключается в том, что «кнопка» исчезает после , который пользователь отправляет. По-видимому, «кнопка» загружается только один раз, когда страница изначально загружена. Я хотел бы знать, как (что лучше всего) , чтобы сохранить кнопку «datepicker» jQuery между кнопками/postbacks.

<Код> index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>


    
        
            <title>testcal - index.xhtml</title>
            <meta charset="utf-8" />
        
        
            
                
                

                    

                    
                        
                    





<!-- optional to populate another field with same value... onchange="$('...hashSymbolHere...queryForm\\:endDate').val($(this).val());"> -->



*

</html>

<Код> TestBean.java

package aaa.bbb.ccc.war;

import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIForm;
import javax.faces.component.UIInput;
import javax.faces.component.UIPanel;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ComponentSystemEvent;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("testBean")
@Scope("view")
public class TestBean implements Serializable
{

    private static final List drpdwnListOrig;  
    private static final String[] prfx = {"aaa","bbb","ccc", "ddd", "eee", "fff","ggg","hhh","iii","jjj","kkk","lll","mmm","nnn","ooo","ppp","qqq","rrr","sss","ttt","uuu","vvv","www","xxx","yyy","zzz"};

    //////////////////////////// [static initializer] ///////////////////////////////
    //////////////////////////// [static initializer] ///////////////////////////////
    //////////////////////////// [static initializer] ///////////////////////////////
    static
    {
        //drpdwnListOrig...
        List l = getListOfStrings();
        drpdwnListOrig = Collections.unmodifiableList(null == l ? new ArrayList() : l);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("drpdwnListOrig", drpdwnListOrig);
        List testList = (List) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("drpdwnListOrig");
    }

    public TestBean()
    {
        parmMap = this.getParmMap();
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("parmMap", parmMap);
    }

    public void reset(ActionEvent event)
    {
        LinkedHashMap m = new LinkedHashMap();
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("parmMap");
        setParmMap(m);
    }

    public String submitQuery()
    {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("hitlistData");
        if (this.getParmMap().isEmpty())
        {
            return "";
        }

        return "/page2.xhtml?faces-redirect=true";
    }


    private static LinkedHashMap parmMap;
    public LinkedHashMap getParmMap()
    {
        LinkedHashMap map = (LinkedHashMap) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("parmMap");

        if (null == map)
        {
            map = new LinkedHashMap();
        }
        return map;
    }

    public void setParmMap(LinkedHashMap map)
    {
        parmMap = map;
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("parmMap", parmMap);
    }


    private static SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    public void validate(ComponentSystemEvent e) throws ParseException
    {

        LinkedHashMap parmMap = this.getParmMap();
        UIForm queryForm = (UIForm) e.getComponent();

        UIInput lastName_c = (UIInput) queryForm.findComponent("lastName");
        String lastName = (String) (lastName_c.getValue());
        UIInput birthDate_c = (UIInput) queryForm.findComponent("birthDate");
        birthDate_c.setValid(true);
        String birthDate = (String) birthDate_c.getValue();

        FacesContext fc = FacesContext.getCurrentInstance();

        if (null != lastName && lastName.trim().length() > 0)
        {
            birthDate_c.setRequired(true);

            if (null == birthDate || birthDate.length() < 1)
            {
                birthDate_c.setValid(false);
                fc.addMessage(birthDate_c.getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "birth date is required", "birth date is required"));
                fc.renderResponse();
            }
            else
            {
                birthDate_c.setValid(true);
            }
        }
        else
        {
            birthDate_c.setValid(true);
            birthDate_c.setRequired(false);
        }
    }

    //////////////////////////// autocomplete ///////////////////////////////    
    //////////////////////////// autocomplete ///////////////////////////////    
    //////////////////////////// autocomplete ///////////////////////////////    
    private static List drpdwnList;

    public static List getDrpdwnList()
    {
        if (null == drpdwnList)
        {
            drpdwnList = (null == drpdwnList ? (List) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("drpdwnListOrig") : drpdwnListOrig);
        }

        return drpdwnList;
    }
    public void setDrpdwnList(List data) throws IOException
    {
        drpdwnList = data;
    }
    public static List drpdwnListComplete(String s)       //autocomplete "completeMethod"...
    {
        List list = getDrpdwnList();
        List drpdwnSuggestions = new ArrayList();
        for (String ss : list)
        {
            if (ss.toLowerCase().contains(s.toLowerCase()))
            {
                drpdwnSuggestions.add(ss);
            }
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("drpdwnSuggestions", drpdwnSuggestions);

        return drpdwnSuggestions;
    }


    //////////////////////////// get listbox values ///////////////////////////////
    //////////////////////////// get listbox values ///////////////////////////////
    //////////////////////////// get listbox values ///////////////////////////////
    public static List getListOfStrings() //(String sql)
    {
        List list = new ArrayList();

        int ii=0;
        String key=null;
        String val=null;
        for (int i=0;i< 3500; i++)
        {

            if (ii > 25)
            {
                ii=0;
            }

            key = (i + "").trim();
            val = (i + prfx[ii]).trim();

            list.add(key + ":" + val);


            ii++;
        }

        return list;

    }    

}

<Код> testcal2.js

$(document).ready(function()
{
    applyDatePicker();
});


function applyDatePicker(){

    $('.datePicker').datepicker(
    {
        showOn: 'button', 
        buttonText: "Choose",
        showButtonPanel: true,
        showOptions: {direction: 'up'},
        changeYear: true,
        changeMonth: true,
        yearRange: "c-120:c+0"
    });
}
1
nl ja de
Привет, Даниэль. Когда страница сначала отображается, рядом с полем ввода находится кнопка datapicker. Когда страница отправляется - на «postback» - селектор, по-видимому, больше не активен, и кнопка исчезла. Мне нужно «сохранить» кнопку, чтобы пользователь не видел ее исчезнуть после отправки (особенно если есть ошибка проверки). Имеет ли это смысл? Дайте мне знать, если мне нужно еще больше объяснить. Спасибо! s
добавлено автор sairn, источник
Привет, Дэниел, я использую функцию $ (document) .ready, и я использую «p: commandButton» для моей кнопки «Отправить» ... Я добавил код, который я тестирую выше ... Можете ли вы более легко увидеть, где я могу заставить кнопку «datapicker» исчезнуть? (Я не уверен, как реализовать предложение, найденное в указанной вами ссылке). Спасибо!
добавлено автор sairn, источник
обновленные примеры исходного кода, в которых я включил исправление, рекомендованное Даниэлем (ниже)
добавлено автор sairn, источник
Отбросьте этот код datepicker в функции и вызовите эту функцию в готовом jQuery + в onsuccess вашего p: commandButton
добавлено автор Daniel, источник
Вы используете f: ajax для отправки? В противном случае вы можете вызвать JS cofe в функции jQuery ready, если вы используете f: ajax, чем посмотрите на stackoverflow.com/a/10270872/617373
добавлено автор Daniel, источник
вы хотите вызвать $ ('# form1 \\: dp'). datepicker ({showOn: 'button', buttonText: "Choose"}); фрагмент кода после f: ajax render ? Вы имеете в виду, что датапикер теряет стиль? или что ? как вы представляете форму?
добавлено автор Daniel, источник

2 ответы

Если бы я понял тебя правильно

поместите js-код в функцию

function applyDatePicker(){
 $('#queryForm\\:dp2').datepicker(
    {
        showOn: 'button',
        buttonText: "Choose"
    });
}

Call it in $(document).ready

$(document).ready(function()
{
   applyDatePicker();
});

And also call it in

2
добавлено
Спасибо, Дэниел. Я скоро попробую ваши предложения и сообщит, что произойдет
добавлено автор sairn, источник
Привет, Даниэль. Ваш яркий пример и объяснение BalusC помогли мне решить эту проблему. Я установил ваше решение - с той лишь разницей, что я использовал «неполный», а не «onsuccess», чтобы сохранить «кнопку» на частичной обратной передаче и т. Д. (Я надеюсь, что правильно использую терминологию - если нет, пожалуйста простите меня) Еще раз спасибо!
добавлено автор sairn, источник
HI Daniel - я использовал «oncomplete» в «submit» «p: commandButton», потому что я выполняю «validate (ComponentSystemEvent e)» в моем контроллере, который может выдавать «facesContext.renderResponse», когда он обнаруживает проверку ошибка. Я не думаю, что это интерпретируется как «успех». Разве это не имеет смысла? (Еще раз спасибо!)
добавлено автор sairn, источник
успех ajax submit не связан с успешностью проверки логики ... поэтому отказ проверки не должен влиять на состояние успеха ajax submit вообще ...
добавлено автор Daniel, источник
Добро пожаловать. Если onsuccess не достигнуто, это означает, что что-то пошло не так ... и вам лучше проверить его ...
добавлено автор Daniel, источник

Конкретная проблема возникает из-за того, что вы обновляете всю форму с помощью update = "@ form" , заставляя также повторно обрабатывать элемент ввода, обработанный jQuery UI, в результате чего пользовательский интерфейс jQuery выглядит так: n'feel быть потерянным. $ (document) .ready() не выполняется повторно в запросах ajax, и, следовательно, элемент ввода остается «простым».

В этой области есть 2 решения:

  1. Do not update the input element itself on ajax response. Update only the parts which really need to be updated. Perhaps it's just only the message?

    update="msgs"
    

    (by the way, those rendered="true" and style="display:none" are very strange)

    You can if necessary specify multiple components spaceseparated.

    update="msgs1 msgs2 msgs3"
    

    You can also just use autoUpdate="true" on message components which you'd like to automatically update on ajax responses. Or if the component in question doesn't support it, wrap it in . See also Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes.


  2. Re-execute the jQuery UI script on complete of ajax request. This part is already answered by Daniel. An alternative to onsuccess is to use OmniFaces' . See also JSF/PrimeFaces ajax updates breaks jQuery event listener function bindings.

1
добавлено
Еще раз спасибо, BalusC. (BTW - я выбрал вариант «2.»). К сожалению, мне не разрешена гибкость использования «Omnifaces». Еще раз спасибо! s
добавлено автор sairn, источник
Привет BalusC - на самом деле будет отображаться любой полевой уровень «», который соответствует ошибке проверки/etc (теги полевых сообщений будут храниться в этом «div»). На данный момент мне нужны только сообщения на уровне поля, соответствующие отображаемому полю. Я должен был объяснить, что «rendered = 'true» является просто заполнителем. В конце концов я хочу дать пользователю возможность выбрать либо (A) поле (в фокусе) , либо (B) «global» «» (в этом случае я бы установил что «placeholder» присвоил атрибуту «false» ............. предполагая, что это имеет смысл вообще. Спасибо, снова!
добавлено автор sairn, источник
Благодарим вас за помощь, BalusC! Я понял, что «document.ready» выполнялся только один раз, но он не знал, как продолжить сохранение кнопки datepicker /. Я попытаюсь включить ваши предложения и предложения Даниэля и сообщить вам об итогах. (FYI - пример, который я предоставил, был «вырублен» из большего приложения. Я использовал группу «msgs» для отображения сообщений, которые соответствуют фокусу поля. -Я не хотел показывать подробные сообщения рядом с полем (который это типичная реализация), и мне не нужен большой список всех сообщений в верхней части страницы.
добавлено автор sairn, источник
Пожалуйста. Я расширил опцию 1, чтобы рассказать о autoUpdate , возможно, вы не знали об этом. Я до сих пор не вижу причин обновлять всю форму, включая поле ввода в этом конкретном случае использования.
добавлено автор BalusC, источник
Хорошо. Пожалуйста.
добавлено автор BalusC, источник
rendered = "true" уже по умолчанию, но display: none скрывает его на клиентской стороне, в результате чего сообщение никогда не появляется, так что это просто странно. JSF выдаст сообщение, если на самом деле есть сообщение, поэтому отображение : none не имеет смысла.
добавлено автор BalusC, источник
Верстка сайтов HTML/CSS/JS/PHP
Верстка сайтов HTML/CSS/JS/PHP
3 439 участник(ов)

Правила группы: напишите !rules в чате. Группа Вк: vk.com/web_structure Freelancer: @web_fl Веб Дизайн: @dev_design Маркетолог: @topmarkening Автор: @M_Boroda