GithubHelp home page GithubHelp logo

ollija / react-native-sortable-grid Goto Github PK

View Code? Open in Web Editor NEW
437.0 437.0 171.0 173 KB

Drag-drop-sortable grid view for react native

License: MIT License

JavaScript 79.09% Python 4.72% Java 3.54% Objective-C 12.65%

react-native-sortable-grid's People

Contributors

gfontenot avatar gitter-badger avatar ollija avatar tqc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-sortable-grid's Issues

Using TouchableOpacity make grid item not orderable

<SortableGrid
    itemsPerRow = { 3 }
    dragStartAnimation = {{transform: []}}
    >
    {
        ['a', 'b', 'c'].map( (letter, index) =>
            <TouchableOpacity key={index}>
                <Text>{letter}</Text>
            </TouchableOpacity>
        )
    }
</SortableGrid>

Add an item

I'm looking into adding an item and then trying to re-order the grid to accommodate the new item.
It currently seems like the last time moves but the other blocks do not re-refresh. Is there a method that I am missing for this?

Running npm install does not install latest code

Running npm install will install this package at 2.0.0. In order to get the latest version with most of the configuration props mentioned in the documentation (2.0.1) you will need to run npm i react-native-sortable-grid@https://github.com/ollija/react-native-sortable-grid --save.

Drag and Drop fails and the Grid collapses.

RN -> 0.52.0
React -> 16.2.0
I use react-native-navigation, maybe that causes the problem?

Hi @ollija, I tried a long time solving this.
Grid displays fine, but drag and drop fails.

Is this a known Issue? Does anybody have similar problems?

Even the simplest example does not work:

 <SortableGrid
                blockTransitionDuration      = { 400 }
                activeBlockCenteringDuration = { 200 }
                itemsPerRow                  = { 4 }
                dragActivationTreshold       = { 200 }
                onDragRelease                = { (itemOrder) => console.log("Drag was released, the blocks are in the following order: ", itemOrder) }
                onDragStart                  = { ()          => console.log("Some block is being dragged now!") }
            >
                {
                    this.state.abc.map( (letter, index) =>
                        <View key={index} style={styles.block}>
                            <Text style={{color: 'white', fontSize: 50}}>{letter}</Text>
                        </View>
                    )
                }

            </SortableGrid>

drag_and_drop_fails

Adding renderHeader prop to component

I am trying to add renderHeader prop in component like a ListView and have the posibility of drag items over the header.

I download the component code and in index.js and in render have added:

  • { this.props.renderHeader && this.props.renderHeader() }
  • And important add style={{flex: 1}} to SortableGrid props.
class SortableGrid extends Component {

    render = () =>
      <Animated.View
        style={ this._getGridStyle() }
        onLayout={ this.assessGridSize }
      >

        { this.props.renderHeader && this.props.renderHeader() }

        { this.state.gridLayout &&
          this.items.map( (item, key) =>
            <Block
              key = { key }
              style = { this._getBlockStyle(key) }
              onLayout = { this.saveBlockPositions(key) }
              panHandlers = { this._panResponder.panHandlers }
              delayLongPress = { this.dragActivationTreshold }
              onLongPress = { this.activateDrag(key) }
              onPress = { this.handleTap(item.props) }
              itemWrapperStyle = { this._getItemWrapperStyle(key) }
              deletionView = { this._getDeletionView(key) }
            >
              {item}
            </Block>
        )}
      </Animated.View>

      ....
}

With that all works fine. But the problem is when i wrap SortableGrid in a ScrollView, because the first render all works fine but after scroll, component re-render and break the ScrollView cutting end elements.

MyScreen code:

     return (
      <ScrollView scrollEnabled={this.state.scrollEnabled}>

        <SortableGrid
          style={{flex: 1}}
          dragActivationTreshold={50}
          onDragStart={ () => this.onDragStart() }
          onDragRelease={ () => this.onDragRelease() }
          renderHeader={ () => this.renderHeader() }
        >
          {
            _.map(data, (item, index) => {
              return this.renderItem(item, index)
            })
          }
        </SortableGrid>

      </ScrollView>
    )

@ollija can you help me with this? If all works fine i could do PR

Different Widget Dimensions not working?

Hi, Love you work great stuff but i need your assistance with the dimensions of the widgets as am trying to achieve something like google keep with different dimensions for each widget however when i try to set the height and width for each widget it doesn't seem to have an effect it just displays the default dimensions i guess, Is there a way that i can set the dimensions of the widget?

