DEV Community

Matthew
Matthew

Posted on

how do I fix readonly <input>, please?

I'm very new to react, this is the first react code I've ever written but I've decades experience in other technologies.

I'm using the html tag to enter data and sometimes it's read/write and sometimes it readonly, that is a problem I need them to always be read/write.

I've found a post on stackover which tell me what is causing the problem but it doesn't explain how to fix the problem. This link https://stackoverflow.com/questions/28315205/why-does-react-make-inputtype-text-fields-readonly-unless-i-supply-onchange

So in my code you can see I've two 's that work, they point to the attributes theXXX and theYYY. However I have an array that is called lstXXXs in my attributes and I display this array, see the line beginning with const htmlLstXXXs = props.attributes.lstXXXs.map

Basically because I have the two variables theXXX and theYYY working I was hoping to copy the same method for updating the array, but whatever I try to do it just won't work, the are readonly.

My function to update the array works, but the 's being readonly is the problem.

Does anyone have any idea how I can fix it so that all my 's tags are read/write?

import { useState } from "react";

wp.blocks.registerBlockType("matthewbaynham/my-wordpress-plugin_stuff", {
    title: "XXX and YYY", 
    icon: "smiley", 
    category: "common",
    attributes: {
        theXXX: { type: "string" },
        theYYY: { type: "string" },
        lstXXXs: [],
    },
    edit: function (props) {
        function updateXXX(e) {
            props.setAttributes({theXXX: e.target.value});
        }

        function updateYYY(e) {
            props.setAttributes({theYYY: e.target.value});
        }

        function updateXXXID(obj, e) {
            alert(obj.id);
            alert(obj.xxx);
            alert(obj.yyy);
            alert(document.getElementById("xxx"+obj.id).value);
            alert("done");
        }

        function updateYYYID(qa) {
            props.attributes.lstXXXs.forEach(function(obj) {
                                 if (obj.id === qa.id) {
                                     const elementXXX = document.getElementById("xxx"+qa.id);

                                     if (elementXXX !== null)
                                     { obj.xxx = elementXXX.value; }

                                     const elementYYY = document.getElementById("yyy"+qa.id);

                                     if (elementYYY !== null)
                                     {obj.yyy = elementYYY.value; }
                                 }
                            });
        }

        function showArray(e) {
            var theText = '';            
            props.attributes.lstXXXs.forEach(function(obj) {
                                 theText += obj.id.toString();
                                 theText += '\n';
                                 theText += obj.xxx;
                                 theText += '\n';
                                 theText += obj.yyy;
                                 theText += '\n';
                                 theText += '\n';
                            });

            alert(theText);                
        }

        function addOneXXX(e) {
            const tmpXXXs = props.attributes.lstXXXs.concat({id:maxID()+1, xxx:"Fred", yyy:"3"});
            props.attributes.lstXXXs = tmpXXXs;

            const divMain = ReactDOM.createRoot(document.getElementById('main'));
            divMain.render(getHTML());
        }

        function maxID() {
            return Math.max(...props.attributes.lstXXXs.map(o => o.id));
        }

        function getHTML() {
            const htmlLstXXXs = props.attributes.lstXXXs.map(
                qa => {
                         return (
                            <div id={"qa"+qa.id}>
                                <p>{qa.id}</p>
                                <input id={"q"+qa.id} type="text" placeholder="Wite" value={qa.xxx} />
                                <input id={"xxx"+qa.id} type="text" placeholder="Write a xxx here." value={qa.xxx} onInput={() => updateXXXID(qa)} />
                                <div id="yyy" class="yyy">
                                    <input id={"yyy"+qa.id} type="text" placeholder="This is where the yyy goes, again change this in the attributes." value={qa.yyy} onChange={() => updateYYYID(qa)} />
                                </div>
                            </div>
                          )
                      });

            return <div id="xxx" class="xxx">
                    <div>
                    <div>{htmlLstXXXs}</div>
                    <div onClick={addOneXXX}>Add to list</div>
                    <div onClick={showArray}>Show Array</div>
                    </div>
                    <input type="text" placeholder="Write a xxx here" value={props.attributes.theXXX} onChange={updateXXX}/>
                    <div id="yyy" class="yyy">
                        <input type="text" placeholder="This is where the yyy goes." value={props.attributes.theYYY} onChange={updateYYY} />
                    </div>
               </div>
        }

        if (typeof(props.attributes.lstXXXs) === "undefined") {
            props.attributes.lstXXXs = [{id:1, xxx:"Maria", yyy:"17"}, 
                                             {id:2, xxx:"Bob", yyy:"2"}, 
                                             {id:3, xxx:"Ed", yyy:"88"}, 
                                             {id:4, xxx:"Wayne", yyy:"666"}]
        }

        return <div id='main'>{getHTML()}</div>       
    },
    save: function (props) {
       return null
    }
})

Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
jhk_info profile image
JHK infotech • Edited

You can also use JavaScript to remove the readonly attribute dynamically.
`

// Remove readonly attribute using JavaScript
document.getElementById("myInput").removeAttribute("readonly");
`

In jQuery
`

<br> // Remove readonly attribute with jQuery<br> $(&quot;#myInput&quot;).prop(&quot;readonly&quot;, false);<br> `