Search code examples
javascriptecmascript-6ecmascript-2016

How do I use one function for 2 variation of components?


Javascript newbie here. I have to write this using plain old Javascript. I have 2 inline edit components, only difference is that one uses icons instead of buttons. The issue I have is I wrote 2 edit functions, assigned to both components, but if I click on the second component it affect the first. Is there a way to focus on one component so it doesn't affect the other, without writing two pairs of functions?

Here's a link to a Codepen I made: https://codepen.io/sfilippone/pen/rNmEKXd

The top example works fine, but the second one (w/buttons) affects the top one. :/

Any help is appreciated. Thanks.

Here's the code:

 <h3>with icons</h3>
<div class="c-inline-edit--icons">
        <div id="c-inline-edit-wrapper" class="border-yes">
            <input id="c-inline-edit-input" class="c-readonly-input" type="text" value="Lorem ipsum" onclick="yesEdit()" readonly/>
            <a id="btn-edit" onclick="yesEdit()"><span class="icon icon-16-edit-default-mono"></span></a>
        </div>

        <div class="c-btn-set-icon">
            <a id="btn-cancel" class="c-btn c-btn-secondary" onclick="noEdit()"><span class="icon-16-close-mono"></span></a>
            <a id="btn-save" class="c-btn c-btn-primary" onclick="noEdit()"><span class="icon-checkmark-mono"></a>
        </div>
    </div>

    <h3>with buttons</h3>
    <div class="c-inline-edit--buttons">
        <div id="c-inline-edit-wrapper" class="border-yes">
            <input id="c-inline-edit-input" class="c-readonly-input" type="text" value="Lorem ipsum" onclick="yesEdit()" readonly/>
            <a id="btn-edit" onclick="yesEdit()"><span class="icon icon-16-edit-default-mono"></span></a>
        </div>

                <div class="c-btn-set">
                    <a id="btn-cancel" class="c-btn c-btn--mini c-btn--info" onclick="noEdit()">Cancel</a>
                    <a id="btn-save" class="c-btn c-btn--mini c-btn--outline" onclick="noEdit()">Save</a>
                </div>

    </div>

The script:

    <script>

        document.addEventListener('keydown', function(event){
            if(event.key === "Escape") {
                noEdit();
            } else if(event.key === "Enter") {
                noEdit();
            }
        });



        function yesEdit() {
            document.getElementById("btn-edit").style.display = "none";
            document.getElementById("btn-save").style.display = "inline-block";
            document.getElementById("btn-cancel").style.display = "inline-block";

            var editWrapper = document.getElementById("c-inline-edit-wrapper");
            editWrapper.classList.replace("border-yes", "border-no");

            var element = document.getElementById("c-inline-edit-input");
            element.removeAttribute("readonly");
            element.classList.replace("c-readonly-input", "c-input");

        }

        function noEdit() {
            document.getElementById("btn-edit").style.display = "inline-block";
            document.getElementById("btn-save").style.display = "none";
            document.getElementById("btn-cancel").style.display = "none";

            var editWrapper = document.getElementById("c-inline-edit-wrapper");
            editWrapper.classList.replace("border-no", "border-yes");

            var element = document.getElementById("c-inline-edit-input");
            element.setAttribute("readonly", "");
            element.classList.replace("c-input", "c-readonly-input");
        }
    </script>

Solution

  • Html id attribute must be unique in the document.

    When button is pressed upper id is triggered first and upper component toggles.

    The shortest way to solve this is to give different ids to your elements and pass id to your "yesEdit" and "noEdit" functions.

    Here is an example: https://codepen.io/emreavcilar/pen/xxdoJVm?editors=1010

    <h1>Inline Edit</h1>
    <br /><br />
    
    <h3>with icons</h3>
    <div class="c-inline-edit--icons">
      <div id="c-inline-edit-wrapper-1" class="border-yes">
        <input id="c-inline-edit-input-1" class="c-readonly-input" type="text" value="Lorem ipsum" onclick="yesEdit(1)" readonly />
        <a id="btn-edit-1" onclick="yesEdit(1)"><span class="icon icon-16-edit-default-mono"></span></a>
      </div>
    
      <div class="c-btn-set-icon">
        <a id="btn-cancel-1" class="c-btn c-btn-secondary" onclick="noEdit(1)"><span class="icon-16-close-mono"></span></a>
        <a id="btn-save-1" class="c-btn c-btn-primary" onclick="noEdit(1)"><span class="icon-checkmark-mono"></a>
      </div>
    </div>
    
    <h3>with buttons</h3>
    <div class="c-inline-edit--buttons">
      <div id="c-inline-edit-wrapper-2" class="border-yes">
        <input id="c-inline-edit-input-2" class="c-readonly-input" type="text" value="Lorem ipsum" onclick="yesEdit(2)" readonly />
        <a id="btn-edit-2" onclick="yesEdit(2)"><span class="icon icon-16-edit-default-mono"></span></a>
      </div>
    
      <div class="c-btn-set">
        <a id="btn-cancel-2" class="c-btn c-btn--mini c-btn--info" onclick="noEdit(2)">Cancel</a>
        <a id="btn-save-2" class="c-btn c-btn--mini c-btn--outline" onclick="noEdit(2)">Save</a>
      </div>
    
    </div>