items mess up when add new items

I come across some problem that items mess up when I add new items, I try to add a new item, and delete previous one of the new item, I find that new item was deleted meanwhile. how to do it? would u give me an example for the functionality of addition.

Using in a ScrollView

If anyone else is using in a ScrollView this might help you. Mainly you have to lock and unlock the scrollview's "scrollEnabled" property.

<ScrollView
    ref='myScrollView'
...

Callback

  setLockGrid(mode) {
    this.refs.myScrollView.setNativeProps({ scrollEnabled: mode });
  }

Pass down this callback to your Sortable Grid implementation:

<FavoritesGrid setLock={this.setLockGrid.bind(this)} style={{flex:1}}/>

Then when you setup your Sortable Grid you need to set the callbacks:

<SortableGrid
          onDragEnd  = { this.onDragEnd.bind(this) }
          onDragStart  = { this.onDragStart.bind(this) }
...

  onDragStart(){
    this.props.setLock(false);
  }

  onDragEnd(){
    this.props.setLock(true);
  }

Delete Mode On Drag (Like iPhone Icons)

Great plugin, I am working on a feature where you can delete items like you can on iPhone home screen (close item on top left) which I replaced "delete.png" with a vector icon.

However running into some issues with the event getting dispatched multiple times. Was wondering if you had any insight.

<TouchableOpacity
                    style        = {{ flex: 1 }}
                    delayLongPress = { this.dragActivationTreshold }
                    onLongPress    = { this.activateDrag(key) }
                    onPress      = { this.handleTap(item.props) }>
                      <View style={ this._getItemWrapperStyle(key) }>
                          { item }
                      </View>
</TouchableOpacity>
 { this.state.deleteModeOn &&
 < TouchableWithoutFeedback onPress={this._onDeleteButtonPress(key)} style={{position:'absolute', top:3, left:3, backgroundColor:'transparent'}}>
                         <Icon
                        style={[ ,
                          {color:'#333', backgroundColor:'transparent'}]}
                        size={22} name={'ios-close-circle'}></Icon>
                        </TouchableWithoutFeedback>
                      }

The method

_onDeleteButtonPress = (blockIndex) => {
    alert("Deleting "+blockIndex);
    //this.setState({activeBlock: blockIndex});
    //this.deleteBlock();
  }

Instead of the _onDeleteButtonPress method only being called when I touch the X icon, it gets called multiple times (twice) on initial press of the Item itself.

nov-22-2016 01-10-19

Customizable Delete View

Would be cool to have an easy way to change the deletion view.

e.g. being able to put an "X" in the top corner similar to native iOS

Still supported?

I see the last commit was 9 months ago. I also see that "componentWillReceiveProps" is still being used. So I'm wondering what is the level of support for this? I'd like to add functionality which allows dragging between grids, but not sure if I should.

Contributing guide

@ollija thank you for the amazing work in this library!

I have some specific needs that I would like to discuss and implement, but without a contributing file, I don't know where to start. Could you please make one?

Thanks in advance.

Android issues

I followed the example provided in the GitHub, I'm using a basic 4x4 grid layout and my code is working perfectly and performance is great on IOS. I have 15 boxes of data. However, when I run it on android, it gives me 30 boxes (it duplicates boxes 1-15 another time for some reason?) and then u can't drag/drop boxes, the entire phone just gets buggy and laggy, and sometimes a box disappears. Is anyone else having these issues?

Performance Issue on Android

This grid has performance issue if we have more than 30 blocks, tested on Android Samsung S4 (JS Dev Mode is off).

Block width is set incorrectly

This :

this.blockWidth = nativeEvent.layout.width / this.itemsPerRow

Should be changed to this :

this.blockWidth = Math.floor(nativeEvent.layout.width / this.itemsPerRow)

