selectbox custom scroll cu JavaScrpt

Discutii si intrebari legate de scripturi si functii JavaScript, jQuery si Ajax, cod JavaScript in general.
dim
Mesaje:61

selectbox custom scroll cu JavaScrpt

Salut

am si eu un buton <select > pt cantitatea care poate selecta de la 1-50 de produse

Cod: Selectaţi tot

                 <div class="select">	  
                          <select   name="quantity[{{ product['cart_id'] }}]" 
                                  onchange='this.form.submit( )'  >
                              {% set cp=50 %}{% for cp in cp..product %} 
                                 <option 
                                      {% if (product['quantity'] == cp) %} {{ "selected" }} {% endif %} 
                                       value="{{ cp }}" >{{ cp }}</option>
                              {% endfor %} 
                          </select>
                     </div>    
cum pot sa fac un script prin care sa pot sa afisez in dropdowns maxim 5 randuri pe care sa le aseze desupra butonului si sa porneasca in tot deuna lista le la 1 indiferent de valuarea selectata ceva de genu asta
nr.png
nr.png (2.18KiB)Vizualizat de 1288 ori
si tot in script daca pot sa introduc ccs pt modificare scrollbar
am incercar cu ::-webkit-scrollbar da nu a functionat
multumesc

MarPlo Mesaje:4343
Poti sa folosesti atributul size pentru determinarea numarului de optiuni vizibile.
De exempu:

Cod: Selectaţi tot

<select size='5' name='sel1'></select>
Iar pentru un custom select dropdown list poti sa folosesti un plugin jQuery, de exemplu: Select2 - jQuery replacement for select boxes (e destul de complex).

Testeaza si codul urmator, il poti modifica cum stii ca sa-l adaptezi la ce vrei sa faci:

Cod: Selectaţi tot

<div class='select'>	  
<select id='sel_1' size='6' name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select>
</div>

<script>
//From: https://marplo.net/

const nr_op =50;  //number of options
let sel_op =48;  //selected option
let str_op ='';
let str_sel_op ='';

for(var i=nr_op; i>0; i--){
  if(i ==sel_op) str_sel_op ='<option selected value="'+i+'">'+i+'</option>';
  else str_op +='<option value="'+i+'">'+i+'</option>';
}
document.getElementById('sel_1').innerHTML = str_op + str_sel_op;
</script>
- Demo:



dim Mesaje:61
Multumesc pt raspuns

Pentru numarului de optiuni vizibile nu ma ajuta size daca il folosesc asa il transforma in lista nu in buton.
Am folosit:

Cod: Selectaţi tot

 <select id='sel_1' onmousedown="if(this.options.length>5){this.size=5;}"  name="quantity[{{ product['cart_id'] }}]" 
                                  onchange='this.form.submit( )'  >
Demo:


am incercat scriptul de la tine si functioneaza doar pt primul produs din lista, urmatoarele nu le mai modifica iar
let ex_sel_op =48 daca ii dau valoarea let ex_sel_op ="quantity[{{ product['cart_id'] }}]" nu imi mai afiseaza in ordine.

M-am uita si prin tutorialele cu jQuery dar nu am gasit ceva cre sa ma ajute in sensu asta.
As dori daca se poate doar sa imi puna lista deasupra in tot deuna indiferent de pozita in pagina si sa o afiseze mereu de la 1

MarPlo Mesaje:4343
Se poate modifica codul de la primul raspuns ca sa functioneze cu mai multe liste.
Daca ai pus quantity[{{ product['cart_id'] }}] pentru optiunea selectata nu functioneaza fiindca acela reprezinta id-ul /numele. Probabil valoarea selectata e la: {{ product['quantity'] }}

Incearca codul din exemplu de mai jos.

- Ca sa functioneze, fiecare tag <select> e necesar sa aibe aceasta sintaxa:

Cod: Selectaţi tot

<select class='sel_cust_op' data-sel_op='nr_op,sel_op'></select>
Unde:
- nr_op = numarul de optiuni.
- sel_op = numarul /valoarea optiunii selectate.

Nu cunosc sintaxa template din codul tau, dar din ce imi dau seama poate ca ar merge asa:

Cod: Selectaţi tot

<select class='sel_cust_op' data-sel_op="50,{{ product['quantity'] }}" name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select>
- Exemplu

Cod: Selectaţi tot

 
<select class='sel_cust_op' data-sel_op='50,48' name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select> - 
<select class='sel_cust_op' data-sel_op='20,8' name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select> - 
<select class='sel_cust_op' data-sel_op='25,17' name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select>

<script>
//From: https://marplo.net/

//Receives: elms=array with <select> objects
function customSelOp(elms){
  for(var n=0; n<elms.length; n++){
    var ar_atr = elms[n].getAttribute('data-sel_op').split(',');
    var nr_op = ar_atr[0].trim()*1;
    var sel_op = ar_atr[1].trim()*1;
    var str_op ='';
    var str_sel_op ='';

    for(var i=nr_op; i>0; i--){
      if(i ==sel_op) str_sel_op ='<option selected value="'+i+'">'+i+'</option>';
      else str_op +='<option value="'+i+'">'+i+'</option>';
    }
    elms[n].innerHTML = str_op + str_sel_op;
    elms[n].addEventListener('mousedown', (e)=>{
      if(e.target.options.length>5){e.target.size=5;}
      e.target.scrollTo(0, 2345)
    });
  }
}

const sel_cust_op = document.querySelectorAll('select.sel_cust_op');
customSelOp(sel_cust_op);
</script>
- Demo:

- -

MarPlo Mesaje:4343
Sau, alta varianta, cu buton cu valoarea selectata separat sub <select> care are "size".
- Exemplu:

Cod: Selectaţi tot

<div class='sel_cust_op' data-sel_op='50,48' style='display:inline-block;'>
<select size='5' name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select>
</div>
<div class='sel_cust_op' data-sel_op='20,8' style='display:inline-block;'>
<select size='5' name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select>
</div>
<div class='sel_cust_op' data-sel_op='25,17' style='display:inline-block;'>
<select size='5' name="quantity[{{ product['cart_id'] }}]" onchange='this.form.submit( )'></select>
</div>

<script>
//From: https://marplo.net/

//Receives: elms=array with <div>s with <select>
function customSelOp(elms){
  for(var n=0; n<elms.length; n++){
    var ar_atr = elms[n].getAttribute('data-sel_op').split(',');
    var nr_op = ar_atr[0].trim()*1;
    var sel_op = ar_atr[1].trim()*1;
    var str_op ='';
    var str_btn ='<input type="button" style="display:block; margin:0 auto;" value="'+sel_op+'"/>';

    for(var i=nr_op; i>0; i--){
      if(i !=sel_op) str_op +='<option value="'+i+'">'+i+'</option>';
    }
    var elm = elms[n].querySelector('select');
    elm.innerHTML = str_op;
    elm.insertAdjacentHTML('afterend', str_btn);
    elm.scrollTo(0,2345);
  }
}

const sel_cust_op = document.querySelectorAll('.sel_cust_op');
customSelOp(sel_cust_op);
</script>
- Demo:

dim Mesaje:61
Multumes
Prima varianta este ok functioneaza acum pt toate produsele.
Cand ai timp si poti as vrea daca poti sa faci si comentariile pt fiecare linie de cod creata ca sa si inteleg mecanismu
acum am copiat ca papagalu :).
Singuru dezavantaj este nu se inchide inapoi fereastra in cazul in care apas valorea deja selectata sau langa tabel

MarPlo Mesaje:4343
Ai codul cu explicatii si va inchide lista select la clic in afara sau pe oricare optiune.

Cod: Selectaţi tot

<select class='sel_cust_op' data-sel_op='50,48' name="quantity[{{ product['cart_id'] }}]"></select> - 
<select class='sel_cust_op' data-sel_op='20,8' name="quantity[{{ product['cart_id'] }}]"></select> - 
<select class='sel_cust_op' data-sel_op='25,17' name="quantity[{{ product['cart_id'] }}]"></select>

<script>
//From: https://marplo.net/

