1

I've tried a couple of formulations of this code and gotten mixed, unspectacular results. The idea is pretty simple: The user enters a search string in the text box, clicks a button, the string is passed to a var search. The search variable then informs the AJAX request, which gets sent off and returns a JSON file. I then display the file in the DOM for now (cleaning it up is the next step, though the file keeps disappearing with the introduction of button click code).

Initially, I had var search declared directly under $(document).ready(. . . and thought my button click code could be used to grab the search string from the text box and update that variable. I was wrong. The variable would not update. If anyone knows why, I'd be fascinated to hear the explanation.

The code below represents an attempt to fix that issue by putting all of the AJAX code in the button click context, so that the search variable is available to the AJAX request. The result is an API error that flashes for a second saying that the search variable is not being passed to the API. Console.log statements reveal nothing beyond that search is not being update and/or passed. What is up with this?

<!DOCTYPE html>

<html lang="en">
    <head>
        <!-- Bootstrap -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
        <!-- CSS -->
        <style>
            .container {
                height: 50vh;
                align-items: center;
            }

        /* code for sliding search box adapted from https://bootsnipp.com/snippets/2o42z */

        </style>
        <!-- JS/JQ -->
        <script>
            $(document).ready(function () {
                // search parameter provided by user started with . .  .
                // var search;
                $("button").on("click", function () {
                    // use .val(), .text() did not do the job
                    var search = $("#searchfield").val();
                    console.log(search);
                    // AJAX request options for WikiMedia API
                    var ajaxOptions = {
                        crossDomain: true,
                        dataType: "json",
                        url: "https://en.wikipedia.org/w/api.php",
                        method: "GET",
                        data: {
                            action:"query",
                            format:"json",
                            titles:search,
                            list:"search",
                            srsearch:search,
                            srprop:"snippet",
                            srlimit:"100",
                            origin:"*"
                        }
                    };
                    console.log(ajaxOptions);
                    $.ajax(ajaxOptions).done(updateDOM);
                });

                function updateDOM (json) {
                    $("#json-text").html(JSON.stringify(json));
                }

            });
        </script>
    </head>
    <body>
        <div class="container">
            <div class="row">
                <div id="json-text"class="col-md-12"> </div>
            </div>
            <div class="row">
                <div class="col-md-12">
                    <form>
                        <input id="searchfield" type="text" placeholder="Search">
                        <button type="submit" class="btn btn-default"></button>
                    </form>
                </div>
            </div>
        </div>
    </body>
</html>

Output of console.log(json)

{batchcomplete: "", continue: {…}, query: {…}} VM145 jquery.min.js:4 XHR finished loading: GET "en.wikipedia.org/w/…*". send @ VM145 jquery.min.js:4 ajax @ VM145 jquery.min.js:4 (anonymous) @ wiki.html:49 dispatch @ VM145 jquery.min.js:3 q.handle @ VM145 jquery.min.js:3

Edit Here's the code for the follow-on question. The button on click event would not update the search variable when it was set like so.

 $(document).ready(function () {
                    var search;
                    $("button").on("click", function () {
                        search = $("#searchfield").val();
                     });

A console.log of search inside the button click would show be updated with data from the textbox on button click, but a console.log of the search var outside of the button click event would reveal that, no matter what, the search variable set under document ready would be set to nothing. I tried changing up the names, so as not to confuse things, but (as expected) this did nothing.

Ryan
  • 1,312
  • 3
  • 20
  • 40
  • In updateDOM please call `console.log(json)`, and tell us what is the output? – Black Dec 03 '17 at 15:12
  • @Black What appeared in the console stayed there for maybe a split second. It began with the words "Batch complete." Interestingly, a full JSON file corresponding to my search term, "French," flashed on the DOM. Why nothing wants to stick around long enough for me to read it is, I assume, because it's all hooked-up to the click of the button. – Ryan Dec 03 '17 at 15:30
  • You should check `preseve log` in the browser console. – Black Dec 03 '17 at 15:31
  • Done. I can see the following: {batchcomplete: "", continue: {…}, query: {…}} VM145 jquery.min.js:4 XHR finished loading: GET "https://en.wikipedia.org/w/api.php?action=query&format=json&titles=French&list=search&srsearch=French&srprop=snippet&srlimit=100&origin=*". send @ VM145 jquery.min.js:4 ajax @ VM145 jquery.min.js:4 (anonymous) @ wiki.html:49 dispatch @ VM145 jquery.min.js:3 q.handle @ VM145 jquery.min.js:3 – Ryan Dec 03 '17 at 15:36

1 Answers1

3

Your button is of type submit and when used inside of a form, it will submit the form.

To stop this behavior, use preventDefault method in the click handler of the submit button.

// pass the parameter "e" for the event 
$("button").on("click", function (e) {
    e.preventDefault();

    // rest of the code
    // ...
});

Here's a demo:

$(document).ready(function() {
  // search parameter provided by user started with 
  // var search;

  $("button").on("click", function(e) {
    e.preventDefault();

    // use .val(), .text() did not do the job
    var search = $("#searchfield").val();
    console.log(search);
    // AJAX request options for WikiMedia API
    var ajaxOptions = {
      crossDomain: true,
      dataType: "json",
      url: "https://en.wikipedia.org/w/api.php",
      method: "GET",
      data: {
        action: "query",
        format: "json",
        titles: search,
        list: "search",
        srsearch: search,
        srprop: "snippet",
        srlimit: "100",
        origin: "*"
      }
    };
    console.log(ajaxOptions);
    $.ajax(ajaxOptions).done(updateDOM);
  });

  function updateDOM(json) {
    $("#json-text").html(JSON.stringify(json));
  }

});
.container {
  height: 50vh;
  align-items: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">

  <div class="row">
    <div class="col-md-12">
      <form>
        <input id="searchfield" type="text" placeholder="Search">
        <button type="submit" class="btn btn-default">search</button>
      </form>
    </div>
    <div class="row">
      <div id="json-text" class="col-md-12"> </div>
    </div>
  </div>
</div>
n4m31ess_c0d3r
  • 3,028
  • 5
  • 26
  • 35
  • Genius! Never would have gotten this. Always assumed if you had a text box & button you were creating a form, hence form tags. Obviously, read too many guide books. Any thoughts on why declaring var search above button click and trying to update it with the text gathered from within the button click didn't work? – Ryan Dec 03 '17 at 16:24
  • Sorry, I don't exactly understand your query. From the looks of it, it should work. may be if you can add the code when you were attempting that time – n4m31ess_c0d3r Dec 03 '17 at 19:23
  • Sure, see the edit at the bottom of the question. The rest of the code is the same. The AJAX stuff is irrelevant here. The button click event simply would not pull the text from the text box and update the search variable declared just under document ready (outside of the button click function's scope). Thx! – Ryan Dec 03 '17 at 19:36
  • 1
    I am hoping you know about `scopes` in js, if not follow this link https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript – n4m31ess_c0d3r Dec 03 '17 at 19:50
  • Thought I did, but evidently not. Will give it a good read. Many thanks! – Ryan Dec 03 '17 at 19:52
  • 1
    Another point, if you have `console.log` in `$(document).ready()` , it will execute only once at DOM ready, but you will not have updated the value of `search` till you click the button, hence it will come up `undefined`. Try adding `console.log` inside `updateDOM` method. – n4m31ess_c0d3r Dec 03 '17 at 19:53