`If nativeEvent.layout.width / this.itemsPerRow isn't an integer (or maybe if the decimal part is greater than 0.5?), then it causes last block in the row to be rendered on the next row. I had this problem on android.

Is it possible to force draggable items stay where they were?

This is what it's required in my current project, when user drags away an item, I'd like to keep that space blank instead of let a nearby item filling the blank. The idea is to make items snapping to the grid but not snapping to each other.

Thoughts and comments are welcome, thanks!

Drag icons in a long ScrollView with autoscroll

Implemented the grid inside a ScrollView and it works fine, but when I have a ton of icons and I want to drag one of the last ones to the first place or viceversa, I have to stop every time I reach the end of the scrollview, release the icon, scroll, and continue dragging later.

¿Anyone has encountered a way to automatically scroll up or down when dragging so it isn't necessary to stop halfway through? Something like this but with the grid:

36520373-c9e2cb7e-17e4-11e8-9e93-4d2389d51fa4

want some inactive items not to be sorted, inactive property is not working

want some inactive items not to be sorted, inactive property is not working as desired.
For inactive child property, document doesn't explains much.

<View key={i} 
                    style={{height:90, width:90, borderRadius:45, borderColor:"#9b9b9b", borderWidth:3, alignItems:"center", justifyContent:"center"}} 
                     inactive ={true}
              >
                        <Entypo name="circle-with-plus" style={{color:"#9b9b9b"}} size={76} />
                </View>

onDragRelease isn't called unless dragged

Hi, I'm trying to prevent a parent view from scrolling by using the onDragStart and onDragReleaseevents; however, if the user long presses on an item and immediately let's go without dragging it anywhere, theonDragReleaseevent is not fired even though theonDragStart` event did fire.

This means if we disable scrolling on the start event and expect to enable scroll on the release event but it never happens, scroll is locked and the user may not know how to fix it.

Doesn't work on actual iPhone (7, iOS 10)?

