美文网首页
城市选择器组件

城市选择器组件

作者: 逸笛 | 来源:发表于2020-09-03 11:33 被阅读0次
图片.png

调用

import CityChoose from "../../../components/CityChoose/index";

   <CityChoose
          className="city-choose-box"
          isOpened={this.state.cityRequireOpen}
          getUserSub={false}
          limit={3}
          onClose={this.handleCityRequireClose.bind(this)}
        ></CityChoose>
import Taro, { Component } from "@tarojs/taro";
import { View, Button, ScrollView } from "@tarojs/components";
import { AtSearchBar } from "taro-ui";
import classNames from "classnames";
import api from "../../utils/network/request";
import user from "../../utils/auth/user";
import "./index.less";

export default class Index extends Component {
  state = {
    searchName: "",
    current: [],
    currentName: [],
    currentLength: 0,
    cityData: [],
    hotCityData: [],
    searchCityData: [],
    scrollTop: 0,
    nowScrollTop: 0
  };

  componentWillMount() {
    this.getData();
  }

  componentDidMount() {}

  componentWillUnmount() {}

  getData() {
    const that = this;
    api.request({
      url: this.props.getUserSub
        ? "/bo/subCitysByFirstLetter"
        : "/public/citysByFirstLetter",
      data: {
        access_token: user.getToken()
      },
      success: function(res) {
        that.setState({ cityData: res.data.result });
      },
      error: function(error) {}
    });

    if (!this.props.getUserSub) {
      api.request({
        url: "/public/hotCitys",
        data: {
          access_token: user.getToken()
        },
        success: function(res) {
          that.setState({ hotCityData: res.data.result });
        },
        error: function(error) {}
      });
    }
  }

  handleSearchChange(value) {
    this.setState({
      searchName: value
    });
  }

  handleSearch() {
    const searchName = this.state.searchName;
    if (searchName === "") {
      return false;
    }
    this.setState({
      scrollTop: 0
    });
    api.request({
      url: "/public/citys",
      data: {
        name: searchName
      },
      success: res => {
        const result = res.data.result;
        if (result.length === 0) {
          Taro.showToast({
            title: "没有搜索到该城市,换个名字搜一下吧",
            icon: "none",
            duration: 1500
          });
        } else {
          this.setState({ searchCityData: result, scrollTop: -200 });
        }
      },
      error: function(error) {}
    });
  }
  onScroll(e) {
    this.setState({
      nowScrollTop: e.detail.scrollTop
    });
  }

  gotoAnchor(indexes) {
    const that = this;
    Taro.createSelectorQuery()
      .in(this.$scope)
      .select(`#${indexes}`)
      .boundingClientRect(rect => {
        that.setState({
          scrollTop: that.state.nowScrollTop + rect.top - 200
        });
      })
      .exec();
  }

