React onClick not working to start a timer - javascript

I know there have been a few of these questions posted but I haven't been able to find an answer to work. My code is below. Everything links, and I was able to get a more simple timer working that just starts timing when the component mounts, but now I want to make it more interactive. however, when I click the button nothing happens. What I am trying to do is have a component that is a button, when clicked it becomes a timer and displays the amount of time passed since clicked. But clicking the button doesn't do any thing.
thanks for the help!
var StartButton = React.createClass({
getInitialState:function(){
return { elapsed: 0, go: false };
},
getDefaultProps: function() {
return {
interval: 1000
};
},
componentDidMount: function(){
console.log('mounted');
},
tick: function(){
console.log('tick')
this.setState({elapsed: new Date() - this.state.start});
},
startCount: function(e){
console.log(e);
console.log('GO!!!')
this.state.props = Date.now;
this.state.go = true;
this.timer = setInterval(this.tick, this.props.interval);
},
render: function(){
var self = this;
var elapsed = Math.round(this.state.elapsed / 100);
var seconds = (elapsed / 10).toFixed(3);
var clickMe = <button onCLick={self.startCount} >GO</button>;
var display = <div>time elapsed {this.state.elapsed}</div>
return (
<div>
{this.state.go ? display : clickMe}
</div>
)
}
})
var AppContainer = React.createClass({
render: function(){
return (<div><StartButton interval={1000} /></div>);
}
})
$(document).ready(function () {
console.log('in ready');
ReactDOM.render(<AppContainer></AppContainer>, document.getElementById('jake'));
});

Not sure if you found all the small errors by now, but in case you haven't, here's a working copy of your component;
var StartButton = React.createClass({
getInitialState:function(){
return { elapsed: 0, go: false };
},
getDefaultProps: function() {
return {
interval: 1000
};
},
componentDidMount: function(){
console.log('mounted');
},
tick: function(){
console.log('tick')
this.setState({elapsed: Date.now() - this.state.start});
},
startCount: function(e){
console.log(e);
console.log('GO!!!')
this.setState({start: Date.now(), go: true})
setInterval(this.tick, this.props.interval);
},
render: function(){
var clickMe = <button onClick={this.startCount} >GO</button>;
var display = <div>time elapsed {Math.round(this.state.elapsed / 1000)} seconds</div>
return (
<div>
{this.state.go ? display : clickMe}
</div>
)
}
})

I think you problem is here with onClick:
var clickMe = <button onClick={self.startCount} >GO</button>;

Related

knockout paging retaining old page on jquery dialog cancel and open

I have an issue with knockout paging .I am using knockout paging on jquery dialog.The issue is when i navigate from page1 to page2 ,page3 or page4 and close the dialog and open the dialog again i see the page which i closed last but not from first page .Attached the jsfiddle below.Please let me know if you have any questions.
http://jsfiddle.net/bharatgillala/yuvNt/57/
var data = [
{Player:"PAGE1", runs:"34889"},
{Player:"PAGE1", runs:"83366"},
{Player:"PAGE1", runs:"52534"},
{Player:"PAGE2", runs:"02232"},
{Player:"PAGE2", runs:"55899"},
{Player:"PAGE2", runs:"90483"},
{Player:"PAGE3", runs:"02565"},
{Player:"PAGE3", runs:"98500"},
{Player:"PAGE3", runs:"20285"},
{Player:"PAGE4", runs:"57757"},
];
var StaticDataExample1 = function(data){
// stuff I care about
this.items = ko.observableArray(data);
// pager related stuff
------------------------------
this.currentPage = ko.observable(1);
this.perPage = 3;
this.pagedItems = ko.computed(function(){
var pg = this.currentPage(),
start = this.perPage * (pg-1),
end = start + this.perPage;
return this.items().slice(start,end);
}, this);
this.nextPage = function(){
if(this.nextPageEnabled())
this.currentPage(this.currentPage()+1);
};
this.nextPageEnabled = ko.computed(function(){
return this.items().length > this.perPage * this.currentPage();
},this);
this.previousPage = function(){
if(this.previousPageEnabled())
this.currentPage(this.currentPage()-1);
};
this.previousPageEnabled = ko.computed(function(){
return this.currentPage() > 1;
},this);
};
ko.applyBindings(new StaticDataExample1(data),document.getElementById("test"));
$(document).on("click", "[id*=atest]", function ()
{
$("#test" ).dialog(
{
height: 420,
width: 430,
modal: true,
buttons: [
{
text: "Save",
},
{
text: "Cancel",
tabIndex: -1,
click: function () {
$(this).dialog("close");
}
}
],
close: function () { }
});
});
You're almost there actually.
Change your ko.applyBindings to this:
var model = new StaticDataExample1(data);
ko.applyBindings(model, document.getElementById("test"));
Then add an open: function to your $(...).dialog({ ... }) options right after the close: option:
close: function () {
},
open: function () {
model.currentPage(1);
}
Fiddle here: http://jsfiddle.net/yuvNt/63/
And it occurred to me just now; you could even just add the model.currentPage(1); call into your existing close: function if you don't want to add an open: function.
Hope that's useful.

