Here are details for my checkin function. I present it here as it flows 
through the logic.

I have a model for checkin
   
    create_table :checkins do |t|
      t.integer :user_id
      t.float :latitude
      t.float :longitude
    end


In my header, I have a prominent checkin/checkout button. 

     <% @voterinfo = Voterinfo.find_by_user_id(current_user.id) %>
          <ul class="nav pull-left">
            <div id="<%=current_user.id %>">
              <% if (@voterinfo.checkin == 1) %>
                  <%= render 'users/checkout' %>
              <% else %>
                  <%= render 'users/checkin' %>
              <% end %>
            </div>
          </ul>

voterinfo is a model that belongs to user where I put lots of temporary 
states for the user. I toggle between voterinfo.checkin == 0 and == 1 for 
checked-out and checked-in status.

_checkin.html.erb

    <% @checkin = Checkin.new %>
    <%= form_for(@checkin) do |f| %>
        <%= f.submit "Check In", class: "btn btn-primary" %>
    <% end %>

In checkins_controller-

     def  create
        render 'users/checkin_form'
     end

_checkin_form.html.erb

    <section id="wrapper">

  <script type="text/javascript" 
src="http://maps.google.com/maps/api/js?sensor=false";></script>
  <article>
    <p>Finding your location: <span id="status">checking...</span></p>
  </article>
  <script>
      function success(position) {
          var s = document.querySelector('#status');

          if (s.className == 'success') {
              return;
          }

          s.innerHTML = "found you!";
          s.className = 'success';

          var mapcanvas = document.createElement('div');
          mapcanvas.id = 'mapcanvas';
          mapcanvas.style.height = '400px';
          mapcanvas.style.width = '560px';

          document.querySelector('article').appendChild(mapcanvas);

          var latlng = new google.maps.LatLng(position.coords.latitude, 
position.coords.longitude);
          var myOptions = {
              zoom: 15,
              center: latlng,
              mapTypeControl: false,
              navigationControlOptions: {style: 
google.maps.NavigationControlStyle.SMALL},
              mapTypeId: google.maps.MapTypeId.ROADMAP
          };
          var map = new 
google.maps.Map(document.getElementById("mapcanvas"), myOptions);

          var marker = new google.maps.Marker({
              position: latlng,
              map: map,
              title:"You are here! (at least within a 
"+position.coords.accuracy+" meter radius)"
          });

          var cookie_val = position.coords.latitude + "|" + 
position.coords.longitude;
          document.cookie = "lat_lng=" + (cookie_val);
      }

      function error(msg) {
          var s = document.querySelector('#status');
          s.innerHTML = typeof msg == 'string' ? msg : "failed";
          s.className = 'fail';

          // console.log(arguments);
      }

      if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(success, error);
      } else {
          error('not supported');
      }

  </script>

  <br></br>

  <%= link_to "Click here AFTER the map displays to finish your Check-In", 
update_checkin_path %>

</section>

Notice that the delay in the navigator.geolocation function does not cause 
the Rails server to wait (neat). The entire function is pure HTML except 
for the last line, which is executed immediately. This is also the "not 
ideal" part (ideally the link would appear after execution, but how to do 
it? and without hanging up the server?), but the wording should do the job. 
If the user clicks anything anyway, no harm done. The checkin status has 
not yet changed, and neither did the location coordinates in the database. 
The location coordinates are put in a cookie. Next, after clicking the 
bottom link to the checkins controller-

def show
    @user = current_user
    @voterinfo = Voterinfo.find_by_user_id(@user.id)
    @voterinfo.checkin = 1
    @voterinfo.save
    lat = cookies[:lat_lng].split("|").first
    lng = cookies[:lat_lng].split("|").second
    @user.update_attributes(:longitude => lng, :latitude => lat)
    @user.save(validate: false)
    sign_in(@user)
    redirect_to root_url
  end

And voila!  Only now does the button in the header change as the status has 
changed.  Finally, to check out, 

   <%= form_tag '/checkins/checkout/' do %>
       <%= submit_tag "CHECK-OUT!", :class => "btn btn-primary" %>
  <% end %>
 
goes to checkins controller- 

  def checkout
    user = current_user
    @voterinfo = Voterinfo.find_by_user_id(user.id)
    @voterinfo.checkin = 0
    @voterinfo.save
    user.latitude = user.latitude_home
    user.longitude = user.longitude_home
    user.save(validate: false)
    sign_in(user)
    redirect_to root_url
  end

The coordinates are replaced with the stored home coordinates, the status 
changes and so will the button in the header.

Thank you for your help and encouragement. The core checkin_form is 
familiar public code; I just added the cookie stuff. 
 







On Friday, February 28, 2014 11:47:44 AM UTC-8, Ephraim Feig wrote:
>
> 0 down vote 
> favorite<http://stackoverflow.com/questions/22102460/page-does-not-update-after-navigator-geolocation-call-in-rails-check-in-check#>
>  
>   
> I am using standard HTML5 location services. A user comes into a cafe, 
> opens the app, clicks on "Check-in!" and the app gets the location and uses 
> it until the user later clicks "Check-out!". 
>
> In my viewer, I call on a script containing navigator.geolocation and it 
> does its job. I successfully pass the latitude and longitude parameters to 
> my controller and it updates everything. But when all is done and I 
> redirect_to root_url, the new page does not refresh (I know at some point I 
> should do it more elegantly and just update the link part, but for now, I 
> just want to get this going and understand what is going on). Here is my 
> code:
>
> In my viewer-
>
>  <% if (@voterinfo.checkin == 0) %>
>               <li>
>                 <h4>    <%= link_to "-->Check-In!", "#", :id => 'findMe' %>   
>    </h4>
>                 <script>
>                   $(function(){
>                      $("a#findMe").click(function(){
>                          if (navigator.geolocation) {
>                              
> navigator.geolocation.getCurrentPosition(function (position) {
>                                  $.post('/users/set_geolocation/', {latitude: 
> position.coords.latitude,
>                                              longitude: 
> position.coords.longitude,
>                                              dataType: 'float'});
>                              }, function () {
>                                  alert('We couldn\'t find your position.');
>                              });
>                          } else {
>                              alert('Your browser doesn\'t support 
> geolocation.');
>                          }
>                       });
>                   })
>                 </script>
>                </li>
>           <% else %>
>               <li> <h4><%= link_to "--->CHECK-OUT!", :controller => :users,
>                                    :method => :set_geolocation %></h4></li>
>           <% end %>
>         </ul>
>   <% end %>
>
> And here is the relevant part of my users_controller-
>
>  def set_geolocation
>   @user = current_user
>   @voterinfo = Voterinfo.find_by_user_id(@user.id)
>   if (@voterinfo.checkin == 0)
>     @user.update_attributes(:longitude => params['longitude'], :latitude => 
> params[:latitude])
>     @user.save(validate: false)
>     sign_in(@user)
>     @voterinfo.checkin = 1
>     @voterinfo.save
>     redirect_to root_url
>   else
>    @voterinfo.checkin = 0
>    @voterinfo.save
>    redirect_to root_url
>   end
>
> end
>
> Thank you for any help here.
>
>
>

-- 
-- 
SD Ruby mailing list
[email protected]
http://groups.google.com/group/sdruby
--- 
You received this message because you are subscribed to the Google Groups "SD 
Ruby" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to