0

I am trying to create js array with key = trener_id and values = selected service ID from the checked checkboxes

Whatever I do the array is being created but also there are many empty values that are being saved in the array. How to avoid this and finally to have a clean JS array with key trener_id and values only selected services IDs

Also is it possible and how to add sub-array that has Price customer and Price trener attached to each selected service value?

The php equivalent of the desired array format would be:

$trener_services = array(1){
[13]=>
  array(2) {
[47]=>array(2){
['Price_customer']=>
string(5) "10.00",
['Price_trener']=>
string(4) "5.00"
}
[45]=>array(2){
['Price_customer']=>
string(5) "60.00",
['Price_trener']=>
string(5) "10.00"
}
  }
}

Hope the question is clear.. Thanks for your time

var trener_services;

$('body').on('change', '.service_check', function() {
 trener_services = new Array();     
    $('.service_check:checked').each(function(){
    var sid = $(this).val();
    var trener_id = $(this).attr('data-trener');

    if(!trener_services[trener_id]){
    trener_services[trener_id] = [];
    }
  trener_services[trener_id].push($(this).val());
  console.log(trener_services);
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<table class="table table-hover table-striped text-left trener_service_table tren_ser_13">
<thead>
<tr>
<th class="text-left success">Select</th>
<th class="text-left success mw20">Service type</th>
<th class="text-left success">Price customer</th>
<th class="text-left success">Price trener</th>
</tr>
</thead>
<tbody><tr class="tren_ser_row_47"> 
<td><input id="service_check_47" data-trener="13" type="checkbox" class="service_check" value="47"></td>
<td><label for="service_check_47">Single play</label></td>
<td><input data-id="47" id="trener_client_price_47" class="short client_price client_price_47" type="text" value="10.00"></td>
<td><input data-id="47" id="trener_bonus_price_47" class="short bonus_price_47" type="text" value="5.00"></td>
</tr>
<tr class="tren_ser_row_45">    
<td><input id="service_check_45" data-trener="13" type="checkbox" class="service_check" value="45"></td>
<td><label for="service_check_45">Double play</label></td>
<td><input data-id="45" id="trener_client_price_45" class="short client_price client_price_45" type="text" value="60.00"></td>
<td><input data-id="45" id="trener_bonus_price_45" class="short bonus_price_45" type="text" value="10.00"></td>
</tr>
<tr class="tren_ser_row_46">    
<td><input id="service_check_46" data-trener="13" type="checkbox" class="service_check" value="46"></td>
<td><label for="service_check_46">Triple play</label></td>
<td><input data-id="46" id="trener_client_price_46" class="short client_price client_price_46" type="text" value="50.00"></td>
<td><input data-id="46" id="trener_bonus_price_46" class="short bonus_price_46" type="text" value="10.00"></td>
</tr>
</tbody>
</table>

7
  • 2
    you have a var trener_services = ... inside your eventhandler. This is totaly unrelated the global var trener_services = ... you define outside of the eventhandler. Ie, everything you do with trener_services inside your eventhandler does not affect the global variable at all... Commented Feb 15, 2023 at 9:54
  • 1
    If you are creating an array with numeric index, the gaps will be automatically filled with empty values; instead you could use an object to have numeric keys. You can then use Object.keys(...), Object.values(...) and Object.entries(...) to retrieve the contents as shown here Commented Feb 15, 2023 at 9:57
  • @derpirscher that was copy/paste error Commented Feb 15, 2023 at 10:05
  • You made it worse... Now you don't have a global variable at all, so you're just throwing away the result of running your function every time... Commented Feb 15, 2023 at 10:10
  • The simplest fix would be to have a global var trener_services; outside your eventhandler and then trener_services = new Array(); (ie without var) inside your eventhandler. So you recreate the whole array every time, a check status changed. Or have a look at @MichaelG answer which uses an object instead of an sparse array Commented Feb 15, 2023 at 10:30

1 Answer 1

1

As one commenter suggested, you must use an Object instead of an Array. (Your trener_id is a string, not a number, unless JQuery automatically converts strings to numbers; I don't use JQuery so I wouldn't know.)

//this is a global variable so you can use it elsewhere
let trener_services;

document.body.addEventListener( "change", () => {

    trener_services = Object.fromEntries(
        //get all the checked services:
        [ ...document.querySelectorAll('.service_check:checked') ].
            //map them to object entries of the form [ key, value ]
            map( checkboxElement => [

                //key: the data-trener attribute
                //checkboxElement.getAttribute( "data-trener" ),

                //key: the checkbox's value field
                checkboxElement.value,

                //value: an array of the checkbox's value as well as the two sibling values you wanted
                [
                    checkboxElement.value,
                    document.querySelector( "#trener_client_price_" + checkboxElement.value ).value,
                    document.querySelector( "#trener_bonus_price_" + checkboxElement.value ).value
                ]

            ] )
    );

    console.log( trener_services );

})

Here is the same function, without the sub-array you requested. (Your question was very unclear, but I am trying my best.)

//this is a global variable so you can use it elsewhere
let trener_services;

document.body.addEventListener( "change", () => {

    trener_services = Object.fromEntries(
        //get all the checked services:
        [ ...document.querySelectorAll('.service_check:checked') ].
            //map them to object entries of the form [ key, value ]
            map( checkboxElement => [

                //key: the data-trener attribute
                //checkboxElement.getAttribute( "data-trener" ),

                //key: the checkbox's value field
                checkboxElement.value,

                //value: only the checkbox's value
                checkboxElement.value

            ] )
    );

    console.log( trener_services );

})
Sign up to request clarification or add additional context in comments.

8 Comments

I created jsfiddle : jsfiddle.net/w5qor2pn and disovered that your code prints each service in separate array, but not all 3 for example in 1 array.. Am I right?
As you asked, "is it possible and how to add sub-array that has Price customer and Price trener attached to each selected service value". I will add a second copy that does not do that, I suppose?
Your changed code prints just the last selected checkbox, but not all selected. Please allow me a minute to create the desired array format which may help you to understand my question. I agree the question is not well /clear asked
I edited my question and added php equivalent of the desired array format with trener #13 selected services, but there will be more than 1 trener selected at once..
Michael G: After I runned some tests your first code can do the job I need and thats why I accepted your answer as correct ! Thank you very much for your time all of you guys !
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.