Tutorial App Newspaper – Laravel + React Native + API Part 5: search box.

React native

Import library react native

TextInput

State

dataAllNews:{},
dataNews:[],
dataBackup:[],

changed ComponentDidMount

  componentDidMount()
  {
    return fetch(baseUrl+"api/news")
    .then((response)=> response.json())
    .then((responseJson)=>{
      this.setState({
        dataAllNews:responseJson,
        dataNews:responseJson.news,
        dataBackup:responseJson.news,
        dataBanner:responseJson.banner
      })
    })
    .catch((error)=>{
      console.log(error)
    })
  }

Filter from search box

  onChangeSearch(text){
    console.log(text)
    const data = this.state.dataBackup
    const newData = data.filter(function(item){
        const itemData = item.title.toUpperCase()
        const textData = text.toUpperCase()
        return itemData.indexOf(textData) > -1
    })
    console.log(newData.length)
    this.setState({
        dataNews: newData,
        textSearch: text,
    })
  }

Searchbox in render

<View style={{width:width, backgroundColor:'gray',padding:8}}>
            <TextInput
              placeholder="Search..."
              style={{ height: 40, borderColor: '#f2f2f2', borderRadius:10, backgroundColor:'white', borderWidth: 1, paddingHorizontal:20 }}
              onChangeText={(text) => this.onChangeSearch(text)}
              value={this.state.textSearch}
            />
          </View>

Changed FlatList

<View style={{height:45}}>
            <FlatList
              horizontal={true}
              data={this.state.dataAllNews.theme}
              keyExtractor = { (item,index) => index.toString() }
              renderItem={({item})=>this._renderItemTheme(item)}
             />
          </View>
          <FlatList
            data={this.state.dataNews}
            scrollEnabled={false}
            keyExtractor = { (item,index) => index.toString() }
            renderItem={({item})=>this._renderItem(item)}
          />

Full source code

import React, { Component } from 'react';

import { Text,
  FlatList,
  Image,
  StyleSheet,
  Dimensions,
  View,
  ImageBackground,
  TouchableOpacity,
  ScrollView,
  TextInput
} from 'react-native';

var {height, width } = Dimensions.get('window');
const baseUrl = "http://192.168.1.15/newspapers/public/"

import Swiper from "react-native-swiper"
import LinearGradient from "react-native-linear-gradient"

export default class App extends Component {

  constructor(props)
  {
      super(props);
      this.state = {
        dataAllNews:{},
        dataNews:[],
        dataBackup:[],
        dataBanner:[],
        selectTheme:0,
        message:"Hola",
        textSearch:""
      }
  }

  static navigationOptions = ({ navigation }) => {
    return {
      headerTitle: (
        <View   style={{ flex: 1,backgroundColor:'transparent',alignItems:'center' }}>
            <Image
            resizeMode="contain"
            style={{ width:width/3,height: '90%'  }}
            source={{uri: "https://www.tutofox.com/wp-content/uploads/2019/10/font_rend.png"}}
          />
        </View>),
      headerTitleStyle: {flex: 1, textAlign: 'center', justifyContent:'center'},
      headerStyle: { backgroundColor:"#f2f2f2" },
    };
  };


  componentDidMount()
  {
    return fetch(baseUrl+"api/news")
    .then((response)=> response.json())
    .then((responseJson)=>{
      this.setState({
        dataAllNews:responseJson,
        dataNews:responseJson.news,
        dataBackup:responseJson.news,
        dataBanner:responseJson.banner
      })
    })
    .catch((error)=>{
      console.log(error)
    })
  }

  onChangeSearch(text){
    console.log(text)
    const data = this.state.dataBackup
    const newData = data.filter(function(item){
        const itemData = item.title.toUpperCase()
        const textData = text.toUpperCase()
        return itemData.indexOf(textData) > -1
    })
    console.log(newData.length)
    this.setState({
        dataNews: newData,
        textSearch: text,
    })
  }