  handleChooseCity(id, name) {
    let current = this.state.current;
    let currentName = this.state.currentName;

    const index = current.indexOf(id);
    if (index === -1) {
      if (this.props.limit == 1) {
        current = [id];
        currentName = [name];
      } else {
        if (this.props.limit == current.length) {
          Taro.showToast({
            title: `最多选择${this.props.limit}项`,
            icon: "none"
          });
          return;
        }
        current.push(id);
        currentName.push(name);
      }
    } else {
      current.splice(index, 1);
      currentName.splice(index, 1);
    }
    this.setState({
      current: current,
      currentName: currentName,
      currentLength: current.length
    });
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.cityrefresh) {
      this.setState({
        current: [],
        currentName: [],
        currentLength: 0
      });
    }
  }
  handleClose(e, status) {
    const data = [];
    const current = this.state.current;
    const currentName = this.state.currentName;

    for (const i in current) {
      data.push({
        id: current[i],
        name: currentName[i],
        cityrefresh: status == 1 ? false : true
      });
    }

    this.props.onClose(data);
  }
  render() {
    const { isOpened, getUserSub } = this.props;
    const {
      current,
      currentLength,
      searchCityData,
      hotCityData,
      cityData,
      scrollTop
    } = this.state;
    const character = [
      "A",
      "B",
      "C",
      "D",
      "E",
      "F",
      "G",
      "H",
      "J",
      "K",
      "L",
      "M",
      "N",
      "P",
      "Q",
      "R",
      "S",
      "T",
      "W",
      "X",
      "Y",
      "Z"
    ];

    const cName = classNames("city-modal", {
      "city-modal--active": isOpened
    });

    return (
      <View className={cName}>
        <View
          className="city-modal__overlay"
          onClick={this.handleClose.bind(this)}
        ></View>
        <View className="city-modal__container">
          <View className="city_change">
            {!getUserSub && (
              <AtSearchBar
                showActionButton
                value={this.state.searchName}
                onChange={this.handleSearchChange.bind(this)}
                onActionClick={this.handleSearch.bind(this)}
              />
            )}
            <ScrollView
              className="city_bottom"
              scrollY
              scrollWithAnimation
              scrollTop={scrollTop}
              onScroll={this.onScroll}
            >
              {!getUserSub && (
                <View>
                  {searchCityData.length > 0 && (
                    <View className="place_city">
                      <View className="place_city_head">
                        <View className="location">搜索记录</View>
                      </View>
                      <View className="at-row at-row--wrap place_city_bottom">
                        {searchCityData.map((item, index) => {
                          const searchBoxClass = classNames(
                            "at-col",
                            "at-col-4",
                            {
                              potch_city: current.includes(item.id),
                              city: !current.includes(item.id)
                            }
                          );

                          return (
                            <View
                              key={item.id}
                              className={searchBoxClass}
                              onClick={this.handleChooseCity.bind(
                                this,
                                item.id,
                                item.name
                              )}
                            >
                              {item.name}
                            </View>
                          );
                        })}
                      </View>
                    </View>
                  )}

                  {/* <View className='place_city'>
                                        <View className='place_city_head'>
                                            <View className='location'>定位城市</View>
                                            <View>
                                                <Image src={positioning} className="picter" />
                                                <Text className='new_place'>重新定位</Text>
                                            </View>
                                        </View>
                                        <View className='at-row at-row--wrap place_city_bottom'>
                                        {current.indexOf(2) === -1 ?
                                                <View className='at-col at-col-4 city' onClick={this.choose_city.bind(this, 2)}>长沙长沙长沙</View>
                                                :
                                                <View className='at-col at-col-4 potch_city' onClick={this.choose_city.bind(this, 2)}>长沙长沙长沙</View>
                                            }
                                        </View>
                                    </View> */}
                  <View className="place_city">
                    <View className="place_city_head">
                      <View className="location">热门城市</View>
                    </View>
                    <View className="at-row at-row--wrap place_city_bottom">
                      {hotCityData.map((item, index) => {
                        const searchBoxClass = classNames(
                          "at-col",
                          "at-col-4",
                          {
                            potch_city: current.includes(item.id),
                            city: !current.includes(item.id)
                          }
                        );

                        return (
                          <View
                            key={item.id}
                            className={searchBoxClass}
                            onClick={this.handleChooseCity.bind(
                              this,
                              item.id,
                              item.name
                            )}
                          >
                            {item.name}
                          </View>
                        );
                      })}
                    </View>
                  </View>
                </View>
              )}

              <View className="place_city">
                <View className="place_city_head">
                  <View className="location">字母索引</View>
                </View>
                <View className="at-row at-row--wrap place_city_bottom">
                  {character.map((item, index) => {
                    return (
                      <View
                        key={item}
                        className="at-col at-col-1 citys"
                        onClick={this.gotoAnchor.bind(this, item)}
                      >
                        {item}
                      </View>
                    );
                  })}
                </View>
              </View>

              <View>
                {cityData.map(letterItem => {
                  return (
                    <View className="place_city" key={letterItem.key}>
                      <View className="place_city_head">
                        <View className="location" id={letterItem.key}>
                          {letterItem.title}
                        </View>
                      </View>
                      <View className="at-row at-row--wrap place_city_bottom">
                        {letterItem.items.map(item => {
                          const searchBoxClass = classNames(
                            "at-col",
                            "at-col-4",
                            {
                              potch_city: current.includes(item.id),
                              city: !current.includes(item.id)
                            }
                          );

                          return (
                            <View
                              key={item.id}
                              className={searchBoxClass}
                              onClick={this.handleChooseCity.bind(
                                this,
                                item.id,
                                item.name
                              )}
                            >
                              {item.name}
                            </View>
                          );
                        })}
                      </View>
                    </View>
                  );
                })}
              </View>
            </ScrollView>
            <View>
              {currentLength === 0 ? (
                <Button
                  className="no_choose"
                  onClick={this.handleClose.bind(this)}
                >
                  取消
                </Button>
              ) : (
                <Button
                  className="choose"
                  onClick={this.handleClose.bind(this, 1)}
                >
                  确定(已选:{currentLength})
                </Button>
              )}
            </View>
          </View>
        </View>
      </View>
    );
  }
}