interval in slideshow. React.js

I have a slideshow which made in React.js. Now i need to make an interval in this slider.
this slider is working, but where should I write an interval?
var SlideBullet = React.createClass({
openSlide: function(){
this.props.certainSlide(this.props.slideNumber)
},
render: function(){
return <span onClick={this.openSlide} className={this.props.classer}>•</span>
}
})
var Slider = React.createClass({
getInitialState: function(){
return {
curslide: 0
}
},
nextSlide: function(e){
e.preventDefault();
var cs = this.state.curslide;
cs++;
if(cs>=Slides.length) {
cs = 0
}
this.setState({curslide:cs});
},
certainSlide: function(number){
this.setState({curslide:number});
},
// is this should be here?
// if so where can i call this function?
// myInterval: function() {
// var interval = setInterval(this.nextSlide, 2000);
// },
render: function(){
var classTag = cx({
'dark-text': this.props.dark
});
var marginleft = this.props.style.width*this.state.curslide*-1;
var newstyle = merge(this.props.style,{'marginLeft':marginleft});
var slides = Slides.map(function(s,i){
return <Slide link={s} key={'slider-slide-key'+i} style={this.props.style}/>
}.bind(this));
var labels = Slides.map(function(s,i){
return <SlideBullet classer={i===this.state.curslide?'current-slide':''} slideNumber={i} certainSlide={this.certainSlide}/>
}.bind(this));
return <div className='slider-holder' style={this.props.style}>
<ul className='ux-at-slider' style={newstyle}>
{slides}
</ul>
<div className='slider-labels'>
{labels}
</div>
</div>
}
})
as you see im not good at reactjs, but i need your help guys.
If you want to pause before showing the next slide, instead of creating a setInterval function, maybe you could add a setTimeout to nextSlide, by changing this line:
this.setState({curslide:cs});
to this:
window.setTimeout(this.setState({curslide:cs}), 2000);

clearInterval not working as I expect it too

I made a demo which is here. All you have to do is start typing in the text field, make sure you have the console open. So as you type, you'll instantly see the OMG Saved, and the counter in the console will go nuts.
Now click the button, watching the console you should see something like 11 or some other value, but you'll also see the counter reset and continues going. I do not want this. I want the counter to stop, I have clicked a button and while the page hasn't refreshed, the counter should stop if I understand these docs on setInterval().
the app I am developing which uses code very similar to this, does not refresh as most single page apps don't. So it is imperative that I have control over this setInterval.
So my question is:
How do I reset the counter such that, until I type again in the input box OR if the input box element cannot be found the flash message does not show up, the interval is set back to 0.
update
The following is the JavaScript code, which is run on the link provided above.
var ObjectClass = {
initialize: function() {
$('#flash-message').hide();
},
syncSave: function() {
$('#content').keypress(function(){
SomeOtherClass.autoSave = setInterval( function(){
$('#flash-message').show();
$('#flash-message').delay(1000).fadeOut('slow');
}, 500);
});
},
listenForClick: function() {
$('#click-me').click(function() {
console.log(SomeOtherClass.autoSave);
clearInterval(SomeOtherClass.autoSave);
});
}
};
var SomeOtherClass = {
autoSave: null
};
ObjectClass.initialize();
ObjectClass.syncSave();
ObjectClass.listenForClick();
You have to put this
clearInterval(SomeOtherClass.autoSave);
before this line:
SomeOtherClass.autoSave = setInterval( function(){
So that you kill the previous interval and you ahve ONLY ONE interval at the same time
Your code will be:
var ObjectClass = {
initialize: function () {
$('#flash-message').hide();
},
syncSave: function () {
$('#content').keypress(function () {
clearInterval(SomeOtherClass.autoSave);
SomeOtherClass.autoSave = setInterval(function () {
$('#flash-message').show();
$('#flash-message').delay(1000).fadeOut('slow');
}, 500);
});
},
listenForClick: function () {
$('#click-me').click(function () {
console.log(SomeOtherClass.autoSave);
clearInterval(SomeOtherClass.autoSave);
});
}
};
var SomeOtherClass = {
autoSave: null
};
ObjectClass.initialize();
ObjectClass.syncSave();
ObjectClass.listenForClick();
What you need to do is use a timeout instead of an interval, like this:
var ObjectClass = {
initialize: function() {
$('#flash-message').hide();
},
syncSave: function() {
$('#content').keypress(function(){
SomeOtherClass.autoSave = setTimeout( function(){
$('#flash-message').show();
$('#flash-message').delay(1000).fadeOut('slow');
}, 500);
});
},
listenForClick: function() {
$('#click-me').click(function() {
console.log(SomeOtherClass.autoSave);
if(typeof SomeOtherClass.autoSave === 'number'){
clearTimeout(SomeOtherClass.autoSave);
SomeOtherClass.autoSave = 0;
}
});
}
};
var SomeOtherClass = {
autoSave: 0
};
ObjectClass.initialize();
ObjectClass.syncSave();
ObjectClass.listenForClick();

how to use one component render many html fragment in reactjs?

I have a button there, when I click this button, i want render a div and append it to body.
and when I click this button again, a new div be rendered.
I want: How many times I click the button, how many div be render.
The follow code can only render one div: ( jsFiddle: http://jsfiddle.net/pw4yq/ )
var $tool = document.getElementById('tool');
var $main = document.getElementById('main');
var partBox = React.createClass({displayName: 'partBox',
render: function(){
return (
React.DOM.div({className:"box"}, "HELLO! ", this.props.ts)
)
}
});
var createBoxBtn = React.createClass({displayName: 'createBoxBtn',
createBox: function(){
var timeStamp = new Date().getTime();
React.renderComponent(partBox( {ts:timeStamp} ), $main);
},
render: function(){
return (
React.DOM.button( {onClick:this.createBox}, "createBox")
)
}
});
React.renderComponent(createBoxBtn(null ), $tool);
Your app should be data driven, meaning the state of your app is kept outside the DOM. In your example, you are essentially keeping a list of Date objects. Put that into a state that you can modify, and render a box for each Date object you have created:
Working JSFiddle: http://jsfiddle.net/pw4yq/6/
var $main = document.getElementById('main');
var partBox = React.createClass({displayName: 'partBox',
render: function(){
return (
React.DOM.div({className:"box"}, "HELLO! ", this.props.ts)
)
}
});
var createBoxBtn = React.createClass({displayName: 'createBoxBtn',
createBox: function(){
var timeStamp = new Date().getTime();
this.props.onClick({ts: timeStamp});
},
render: function(){
return (
React.DOM.button({onClick: this.createBox}, "createBox")
)
}
});
var app = React.createClass({
displayName: "app",
getInitialState: function() {
return {
partBoxes: []
};
},
createBox: function(partBox) {
this.state.partBoxes.push(partBox);
this.forceUpdate();
},
render: function() {
return (
React.DOM.div(null,
createBoxBtn({onClick: this.createBox}),
this.state.partBoxes.map(function(pb) {
return partBox({key: pb.ts, ts: pb.ts});
})
)
);
}
});
React.renderComponent(app(null), $main);

javascript show override-able message with timeout

var message;
function Message(message) {
(function () {
$('#configMsg').html(message);
}());
this.timer = setTimeout(function () {
$('#configMsg').html('');
}, 5000);
}
$('#foo').click(function () {
message = new Message('foo');
});
$('#bar').click(function () {
message = new Message('bar');
});
What I'm trying to do is display message for 5 seconds, but if I display a new message the timer should be reset to 5 seconds.
My theory was that if I overwrite the message var which contains a Message function with a new Message function the old one will be destroyed along with the timer that it contains.
But its not working out, I think the old timer still exists as sometimes a message is displayed for less than 5 seconds.
Here is a fiddle http://jsfiddle.net/sgRrk/
function Message(message) {
var elem = $('#configMsg');
elem.html(message);
window.clearTimeout(elem.data("timer")); //if there is a previous timer, cancel it
elem.data("timer", setTimeout(function () { //store the timer reference to remove
elem.html('');
}, 5000));
}
What about a function that has a private timer and a public messsage() method?
function messager() {
var timer;
return {
message : function(message){
$('#configMsg').html(message);
clearTimeout(timer);
timer = setTimeout(function () {
$('#configMsg').html('');
}, 5000);
}
};
}
var msgr = new messager();
$('#foo').click(function () {
msgr.message('foo');
});
$('#bar').click(function () {
msgr.message('bar');
});
Fiddle THIS!
If you want to overwrite a variable that is part of an object, as in this.timer, don't create new instances of the object on every click, do it the easy way and use the same function, and clear the timeout on subsequest clicks
function message(message) {
$('#configMsg').html(message);
clearTimeout(this.timer);
this.timer = setTimeout(function () {
$('#configMsg').html('');
}, 5000);
}
$('#foo').click(function () {
message('foo');
});
$('#bar').click(function () {
message('bar');
});
FIDDLE
You want to clear your timer each time you create a new message.
var message;
var timer;
function Message(message) {
clearTimeout(timer);
(function () {
$('#configMsg').html(message);
}());
timer = setTimeout(function () {
$('#configMsg').html('');
}, 5000);
}
$('#foo').click(function () {
message = new Message('foo');
});
$('#bar').click(function () {
message = new Message('bar');
});
You need to save a timeout reference and reset it when a new timeout is created:
var message,
timer;
function Message(message) {
(function () {
$('#configMsg').html(message);
}());
if ( typeof timer != 'undefined' ) {
clearTimeout( timer );
delete timer;
}
timer = setTimeout(function () {
$('#configMsg').html('');
}, 5000);
}
$('#foo').click(function () {
message = new Message('foo');
});
$('#bar').click(function () {
message = new Message('bar');
});
Fiddle

Categories

Resources