I had created an imageGallery application built over React-Native.
The basic requirement is
Mobile View shows 3 images per row.
Tablet View shows 5 images per row.
Device detection is done using react-native-device-detection
The number of images per row is limited using Dimensions object.
const Device = require('react-native-device-detection');
if(Device.isTablet) {
Object.assign(styles, {
image: {
width: Dimensions.get('window').width / 5 - 10 ,
height: Dimensions.get('window').width / 5 - 10,
}
});
}
if(Device.isPhone) {
Object.assign(styles, {
image: {
width: Dimensions.get('window').width / 3 - 10 ,
height: Dimensions.get('window').width / 3 - 10,
}
});
}
This works fine in mobile and also in the simulator (Nexus 7).
Checked with https://material.io/devices/. Nexus 7 comes under Tablet.
Nexus 7 Emulator Screenshot
Nexus 7 Device Screenshot
But in the device (Nexus 7) it shows 3 images per row.(Mobile behavior).
How can this be fixed?
Nexus 7 is actually a mini tablet as per manufacturer. react-native-device-detection identifies the device on the basis of their height/width and pixelDensity like this.
isPhoneOrTablet() {
if(this.pixelDensity < 2 && (this.adjustedWidth >= 1000 || this.adjustedHeight >= 1000)) {
this.isTablet = true;
this.isPhone = false;
} else if(this.pixelDensity === 2 && (this.adjustedWidth >= 1920 || this.adjustedHeight >= 1920)) {
this.isTablet = true;
this.isPhone = false;
} else {
this.isTablet = false;
this.isPhone = true;
}
}
There is a chance for wrong info if the device has unorthodox sizes, you can add your own custom calculations to make it more accurate.
Related
I use react Grid-layout : https://github.com/react-grid-layout/react-grid-layout
I do not understand why the number of column does not update in my table through the web browser.
In fact, this.props.cols.lg is either 17 or 24.
When it's 17, my table is displayed correctly. On the other hand, when I choose a period with 24 columns, my columns are placed one below the other from the 18th.
this.props.cols.lg to the correct value (17 or 24) but my HTML page does not update to the design level.
This is the right table on one single row :
Right table
Like you can see, the firefox web console shows react properties are good with 17 :
and the bad table
Bad table
here again, the firefox web console shows react properties are right (24) but not applied by the web browser :
Important information,
this.props.cols.lg=loopValue+1; **contains the right value (17 or 24) but apply on 17**
Thank you in advance for your help.
Here is a part of my code:
import React, { useState, useEffect, Fragment } from 'react';
import { WidthProvider, Responsive } from "react-grid-layout";
import ReactTooltip from 'react-tooltip';
import _ from "lodash";
import { Button, Container } from 'react-bootstrap';
const ResponsiveReactGridLayout = WidthProvider(Responsive);
import { Responsive as ResponsiveGridLayout } from 'react-grid-layout';
/**
* This layout demonstrates how to use a grid with a dynamic number of elements.
*/
export class AddRemoveLayout extends React.PureComponent {
//les propriétés par défaut
static defaultProps = {
className: "layout border-darken-1 child-background-color",
cols:
{ lg: 10, md: 10, sm: 10, xs: 10, xxs: 10 },
width: 1000,
margin: [0, 0],
preventCollision: true,
autoSize: true,
// preventCollision: true,
rowHeight: 70,
// Build HTML to insert
render() {
//Week
let createDateItem =
(x, y, day) => ({
i: `date-${x}_${y}`,
x,
y,
w: 1,
h: 1,
myText: `${day}` ,
static: true
});
/**
*
* #param {*} y
* #param {*} xStart
* #param {num semaine} dateStart
* #param {nombre semaine total} count
*/
let getDateItems =
(y, xStart, dateStart, count,dateEnd) => {
let items = [];
let loopValue = 0;
while(dateStart<=dateEnd){//semainee
if(loopValue>1){
dateStart.setDate(dateStart.getDate() + 7)
}
if(dateStart<=dateEnd){
items.push(
createDateItem(xStart + loopValue, y, loopValue === 0 ? 0 :
(dateStart.getDate()+"/" +(dateStart.getUTCMonth()+1)+ " (Sem. "+loopValue +") ")
))
}
loopValue++;
}
console.log('props:')
console.log(this.props);
this.props.cols.lg=loopValue+1;
this.props.cols.md=loopValue+1;
this.props.cols.sm=loopValue+1;
this.props.cols.xs=loopValue+1;
this.props.cols.xxsloopValue+1;
console.log(this.props);
// console.log(AddRemoveLayout.defaultProps)
return items;
}
;
We found the solution :
data: { idHoraire: 1 },
It was always the same item sent to PHP, with this code, I have a great dispaly of my cols because I either send 1 (17 cols) or 2 (25 cols) :
data: { idHoraire: url === "index2" ?2 : 1, },
I'm using JointJS in a React environment to create a Directed graph from some Neo4j data. My problem is that elements are being generated off the paper As pictured here, "test6" is generated mostly off the page and "test10" isn't even shown. I would like all elements to be displayed on the paper, without overlapping each other or links if possible.
My paper is defined with only a width dimension set equal to the div width and the div is styled to be 100% width
...
width: $('#paper').width(),
...
and
render(){
return(
<React.Fragment>
<div id="paper" style={{width:'100%'}}></div>
</React.Fragment>
)
}
The code for generating an element is as follows:
function makeElement(node) {
var maxLineLength = _.max(node.name.split('\n'), function(l) { return l.length; }).length;
var letterSize = 12;
var width = 2 * (letterSize * (0.6 * maxLineLength + 1));
var height = 2 * ((node.name.split('\n').length + 1) * letterSize);
return new joint.shapes.basic.Rect({
id: node.id,
size: { width: 100, height: height },
attrs: {
type:'node',
text: {
text: node.name,
'font-size': letterSize,
'font-family': 'monospace' },
rect: {
width: width, height: height,
rx: 5, ry: 5,
stroke: '#555'
}
}
});
}
Thanks in advance :)
EDIT: I don't have the exact solution yet, but in the meantime I used this to make the paper draggable to view all nodes
I was looking for a way to create my own mars map in a website, using google maps.
I found this example in google map api
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 0, lng: 0},
zoom: 1,
streetViewControl: false,
mapTypeControlOptions: {
mapTypeIds: ['moon']
}
});
var moonMapType = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
var normalizedCoord = getNormalizedCoord(coord, zoom);
if (!normalizedCoord) {
return null;
}
var bound = Math.pow(2, zoom);
return '//mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw' +
'/' + zoom + '/' + normalizedCoord.x + '/' +
(bound - normalizedCoord.y - 1) + '.jpg';
},
tileSize: new google.maps.Size(256, 256),
maxZoom: 9,
minZoom: 0,
radius: 1738000,
name: 'Moon'
});
map.mapTypes.set('moon', moonMapType);
map.setMapTypeId('moon');
}
// Normalizes the coords that tiles repeat across the x axis (horizontally)
// like the standard Google map tiles.
function getNormalizedCoord(coord, zoom) {
var y = coord.y;
var x = coord.x;
// tile range in one direction range is dependent on zoom level
// 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
var tileRange = 1 << zoom;
// don't repeat across y-axis (vertically)
if (y < 0 || y >= tileRange) {
return null;
}
// repeat across x-axis
if (x < 0 || x >= tileRange) {
x = (x % tileRange + tileRange) % tileRange;
}
return {x: x, y: y};
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script
async
defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
https://jsfiddle.net/dobleuber/319kgLh4/
It works perfect, but I would like to create the same thing with react using react-google-maps.
I looked out in the react-google-maps code but I only see getters no setters for the map props:
getMapTypeId, getStreetView, ect.
Is there any way to achieve this without modify the react-google-maps code?
Thanks in advance
use props mapTypeId="moon" in react-google-maps
I've found a better way to solve this that preserve the changes on re-render, leaving it here to anyone who comes here.
there is an onLoad function that exposes a map instance, we can use this to set mapTypeId instead of passing it as an option. In this way, if the user changes the map type later, it will preserve the changes on re-render.
<GoogleMap
onLoad={(map) => {
map.setMapTypeId('moon');
}}
/>
Hi I need to convert or use the sent integer value from the checkboxes at the reserve page to the view/print transaction page.
Please see my old question:
How to add IDs of a checkbox in angular js
I am able to get the values from the database and display it on the view page the only problem is that the checkboxes are null. There are 5 checkboxes on the reservation page (Laptop, Headset, Projector, Tablet, Speakers) so the possible combinations are 32 that's why i used to send an integer from 0 - 31 to the database because there's only one column for the reserved items.
I have successfully manage (with the help of this community) to post and get values from the database.
Now please help me to convert/use that INT value to automatically set the checkbox value to true if it was checked by the user on the reserve page.
Example:
Laptop = 1; Headset = 2; Projector = 4; Tablet = 8; Speakers = 16
The user checks (reserve page)
✓ Laptop, Headset, ✓ Projector, Tablet, ✓ Speakers
The value on the DB: 21
One the view/print page
I need to use the int value on the DB (which is 21) to automatically check the checkbox ✓ Laptop, Headset, ✓ Projector, Tablet, ✓ Speakers in read-only disabled mode .
So far this is my code in html and controller:
function getReservedRequestsById(reservedRequestId) {
var key = reservedRequestId;
return dataservice.getReservedRequests(key).then(function (data) {
vm.ReservedRequestId = data.data;
console.log(vm.ReservedRequestId);
logger.info('ACTIVATED');
//CheckBox
if (vm.ReservedRequestId.Items > 15) {
$scope.chkItems.forEach(function (Item) {
if (Item.id == 16) {
Item.value = true;
}
})
}
else if ((16 > vm.ReservedRequestId.Items > 7) || (32 > vm.ReservedRequestId.Items > 23)) {
$scope.chkItems.forEach(function (Item) {
if (Item.id == 8) {
Item.value = true;
}
})
}
else if ((8 > vm.ReservedRequestId.Items > 3) || (16 > vm.ReservedRequestId.Items > 11) || (24 > vm.ReservedRequestId.Items > 19) || (32 > vm.ReservedRequestId.Items > 27)) {
$scope.chkItems.forEach(function (Item) {
if (Item.id == 4) {
Item.value = true;
}
})
}
// AND also for 1 & 2 i did not put it here because i would like to just test if it is working on the three check boxes. If it is working i'll just add the other two
}
<md-input-container class="md-block" flex-gt-sm>
<label class="force-input-label">Items</label>
</br>
<div ng-repeat="chkItem in chkItems">
<md-checkbox name="chkItem.name" ng-model="chkItem.value" readonly>{{chkItem.name}}
</div>
</md-input-container>
it is not currently working
Need help and advice
Not good in english as well as in angularjs/web development : )
your help is greatly appreciated!
I fixed your code. I only kept the logic you provided. The problem was that 16 > x > 7 is not a correct syntax in javascript. You have to use &&.
//Laptop = 1; Headset = 2; Projector = 4; Tablet = 8; Speakers = 16
var chkItems = [{
id: 1,
name: 'Laptop',
value: null,
}, {
id: 2,
name: 'Headset',
value: null
}, {
id: 4,
name: 'Projector',
value: null
}, {
id: 8,
name: 'Tablet',
value: null
}, {
id: 16,
name: 'Speakers',
value: null
}];
var items = 21;
if (items >= 16) {
selectItem(16);
}
if ((items < 16 && items > 7) || (items < 32 && items > 23)) {
selectItem(8);
}
if ((items < 8 && items > 3) || (items < 16 && items > 11) || (items < 24 && items > 19) || (items < 32 && items > 27)) {
selectItem(4);
}
console.log(chkItems);
function selectItem(id) {
chkItems.map(function(elem) {
if (!elem.value)
elem.value = (elem.id === id);
return elem;
});
}
I have ExtJs 4 Area chart with Time serie. I'd like user to be able to horizontally select part of chart and then obtain higher density data from server adequately. Problem is I can't get boundary dates from selection. I've got:
var chart = Ext.create('Ext.chart.Chart', {
store: store,
enableMask: true,
mask: 'horizontal',
listeners: {
select: {
fn: function(me, selection) {
console.log(arguments); // selection = Object { height: 218, width: 117, x: 665, y: 123 }
}
},
...
But select listener provides only pixel data. Is there some way to get boundary axis data (e.g. { from: 2013-08-01, to: 2013-08-20 } or some way to unproject pixels to values? I'm desperade I would say it's such a basic thing but can't find solution anywhere. Thanks in advance.
Well.. it probably doesn't exists a method for this. After digging into source code I've utilized lines from chart.setZoom() method to create function for manual unprojecting of mask selection to X axis data:
var unprojectXAxis = function(chart, selection) {
zoomArea = {
x : selection.x - chart.el.getX(),
width : selection.width
};
xScale = chart.chartBBox.width,
zoomer = {
x : zoomArea.x / xScale,
width : zoomArea.width / xScale
}
ends = chart.axes.items[0].calcEnds();
from = (ends.to - ends.from) * zoomer.x + ends.from;
to = (ends.to - ends.from) * zoomer.width + from;
return { from: new Date(from), to: new Date(to) };
}