Search code examples
javascriptsveltesvelte-3

js Template literal in querySelectorAll producing error with checkbox:checked condition


This is my third time for this issue today. Everytime someone answers my question, I'm very grateful for the help but the issue partially resolved the easy part. The important part still not producing the desired output.

I've a form with options grouped by the option group name. I'm trying to use template literal to get the optiongroup name in my js code to check if the input checkbox checked or not. Should be easy but I'm unable to succeed in this last part.

My form is typical using svelte and html

<form name="optionsform" on:submit|preventDefault={()=>collectoptions(itemid, itemprice, itemname,  itemdescription, variationname, variationprice)}>
    
    {#if option['rules'] == "exactly"}
    {#each option.optiongroupitems as optionitem, index} 
    <li style="list-style : none;">
    <label>
        <input  type="checkbox" class={option.groupheader} bind:group={values.exactly} value={optionitem.name} on:click={()=> Validateexactly(option.rulesnumber.number, option.groupheader, optionitem.name)} >
         {optionitem.name} : {optionitem.price}
    </label>
    </li>
    {/each}
    {/if} 
    <button type="submit" >Add To cart</button>
    </form>

validateexactly function :

 function Validateexactly(limit, groupheader, name) { 
    let getexactlygroup = `${groupheader}` 
    console.log("this is logging corrertly the option group name :", getexactlygroup)
    
    exactlylimit = limit
    var checks = document.querySelectorAll(".getexactlygroup"); // how do I reference option.groupheader correctly?  
    checks.forEach((item, index)=>{
    
      console.log("showing empty list array ", item) 
    
    })
    
    for (var i = 0; i < checks.length; i++)
     checks[i].onclick = selectiveCheck;
    function selectiveCheck (event) {  
     var checkedChecks = document.querySelectorAll('.getexactlygroup'[type="checkbox"]:checked');//showing errors that selector is invalid selector. 
     if (checkedChecks.length >= exactlylimit + 1){
       return false;
     }
    }
    
    } 

After few kind people posting their answers, I got this part working:

let checks = document.querySelectorAll(`.${getexactlygroup}`); 

And now I'm able to see in the console.log all my option group input grouped correctly.

The issue that I've trying for the past hour is this line:

var checkedChecks = document.querySelectorAll( `.${getexactlygroup}`.input[type="checkbox"][checked]);

I tried the following and I get error that type is not a valid selector, input is not a valid selector. So how, I failed from the previous answers how to use template literal. I read the template literal on MDN, then querySelector section.

var checkedChecks = document.querySelectorAll( `.${getexactlygroup}`.input[type="checkbox"]:[checked]); 

var checkedChecks = document.querySelectorAll( `.${getexactlygroup}`input[type="checkbox"]:[checked]);

var checkedChecks = document.querySelectorAll( `.${getexactlygroup}`.input[type="checkbox"][checked]); 
var checkedChecks = document.querySelectorAll( " `.${getexactlygroup}`.input[type="checkbox"]:[checked]");

In MDN, someone wrote that : Note: Characters that are not part of standard CSS syntax must be escaped using a backslash character. Since JavaScript also uses backslash escaping, be especially careful when writing string literals using these characters. See Escaping special characters for more information.

How do I use the .${getexactlygroup}[input type checkbox] : checked in js? I'm so frustrated and I don't think it is that difficult but I'm unable to figure it out. Any js ninja out there with rock solid js knowledge who can help me?


Solution

  • You don't need any query selector in svelte in this case. I would build a checkbox component like this:

    <script> 
    //there are variables to export
      export let value
      export let group
      export let name
      export id
      export let checked
    
    // this is a function to "catch" your changes if the answer that you expect is equal to value that the user will check
    
    function onChange(event: Event) {
        group = (<HTMLInputElement>event.target).value;
      }
      $: checked = (group === value)
    
    </script>
    
    
    <input type="checkbox" id={id} bind:group={ group } value={ value } name={ name } on:change="{ onChange }" { checked }/>
    <slot/>