//Receives: elms=array with <select> objects
function customSelOp(elms){
  //parcurge array-ul
  for(var n=0; n<elms.length; n++){
    //preia valorile din atributul 'data-sel_op', le separa dupa ',' si le adauga ca numere in 2 variabile
    var ar_atr = elms[n].getAttribute('data-sel_op').split(',');
    var nr_op = ar_atr[0].trim()*1;  //numar de optiuni
    var sel_op = ar_atr[1].trim()*1; //optiunea selectata
    var str_op ='';  //pt. sirul cu optiuni
    var str_sel_op ='';  //pt. sirul cu optiunea selectata

    //construeste sirurile cu optiuni
    for(var i=nr_op; i>0; i--){
      if(i ==sel_op) str_sel_op ='<option onclick="this.parentNode.size=1" selected value="'+i+'">'+i+'</option>'; //la clic pe ea face size 1 la elementul parinte
      else str_op +='<option value="'+i+'">'+i+'</option>';
    }

    //adauga optiunile si cea selectata la urma
    elms[n].innerHTML = str_op + str_sel_op;

    //inregistrare evenimente

    elms[n].addEventListener('mousedown', (e)=>{
      if(e.target.options.length>5)e.target.size =5; //nr. optiuni vizibile
      e.target.scrollTo(0, 2345); //face scroll in jos de tot in lista select
    });

    //la click in afara listei seteaza size 1
    elms[n].addEventListener('blur', (e)=>{
      e.target.size =1;
    });

    //la evenimentul change face size 1 si trimite form-ul in care e lista
    elms[n].addEventListener('change', (e)=>{
      e.target.size =1;
      e.target.form.submit();
    });
  }
}

//preia elementele select cu class='sel_cust_op' si apeleaza functia cu ele
const sel_cust_op = document.querySelectorAll('select.sel_cust_op');
customSelOp(sel_cust_op);
</script>

dim Mesaje:61
Multumesc mult pt ajutor am verificat acum si functioneaza perfect.
Mai am cateva modificar de facut cu css pt aspect,
in mare am reusit sa il modific. Bara de scroll nu prea merge schimbata
am incercat cu -webkit-scrollbar si il modifica dor in chrome.
Da oricum asta e alta problema si daca nu reusesc singur o sa deschid alta pagina in categoria css.
Multumesc inca o data

dim Mesaje:61
Salut
Am revenit dupa ce am testa scriptul in mai multe browsere:
Chrome - ok;
Mozilla Firefox - ok;
Opera - ok;
Maxthon 4.4 - ok;
Microsoft Edge - Imi afiseaza lista derulata la 50 si nu se paote selecta valoarea!!!
Internet Explorer 11 - Nu afiseza nimic in lista si nici ca nr selectat!!!
Safari -Nu afiseza nimic in lista si nici ca nr selectat!!!

Nu am putut testa de pe mobil.

Intrebarea este daca se paote rezolva si problema asta??

MarPlo Mesaje:4343
Inlocuieste inregistrarea 'mousedown' din codul anterior cu acesta:

Cod: Selectaţi tot

  elms[n].addEventListener('mousedown', (e)=>{
    if(e.target.size<4){
        if(e.target.options.length>5)e.target.size =5; //nr. optiuni vizibile
        e.target.scrollTo(0, 2345); //face scroll in jos de tot in lista select
      }
    });
 
Rezolva problema de selectare in Microsoft Edge.
Functia scrollTo() nu functioneaza in Microsoft Edge si nu am gasit alternatjva, de aceea in el nu merge scroll la prima optiune de jos.

Nu am Internet Explorer 11 si nici Safari pentru test.

dim Mesaje:61
Internet Explorer 11 il gasesti instalat cu sigurant in windows accessories daca ai win 10 instalat

ideea e ca in ambele si in ie11 si in safari in console da eroare

Cod: Selectaţi tot

 elms[n].addEventListener('mousedown', (e)=>{
index.php:555SyntaxError: Unexpected token '>'
    if(e.target.size<4){

MarPlo Mesaje:4343
Inlocuieste codul care l-ai postat cu acesta:

Cod: Selectaţi tot

 elms[n].addEventListener('mousedown', function(e){
    if(e.target.size<4){