2

Here is my problem : I have a bunch of <p>HTML. For example : <p> Paris </p> <p>London</p> <p> NewYork</p>

When I want to get the Text of a specific <p> when I click on it, I do (using JQuery)

    $("#saved_research").click(function(){
        console.log($(this).text());
    });

it returns me ParisLondonNewYork. And not the specific text of the <p>.

Do you know why ?

Respectfully,

Here is the exact HTML

<!DOCTYPE html>
<html lang="fr">
<head>
    <title>My News</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">

    <link rel="shortcut icon" type="image/x-icon" href="favicon-js.ico">
    <link rel="stylesheet" type="text/css" media="screen" href="news.css">
</head>
<body onload="init();">
    <header>
        <img id="banniere" src="img/job.png"/>
    </header>
    <!--HERE -->
    <div id="recherches">
        <h3 class="titre"> recherches stockées</h3>
        <div id="recherches-stockees">
        </div>

        <h3 class="titre">nouvelle recherche</h3>
        <div id="nouvelle-recherche">
                <input type="text" name="zone_saisie" id="zone_saisie"/>
            <img id="disk" class="icone-disk" src="img/disk30.jpg" onclick="ajouter_recherche()" />
            <BR/>
            <input id="bouton_recherche"type="button" value="OK" onclick="rechercher_nouvelles()"/>
        </div>
    </div>

    <div id="zone-centrale">
        <div id="resultats-container">
            <h3 class="titre">résultat</h3>
            <div id="wait"></div>
            <div id="resultats"></div>
        </div>
    </div>

    <!-- Inclusion des librairies jQuery & Scripts JS -->
    <script
        src="https://code.jquery.com/jquery-3.4.1.js"
        integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
        crossorigin="anonymous"></script>
    <script
            src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
            integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
            crossorigin="anonymous"></script>
    <script src="scripts/jquery.cookie.js"></script>

    <script src="scripts/util.js"></script>
    <script src="scripts/news.js"></script>

</body>
</html>

Here is the exact JS

// Tableau contenant des chaines de caractères correspondant aux recherches stockées
var recherches = [];
// Chaine de caractères correspondant à la recherche courante
var recherche_courante;
// Tableau d'objets de type resultats (avec titre, date et url)
var recherche_courante_news = [];

/*class Paragraphe{
    constructor(id,value){
        this.id = id;
        this.value = value;
    }
}*/


/*1.1 */    
//si clic sur l'image disk alors ajout chaine au tableau recherches[]
//function ajouter_recherche()
function ajouter_recherche(){
    //recuperer la chaine de carachtere
    //verifier si dans recherches, il y a la meme recherche
    const donneeEntree = $("#zone_saisie").val();
    if(recherches.indexOf(donneeEntree) == -1){
        recherches.push(donneeEntree);
        //ajouter l'element aux recherches stockées
        $("#recherches-stockees").prepend('<p class="titre-recherche" ><label onclick=selectionner_recherche(this)>'+donneeEntree+'</label><img src="images/croix30.jpg" class="icone-croix " onclick="supprimer_recherche(this)"/></p>');
        //sauvegarde dans sessionStorage(plus de place que cookie) pour conserver les recherches deja effectuées
        localStorage.setItem("recherches",JSON.stringify(recherches));
    }
    //si clic sur le label => selectionner_recherche(this)
    //si clic sur croix => supprimer_recherche(this)
}


function supprimer_recherche(elt) {
    //supprimer l'element p dans recherches-stockees
    $(elt).parent().remove();


    //  localStorage.clear(); == localStorage.removeItem("recherches");
    //supprimer la recherche du tableau recherches[]
    const indexSupprimer = recherches.indexOf($(elt).parent().parent().val());
    recherches.splice(indexSupprimer);
    //supprimer dans localstorage aussi
    //localStorage.removeItem(this);
    //c'est moche A REFAIRE
    localStorage.setItem("recherches",JSON.stringify(recherches));
}

//controller
function selectionner_recherche(elt) {
    $("#zone_saisie").val("");
    $("#resultats").empty();
    //jquery ??????
    $("#zone_saisie").val(elt.innerText); 
    recherche_courante = elt.innerText;

    //variable globale recherche_courante_news => cookie
    //localstorage.getItem => recuperer le "cookie" === nom de la recherche
    recherche_courante_news = JSON.parse(localStorage.getItem($("#zone_saisie").val()));
    //affichage des recherche sauvegardées dans la zone resultats
    $.each(recherche_courante_news,function(index,value){
        $("#resultats").append('<p class="titre_result"><a class="titre_news" href='+decodeHtmlEntities(value.url)+
        ' target="_blank">'+decodeHtmlEntities(value.titre)+
        '</a><span class="date_news">'+decodeHtmlEntities(value.date)+'</span><span class="action_news" onclick="sauver_nouvelle(this)"><img src="img/horloge15.jpg"/></span></p>'); 
    });

}



