1

On page load my code compares user position against coordinates of each tram stop and chooses the closest one which works absolutely fine.

The problem is with onchange=tram_stops(this.value) as when I change the value I am getting an error:

SCRIPT438: SCRIPT438: Object doesn't support property or method 'tram_stops'

Does anyone know how to sort this out?

@extends('master') @section('title', 'Trams')
@section('extrafiles')
    <script type="text/javascript" src="{{ asset('js/tram.js') }}"></script>
@endsection
@section('content')
<section class="container">
  <div class="row">
    <div class="col-xs-12">
      <h1>Metrolink Times</h1>
    </div>
  </div>
  <div class="row">
    <div class="col-xs-12">
      <div class="form-group">
        <label for="tram_stops">Select a station:</label>
        <form id="tram_stops">
          <select id="tram_dropdown" class="form-control" onchange="tram_stops(this.value);">
            @foreach($entities as $entity)
              <option data-lng="{{ $entity->_geoloc->lng }}" data-lat="{{ $entity->_geoloc->lat }}"  value="{{empty($entity->_geoloc->slug) ? 'no-slug' : $entity->_geoloc->slug}}">{{$entity->name}}</option>
            @endforeach
          </select>
        </form>
      </div>
    </div>
    <div id="display">
    </div>
  </div>
</section>
@endsection
$(document).ready(function() {
  var user_lat;
  var user_lng;
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition);
  } else {
    alert("Geolocation is not supported by this browser.");
  }

  function showPosition(position) {
    var distanceArray = [];
    var slugArray = [];
    user_lat = position.coords.latitude;
    user_lng = position.coords.longitude;
    $("option").each(function() {
      var unit = "K";
      var tram_lat = $(this).attr("data-lat");
      var tram_lng = $(this).attr("data-lng");
      var slug = $(this).attr("value");
      var radlat1 = Math.PI * tram_lat / 180
      var radlat2 = Math.PI * user_lat / 180
      var theta = tram_lng - user_lng;
      var radtheta = Math.PI * theta / 180
      var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
      dist = Math.acos(dist)
      dist = dist * 180 / Math.PI
      dist = dist * 60 * 1.1515
      if (unit == "K") {
        dist = dist * 1.609344
      }
      if (unit == "N") {
        dist = dist * 0.8684
      }
      slugArray.push(slug);
      distanceArray.push(dist);
    });
    var closest = Math.min(...distanceArray);
    var index = (distanceArray.indexOf(closest));
    var slug = (slugArray[index]);
    if (sessionStorage.getItem("item") === null) {
      sessionStorage.setItem("item", slug);
      timeout();
    } else {
      timeout();
    }
  }
});

function timeout() {
  setTimeout(function() {
    var tram_val = sessionStorage.getItem("item");
    tram_stops(tram_val);
    $("#tram_dropdown").val(tram_val);
  }, 30000);
}

function tram_stops(tram_value) {
  sessionStorage.setItem("item", 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')
    }
  });
  timeout();
}
1
  • This is not plain HTML Commented Aug 25, 2017 at 9:52

3 Answers 3

1

Instead of adding an onchange="" attribute, you would be better off listening for an event. Here is an example of how to do it:

$("body").on("change", "#tram_dropdown", function(){
    sessionStorage.setItem("item", 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')
        }
    });
    timeout();
});

Hope this helps!

Sign up to request clarification or add additional context in comments.

2 Comments

this way, doesn't actually trigget the function
how no? On each change of your <select> tag this will be executed. Check your code for errors. but the event should be fired.
1

Reason

This happens if you have a function in javascript of the same name as any HTML element id. In your case, tram_stops is, you have form id and a function of this name.

 <form id="tram_stops">

Solution

Change form id or change the function name or attach onchange event dynamically using jQuery:

$("body").on("change", "#tram_dropdown", function(){/*Your Code*/});

3 Comments

that was the case, weird that it was working before, now I get: 'tram_stops' is not defined
You could try binding the event through code instead of inline, as N. Ivanov suggested if you still have issues after fixing the naming collision.
That seems not to trigget the function when I attach onchange event dynamically
-1

Change onchange function to:

 onchange="tram_stops();"

Then get the value using jquery like this:

var tram_value = $('#tram_dropdown').val();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.