0

So I already have these elements in my page:

<button id="addMore" class="button" style="background-color: green;">+</button>
<button id="removeMore" class="button" style="background-color: red;">-</button>
<div id="fieldList">
       
       <select style="width:100%" id="prisplan" name="prisplan[]" required>
           <option selected value="">Velg prisplan</option>
           <?php foreach($eachlines as $lines){ //add php code here
           echo "<option value='".$lines."'>$lines</option>";
           }?>
        </select>
        
        <input type="text" name="gsm[]" placeholder="GSM" required onkeypress='return event.charCode >= 48 && event.charCode <= 57'/>
      
    </div>

When pressing the + button, it adds new elements. This works perfectly:

$(function() {
  $("#addMore").click(function(e) {
    e.preventDefault();
    
    // Get the element of prisplan
    var itm = document.getElementById("prisplan");
    // Copy the element and its child nodes
    var cln = itm.cloneNode(true);
    // Append the cloned element to list
    document.getElementById("fieldList").appendChild(cln);
    
    $("#fieldList").append("<input type='text' placeholder='GSM' name='gsm[]' required onkeypress='return event.charCode >= 48 && event.charCode <= 57'>");
    
    });
});

Now I also want a remove button. That button should remove the last added elements from "addMore" button, but never remove the original elements. How can I do this? The code below is what I've got so far, but that removes everything.

$(function() {
  $("#removeMore").click(function(e) {
    e.preventDefault();
    
    $('#fieldList').remove();

    });
});

How can I accomplish this?

4 Answers4

0

To remove all items except the first ones change:

$('#fieldList').remove();

to

$('#fieldList > select:not(:first),input:not(:first)').remove();

To remove one item each time from the end

 $("#removeMore").click(function(e) {
          //get select/input elements
          const elLen = $('#fieldList > select,input');

          //each time you remove a select/input element,
          //array length decreases and with an if statement you can handle 
          //which elements to delete 
          if(elLen.length > 2){
           $('#fieldList > select:last-child,input:last-child').remove();
          }
 });
Marios Nikolaou
  • 1,326
  • 1
  • 13
  • 24
0

Just add a container for the select tag and input tag. So you'll have more control when deleting a group of elements

$(function () {
  $('#addMore').click(function (e) {
    e.preventDefault();
    // Get the element of prisplan
    var itm = document.getElementsByClassName('my-container')[0];

    // Copy the element and its child nodes
    var cln = itm.cloneNode(true);

    // Remove input of cloned element
    cln.removeChild(cln.lastElementChild);

    // Append the cloned element to list
    document.getElementById('fieldList').appendChild(cln);

    $('.my-container:last-child').append(
      `<input type='text' placeholder='GSM' name='gsm[]' required onkeypress='return event.charCode >= 48 && event.charCode <= 57'>`
    );
  });

  $('#removeMore').click(function (e) {
    e.preventDefault();

    const containers = $('.my-container');

    // Remove last added containers, leave only 1 original container
    if (containers.length > 1) $('.my-container:last-child').remove();
  });
});
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<button id="addMore" class="button" style="background-color: green">+</button>
<button id="removeMore" class="button" style="background-color: red">-</button>
<div id="fieldList">
  <div class="my-container">
    <select style="width: 100%" id="prisplan" name="prisplan[]" required>
      <option selected value="">Velg prisplan</option>
      <option value='".$lines."'>$lines</option>
    </select>

    <input
      type="text"
      name="gsm[]"
      placeholder="GSM"
      required
      onkeypress="return event.charCode >= 48 && event.charCode <= 57"
    />
  </div>
</div>

Happy Coding!

Techuila
  • 1,237
  • 8
  • 12
0

You could add a frequency map to the select drop-down to indicate the occurance of each type. You could dynamically add fields with a remove button.

const
  typeSel = document.querySelector('.type-sel'),
  fieldsEl = document.querySelector('.fields');

const main = () => {
  initCounts(typeSel);

  document.querySelector('.add-btn').addEventListener('click', handleAdd);
  fieldsEl.addEventListener('click', handleRemove);
};

const
  setData = (el, key, value) => el.dataset[key] = JSON.stringify(value),
  getData = (el, key) => JSON.parse(el.dataset[key]);

