Search code examples
javascriptjqueryprimefacespreventdefault

clone primefaces components with jquery


I have a div component to clone that contains primefaces components and that goes like this :

<div id="languageBox1">
    <p>
        <h:form>
            <label>Language</label>
            <p:selectOneMenu value="#{candidateController.language}">
                <f:selectItem itemLabel="Select Language" itemValue="language"></f:selectItem>
                <f:selectItems value="#{candidateController.languages}"
                               var="l" itemLabel="#{l}" itemValue="#{l}"></f:selectItems>
                <p:ajax event="change"
                        update=":formShowResult:candidateList :resultNumberForm"
                        listener="#{candidateController.valueChangeListener}"></p:ajax>
            </p:selectOneMenu>
            <p:selectOneMenu value="#{candidateController.languageLevel}">
                <f:selectItem itemLabel="Select Level" itemValue=""></f:selectItem>
                <f:selectItems value="#{candidateController.level}" var="lv"
                               itemLabel="#{lv}" itemValue="#{lv}"></f:selectItems>
                <p:ajax event="change" update=":formShowResult:candidateList"
                        listener="#{candidateController.valueChangeListener}"></p:ajax>
            </p:selectOneMenu>
            <button id="addLanguage" class="active_grey full">Add</button>
        </h:form>
    </p>
</div>

And I've created a script to clone this div, that goes like this:

$("#addLanguage").on("click",function(e){
    e.preventDefault();
    $("#languageBox1").clone().appendTo("#languageBox2");
});

Now my problem is, the cloned selects won't work, I just can't select any option and it won't open any more, I thought the preventdefault instruction made frozen but I'm using it to prevent the button from submitting the form.


Solution

  • Okay, let's fix your code. I've modified it like this.

    <div class="language-container">
        <div class="language-box">
            <p>
                <h:form>
                    <label>Language</label>
                    <p:selectOneMenu value="#{candidateController.language}">
                        <f:selectItem itemLabel="Select Language" itemValue="language"></f:selectItem>
                        <f:selectItems value="#{candidateController.languages}"
                            var="l" itemLabel="#{l}" itemValue="#{l}"></f:selectItems>
                        <p:ajax event="change"
                            update=":formShowResult:candidateList :resultNumberForm"
                            listener="#{candidateController.valueChangeListener}"></p:ajax>
                    </p:selectOneMenu>
                    <p:selectOneMenu value="#{candidateController.languageLevel}">
                        <f:selectItem itemLabel="Select Level" itemValue=""></f:selectItem>
                        <f:selectItems value="#{candidateController.level}" var="lv"
                            itemLabel="#{lv}" itemValue="#{lv}"></f:selectItems>
                        <p:ajax event="change" update=":formShowResult:candidateList"
                            listener="#{candidateController.valueChangeListener}"></p:ajax>
                    </p:selectOneMenu>
                    <button class="addLanguage active_grey full">Add</button>
                </h:form>
            </p>
        </div>
    </div>
    

    What I've did is I added a language-container as a parent for your language box. Assuming-ly your language box will be your child that will repeat over and over again.

    I've removed the ids for convenience sake and I changed it to class. Since we should know the basic rules that ids SHOULD be unique. That's why we'll be using class.

    Now we're gonna call a click event handler on every .addLanguage has been clicked.

    $(document).on("click", ".addLanguage", function() {
        $(".language-box:first-child").clone().appendTo(".language-container");    
    });
    

    What this does is, everytime that .addLanguage has been clicked. The Language box class (child box) will be cloned (first child / element) and append to the parent class .language-container.

    For you to appreciate it, here's a jsfiddle.

    https://jsfiddle.net/2tuqu2oL/