Hello, there was a problem with JS, in which I am very weak, made such a code, which outputs a unique data-id for entering into the database and adds, deletes an element from the field, transferring it to another.

Actually 2 problems:

  1. With 1 transfer of elements, everything works as it should, but when you transfer an element back, something strange happens with the entry in the database of a unique data-id
  2. Is there any way to solve the problem with a crutch var data_post = , where useritems.shift is repeated 10 times and botitems.shift 10 times (it seems that a cycle is needed here).

Here is the executable code (but for some reason it does not work here, it may not be configured this way)

 var useritems = []; var botitems = []; function addtrade(inv, object) { if (inv === "user") { if (useritems.length < 10) { useritems.push($(object).attr("data-id")); $(object).attr("onClick", "removetrade('user', this);"); $(".tradehave").append($(object)); } } else { if (botitems.length < 10) { botitems.push($(object).attr("data-id")); $(object).attr("onClick", "removetrade('bot', this);"); $(".tradewant").append($(object)); } } } function removetrade(inv, object) { if (inv === "user") { useritems.pop($(object).attr("data-id")); $(object).attr("onClick", "addtrade(\'user\', this);"); $(".inventoryload").append($(object)); } else { botitems.pop($(object).attr("data-id")); $(object).attr("onClick", "addtrade(\'bot\', this);"); $(".botinventoryload").append($(object)); } } function tradesend() { if (useritems.length > 0) { var data_post = { w1: useritems.shift(), w2: useritems.shift(), w3: useritems.shift(), w4: useritems.shift(), w5: useritems.shift(), w6: useritems.shift(), w7: useritems.shift(), w8: useritems.shift(), w9: useritems.shift(), w10: useritems.shift(), h1: botitems.shift(), h2: botitems.shift(), h3: botitems.shift(), h4: botitems.shift(), h5: botitems.shift(), h6: botitems.shift(), h7: botitems.shift(), h8: botitems.shift(), h9: botitems.shift(), h10: botitems.shift() }; console.log(data_post); } } 
 .inventoryload { background: yellow; border: 1px solid; height: 100px; width: 100px; } .botinventoryload { background: yellow; border: 1px solid; height: 100px; width: 100px; } .tradewant { background: orange; border: 1px solid; height: 100px; width: 100px; } .tradehave { background: orange; border: 1px solid; height: 100px; width: 100px; } .inv { float: left; } .trade { float: left; } .item { background: white; border: 1px solid; height: 20px; width: 20px; margin: 2px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="inv"> <div class="inventoryload"> <p class="item" onClick="addtrade('user', this);" data-id="1111"></p> <p class="item" onClick="addtrade('user', this);" data-id="1251"></p> <p class="item" onClick="addtrade('user', this);" data-id="4444"></p> </div> <div class="botinventoryload"> <p class="item" onClick="addtrade('bot', this);" data-id="3251"></p> <p class="item" onClick="addtrade('bot', this);" data-id="8018"></p> <p class="item" onClick="addtrade('bot', this);" data-id="6543"></p> </div> </div> <div class="trade"> <div class="tradehave"> </div> <div class="tradewant"> </div> </div> <button onClick="tradesend();" id="button">Обменять</button> 

Here is the code itself:

addtrade(inv, object) - transfers to the required field
removetrade(inv, object) - removes from the required field, transfers to the initial
tradesend() - on the button that sends the request to the database

 var useritems = []; var botitems = []; function addtrade(inv, object) { if(inv === "user"){ if(useritems.length < 10) { useritems.push($(object).attr("data-id")); $(object).attr("onClick", "removetrade(\'user\', this);"); $(".tradehave").append($(object)); } else { alertify.error("Ошибка!"); } } else { if(botitems.length < 10) { botitems.push($(object).attr("data-id")); $(object).attr("onClick", "removetrade(\'bot\', this);"); $(".tradewant").append($(object)); } else { alertify.error("Ошибка!"); } } } function removetrade(inv, object) { if(inv === "user"){ useritems.pop($(object).attr("data-id")); $(object).attr("onClick", "addtrade(\'user\', this);"); $( ".inventoryload" ).append($(object)); } else { botitems.pop($(object).attr("data-id")); $(object).attr("onClick", "addtrade(\'bot\', this);"); $( ".botinventoryload" ).append($(object)); } } function tradesend() { if(useritems.length > 0){ var data_post = {w1: useritems.shift(),w2: useritems.shift(),w3: useritems.shift(),w4: useritems.shift(),w5: useritems.shift(),w6: useritems.shift(),w7: useritems.shift(),w8: useritems.shift(),w9: useritems.shift(),w10: useritems.shift(), h1: botitems.shift(),h2: botitems.shift(),h3: botitems.shift(),h4: botitems.shift(),h5: botitems.shift(),h6: botitems.shift(),h7: botitems.shift(),h8: botitems.shift(),h9: botitems.shift(),h10: botitems.shift()}; console.log(data_post); $.ajax({ type: "POST", url: "tradesend.php", data: data_post, success: function(){ window.location.replace("/"); }, error: function(){ alertify.error("Ошибка!"); } }); } else { alertify.error("Ошибка!"); } } 
  • the pop method of an array does not accept a parameter, it simply deletes the last element of the array and returns it, that is, these two entries are absolutely equivalent: useritems.pop($(object).attr("data-id")); and useritems.pop(); - Grundy
  • And then how can you do? Bad in JS I delve very much - 100ROZE
  • I don’t really understand what the code generally does and what html markup corresponds to it, it looks like half of the code can be thrown out here, but without a minimal reproducible example that can be run and see how it works now, the solution might not work - Grundy
  • corrected the snippet, the problem was in shielding quotes, now it works as intended? - Grundy
  • Yes, that's exactly how it works, thank you. Well, actually, here is an example of work, I need to fix this fatal problem with data-id, so that it puts exactly those data-id that remained in the orange fields after all frauds with transfer and 2 problem is a large number lines with .shift, is it possible to somehow implement this in 1 line by the type of cycle? (w and h are required, these are keys for correct entry in the database) - 100ROZH

1 answer 1

The delete error is due to the fact that the pop function deletes the last element of the array.

As a solution, you can determine the index of the element to be deleted using the indexOf function , and then delete the found element using the splice function

For example:

 var id = $(object).attr("data-id"); var index = useritems.indexOf(id); useritems.splice(index,1); 

Regarding the collection of the object: you can use the reduce function , for example:

 useritems.reduc(function(acc,el,index){ acc['w'+(index+1)]=el; return acc; },{}); 

In addition, a few notes:

  1. If jQuery is used, adding event handlers is also worth using it, and not using the onclick / attribute
  2. There is a lot of duplicate code, in which only the array with which operations are performed differ by and large.
  3. Since handlers depend on the container in which the elements are located, it makes sense to use event delegation and add a handler to the container itself using the on function rather than a specific element.

In the end, everything might look like this:

 var useritems = []; var botitems = []; function addTrade(items, dest) { if (items.length < 10) { items.push($(this).attr('data-id')); $(this).appendTo(dest); } } function removetrade(items, dest) { items.splice(items.indexOf($(this).attr('data-id')), 1); $(this).appendTo(dest); } function addRemoveInit(items, src, dest) { $(src).on('click', '.item', function() { addTrade.call(this, items, dest); }); $(dest).on('click', '.item', function() { removetrade.call(this, items, src); }); } addRemoveInit(useritems, '.inventoryload', '.tradehave'); addRemoveInit(botitems, '.botinventoryload', '.tradewant'); function tradesend() { if (useritems.length > 0) { var data_post = reduceItems(botitems, 'h', reduceItems(useritems, 'w', {})); console.log(data_post); } } function reduceItems(items, prefix, start) { return items.reduce(function(acc, el, index) { acc[prefix + (index + 1)] = el; return acc; }, start); } 
 .inventoryload { background: yellow; border: 1px solid; height: 100px; width: 100px; } .botinventoryload { background: yellow; border: 1px solid; height: 100px; width: 100px; } .tradewant { background: orange; border: 1px solid; height: 100px; width: 100px; } .tradehave { background: orange; border: 1px solid; height: 100px; width: 100px; } .inv { float: left; } .trade { float: left; } .item { background: white; border: 1px solid; height: 20px; width: 20px; margin: 2px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="inv"> <div class="inventoryload"> <p class="item" data-id="1111">1111</p> <p class="item" data-id="1251">1251</p> <p class="item" data-id="4444">4444</p> </div> <div class="botinventoryload"> <p class="item" data-id="3251">3251</p> <p class="item" data-id="8018">8018</p> <p class="item" data-id="6543">6543</p> </div> </div> <div class="trade"> <div class="tradehave"> </div> <div class="tradewant"> </div> </div> <button onClick="tradesend();" id="button">Обменять</button> 

  • Thank you for such a detailed answer, I will take into account, then I will check, accomplish your goal - 100ROZH