2

I have API running locally on http://127.0.0.1:8000/api/node/ . The API have structure like this :

{
"id": ,
"node_id": ,
"latitude": "",
"longitude": "",
"location": ""
}

The id is automatically generated from the system. And I have form look like this http://jsfiddle.net/estri012/2c6bz0ap/5/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <!-- leaflet css -->
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
    crossorigin=""/>
    <!--leaflet js after leaflet css-->
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
    integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
    crossorigin=""></script>
    <title>Fetch JSON from API</title>
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<style>
    html, body {
    min-height: 100%;
    }
    body, div, form, input, select { 
    padding: 0;
    margin: 0;
    outline: none;
    font-family: Roboto, Arial, sans-serif;
    font-size: 14px;
    color: #666;
    line-height: 22px;
    }
    h1, h4 {
    margin: 15px 0 4px;
    font-weight: 400;
    }
    span {
    color: red;
    }
    form {
    width: 100%;
    padding: 20px;
    background: #fff;
    box-shadow: 0 2px 5px #ccc; 
    }
    input {
    width: calc(100% - 10px);
    padding: 5px;
    border: 1px solid #ccc;
    border-radius: 3px;
    vertical-align: middle;
    }
    input:hover, textarea:hover, select:hover {
    outline: none;
    border: 1px solid #095484;
    }
    .name input {
    margin-bottom: 10px;
    }
    option {
    background: #fff;
    }
    select, table {
    width: 100%;
    }
    textarea {
    width: calc(100% - 6px);
    }
    .btn-block {
    margin-top: 20px;
    text-align: center;
    }
    button {
    width: 150px;
    padding: 10px;
    border: none;
    -webkit-border-radius: 5px; 
    -moz-border-radius: 5px; 
    border-radius: 5px; 
    background-color: #095484;
    font-size: 16px;
    color: #fff;
    cursor: pointer;
    }
    button:hover {
    background-color: #0666a3;
    }
    @media (min-width: 568px) {
    .name {
    display: flex;
    justify-content: space-between;
    }
    .name input {
    width: 47%;
    margin-bottom: 0;
    }
    }
  </style>
</head>
<body>
    <form action="/">
        <h1>Add Node</h1>
        <h4>Node ID</h4>
        <div class="name">
          <input type="text" name="name" placeholder="node id" id="node_id" />
        </div>
    <h1>Get the latitude and longitude of the node</h1>

    <p>
        latitude: <span id="latitude"></span><br />
        longitude: <span id="longitude"></span>
    </p>
    <style>
        #node1Map { height: 260px; }
      </style>
      <div id="node1Map"></div>
    <script>
    const mymap = L.map('node1Map').setView([0, 0], 1);
    const attribution ='&copy: <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';

    const tileUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
    const tiles = L.tileLayer(tileUrl, { attribution });
    tiles.addTo(mymap);

     // get coordinate
     var latitude, longitude, marker;
     mymap.on('click', function(e) {
     if(marker) mymap.removeLayer(marker);
     latitude = e.latlng.lat;
     longitude = e.latlng.lng;
     console.log(latitude);
     console.log(longitude);
     marker = L.marker([latitude, longitude]).addTo(mymap);
     document.getElementById('latitude').textContent = latitude;
     document.getElementById('longitude').textContent = longitude;
     });
    </script>

<h4>Location Address</h4>
<input type="text" id="location" />       
<div class="btn-block">
<button type="submit" href="/">Submit</button>
</div>
</form>
</body>
</html>

So, the user must fill the node id and location. For the latitude and longitude, the user can get the value from clicking marker on the map. The problem is how to save the data for node id, latitude, longitude, and location with click the submit button to the API? Anybody can help me? I don't know how to to do it.

Edit : I know there is something like this :

const data = {node_id, latitude, longitude, location};
const options = {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
};
fetch('http://127.0.0.1:8000/api/node/', options);

But I don't know how and where to put it. And I think there is something wrong with my html code too. Can someone help me to fix it?

2
  • you could user jQuery for that: api.jquery.com/jQuery.post/… Commented May 13, 2020 at 9:10
  • @Argee I have tried it but I confused Commented May 13, 2020 at 9:37

1 Answer 1

2

Instead of using simple paragraphs <p>, the trick is to include lat/lon values as a part of your form, using <input> tag and name attribute :

<div class="geo-lat">
   <label for="lat_id">Latitude* :</label>
   <input type="text" name="lat" placeholder="Latitude °" id="lat_id" />
</div>
<div class="geo-lon">
   <label for="lon_id">Longitude* :</label>
   <input type="text" name="lon" placeholder="Longitude°" id="lon_id" />
</div>

Now, when you want to retrieve values from the map with click action, set the lat/lon values directly for inputs:

<script> 
    map.on('click', function(e) {
        const latitude = e.latlng.lat;
        const longitude = e.latlng.lng;
        document.getElementById('lat_id').value = latitude;
        document.getElementById('lon_id').value = longitude;
    });
</script>

Also, it's better to define what type of method you want to use for your form. see <form> MDN reference

  1. GET form method

Submit button will send GET http request (and reload your page) to the path defined in action attribute :

http://<server-name>/<action>?node=nodeid&lat=41&lon=2&location=
  1. POST form method

Submit button will send POST http request (and reload your page) to the path defined in action attribute, with following content:

node=nodeid&lat=41&lon=2&location=
  1. ** CUSTOM form submit **

First, as an example, you can add an id to your form :

<form id="form_id" method="POST" action="/<your-endpoint>"

If you want a different behavior, like sending request without refresh page or reformat your data, you can use an event listener on submit button as:

<script>
document.getElementById('form_id').addEventListener("submit", function(evt) {
    evt.preventDefault();
    // Do personal action you want on submit form
}, true);
>/script>

If you want to use jQuery and want to perform manually things:

$( "#form_id" ).submit(function( event ) {
  // prevent form refresh and other default form behaviors
  event.preventDefault();

  // Retrieve the form values
  var $form = $( this ),
  node = $form.find( "input[name='node']" ).val(),
  lat = $form.find( "input[name='lat']" ).val(),
  lon = $form.find( "input[name='lon']" ).val(),
  location = $form.find( "input[name='location']" ).val(),
  url = $form.attr( "action" );

  // You could validate data (be careful to validate server side also, more important) or do whatever you like with your data
// if (location.isNotInEurope()) return;


  // Send the raw or fomatted data with post request
  $.post(url, { 
    node: node,
    lat: lat,
    lon: lon,
    location: location
  });
});

TLDR - Summary

Based on your fiddle, here is the corrected one : http://jsfiddle.net/rcu0491b/

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

6 Comments

I use the <form id="form_id" method="POST" action="/<your-endpoint>". And it is work, the data can be saved. But after I click the submit button, the page redirecting into my endpoint URL. How to make the page stay, not redirecting to other URL?
Sorry I made a mistake, I used a wrong id for jQuery selector to reference the form. Use #form_id instead of #searchForm. So apply the last JavaScript block code I gave you : $( "#form_id" ).submit(function......
I use the <form id="form_id" method="POST" action="/<mydjangorestapi-endpoint>". After I click submit button the page redirecting to my django rest api endpoint. How to make the page not redirecting to my endpoint but still can save my data? I want my page to redirecting to another page instead my django rest API page
Did you try the 3. CUSTOM code snippet of my answer ? The idea is to prevent from submit to redirect to your action path, using event.preventDefault. Then, do whatever you want to do. If you want to redirect to another url (let say /custom-view), add js like window.location = '/custom-view'
I tried it. But if I do something like that, the data won't save in my API
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.