Jump to content

Change button text and function name


richarddunnebsc

Recommended Posts

I have a table, 1 row with 4 cells.  Cell 0 input type button, value "+", class="buttons", with onclick="AddRow()", Cell 1 input type text, Cells 2 & 3 inputs type number

On click I want to add a new row, then change the button function on the preceding row from AddRow to DeleteRow, and change the value of that button from + to -

I have added a new row, its the other parts I'm struggling to figure out.  Any guidance appreciated.  This is what I have at the moment

var rowsCount = $('.buttons').length-2;
document.getElementsByClassName('buttons')[rowsCount].prop("value", "-");

 

Link to comment
Share on other sites

Rather than try and change the button, just add a second button for delete row and control which one is for the row visible with CSS.  That can possible be done easily by taking advantage of the :last-child pseudo selector.  For example:

<div id="input-grid">
  <div class="row">
    <div>
      <button type="button" name="add-row">
         +
      </button>
      <button type="button" name="delete-row">
         -
      </button>
    </div>
    ...
  </div>
</div>

With CSS:

.row button[name=add-row], .row:last-child button[name=delete-row] {
  display: none;
}

.row:last-child button[name=add-row]{
  display: inline;
}

The CSS sets the first sets add-row button to not be displayed for all rows, and the delete-row button to not be displayed in the last row.  The next rule overrides the first to make the add-row button visible in the last row.

With that, you don't need to futz around with maintaining your buttons in your JS code, just add or remove rows as needed and the correct button will show automatically.

Link to comment
Share on other sites

I have decided to try cloning.

var table = $("#tableName");
var second = $('#tableName tr').eq(2);
var clone = second.cloneNode(true);
alert();

JavaScript doesn't seems to like cloneNode(), the alert is not executing.  Basically I need to copy the second row of the table and append it to the end.  I can then replace the input function and value of the button.  Any ideas/suggestions?

Link to comment
Share on other sites

I got the clone working

var x=document.getElementById("tableName");
var node=x.rows[1].cloneNode(true); 
x.appendChild(node);

What I want to do next is replace an input event listener using removeEventListener then addEventListener.  This is what I have

var row = document.getElementById('tableName').length-1;
document.getElementById('tablename')[row].removeEventListener("click",AddRow);

Its not working needless to say

Link to comment
Share on other sites

Here's my take on your problem

<!DOCTYPE=html>
<html lang="en">
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> 
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type='text/javascript'>
    function btnclick(thebtn)
    {
        if ($(thebtn).html() == "+")  {
            $(thebtn).html("-")
            addrow()
        }
        else {
            delrow(thebtn)
        }
    }
    
    function delrow(thebtn)
    {
        $(thebtn).parent().parent().remove()
    }
    
    function addrow()
    {
        let r = $("<tr>")
        let b = $("<span>", {"html":"+", "onclick":"btnclick(this)", "class":"bttn w3-button w3-light-gray"});
        let td1 = $("<td>", {"class":"ca"})
        let td2 = $("<td>")
        let td3 = $("<td>")
        let td4 = $("<td>")
        let i1 = $("<input>", {"name":"name[]", "type":"text"})
        let i2 = $("<input>", {"name":"val1[]", "type":"number"})
        let i3 = $("<input>", {"name":"val2[]", "type":"number"})
        $(td1).html(b)
        $(td2).html(i1)
        $(td3).html(i2)
        $(td4).html(i3)
        $(r).append(td1).append(td2).append(td3).append(td4)
        $("#rows").append(r)
    }
</script>
<style type='text/css'>
    table {
        border-collapse: collapse;
        width: 600px;
    }
    td, th {
        padding: 4px;
    }
    .ca {
        text-align: center;
    }
</style>
</head>
<body>
<header class='w3-container w3-padding'>
    <h1>Example</h1>
</header>

<form>
<table border='1'>
    <tr>
        <th>Action</th>
        <th>Name</th>
        <th>Val 1</th>
        <th>Val 2</th>
    </tr>
    <tbody id='rows'>
    <tr>
        <td class='ca'><span class='bttn w3-button w3-light-gray' onclick='btnclick(this)'>+</span></td>
        <td><input type='text' name='name[]' ></td>
        <td><input type='number' name='val1[]' ></td>
        <td><input type='number' name='val2[]' ></td>
    </tr>
    </tbody>
</table>
<input type="submit">
</form>
</body>
</html>

 

Link to comment
Share on other sites

After some reflection I have changed the design to hopefully simplify. The table must have at least one input row .   Instead of using one table I am using 3.  Table 1 contains a header row and row 1 which is required.  If the user needs/wants to add one or more additional rows, those rows are in a separate table.  The third table contains the addRow button.  To add a row, if the 2nd table is empty, add a row dynamically.  If not empty, clone the last row and append at the end.

In adding a row dynamically, when adding an event listener to an input button, does a parameter have/need to be added separately?  If so, how do I do that?

Link to comment
Share on other sites

3 hours ago, richarddunnebsc said:

In adding a row dynamically, when adding an event listener to an input button, does a parameter have/need to be added separately?  If so, how do I do that?

Not entirely sure what you mean.  If you're using addEventListener then whatever function you give it will be given a single event parameter.  If you need others, then you use an intermediate function (usually a closure/inline function).

node.addEventListener('click', function(){
  yourOtherFunction(andParameter);
});

 

Out of curiosity, did you look at the example I linked in my first post?  Is there any particular reason you seem to be avoiding that method?  Splitting your single table up in to three separate tables isn't really a great solution.  If it's because I used divs rather than tables, then here is a table version of it.

Link to comment
Share on other sites

I did look at the example, I just decided to go with a different design.   My problem at the moment is the event listener is not being added to the delete row button

var cell3 = document.createElement("td");
cell3.style.width = "5%";
var ele3 = document.createElement("input");
ele3.type = "button";
ele3.value = "-";
ele3.style.width = "100%";
ele3.addEventListener('click', function() {DeleteRow});
cell3.appendChild(ele3);
row.appendChild(cell3);
table.appendChild(row);

 

Link to comment
Share on other sites

2 hours ago, richarddunnebsc said:

My problem at the moment is the event listener is not being added to the delete row button

That is why I was asking about if you looked at the example.  Doing it the way I showed does not require adding new event handlers to each row.  You add your event handlers to the parent element which doesn't change and then used the passed in event details manipulate the row.

2 hours ago, richarddunnebsc said:
ele3.addEventListener('click', function() {DeleteRow})

The function name alone does not call the function, you need to follow it with ().

ele3.addEventListener('click', function() { DeleteRow(); })

If you're not going to pass parameters, then you can skip the intermediate function and pass in a reference to your DeleteRow function directly, which you do by using just the name and no ().

ele3.addEventListener('click', DeleteRow)

 

Link to comment
Share on other sites

Each new row has a delete button, so each delete button needs an event listener.  The way I'm doing it, I only need to add an event listener once, to the second row, because I with each subsequent row added, its just a copy and paste of that row second row.  At the moment, the event listener is not being added to the delete button.  

var ele3 = document.createElement("input");
ele3.type = "button";
ele3.value = "-";
ele3.style.width = "100%";
ele3.addEventListener('click', function(e){DeleteRow();});

Can event listeners be added to elements this way?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.