Buck Buck - 2 months ago 23
jQuery Question

Make dynamic selector jQuery

I have a script in jQuery (2.1.4) who add a button to specific block

Example :

<div class="dr_ing_list">
<?php
$ingredients=explode(';', $donnee['ingredients']);
foreach ($ingredients as $value) {
echo "<p>".$value."</p></br>";
}
?>
</div>
<div class="dr_met_list">
<?php
$methode=explode(';', $donnee['methode']);
foreach ($methode as $value) {
echo "<p>".$value."</p></br>";
}
?>
</div>


i get the class of each div for make a dynamic selector, but i have an error :

Uncaught Error: Syntax error, unrecognized expression: ".dr_ing_list p:last"

Here's my jQuery script :



var block_button = 0;
$(".fa-lg").click(function(e){
e.preventDefault;
var categorie = $(this).parent().attr('class');
var selector = categorie+' p:last';
selector = '".'+selector+'"';
alert(selector);
$(selector).after("<button class='cta' type='button'>Valider les modifications</button>");
});

p{
margin: 0;
}

.dr_ing_list{
width:300px;
border: 1px solid black;
border-radius: 5px;
margin-bottom:10px;
}

.dr_met_list{
width:300px;
border: 1px solid black;
border-radius: 5px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dr_ing_list">
<button type="button" class="fa-lg">edit</button>
<p>Butter</P></br>
<p>Milk</P></br>
<p>Egg</P></br>
<p>Flour</P></br>
</div>

<div class="dr_met_list">
<button type="button" class="fa-lg">edit</button>
<p>Shake</P></br>
<p>Don't drink</P></br>
<p>Re shake</P></br>
<p>You can drink</P></br>
</div>





Where is my error ? Thanks

Answer

Your error is in this line:

selector = '".'+selector+'"';

Change it to:

selector = '.'+selector;

Why? The selector in first case is a string containing: "."dr_ing_list p:last"" instead it must be: ".dr_ing_list p:last" (double quotes).

The snippet:

var block_button = 0;
$(".fa-lg").click(function(e){
  e.preventDefault;
  var categorie = $(this).parent().attr('class');
  var selector = categorie+' p:last';
  selector = '.'+selector;
  console.log(selector);
  $(selector).after("<button class='cta' type='button'>Valider les modifications</button>");
});
p{
  margin: 0;
}

.dr_ing_list{
  width:300px;
  border: 1px solid black;
  border-radius: 5px;
  margin-bottom:10px;
}

.dr_met_list{
  width:300px;
  border: 1px solid black;
  border-radius: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="dr_ing_list">
    <button type="button" class="fa-lg">edit</button>
    <p>Butter</P></br>
    <p>Milk</P></br>
    <p>Egg</P></br>
    <p>Flour</P></br>
</div>

<div class="dr_met_list">
    <button type="button" class="fa-lg">edit</button>
    <p>Shake</P></br>
    <p>Don't drink</P></br>
    <p>Re shake</P></br>
    <p>You can drink</P></br>
</div>

A reduced form of your code could be:

  • nextAll: Get all following siblings of each element in the set of matched elements, optionally filtered by a selector.
  • jQuery Create element on the fly: in this way you avoid to write html as string, avoiding in this way potential errors

so, the new snippet is:

var block_button = 0;
$(".fa-lg").click(function (e) {
  e.preventDefault;
  $(this).nextAll('p:last').after($('<button/>', {
    class: 'cta',
    type: 'button',
    text: 'Valider les modifications'
  }));
});
p {
  margin: 0;
}

.dr_ing_list {
  width: 300px;
  border: 1px solid black;
  border-radius: 5px;
  margin-bottom: 10px;
}

.dr_met_list {
  width: 300px;
  border: 1px solid black;
  border-radius: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="dr_ing_list">
    <button type="button" class="fa-lg">edit</button>
    <p>Butter</P></br>
    <p>Milk</P></br>
    <p>Egg</P></br>
    <p>Flour</P></br>
</div>

<div class="dr_met_list">
    <button type="button" class="fa-lg">edit</button>
    <p>Shake</P></br>
    <p>Don't drink</P></br>
    <p>Re shake</P></br>
    <p>You can drink</P></br>
</div>