.city-modal {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  visibility: hidden;
  -webkit-transition: visibility 200ms ease-in;
  -o-transition: visibility 200ms ease-in;
  transition: visibility 200ms ease-in;
  z-index: 99999;

  .city-modal__overlay {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    position: absolute;
    background-color: rgba(0, 0, 0, 0.3);
    // z-index: 2000;
    opacity: 0;
    display: none;
  }

  .city-modal__container {
    height: 85vh;
    width: 98vw;
    position: absolute;
    left: 1vw;
    bottom: 0;
    -webkit-transform: unset;
    -ms-transform: unset;
    transform: unset;
    border-radius: 12px;
    background-color: #fff;
    overflow: hidden;
    -webkit-transition: opacity 200ms ease-in;
    -o-transition: opacity 200ms ease-in;
    transition: opacity 200ms ease-in;
    z-index: 999;
    opacity: 0;
    display: none;

    .city_change {
      // height: 5000px;
      .city_bottom {
        margin-bottom: 20px;
        overflow: scroll;
        position: relative;
        height: 71vh;

        .place_city {
          padding: 0 25px;
          margin-top: 10px;

          :after {
            content: "";
            width: 215px;
          }

          .place_city_head {
            display: flex;

            .location {
              font-size: 30px;
              color: #333333;
              font-weight: bold;
              flex: 1;
            }

            .picter {
              width: 26px;
              height: 36px;
            }

            .new_place {
              font-size: 30px;
              color: #ebc87f;
              margin-left: 18px;
            }
          }

          .place_city_bottom {
            display: flex;
            justify-content: space-between;
            flex-flow: row wrap;

            .city {
              font-size: 30px;
              color: #333333;
              background-color: #f7f7f7;
              min-width: 200px;
              text-align: center;
              margin-top: 23px;
              padding: 10px;
            }

            .citys {
              font-size: 30px;
              color: #333333;
              background-color: #f7f7f7;
              min-width: 76px;
              text-align: center;
              margin-top: 10px;
              margin-left: 10px;
            }

            .potch_city {
              font-size: 30px;
              color: #ffffff;
              background-color: #ebc87f;
              min-width: 200px;
              text-align: center;
              padding: 15px 5px;
              margin-top: 23px;
              padding: 10px;
            }
          }
        }
      }
      .no_choose&&.choose::after {
        display: none;
      }
      .no_choose {
        font-size: 35.75px;
        color: #ffffff;
        background-color: #d2d2d2;
        width: 90%;
        border-radius: 50px;
        bottom: 40px;
        margin: 10px auto 30px auto;
        border-radius: 50px;
        z-index: 99999;
      }

      .choose {
        font-size: 35.75px;
        color: #ffffff;
        background-color: #ebc87f;
        width: 90%;
        bottom: 40px;
        margin: 10px auto 30px auto;
        border-radius: 50px;
        z-index: 99999;
      }
    }
  }
}

.city-modal--active {
  visibility: visible;

  .city-modal__overlay {
    opacity: 1;
    display: block;
  }

  .city-modal__container {
    opacity: 1;
    display: block;
  }
}

.at-search-bar__placeholder-wrap {
  display: block;
  line-height: 30px;
}


相关文章

网友评论

      本文标题:城市选择器组件

      本文链接:https://www.haomeiwen.com/subject/tcmnsktx.html