Viewed   4.6k times

I have a search form where I'm trying to have it output the results at the bottom of the page without reloading.

<form action='' method='post'>
<div id="search-form">      
<input type="text" name="search" class="search-field" id="search" value="" />
<div class="submit-container">
<button type="button" value="" class="submit" id="searchbutton" onclick="searchoutput()" /></button>
            </div>
  </form>
  <br><br>
  <p>Type First Name</p>

I want the search results to show below when the button is clicked, using Ajax call to another script. I keep getting an error: "Uncaught ReferenceError: searchoutput is not defined at HTMLButtonElement.onclick

Here is my javascript (using jquery):

$( document ).ready(function() {
function searchoutput() {
     if($(".search-field").val().length > 5) { //only shows results when more than 5 characters have been entered
        var search = $(".search-field").val();
        var update = $(".result");
        var goal = 0;
        $.get("query-include.php" , {search: search, goal: goal})
        .done(function( data ) {
          update.empty();
          update.append(data);
          $(this).remove();
                                });
                                             };
                         } 
  $( ".search-field" ).keydown(function() {
      var update =$(".results");
      update.empty();
                                       });
                             });

I have checked other posts and spent a long time trying to get the solution on my own. The odd thing is if I add an event listener for "keyup" in order to run the same function searchoutput as the user types:

var searchfield = document.getElementById("search");
searchfield.addEventListener("keyup", searchoutput);

Then I don't get the ReferenceError and the script runs fine.. I only get the function issue on button click.

 Answers

5

It's a scoping issue - searchOutput is defined within the scope of the $(document).ready() function. What you could try is to declare a var for searchOutput before that code, then assign it to the function like this:

var searchOutput;
$( document ).ready(function() {
  searchOutput = function () {
   if($(".search-field").val().length > 5) {
   //etc.
Tuesday, November 22, 2022
3

Never use .onclick(), or similar attributes from a userscript! (It's also poor practice in a regular web page).

The reason is that userscripts operate in a sandbox ("isolated world"), and onclick operates in the target-page scope and cannot see any functions your script creates.

Always use addEventListener()Doc (or an equivalent library function, like jQuery .on()).

So instead of code like:

something.outerHTML += '<input onclick="resetEmotes()" id="btnsave" ...>'


You would use:

something.outerHTML += '<input id="btnsave" ...>'

document.getElementById ("btnsave").addEventListener ("click", resetEmotes, false);

For the loop, you can't pass data to an event listener like that See the doc. Plus every time you change innerHTML like that, you destroy the previous event listeners!

Without refactoring your code much, you can pass data with data attributes. So use code like this:

for (i = 0; i < EmoteURLLines.length; i++) {
    if (checkIMG (EmoteURLLines[i])) {
        localStorage.setItem ("nameEmotes", JSON.stringify (EmoteNameLines));
        localStorage.setItem ("urlEmotes", JSON.stringify (EmoteURLLines));
        localStorage.setItem ("usageEmotes", JSON.stringify (EmoteUsageLines));
        if (i == 0) {
            console.log (resetSlot ());
        }
        emoteTab[2].innerHTML  += '<span style="cursor:pointer;" id="' 
                                + EmoteNameLines[i] 
                                + '" data-usage="' + EmoteUsageLines[i] + '">'
                                + '<img src="' + EmoteURLLines[i] + '" /></span>'
                                ;
    } else {
        alert ("The maximum emote (" + EmoteNameLines[i] + ") size is (36x36)");
    }
}
//-- Only add events when innerHTML overwrites are done.
var targetSpans = emoteTab[2].querySelectorAll ("span[data-usage]");
for (var J in targetSpans) {
    targetSpans[J].addEventListener ("click", appendEmote, false);
}

Where appendEmote is like:

function appendEmote (zEvent) {
    //-- this and the parameter are special in event handlers.  see the linked doc.
    var emoteUsage  = this.getAttribute ("data-usage");
    shoutdata.value += emoteUsage;
}


WARNINGS:

  • Your code reuses the same id for several elements. Don't do this, it's invalid. A given ID should occur only once per page.
  • Every time you use .outerHTML or .innerHTML, you trash any event handlers on the affected nodes. If you use this method beware of that fact.
Thursday, September 1, 2022
 
2

Your error is because you have defined your function inside:

<script type="text/javascript" src="lib.js">

the correct way is to close that script tag first like so:

<script type="text/javascript" src="lib.js"></script>

and then defining the script tag again to define the function like so:

<script>
function(){
    //body of function
};
</script>

<script type="text/javascript" src="lib.js"></script>
<script>
  function decryptfun() {
    var pass = "hjubjbjhdgyuwj";
    var encrtoken = "abcdefghijklmn";

    //var p = lib.decrypt(encrtoken, atob(pass)); //USE THIS IN YOUR CASE
    var p = "test"; //just for example
    alert(p);
  }
</script>
<h1>Decrypt Operation</h1>
<input type="button" onclick="decryptfun()" value="Click">
Saturday, December 17, 2022
 
legion
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :