I need to un-render some react component for mobile user
How to un-render component when user come from mobile device?
Thanks
I think this would be a simple solution:
Outside component:
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
Inside component:
React.createClass({
getInitialState: function() {
return {
isMobile: isMobile.any(),
...
}
},
...
render: function() {
{ // base the display of the component on the boolean this.state.isMobile
If the if/else becomes more complex than a simple ternary, be sure to move it out of render() to a helper.
Hope this helps!
Edit: This could help with your conditional rendering if that isn't something you've done a ton of. How to load components conditionally in ReactJS
Mobile testing code source: http://www.abeautifulsite.net/detecting-mobile-devices-with-javascript/
Related
I have implemented Fullcalendar Custom View by referring document Custom Views via JS classes. It seems to worki fine, but the destroy method throws an error: View.prototype.destroy.apply is not function.
I have used the below code:
var FC = $.fullCalendar;
var View = FC.View;
var BlankView;
BlankView = View.extend({
initialize: function() {
// View.prototype.initialize.apply(this, arguments);
},
setHeight: function(height, isAuto) {
},
render: function () {
this.title = this.title || 'TestView';
if (this.el[0].children.length === 0) this.el.addClass('fc-basic-view').html(this.renderHtml());
},
destroyEvents: function() {
// responsible for undoing everything in renderEvents
},
destroy: function() {
View.prototype.destroy.apply(this, arguments);
},
renderHtml: function () {
this.el.html('<div></div>');
},
});
FC.views.blank = BlankView;
Any clues to achieve the destroy method in custom views?
I have developed a Component base application in which I have developed a different Component but at time of rendering I have to render based on user action currently what I have tried is mentioned below.
My Component looks like:
var React = require('react');
var Constants = require('../constants/ActionTypes');
var ItemRelationStore = require('../stores/ItemRelationStore');
var ItemStore=require('../stores/ItemStore');
var TreeView=require('./TreeView.react');
var childNodes={};
function getItemRelationState() {
return {
Items:JSON.parse(JSON.stringify(ItemStore.getItem())),
Items1:JSON.parse(JSON.stringify(ItemStore.getItem1()))
};
}
// Define main Controller View
var ItemPage = React.createClass({
// Get initial state from stores
getInitialState: function() {
return getItemRelationState();
},
// Add change listeners to stores
componentDidMount: function() {
ItemStore.CallItem("TenantId",this.props.MetaItemId,this.props.Key);
ItemStore.addChangeListener(this._onChange);
},
// Remove change listers from stores
componentWillUnmount: function() {
ItemStore.removeChangeListener(this._onChange);
},
// Render our child components, passing state via props
render: function() {
var itemslist;
if(this.props.Key==1)
{
itemslist=this.state.Items;
}
else
{
itemslist=this.state.Items1;
}
var metaid=this.props.MetaItemId;
childNodes= Object.keys(itemslist).map(function(item,index){
return (
{
title:itemslist[item].Name,
Id: itemslist[item].Id,
metaitemId:metaid
}
)
});
var tree= {
title: this.props.MetaItemName,
metaitemId:metaid,
childNodes: [
{childNodes}
]
};
return (
<div className="treeview">
<TreeView node={tree}/>
</div>
);
},
// Method to setState based upon Store changes
_onChange: function() {
this.setState(getItemRelationState());
}
});
module.exports = ItemPage;
Now when I used static in another component like
var Item=require('../../Item');
React.render(<Item MetaItemName={"Users"} MetaItemId={1} Key={1}/>,document.getElementById("firstCol"));
then it's working fine. but I want to render dynamically so I have prepared one CustomeComponent like
var React = require('react');
var Item=require('../Item');
var CustomComponent = React.createClass({
// Get initial state from stores
getInitialState: function() {
return null;
},
// Add change listeners to stores
componentDidMount: function() {
},
componentWillReceiveProps: function(nextProps) {
// Load new data when the dataSource property changes.
if (nextProps.dataSource != this.props.dataSource) {
this.loadData(nextProps.dataSource);
}
},
// Remove change listers from stores
componentWillUnmount: function() {
},
// Render our child components, passing state via props
render: function() {
var InputType=this.props.inputType;
console.log(InputType);
return (
<InputType/>
);
},
// Method to setState based upon Store changes
_onChange: function() {
}
});
module.exports = CustomComponent;
and I am calling this custom component like
React.render(<CustomComponent inputType="Item" />,document.getElementById("secondCol"));
but it's not working i mean to say nothing render on Page.
I just want to know how we can Achive dynamic rendering in React.
Thanks in Advance.
Maybe React.render(<CustomComponent inputType={Item} />,document.getElementById("secondCol"));?
I can not understand why in my Backbone app (Todo app) after I reload a page (CTRL+F5) a filterTodos method does not get called. When I simply click on links to filter Todos ("Active", "Completed") - it does get called.
You can see this feature in links below. No matter how many times you click Refresh in Browser - correct filtered results are displayed:
http://todomvc.com/architecture-examples/backbone/#/completed
http://todomvc.com/architecture-examples/backbone/#/active
I have a theory that it's because I am triggering a filter event from Router too early - a TodosView is not initialized yet and therefore it does not listenTo filter event yet.
But how a Router can inform a View to re-render itself (based on filter) if this View does not exist yet? Can't it be achieved via triggering some event in Router as I do? One possible option is to have a global variable app.FilterState.
Is there any other methods of communications between a Router and a non-constructed yet View?
For app.FilterState I will set its state in Router and then check it in View and call filterTodos function manually like so and it will work:
views/todos.js
render: function() {
app.Todos.each(function(todo) {
this.renderTodo(todo);
}, this);
if (app.FilterState !== 'all') { // <--- ADDED CODE
this.filterTodos(app.FilterState);
}
return this;
}
Existing source code:
routers/router.js
var app = app || {};
var Router = Backbone.Router.extend({
routes: {
'all': 'all',
'active': 'active',
'completed': 'completed'
},
all: function() {
console.log('all');
app.Todos.trigger('filter', 'all');
},
active: function() {
console.log('active');
app.Todos.trigger('filter', 'active');
},
completed: function() {
console.log('completed');
app.Todos.trigger('filter', 'completed');
}
});
app.Router = new Router();
Backbone.history.start();
views/todos.js
var app = app || {};
app.TodosView = Backbone.View.extend({
el: '#todo-list',
initialize: function(todos) {
console.log('initialize begin');
app.Todos.reset(todos);
this.listenTo(app.Todos, 'add', this.addOneTodo);
this.listenTo(app.Todos, 'filter', this.filterTodos);
this.render();
console.log('initialize end');
},
render: function() {
app.Todos.each(function(todo) {
this.renderTodo(todo);
}, this);
return this;
},
renderTodo: function(todo) {
var todoView = new app.TodoView({model: todo});
this.$el.append(todoView.render().el);
},
addOneTodo: function(todo) {
this.renderTodo(todo);
},
filterTodos: function(filterType) {
console.log('filter'); // <--- CODE DOES NOT REACH THIS LINE WHEN CALLED ON BROWSER'S REFRESH (F5)
var active = app.Todos.active();
var completed = app.Todos.completed();
if (filterType === 'active') {
// hide remaining
_.each(completed, function(todo) {
todo.trigger('hide');
});
//show active
_.each(active, function(todo) {
todo.trigger('show');
});
}
else if (filterType === 'completed') {
_.each(completed, function(todo) {
todo.trigger('show');
});
//show active
_.each(active, function(todo) {
todo.trigger('hide');
});
}
else if (filterType === 'all') {
app.Todos.each(function(todo) {
todo.trigger('show');
});
}
}
});
Have you considered using Backbone Marionette? It comes with a built in pub sub communication system built in that makes it super easy to do this. Overall it gives you a great organization/modularization of your code by utilizing the pub sub system.
i have a problem,
i would like to disable the parallax effect on my website when he is on a mobile device, so i looked on different forum, and i found this code :
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
jQuery(document).ready(function(){
if( !isMobile.any()){
$(window).stellar();
}
});
But that didn't work, there is no way to disable stellar with a simple code ?
(i find a another code to detecte the device)
if(jQuery.browser.mobile)
{
console.log('You are using a mobile device!');
}
else
{
console.log('You are not using a mobile device!');
}
this one works (with the .js).
But i still dont know how to disable stellar.
Thanks guys
Following your first example change the last part with this:
if( !isMobile.any() )
$(function(){
$.stellar({
horizontalScrolling: false,
verticalOffset: 50
});
});
For me it worked well, the statement says: "If NOT mobile then initialize Stellar".
Note that the list of mobile agents you provided is not complete, it's for the majority of devices tho, but keep that in mind!
this code worked for me;
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
jQuery(document).ready(function(){
jQuery(window).stellar({
horizontalScrolling: false,
hideDistantElements: true,
verticalScrolling: !isMobile.any(),
scrollProperty: 'scroll',
responsive: true
});
});
Using ExtJS, how to prevent a component from being rendered into DOM based on a condition? The code would probably be something like this (I'm using Sencha Architect to generate the code, so I'm not 100% familiar with the syntax)
Ext.define('MyApp.view.MyButton', {
extend: 'Ext.button.Button',
text: 'MyButton',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
listeners: {
beforerender: {
fn: me.onButtonBeforeRender,
scope: me
}
}
});
me.callParent(arguments);
},
onButtonBeforeRender: function(component, eOpts) {
if (MyCondition) {
// all good, go on with rendering this component
}
else {
// no good, abort, this component should not be rendered
}
}
});
You can just return false to stop the rendering of the component. Check the docs.
So maybe your function would look something like this:
onButtonBeforeRender: function(component, eOpts) {
if (MyCondition) {
// all good, go on with rendering this component
return true;
}
else {
// no good, abort, this component should not be rendered
return false;
}
}