//model
function init() {
    //recuperer les données du stockage local
    let obj_json = localStorage.getItem("recherches");
    let obj = JSON.parse(obj_json);
    if(obj != ""){
        $(obj).each(function(index,value){
            recherches.push(value);
            $("#recherches-stockees").prepend('<p class="titre-recherche" ><label onclick=selectionner_recherche(this)>'+value +'</label><img src="images/croix30.jpg" class="icone-croix " onclick="supprimer_recherche(this)"/></p>');
        });
    }
    //on remplit la partie recherches-stockées de ces données


}

//model
function rechercher_nouvelles() {
    //faire une requeste get ? !!!pas secure!!! avec les données de recherche_courante ? ou direct avec value ?
    //on nettoye la zone de resultat pour eviter d'afficher encore et encore
    $("#resultats").empty();
        $("#wait").css("display","block");
        const data = $("#zone_saisie").val();
        //.get est asynchrone
        $.get("https://carl-vincent.fr/search-internships.php?data="+data,maj_resultats);
    //vider recherche_couraznt_news sinon tout les cookies se superposeront ( 1: coucou ..... 2 : coucou, salut)
    recherche_courante_news = []; //argh c moche
    //et on la remplis avec le contenu du localstorage de la recherche en question
    //on ne peut pas utiliser $("#zone_saisie").val() car si l'utilisateur change la recherche mais veut quand m
    //même faire l'action alors ça marchera pas => exemple impossible d'acceder à l'element car non existant
    //il faudrait récuperer le label sur la recherche_saved sur laquelle on clic
/*  recherche_courante_news = JSON.parse(localStorage.getItem($("#recherches-stockees").click(function(){
        return $(this).text();
    })
    ));*/
    /*$("#recherches-stockees > p").click(function(){
        console.log($(this).text());
        alert("yes");
    })*/

//HERE/////////////////////////////////////////

    $('#recherches-stockees > p').on('click', function() {
        console.log($(this).text());
    });

}


//function callback => si jamais la requete ajax get reussis alors on fait celle ci
//view
function maj_resultats(res) {
    $("#wait").css("display","none");

    //res est un objet de plusieurs offres, on veut toute les afficher dans la case resultat
    $(res).each(function(index,value){
        $("#resultats").append('<p class="titre_result"><a class="titre_news" href='+decodeHtmlEntities(value.url)+
        ' target="_blank">'+decodeHtmlEntities(value.titre)+
        '</a><span class="date_news">'+decodeHtmlEntities(value.date)+'</span><span class="action_news" onclick="sauver_nouvelle(this)"><img src="img/horloge15.jpg"/></span></p>'); 
    });


}

//manque : creer un objet à envoyer 
//delete dans recherche_courante_news   

function sauver_nouvelle(elt) {
    //parentElement => titre
    let obj = {
        "titre" : $(elt).parent().find("a").text(),
        "date" : $(elt).parent().find(".date_news").text(),
        "url" : $(elt).parent().find("a").attr('href')
    }
    //$(elt).firstChild.attr("src","");
    //$(elt).attr("src","img/disk15.jpg");
    $(elt).html("<img src = img/disk15.jpg />");
    $(elt).attr("onclick","supprimer_nouvelle(this)");
    //creer l'objet il faut
    if(indexOfResultat(recherche_courante_news,obj) == -1){
        recherche_courante_news.push(obj);
        localStorage.setItem("recherches_courante_news",JSON.stringify(recherche_courante_news));
    //on a donc 1 cookie par recherche, faire des verif pour pas pouvoir mettre le même plusieurs fois ??
        localStorage.setItem( $("#zone_saisie").val(),JSON.stringify(recherche_courante_news));
    }
}


function supprimer_nouvelle(elt) {
    let obj = {
        "titre" : $(elt).parent().find("a").text(),
        "date" : $(elt).parent().find(".date_news").text(),
        "url" : $(elt).parent().find("a").attr('href')
    }
    //$(elt).attr("src","");
    //$(elt).attr("src","img/horloge15.jpg");
    $(elt).html("<img src = img/horloge15.jpg />");
    $(elt).attr("onclick","sauver_nouvelle(this)");
    if(indexOfResultat(recherche_courante_news,obj) != -1){
        recherche_courante_news.splice(indexOfResultat(obj,recherche_courante_news));
        localStorage.setItem("recherches_courante_news",JSON.stringify(recherche_courante_news));
        localStorage.setItem($("#zone_saisie").val(),JSON.stringify(recherche_courante_news));

    }
}



