0

I have a problem with my search.

Problem 1 Currently if I type in the field it is searching however the search never ever stops, so if I type hello, it will make about 500 requests within a minute.

Problem 2

I am searching in film table to find matching 'title' as well as find business name corresponding to business_id in business table.

Problem 3

Each time request is made it brings back master page again i.e. loading all js and css (which might be why it is making so many requests?) but if I don't extend master, result blade doesn't work.

however even if I input 'e' it brings me back 'guardians of the galaxy' which doesn't have 'e' My thoughts are that it is searching throught business table as well somehow. They have both eloquent one to one relationships

Controller:

public function cinema_search($cinema_value) {
$cinema_text = $cinema_value;
    if ($cinema_text==NULL) {
        $data = Film::all();
    } else {
        $data = Film::where('title', 'LIKE', '%'.$cinema_text.'%')->with('business')->get();
    }
    return view('cinemasearch')->with('results',$data);
}

Form::

<form id="cinema_display">
    <div class="form-group">
        <input type="text" class="form-control" id="search_cinemas" onkeyup="search_cinema(this.value);" placeholder="Search film">
            </div>
        <div id="show"
        </div>
            </div>
    </form>

ajax:

function search_cinema(cinema_value) {
    $.ajax({
        url: '/cinemasearch/' + cinema_value,
        type: 'post',
        dataType: 'html',
        success: function(data) {
            $('#show').append(data);
            $('.se-pre-con').fadeOut('slow', function () {
            $(".container").css({ opacity: 1.0 });
            });
        },
        error: function(data) {

        },
        headers: {
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
        }                 
    });
}

cinemasearch.blade(results):

@extends('master') @section('title', 'Live Oldham') @section('content')
@section('content')
                                    <table style="width:100%">
                                        @if (isset($results) && count($results) > 0)
                                            @foreach( $results as $film )
                                                <tr>
                                                    <td>{{ $film->business->name }}</td>
                                                    <td>{{ $film->title }}</td>
                                                    <td>{{ $film->times}}</td>
                                                </tr>
                                            @endforeach
                                        @endif
                                    </table>
@endsection


function search_data(search_value) {  

$.ajax({

        url: '/searching/' + search_value,

        type: 'post',

        dataType: 'html',

        success: function(data) {

            $('#show_search_result').append(data);

            $('.se-pre-con').fadeOut('slow', function () {

            $(".container").css({ opacity: 1.0 });

            });

        },

        error: function(data) { 

            $('body').html(data); 

        },

        headers: {

        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')

        } 

    });

}

function tram_stops(tram_value) {

    $.ajax({

        url: '/tramsearch/' + tram_value,

        type: 'post',

        dataType: 'html',

        success: function(data) {

            $("#display").html(data);

            var tram_value = tram_value;

        },

        error: function(data) {

            

        },

        headers: {

        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')

        } 

    });

}

/*

setInterval(tram_stops, (30 * 1000));

*/

function search_cinema(cinema_value) {

    $.ajax({

        url: '/cinemasearch/' + cinema_value,

        type: 'post',

        dataType: 'html',

        success: function(data) {

                var items = JSON.parse(data);

                var showElement = $('#show');

                showElement.html('');

                $.each(data, function() {

                   showElement.append(this.title +' '+ this.times+'<br />');

                });

        },

        error: function(data) {


        },

        headers: {

        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')

        } 

    });

}
vimuth
  • 5,064
  • 33
  • 79
  • 116
Przemek
  • 834
  • 6
  • 21
  • 49

2 Answers2

0

You are returning the wrong response type from cinema_search. Ajax expects a JsonResponse, not what the view helper returns which is \Illuminate\Http\Response. Put your search results in:

return response()->json(['results' => $data]);

to start with if you just want the data. If you want to actually return the rendered view file, you would need to do:

return response()->json(['results' => view('cinemasearch')->with('results',$data)->render()]);

