Domanda

As a Dojo newbie, I am trying to create a simple wizard of pages using a plain JS array as a stack that I push and pop the cloned main content DOM node onto and off (without using the StackContainer)

The problem is that when I go back to a previous page and 'repopulate' the page with the cloned main content node popped off the stack, the controls (in this example code, the radio buttons, but I have similar problem with selecting rows in a DataGrid dijit that I'm not showing but is more of importance for my app) appears to be the same as I previously saw (e.g. the radio button is the same one as I previously selected). But

  • I can't seem to interact with them, e.g. couldn't select the other radio button at all
  • Neither control is, in fact, selected, despite of the page appearance.
  • If I change these radio buttons from dijits to plain html input controls, there is no such problem.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<link rel="stylesheet" type="text/css"
    href="../dojo/dijit/themes/dijit.css">
<link rel="stylesheet" type="text/css"
    href="../dojo/dijit/themes/soria/soria.css">    

<title>TestSimplerStillS1</title>
<script>dojoConfig = {parseOnLoad: true}</script>
<script src='../dojo/dojo/dojo.js'></script>
<script>
    // The stack used for the wizard
    var mainContentStack=[] 

    dojo.ready(function(){
        // Reset the stack
        mainContentStack=[];

        // Add the radio btns 
        var radioData11 = {value: "Radio1.1", label: "Radio1.1_lbl"};
        var radioData12 = {value: "Radio1.2", label: "Radio1.2_lbl"};
        populateNextPageRadioBtns("radios1", [radioData11, radioData12]);

        // disable the back btn for the first page
        dojo.byId("backBtn").disabled=true;
    });

    function onNextClicked() {

        // Push the main content onto a stack to store
        pushCloneOnStack();

        // Find the selected radio btn and display it
        displaySelectedRadio();

        // Clear the existing radio btns  
        destroyAll("rdbtns_div_id");

        // disable the next btn for the last page
        dojo.byId("nextBtn").disabled=true;
    }

    function displaySelectedRadio() {
        var rdDivs = dojo.byId("rdbtns_div_id").children;
        for (var i = 0; i < rdDivs.length; i++) {
            rdDiv = rdDivs[i];
            if (rdDiv !== null) {
                var rd = rdDiv.children[0].children[0];
                if (rd.checked) {
                    dojo.byId("rdbtns_sel_div_id").innerHTML=rd.value;
                }
            }
        }
    }

    function onBackClicked() {
        popAndAssignFromStack();
    }

    function destroyAll(nodeId){
        var wContainers = dojo.byId(nodeId);
        dojo.forEach(dijit.findWidgets(wContainers), function(w) {
                w.destroyRecursive(false);
        });
        dojo.byId(nodeId).innerHTML = "";
    }

    function populateNextPageRadioBtns(grpIdentifier, radioBtnDataArray){
        // Create new radio btns
        require(['dojo/_base/array'], function(array){
            var i = 0;
            array.forEach(radioBtnDataArray, function(radioBtnData){
                // Create the radio btns and default the 1st radio btn to be checked
                createRadioBtn(grpIdentifier, radioBtnData, (i==0));
                i++; 
            });
        });
    }

    function createRadioBtn(nextPageSqlStr, radBtnData, isChecked){
        var radGrpName = "rd_" + nextPageSqlStr + "_grp_name";
        var radVal = radBtnData.value;
        var radLbl = radBtnData.label;

        // Only create radio btn contrl set if there is a 'val' prop for the radio button 
        if(radVal){
            var radId = "rd_" + radVal + "_id"; 

            // Create new container DIV
            var rdDiv = dojo.create("div", {
                id : "rd_" + radVal + "_div_id"
            });

            // Create the radio btn and put it into the new DIV
            dojo.require("dijit.form.RadioButton");
            var radioB = new dijit.form.RadioButton({
                id: radId,
                checked: isChecked, 
                value: radVal,
                name: radGrpName
            });
            dojo.place(radioB.domNode, rdDiv, "last");

            // Create the label and put it into the new DIV 
            if(radLbl){
                var radioBlbl = dojo.create("label", {
                    "for": radId,
                    innerHTML: radLbl 
                });
                dojo.place(radioBlbl, rdDiv, "last");
            }

            // Put the new DIV into the static radio btns containing DIV
            dojo.place(rdDiv, dojo.byId("rdbtns_div_id"), "last");
        }
    }

    function pushCloneOnStack() {

        /// Push cloned node onto the stack
        var contentDomPush = dojo.byId("mycontentdiv");
        var cloned = dojo.clone(contentDomPush);
        dojo.attr(cloned, "id", "mycontentdivCloned");
        mainContentStack.push(cloned);

        // Every push means there is a page to go back to, so enable back btn
        dojo.byId("backBtn").disabled = false;
    }

    function popAndAssignFromStack() {
        if (mainContentStack && mainContentStack.length > 0) {

            // Overwrite the main content with the version popped from the stack
            var contentDomPop = mainContentStack.pop();
            // Clear the div 
            destroyAll("mycontentdiv");
            dojo.attr(contentDomPop, "id", "mycontentdiv");         
            dojo.place(contentDomPop, dojo.byId("mycontentcontainerdiv"), "only");

            // Every pop means there is a page to go forward to, so enable next btn
            dojo.byId("nextBtn").disabled = false;
        }

        if (mainContentStack.length == 0) {
            // Nothing more to pop means there is no page to go back to, so disable the back btn
            dojo.byId("backBtn").disabled = true;
        }
    }

</script>
</head>

<body class="soria">
    <div id="mycontentcontainerdiv">
        <div id="mycontentdiv">
            Radios Btns:
            <div id="rdbtns_div_id"></div>
            <br>
            Radio Selected:
            <div id="rdbtns_sel_div_id"></div>
        </div>
    </div>
    <br>
    <div id="btnsDiv">
        <button data-dojo-type="dijit/form/Button" type="button" id="backBtn">
            Back
            <script type="dojo/on" data-dojo-event="click">
                onBackClicked();
            </script>
        </button>
        <button data-dojo-type="dijit/form/Button" type="button" id="nextBtn">
            Next
            <script type="dojo/on" data-dojo-event="click">
                onNextClicked();
            </script>
        </button>
    </div>

</body>
</html>
È stato utile?

Soluzione

The problem is that you are in an odd place, you cloned the widgets DOM, but the reference to the widget in the registry is removed in your destroy(if you do a dijit.registry.toArray() you will see the radio buttons are not there). So you have the DOM aspect of the widget but none of its backend support.

What you can do is keep a copy of the DOM before the parser has parsed it. You would have to create the radiobuttons as html first, clone then run the parse command. After you do the destroy you can re-add the nonparsed html back, then run the parser again.

Here is somebody that had the same problem: http://www.developer-corner.com/2011/06/cloning-dijit-widgets.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top