const applyCount = (freq, key, amount = 1) =>
  ({ ...freq, [key]: (freq[key] || 0) + amount });

const frequencyThunk = prop => ({
  init: sel => setData(sel, prop, [...sel.options].reduce((acc, opt) =>  
    ({ ...acc, [opt.value]: 0 }), {})),
  update: (sel, key) => setData(sel, prop, applyCount(getData(sel, prop), key)),
  retrieve: (sel, key) => getData(sel, prop)[key]
});

const
  selCountFreq = frequencyThunk('counts'),
  initCounts = selCountFreq.init,
  updateCount = selCountFreq.update,
  retrieveCount = selCountFreq.retrieve;

const handleAdd = e => {
  const
    value = typeSel.value,
    index = retrieveCount(typeSel, value),
    fieldEl = document.createElement('div'),
    labelEl = document.createElement('label'),
    inputEl = document.createElement('input'),
    buttonEl = document.createElement('button');
  
  labelEl.textContent = `${value.toUpperCase()}_${index}`;
  fieldEl.classList.add('field');
  Object.assign(fieldEl.dataset, { type: value, index: index });
  buttonEl.textContent = 'Remove';
  buttonEl.dataset.action = 'remove';
  
  fieldEl.append(labelEl);
  fieldEl.append(inputEl);
  fieldEl.append(buttonEl);
  fieldsEl.append(fieldEl);
  
  updateCount(typeSel, value);
};

const handleRemove = e => {
  if (e.target.dataset.action === 'remove') {
    e.target.closest('.field').remove();
  }
};

main();
.controls {
  margin-bottom: 1em;
}

.fields {
  display: grid;
  grid-auto-flow: row;
  grid-row-gap: 0.5em;
}

.field {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: 0.25fr 1fr 0.25fr;
  grid-column-gap: 0.25em;
}

button[data-action="remove"] {
  cursor: pointer;
}
<form onsubmit="return false;">
  <div class="controls">
    <select class="type-sel">
      <option value="a">Input A</option>
      <option value="b">Input B</option>
      <option value="c">Input C</option>
    </select>
    <button class="add-btn">Add</button>
  </div>
  <div class="fields">
    <div class="field">
      <label>Sticky A</label>
      <input value="" />
    </div>
    <div class="field">
      <label>Sticky B</label>
      <input value="" />
    </div>
  </div>
</form>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

Here is a working sample, but you have some very bad practices in your code, for instance you must NEVER have a duplicate of an ID in your document, try using a class instead. That is why I edited the id='prisplan' to class='prisplan' but the work is not done you could see that after removing the select the imput is still there. To fix this easiest way would be to wrap the select and input in a div with a class and remove it with it's contents when the button is pressed

$(function() {
  $("#addMore").click(function(e) {
    e.preventDefault();
    
    // Get the element of prisplan
    var itm = document.getElementsByClassName("prisplan")[0];
    // Copy the element and its child nodes
    var cln = itm.cloneNode(true);
    // Append the cloned element to list
    document.getElementById("fieldList").appendChild(cln);
    
    $("#fieldList").append("<input type='text' placeholder='GSM' name='gsm[]' required onkeypress='return event.charCode >= 48 && event.charCode <= 57'>");
    
    });
    $("#removeMore").click(function(e) {
    e.preventDefault();
    let allSelects = document.getElementsByClassName("prisplan")
    document.getElementsByClassName("prisplan")[allSelects.length -1].remove();

    })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addMore" class="button" style="background-color: green;">+</button>
<button id="removeMore" class="button" style="background-color: red;">-</button>
<div id="fieldList">
       
       <select style="width:100%" class="prisplan" name="prisplan[]" required>
           <option selected value="">Velg prisplan</option>
           <?php foreach($eachlines as $lines){ //add php code here
           echo "<option value='".$lines."'>$lines</option>";
           }?>
        </select>
        
        <input type="text" name="gsm[]" placeholder="GSM" required onkeypress='return event.charCode >= 48 && event.charCode <= 57'/>
      
    </div>
Kolyo Peev
  • 145
  • 2
  • 11