then inject that into your DOM. The problem with rendering server side is nothing is bound client side so if you have any interaction requiring JS, you'll need to create those manually in your success callback.

  • second example returns: {"results":"\r\n\r\n\r\n\t\r\n\t\r\n \r\n \r\n \r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n \r\n\t – Przemek Jun 16 '17 at 14:05
  • and first example still returns the same results i.e. 'guardians of the galaxy' when I type 'e' but this time as a json – Przemek Jun 16 '17 at 14:06
  • What does $cinema_value contain immediately after receiving your request with just 'e'? –  Jun 16 '17 at 14:07
  • console.log just before ajax gives me 'e' – Przemek Jun 16 '17 at 14:09
  • No what does $cinema_value contain when it's received in the server immediately at public function cinema_search($cinema_value) { –  Jun 16 '17 at 14:10
  • it is e as well I returned the value and that's what I get – Przemek Jun 16 '17 at 14:14
0

Problem 1: Remove the keyUp event in your html and add an event in Jquery.

Your HTML structure is not correct
This:

<form id="cinema_display">
    <div class="form-group">
        <input type="text" class="form-control" id="search_cinemas" onkeyup="search_cinema(this.value);" placeholder="Search film">
            </div>
        <div id="show"
        </div>
            </div>
    </form>

Should be:

<form id="cinema_display">
    <div class="form-group">
        <input type="text" class="form-control" id="search_cinemas" onkeyup="search_cinema(this.value);" placeholder="Search film">

        <div id="show">
        </div>
    </div>
</form>

Then again you should consider to remove the onkeyup event. And change add it in Jquery to something like this:

Problem 2 & 3: I would recommend a raw Query and return an json instead of a view. And you shouldn't check if($cinema_text === NULL) this won't be the case ever. Unless you put NULL in your url and even then it will be an String and not NULL and if('NULL' === NULL) returns false look at this post for the diff of == and ===.

public function cinema_search($cinema_value) {
$cinema_text = $cinema_value;
    if (empty($cinema_text)) {
        $data = Film::all();
    } else {
        $data = DB::select('*')
          ->from('films')
          ->join('businesses', 'businesses.id', '=', 'films.business_id')
          ->where('films.title', 'LIKE', '%'.$cinema_text.'%')
          ->orWhere('bussiness.title', 'LIKE', '%'.$cinema_text.'%')
          ->get();
    }
    return response()->json(['results' => $data]);
}

Then in your JavaScript do something like this:

$( document ).ready(function() {
  console.log( "ready!" );
  $( "#search_cinemas" ).change(function() {
    search_cinema(this.value);
    console.log( "New value"+this.value+"!" );
  });
  function search_cinema(cinema_value) {
      console.log('setup ajax');
      $.ajax({
          url: '/cinemasearch/' + cinema_value,
          type: 'post',
          success: function(data) {
                console.log('success!');
                var showElement = $('#show');
                showElement.html('');
                $.each(items, function() {
                   showElement.append(this.title +' '+ this.times+'<br />');
                  });
          },
          error: function(data) {
              console.log(data);
          },
          headers: {
          'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
          }                 
      });
  }

});
tprj29
  • 234
  • 1
  • 11
  • how would I output that json response? and should the .change function wrap the ajax or what? if I put this on it's own it doesn't work – Przemek Jun 16 '17 at 15:14
  • You should be fine just calling `search_cinema(this.value)` within the anonymous function. Look at my edits. – tprj29 Jun 16 '17 at 15:24
  • your js is giving me jquery.js:528 Uncaught TypeError: Cannot use 'in' operator to search for 'length',and ochange is not being called – Przemek Jun 16 '17 at 15:26
  • I forgot the `JSON.parse(data)` please try it agian with my new code. Can u be a litle bit more specific on the On change event. Have you tried to JQuery documentation? – tprj29 Jun 16 '17 at 15:33
  • still gives me wrong result, i've put your on change in my js but it doesn't trigger the event – Przemek Jun 16 '17 at 15:35
  • Can you give a snippet of your js code maybe i can make you a fiddle. – tprj29 Jun 16 '17 at 16:46
  • Can you copy paste my js code and give an output of the console. [See here how to use JavaScript Console](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools) – tprj29 Jun 16 '17 at 17:52