The library works great on iPhone simulator (it's amazing!), however when testing on an actual iPhone, I can't drag anything.

Do I need to do anything special to get it to work on an actual device?

iPhone 7, iOS 10
"react-native": "^0.36.0",
"react-native-sortable-grid": "^1.2.1",

seems to swallow child updates

  1. add onTap handler to children
  2. inside onTap, change image in child
  3. no update is seen

Everything behaves normally when parent is removed

Props not updating inside <SortableGrid>

Hi @ollija, I have several 'cell's inside this sortable grid. Some cells have props connected to a remote API. Apparently the cells that are inside the sortable_grid don't update and those which are outside do update.
My main question is: Do props inside are updatable?

<SortableGrid>
 <View style={styles.defaultCell} key={key_item}>
  <Text style={styles.cellTitle}>Availability</Text>
  <Text style={styles.cellValue}>{this.props.activity}%</Text>. //This doesn't update
 </View>
 </SortableGrid>
 <View style={styles.defaultCell} key={key_item}>
  <Text style={styles.cellTitle}>Availability</Text>
  <Text style={styles.cellValue}>{this.props.activity}%</Text>. //This does get updated
 </View>

Evaluate the order of elements

Thank you for the module. It's not an issue but perhaps you can guide me or implement it in future releases. Is there any way of comparing the elements (numbers) and deciding if the re-arranged elements are sorted from the lowest to the highest? How would I approach it?

Thanks

drag and drop fails on adding new items

In Drag-and-drop -style rearrangable grid view,
Drag-and-drop works fine as far as it is assigned with items prior.
But drag and drop doesnot work if i try to add new items to it dynamically.
Please help with a solution.

onDragStart not working with delete functionality?

Hello,

When I update the state inside of my own component, along with onDeleteItem. For instance this works.

onDragStart = () => {
	this.setState({toScrollEnabled: false});
}
<SortableGrid
	ref={'SortableGrid'}
	itemsPerRow={4}
	// onDeleteItem={this.onDeleteItem}
	onDeleteItem={item => console.log('Item was deleted:', item)}
	//onDragStart={this.onDragStart}
	onDragRelease={this.onDragRelease}
>

But this doesn't. It adds an extra component to the end of the array?

<SortableGrid
ref={'SortableGrid'}
itemsPerRow={4}
// onDeleteItem={this.onDeleteItem}
onDeleteItem={item => console.log('Item was deleted:', item)}
onDragStart={this.onDragStart}
onDragRelease={this.onDragRelease}
>

inactive props doesn't work for me

my react-native code is
<SortableGrid
key={"sortableGrid"}
style={{ margin: 10,flex:1}}
itemsPerRow={3}
dragActivationTreshold={100}
ref={'SortableGrid'}
dragStartAnimation={this.getDragStartAnimation()}
onDragRelease={(item, index) => this.onDragRelease(item, index)}
onDragStart={() => this.startCustomAnimation()}
>
{
this.state.media.map((item, index) => {
return (
item !== "empty"
?
<View style={{ height: 106, width: 106, alignSelf: "center" }} key={unique-key-${index}}>
<Image source={{ uri: item.image_id === "" ? item.thumbnail : item.image }} style={{
width: 100,
height: 100,
borderRadius: 20,
alignSelf: "center",
borderColor: '#ababab',
borderWidth: 2
}} />
<TouchableOpacity style={[styles.Indicator, { borderWidth: 1, borderColor: "#ababab", borderRadius: 10, backgroundColor: "#FFF" }]} onPress={() => this.removeMedia({ item, index })}>
<Image source={require("../../assets/images/error.png")} style={{ height: 20, width: 20, alignSelf: "center", }} resizeMode="contain" />

:
<TouchableOpacity onPress={() => this.getImageOrVideo(index)} key={key-${index}} inactive = {true}>
<View style={[styles.cellEmptyImg, { alignSelf: "center" },]}>
<Image source={require("../../assets/images/button.png")} style={{ height: 50, width: 50, }} resizeMode="cover" />
add photo


)
})
}

Threshold spelling

Thank you for this react-native-sortable-grid, its working awesome.

I know its headache but you need to refactor treshold to threshold.

Laggy

Should try to update to use useNativeDriver for smooth 60fps.

Example of Dynamically Adding/Removing Children

Is there any example of how to dynamically add and remove children? If you add a child to the array do you have to re-render all of the children, or would it be best to use a state object?

Is there an example where item values change on reorder?

I'm using the library to create a photo grid that supports adding, deletion, and reordering of photos. I am storing all of my data in a redux store from which the grid is populated. Adding and deleting photos works fine, but I'm having some trouble with rearranging photos.

Here is the data structure I'm using for my photos ( in Redux reducer):

photos: {"0" : null, "1" : null, "2" : null, "3" : null, "4" : null, "5" : null}

This is my component code so far:

` const PhotoUpload = ({ navigation }) => {

// Redux hooks
const photos = useSelector(state => state.user.user.photos);
const dispatch = useDispatch();


// function to reorder the images
reorderImages = (itemOrder) => {
  const temp = {}
  const photosCopy = {...photos}

  const array = itemOrder.itemOrder

  for (let index = 0; index < array.length; index++) { 
     let e = array[index]
     let key = e.key
     let order = e.order

     temp[order] = photosCopy[key]
  }

  dispatch(setStorePhotos(temp));
}


return (
 <>
    <SortableGrid
    // ... other props ommitted
    onDragRelease       = { (itemOrder) => reorderImages(itemOrder) }
    onDragStart         = { (photo) => console.log("Block: ", photo, " is being dragged now!") } >

    {
        Object.keys(photos).map((key) => 

           <View key={ key } onTap={() => this.pickSingle(true, false, key)} >
               <Image defaultSource={ require('./default-avatar.png') } source={ getPhoto(key) } />
               //... add/delete buttons ommitted
           </View>

        )
    }
    </SortableGrid>
 </>

)
}`

I am testing adding two images and then swapping their positions. After the reorderImages function returns, I log all of the filenames in the photos object. Everything is in the right order:

0 IMG_0002.JPG

1 IMG_0001.JPG

2 null

3 null

4 null

5 null

The images in the Grid are still in the original order though:
Screen Shot 2020-01-08 at 4 14 35 PM

And when I go to delete the first image, it thinks I'm clicking the second image, so it just sets the first image to null and doesn't slide the other image to the left (part of my deletion logic).

Screen Shot 2020-01-08 at 5 01 16 PM

I don't know whether I have a logical error or if this is some interaction between redux and the SortableGrid but I've already spent a significant amount of time working on this and I need some fresh eyes.

Square content always?

Hi, first that all thanks for taking your time to do this.
I've seen that this always produces square content so it's not possible to do something like this
screen shot 2017-08-24 at 5 12 08 pm

A new prop, like blockHeight can make it different.

Thanks,
BTW, I can submit a PR for this if necessary.

Android performance is sluggish and unusable

I have a 3x2 grid set up and it works fine on my ios simulator. However, when I load my app on an android simulator or my phone (galaxy s9+) the drag n drop functionality takes a massive hit making it unusable. When I tap to toggle delete mode it doesn't display the "trash" icons like it does on ios and the drag to delete functionality is compromised. Is there anything I can do to improve performance on android?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.