//Autocompletion
//A chaque Entrée de clavier => keyup, verifier si le mot n'a pas une ressemblance dans le localstorage (recherches sauvegardées)
//Apparement Jquery UI le fait tres bien

//Model et view
var test = ['Grenoble','Lyon','Paris'];
$("#zone_saisie").autocomplete({
    source : recherches,
    focus : true
}).keypress(function(event){
    if(event.keyCode === 13){
        rechercher_nouvelles();
    }
});

4
  • What is #saved_research? It is one of those <p>s, or something else? Commented Mar 23, 2020 at 2:53
  • #saved_research is '<div>' that contains all the "history", all the <p> Commented Mar 23, 2020 at 2:55
  • 1
    $('#saved_research>p').click(function(){}); instead. Commented Mar 23, 2020 at 3:03
  • @Crakenar see the edited part of my answer as to why your code was not working. If you have elements that are dynamically added to the page, you cannot use .click() Commented Mar 23, 2020 at 4:26

3 Answers 3

2

Seems like the reason you are getting all the concatenated p text is because you are handling the click event on the parent div, and the this reference is to that div. Calling .text() on this parent reference gives all the child text. The click handler should be invoked with an event object that has the specific target, and you can use that to get the text only of what was clicked.

$("#saved_research").click(function(event){
  var x = event.target; // event.target has the exact element clicked
  console.log($(x).text()); // the text of the clicked element
});
Sign up to request clarification or add additional context in comments.

3 Comments

I wouldn't advise attaching Events to a parent Element, just to get the child as a target. It leads to unnecessary Event processing.
@StackSlave well it depends, I think in the case of having a potentially large list of sibling elements, putting the handler on the direct parent makes sense.
Should be no problem having jQuery assign Events to the proper Elements. Even a very large list.
2

Add the listener to the <p>s, not the parent container, and then referencing this inside the listener will refer to a <p>, so $(this).text() will give you the text of an individual <p>:

$('#saved_research > p').on('click', function() {
  console.log('1p',$(this).children().eq(0).text());
  console.log('2p',$(this).children().eq(1).text());
  console.log('3p',$(this).children().eq(2).text());

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="saved_research">
<p>Paris</p> <p>London</p> <p>NewYork</p>
</div>

Or use event delegation:

$('#saved_research').on('click', 'p', function() {
  console.log($(this).text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="saved_research">
<p>Paris</p> <p>London</p> <p>NewYork</p>
</div>

19 Comments

While this prob works it adds a separate handler to all the p elements, which could be numerous. I would say to still have the handler attached just to the parent div, but use event.target to get the clicked element reference from that point
@KaeyangTheG If there are so many elements that that's a real problem (which is pretty unlikely), the event delegation method accomplishes exactly that. jQuery can accomplish it much more concisely than by doing it manually.
@Crakenar Do you mean you have multiple #saved_research elements? That's invalid HTML - there should only be one element with a particular ID in the whole document. Use classes instead.
@KaeyangTheG, OP wants the Events on those specific Elements, not the parent. Why process on the parent if you're not clicking the Element you want?
I have one #saved_research and when i add my <p> , they have their own class.
|
1

So, your javascript is saying "get all the <p> inside of #saved_research" You'll need to add a specific identifier to your html. There are many ways to do this, but one of the best ways to do this is with data attributes:

<div id="saved_research">
   <p data-paragraph="1">Paris</p>
   <p data-paragraph="2">London</p>
   <p data-paragraph="3">New York</p>
</div>

$("#saved_research").click(function() {
    console.log($("[data-paragraph='1']").text());
});

Use data attributes - rather than ids or classes - to denote things in your html that are related to javascript. This is considered by some (myself included) to be a best practice. It allows you to know what in your html is specifically for javascript. For example, when you're looking at your html in the future, will you remember that id #saved_research is used by javascript? If not, someone doing design work on the page may change #saved_research to #save_research thinking it is only involved with the CSS. Thus, they break the javascript. By using data attributes, it's very clear: this identifier is used for javascript.

Edit: based on your comment about the html not existing on the page when the page loads, here's what you need to do:

$(window.document).on('click', "#saved_research", function() {
    console.log($("[data-paragraph='1']").text());
});

Notice the different format, with .on('click' ? This format is required when you have elements that are dynamically added to the page. The .click format only works if the element exists on the page when the page first loads. You can use this .on('click' format with any of the other answers listed on this page, they all work with this format.

Comments

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.