Home > Software engineering >  'This' in a dynamic list using Jquery
'This' in a dynamic list using Jquery

Time:04-13

I have a script that works for updating plus or minus in a quantity selector in a dynamic list. But I need to convert the code so that it only updates the 'current' list item quantity not all of them in the list.

enter image description here

How can I change the syntax so the following code will only update the one list item quantity, not all of them:

jQuery(document).ready(function(){
    // This button will increment the value
    $('.qtyplus').click(function(e){
        // Stop acting like a button
        e.preventDefault();
        // Get the field name
        var fieldName = $(this).attr('data-plus-number');
        // Get its current value
        var currentVal = parseInt($('input[id=' fieldName ']').val());
        // If is not undefined
        if (!isNaN(currentVal)) {
            // Increment
            $('input[id=' fieldName ']').val(currentVal   1);
        } else {
            // Otherwise put a 0 there
            $('input[id=' fieldName ']').val(1);
        }
    });
    // This button will decrement the value till 0
    $(".qtyminus").click(function(e) {
        // Stop acting like a button
        e.preventDefault();
        // Get the field name
        var fieldName = $(this).attr('data-minus-number');
        // Get its current value
        var currentVal = parseInt($('input[id=' fieldName ']').val());
        // If it isn't undefined or its greater than 0
        if (!isNaN(currentVal) && currentVal > 1) {
            // Decrement one
            $('input[id=' fieldName ']').val(currentVal - 1);
        } else {
            // Otherwise put a 0 there
            $('input[id=' fieldName ']').val(1);
        }
    });
});

HTML:

<div >
  <input type='button' value='-' class='qtyminus' field='quantity' data-minus-number="updates_large_{{ item.id }}" />
  <input type='number' id="updates_large_{{ item.id }}" name="updates[]" data-name='quantity' value="{{ item.quantity }}" min="1" class='qty quantity-selector' />
  <input type='button' value=' ' class='qtyplus' field='quantity' data-plus-number="updates_large_{{ item.id }}" />
</div>

CodePudding user response:

I'm not sure I understand what you need.

But you want to click the and - icon and want the closest input field to increase or decrease the current value correctly?

If this is the case, you can go about it this way:

jQuery(document).ready(function() {
  $(document).on('click', '.qtyplus, .qtyminus', function(e) {
    // Detect which class has been clicked.
    let clicked_class = $(this).attr("class");
    // Find the closest element with the class 'quantity-selector'
    let qty_element = $(this).parent().find('.quantity-selector');
    // View the current input value and adjust the value with   or -
    let cur_val = parseInt(qty_element.val())   (clicked_class === 'qtyminus' ? -1 :  1);
    // update the input value, if the cur_val is 0 or less, add 1 by default (don't allow minus values)
    qty_element.val(!isNaN(cur_val) && cur_val > 0 ? cur_val : 1);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div >
  <input type="button" value="-"  field="quantity" data-minus-number="updates_large_10" />
  <input type="number" id="updates_large_10" name="updates[]" data-name="quantity" value="10" min="1"  />
  <input type="button" value=" "  field="quantity" data-plus-number="updates_large_10" />
</div>

<div >
  <input type="button" value="-"  field="quantity" data-minus-number="updates_large_11" />
  <input type="number" id="updates_large_11" name="updates[]" data-name="quantity" value="10" min="1"  />
  <input type="button" value=" "  field="quantity" data-plus-number="updates_large_11" />
</div>

CodePudding user response:

It might be a good idea to keep track of the count of items in a "state" and just render your view based on that state.

In my snippet, I added the increment/decrement directly to the items in the state (this might not be best practice, but hey! :) ), but you can create actions/mutations that make it cleaner (look for the Flux/Redux pattern).

I would suggest: do NOT keep data in the UI - the UI is (mostly) for presentational purposes, try not relying on data read from it (if possible).

const getItem = () => {
  let _count = 0
  const _id = Date.now()
  return {
    get id() {
      return _id
    },
    get count() {
      return _count
    },
    increment() {
      _count = _count   1
    },
    decrement() {
      _count = _count - 1
    },
  }
}

const state = {
  items: []
}

const getItemTemplate = (item) => `
  <div data-id="${item.id}">
    ${item.id}:
    <button >-</button>
    ${item.count}
    <button > </button>
  </div>
`

const getItemsHtml = ({ items }) => items.map(getItemTemplate).join('')

const updateItemsList = (selector) => (html) => jQuery(selector).html(html)

const updateItemsContainer = updateItemsList(".container")

const updateView = (state) => {
  const itemList = getItemsHtml(state)
  updateItemsContainer(itemList)
}

const getItemFromList = (thisItem) => {
  const thisId = jQuery(thisItem).parent().attr("data-id")
  return state.items.find(({ id }) => id == thisId)
}

jQuery(document).ready(function($) {
  $("#btn-add-item").on("click", function() {
    state.items = [...state.items, getItem()]
    updateView(state)
  })

  $(".container").on("click", ".increment", function() {
    const item = getItemFromList(this)
    item.increment()
    updateView(state)
  })

  $(".container").on("click", ".decrement", function() {
    const item = getItemFromList(this)
    item.decrement()
    updateView(state)
  })

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn-add-item">ADD ITEM  </button>
<div ></div>

  • Related