  render(){
    return(
      <ScrollView>
        <View style={{flex:1,backgroundColor:'#f8f8f8'}}>
          <View style={{width:width, backgroundColor:'gray',padding:8}}>
            <TextInput
              placeholder="Search..."
              style={{ height: 40, borderColor: '#f2f2f2', borderRadius:10, backgroundColor:'white', borderWidth: 1, paddingHorizontal:20 }}
              onChangeText={(text) => this.onChangeSearch(text)}
              value={this.state.textSearch}
            />
          </View>
          <View style={{height:200}}>
            <Swiper>
              {this.state.dataBanner.map((itemimag)=>{
                return(
                  <ImageBackground style={{width:width,height:200}} source={{uri:  baseUrl+"storage/"+itemimag.image }}>
                    <LinearGradient style={styles.fondoBanner} colors={[ 'transparent', 'black']} >
                      <Text style={styles.textBanner} numberOfLines={2}>{itemimag.title}</Text>
                    </LinearGradient>
                  </ImageBackground>
                )
              })}
            </Swiper>
          </View>
          <View style={{height:45}}>
            <FlatList
              horizontal={true}
              data={this.state.dataAllNews.theme}
              keyExtractor = { (item,index) => index.toString() }
              renderItem={({item})=>this._renderItemTheme(item)}
             />
          </View>
          <FlatList
            data={this.state.dataNews}
            scrollEnabled={false}
            keyExtractor = { (item,index) => index.toString() }
            renderItem={({item})=>this._renderItem(item)}
          />
        </View>
      </ScrollView>
    )
  }

  _renderItemTheme(item){
    return(
      <TouchableOpacity onPress={()=>this.setState({selectTheme:item.id})}>
        <View style={this.state.selectTheme==item.id?styles.divtheme:styles.divtheme2}>
          <Text style={this.state.selectTheme==item.id?styles.textTheme:styles.textTheme2}>{item.name} </Text>
        </View>
      </TouchableOpacity>
    )
  }

  _renderItem(item){
    if (this.state.selectTheme==item.theme||this.state.selectTheme==0) {
      console.log("Mira "+item.title)
      return(
        <TouchableOpacity onPress={()=>this.props.navigation.navigate("Details",{news:item})} >
          <View style={[styles.divnews,styles.shadows]}>
            <Image style={styles.imagenew} source={{uri : baseUrl+"storage/"+item.image}} />
            <View style={{padding:5}}>
              <Text style={styles.titleNews} numberOfLines={2}>{item.title}</Text>
              <Text style={styles.themeNews}>{item.name}</Text>
              <Text>{item.created_at}</Text>
            </View>
          </View>
        </TouchableOpacity>
      )
    }
  }

}

const styles = StyleSheet.create({
  imagenew:{
    width:width/3,
    height:width/3,
    resizeMode:'cover',
    borderRadius:5
  },
  shadows:{
    elevation:4,
    shadowOpacity:0.3,
    shadowRadius:50,
    shadowColor:'gray',
    shadowOffset: { height:0, width:0 }
  },
  divnews:{
    width:width-10,
    backgroundColor:'white',
    margin:5,
    flexDirection:'row',
    borderRadius:5
  },
  titleNews:{
    width:((width/3)*2)-20,
    fontSize:22
  },
  themeNews:{
    color:"#c2191c",
    fontSize:20
  },
  headernews:{
    width:width,
    height:50,
    backgroundColor:"#f2f2f2",
    alignItems:'center',
    justifyContent:'center'
  },
  logonews:{
    height:45,
    width:width/3,
    resizeMode:'contain'
  },
  textBanner:{
    fontSize:25,
    color:'white'
  },
  fondoBanner:{
    flex:1,
    justifyContent:"flex-end",
    padding:10
  },
  divtheme:{
    height:42,
    borderTopWidth:3,
    padding:10,
    borderColor:'#c2191c',
    backgroundColor:'white'
  },
  textTheme:{
    color:'black'
  },
  divtheme2:{
    height:42,
    borderBottomWidth:3,
    borderColor:"#c2191c",
    padding:10,
    backgroundColor:"#343434"
  },
  textTheme2:{
    color:"white"
  }

})

Añadir un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *