This is the 14th day of my participation in the August Text Challenge.More challenges in August

Today is my little brother (wechat small program) in the work encountered a scene — choose a location around the school, feel very useful, let him share with you.

This time, I would like to share with you the method of selecting a school and address in the country in wechat mini program. After investigation, I found that most websites provide the name of the school in the country is some old schools, such as relatively new or remote schools in the local area generally can not be found. Considering that this is definitely not possible, I continued to look for a more comprehensive way. Finally, I came to the idea that the service provided by the map provides the most comprehensive school. Here, Tencent Map’s open interface is used as an example for demonstration.

1. Prepare

By reading the map of tencent open platform that WeChat small program can download the SDK provides direct call interface to use tencent maps, of course also can oneself to encapsulate the URL request and return to their data, should be used in this example, because the SDK package called when certain interfaces, and more time in the sample the same interface, This would cause the error of frequently calling the interface.

In the process, I will also use the vant of the good team to display the information of the school, so I need to install it in advance and rely on it for backup. Please refer to the official website for specific installation steps

2. The actual combat

2.1 Configuring The Applet Permission

The first is to let the user open the positioning permission for our small program when entering the applet. We need to add the following code in the app.json file:

"permission": {
  "scope.userLocation": {
    "desc": "Your location information will be used to display the effects of the applet location interface."}}Copy the code

Add this field, when the small program used to locate the system, it is found that the permission of the small program is not given to the user will give the permission to the small program, the effect is as follows:

2.2 Encapsulating tool functions

2.2.1 Global functions and variables

app.js

// Global variables
globalData: {
    userInfo: null
  },
// Global import method, easy to import third-party packages
require: ($url) = > require($url)
Copy the code

2.2.2 Tool functions

util.js

// Introduce SDK core classes
const QQMapWX = require('./qqmap-wx-jssdk.min.js');
// Instantiate the API core class
let key = ' ';
let qqmapsdk;
key &&(qqmapsdk = new QQMapWX({
  key / / required
}));
module.exports = {
  qqmapsdk,
  key
}
Copy the code

Here we introduce the SDK and directly transmit the instantiated object, but we need to open the interface secret key for Tencent’s map. Here we do not provide my key, but transmit the key because we need to use it later. In order not to expose our own key, the key is generally stored in the backend config during development. I’m going to do it on the front end for the sake of demonstration.

2.3 Processing before skipping site selection page

Mobile phone positioning not only requires wechat permission to open, and our mobile phone also has a positioning system permission to open, so before the formal positioning, in order to better experience our function we usually need a series of operations, here I simply use button as a jump.

wxml

<view>
	<van-btn bind:tap="gotoMap" type="info">Access map</van-btn>
</view>
Copy the code

First we need to add a click event to the button, so we can do a lot of things here; Let’s take a look at the JS code.

// Import the required utility functions
const app = getApp();
const {qqmapsdk} = app.require('utils/util');
Page({
  /** * map start position */
  // Click the button to jump to the map page
   gotoMap(){
     wx.showLoading({
       title: "Jumping to map page"
     })
    // There are a few things to do before jumping to improve user experience
    // 1. Verify that the user has enabled location, if not, boot
    // 2. Verify the location permission of the program, if not, then boot
    // 3. Do the above two points to start the jump
    wx.getLocation({
      success(res){
        wx.navigateTo({
          url: "/pages/map/index"})},fail(e){
        if (e && (e.errCode == 2 || e.errCode == 404)) {
          wx.showModal({
            title: "Tip".content: 'Failed to obtain location information. Please check whether the location information of mobile phone is disabled.'.showCancel: false})}else if (e && ((e.errMsg.indexOf('getLocation:fail auth deny') != -1) || (e.errMsg.indexOf('system permission denied') != -1))) {
          showModal({
            title: "Tip".content: 'Failed to obtain location information, please check whether wechat has location permission'.confirmText: "Recapture".success(res){
              if(res.confirm === true){
                detectSettings()
              } else if(res.cancel == true) {return; }}})}else if(e.errMsg.indexOf("Often")! = = -1){
          wx.showModal({
            title: "Tip".content: "The location information interface is called too frequently. Please wait 10-30 seconds.".showCancel: false})}},complete(){
        wx.hideLoading()
      }
    })
    // Enable the wechat location permission
    function detectSettings(){
      wx.getSetting({
        success(res){
          if(res && (res.authSetting["scope.userLocation"]! = =undefined && res.authSetting["scope.userLocation"]! = =true)){
            wx.showModal({
              title: "Tip".content:"The small program does not have the location permission, please go to set the location permission of wechat small program.".confirmText: "Go to Settings".success(res){
                if(res.cancel == true) {return
                } else if (res.confirm === true){
                  wx.openSetting({
                    success(result){
                      if(result && (result.authSetting["scope.userLocation"]! = =undefined && result.authSetting["scope.userLocation"= = =true)){
                        wx.navigateTo({
                          url: "/pages/map/index"})}else {
                        wx.navigateTo({
                          url: "/pages/index/index"},},},},fail(){
                wx.navigateTo({
                  url: "/pages/index/index"})}})}else {
            wx.navigateTo({
              url: "/pages/map/index"})}},complete(){
          wx.hideLoading()
        }
      })
    }
   }
})
Copy the code

See the code to see the effect, we emphasize that there is no jump conditions, as shown in the GIF:

The GIF above does not do the processing of the mobile phone positioning system is not open, this demonstration in this aspect of the processing is relatively simple, just a hint is gone, daily development generally have other better processing methods, not open effect is as follows:

2.4 Handling after A Jump

2.4.1 Page Initialization

After the processing in the previous step, we have confirmed that the two permissions of the mobile phone have been given, so we start to process the map site selection page. Before we start, let’s see what the finished product looks like, as follows:

wxml

<! --pages/map/index.wxml-->
<view class="fixed top">
  <van-search bind:search="searchSchool" placeholder="Please enter school name" model:value="{{schoolName}}" />
  <view class="school-nav">
    <text class="left">Nearby schools</text>
    <view class="right" bind:tap="changeCity">
      <van-icon name="location-o" />
      <text>{{city | | "Beijing"}}</text>
    </view>
  </view>
</view>
<view class="addr-cell" bindtap="subData">
  <block wx:for="{{options}}" wx:key="index">
    <van-cell data-chooseOpt="{{item}}" title-width="70vw" title="{{item.title}}" value="" label="{{item.address}}" />
  </block>
  <view id="txt" class="btm">
    <text wx:if="{{options.length}}">{{count>0 ? "Drop down refresh for more information" : "Already bottom "}}</text>
    <text class="no-data" wx:else>No relevant data have been obtained...</text>
  </view>
</view>	
Copy the code

The overall framework is what WXML looks like above, or what it would look like if all the data were supplied. Then go on to explain his logical implementation!

// Import the required utility functions
const app = getApp();
const {qqmapsdk,key} = app.require('utils/util');
// Initialize the lifecycle function
onLoad: function (options) {
  _this = this;
  _this.init()
},
Copy the code

The following functions are used not only at load time, but also later, and I use the parameters passed in to distinguish them. If it is called at load time, it simply retrieves the user’s current location for display. If an address is passed in, it will be used for address inverse resolution.

// You resolve the address and get the current location
init(location){
  let query = {
    success(res){
      console.log(res)
      if(res.status === 0) {
        // console.log(res.result.location)
        app.globalData.adInfo = res.result.ad_info;
        _this.setData({
          city: res.result.ad_info.city,
          lat: res.result.location.lat,
          lng: res.result.location.lng,
        })
        _this.qqSearch();
      } else {
        wx.showModal({
          title: 'tip'.content:res.message || "Failed to obtain geo-location information.".showCancel: false})}},fail(e){
      console.log(e)
    }
  }
  location && (query.location = location);
  qqmapsdk.reverseGeocoder(query);
}
Copy the code

2.4.2 Search Function Implementation

// If you enter a city, only the city will be displayed, not the school
searchSchool(e){
  // No input or enter a space
  if(e && (! e.detail || e.detail.trim() ===' ')){
    wx.showToast({
      title: "Please enter a valid school name".icon: 'none'.duration: 2000
    })
    return
  }
  _this.setData({
    options: [].count: -2
  })
  _this.qqSearch(e.detail);
},
qqSearch(name){
  // The school name entered in the input box
  wx.showLoading({
    title: "Getting information."
  })
  const mks = [];
  let count,
      boundary= `nearby(${_this.data.lat}.${_this.data.lng}`, 1000);
  search(name)
  function search(name){
    const opts = {
      keyword: 'university'.// Search for keywords
      page_size: 15.page_index: _this.data.pageIndex, // Get more
      key: key,
      boundary
    };
    if(name){
      opts.boundary = `region(${_this.data.city}) `
      opts.keyword = name
    }
    // To avoid errors caused by frequently calling the interface, only URL can be used to obtain relevant information
    wx.request({
      url: "https://apis.map.qq.com/ws/place/v1/search".method: "get".data: {... opts },success: function (res) { // Callback after successful search
        console.log(res)
        if(res.statusCode ! = =200|| (res.data && res.data.status ! = =0)) return;
        // Initialization and other states
        // The calculation can slide down several times to get more
        if(_this.data.count === -1 || _this.data.count === -2){
          count = res.data.count && Math.floor(res.data.count/10);
        }else {
          count = --_this.data.count;
        }
        for (let i = 0; i < res.data.data.length; i++) {
          mks.push({ // Get the result and place it in the MKS array
            title: res.data.data[i].title,
            address: res.data.data[i].address,
          })
        }
      },
      fail: function (e) {
        console.log(e)
        wx.showToast({
          title: JSON.stringify(e) || "Failed to obtain map information".icon: "none".duration: 3000})},complete: function (){
        setTimeout(() = >{ wx.hideLoading() mks.push(... _this.data.options); _this.setData({// Sets the markers attribute to display the search results on the map
            options: mks,
            count
          })
        },1000)}}); }},Copy the code

2.4.3 Slide to the bottom to get more

// Slide down to the bottom of the lifecycle function
onReachBottom: function () {
  _this.data.pageIndex = ++_this.data.pageIndex;
  _this.data.count && _this.qqSearch();
},
Copy the code

2.4.4 Submitting Data

For submitted data here is not much to do, the choice of a reminder, in the actual development of the general need to save the data in the database for another purpose.

subData(e){
  const data = e.target.dataset.chooseopt;
  // Handle the case of clicking the prompt text
  if(! data)return;
  wx.showModal({
    title: "Tip".content: 'Your school is [${data.title}】吗?`.success(res){
      / / cancel
      if(res.cancel) {
        return;
      } else if (res.confirm){
        / / sure
        // Add or modify the request to the back end, usually need detailed address, here simple processing
        wx.showToast({
          title: data.title,
          icon: "none"})}},fail(){
      wx.showToast({
        title: "Failure".icon: "error"})}})}Copy the code

2.4.5 Switching cities

changeCity(){
  _this.setData({
    options: [].count: -2.// Easy two-way data binding, empty the contents of the input field upon entering
    schoolName: ' '
  })
  wx.chooseLocation({
    latitude:_this.data.lat,
    longitude:_this.data.lng,
    success(res){
      if(res.errMsg === "chooseLocation:ok") {// Get the selected location, the latitude and longitude will be resolved through the address inverse resolution
        _this.init(`${res.latitude}.${res.longitude}`); }},// Press the cancel button
    fail(e){
      if(e.errMsg === "chooseLocation:fail cancel"){ _this.init(); }},complete(){}})}Copy the code

At this point, the micro channel small program school choice is all completed, the actual combat step by step slowly realize down the logic is not complex.

1. If you think this article is good, share and like it so that more people can see it

2. Welcome to pay attention to the front end line and surface of the public account