Trigger onClick event for a ReactJS element - javascript

I have a list of elements that are loaded with reactjs and at the end of that list there is a button that loads more items via onclick event using reactjs.
I want to create a function that using javascript or jquery, trigger the onclick event to load all the items instead of clicking one by one on the load more items.
I tried to do it using a interval in jquery but the $element.trigger('click') is not working, does nothing.
Can anyone help me with this? please.
ReactJS:
var ConversationShowMore = React.createClass({
getInitialState: function(){
return {show: false, next_comments: ""};
},
loadMoreComments: function(){
this.setState({show: true});
},
render: function(){
var obj = this.props.next_comments || "";
if (obj != "" && requesturl != obj) {
if (this.state.show) {
return (
<ConversationBox url={this.props.next_comments} />
)
}else{
return (
<a onClick={this.loadMoreComments} className="showmoreconversations" href="#" role="button"><span>Load more conversations...</span></a>
)
}
}else{
return (
<div></div>
)
}
}
});
Javascript/jQuery:
var tid = setInterval(myCode, 5000);
function myCode() {
if($("#conversationContainer a.showmoreconversations").length){
$("#conversationContainer a.showmoreconversations").trigger('click');
}else{
abortTimer();
}
}
function abortTimer() {
clearInterval(tid);
}

When component is mounted, you will trigger request to load more comments. When this request is complete, you schedule another request in X miliseconds.
loadMoreComments(){
console.log('loaded more comments');
// Probably, you will trigger async request. Call following line when this request is complete.
this.timeout = window.setTimeout(this.loadMoreComments, 5000);
},
componentDidMount() {
this.loadMoreComments();
},
Remember to cancel scheduled request when unmounting component. Otherwise, it will run virtually forever (and will surely case exception to be thrown)
componentWillUnmount() {
window.clearTimeout(this.timeout);
},
Working example over here: https://jsfiddle.net/69z2wepo/34030/

Related

Rate limiting calls to a function without an event listener (throttle)

I have a long infinite scroll page full of videos that I am refreshing a sticky ad on. On each scroll to a new video the URL is updated. Each URL update fires a callback that calls the refresh function. I would like to rate limit how fast the function can be fired so that refresh calls don't happen too fast if the user scrolls too quickly.
I have been able to get throttle working in a test environment while using an event listener for a button click instead of the URL change callback, but have been unable to find a way to make it work without an event listener.
Here's the base code, as you can see I need to rate-limit how fast refreshFirstSlot is called.
// Function which refreshes the first slot
var refreshFirstSlot = function () {
googletag.cmd.push(function () {
googletag.pubads().refresh([adSlot1]);
});
};
// UrlUpdate is called each time the URL updates
UrlUpdate = function (url, type) {
refreshFirstSlot();
};
// throttle code
const throttle = (callback, delay) => {
let throttleTimeout = null;
let storedEvent = null;
const throttledEventHandler = (event) => {
storedEvent = event;
const shouldHandleEvent = !throttleTimeout;
if (shouldHandleEvent) {
callback(storedEvent);
storedEvent = null;
throttleTimeout = setTimeout(() => {
throttleTimeout = null;
if (storedEvent) {
throttledEventHandler(storedEvent);
}
}, delay);
}
};
return throttledEventHandler;
};
// adding the refresh call
var returnedFunction = throttle(function () {
refreshFirstSlot();
}, 5000);
// final call
UrlUpdate = function (url, type) {
returnedFunction();
};
Where am I going wrong here?
You could do something like this :
load your page => call your ad
scroll your page => refresh your ad unless previous call has not been rendered / ended
and so on...
To do so, you can use Google Publisher Tag's events (see here). Here is a simple example :
var refreshReady = false;
//slotRequested
googletag.pubads().addEventListener('slotRequested', function(event) {
var slotId = event.slot.getSlotElementId();
if(slotId === adSlot1.getSlotElementId()) {
//every time adSlot1 is requested, we disable the refresh variable
refreshReady = false;
}
});
//slotRenderEnded
googletag.pubads().addEventListener('slotRenderEnded', function(event) {
var slotId = event.slot.getSlotElementId();
if(slotId === adSlot1.getSlotElementId()) {
//every time adSlot1 has been rendered, we enable the refresh variable
refreshReady = true;
}
});
var refreshFirstSlot = function () {
if(refreshReady) {
googletag.cmd.push(function () {
googletag.pubads().refresh([adSlot1]);
});
}
else {
console.log('not yet !');
}
};
UrlUpdate = function (url, type) {
refreshFirstSlot();
};
You could add a timeout to make sure the ad is not refreshed as soon as rendered (improve viewability)

WinJS listview iteminvokedHanlder how to

I'm using the iteminvokedHandler and was wonder if there is a better way to interact with the listView.
Currently using this:
WinJS.UI.processAll(root).then(function () {
var listview = document.querySelector('#myNotePad').winControl;
listview.addEventListener("iteminvoked", itemInvokedHandler,false);
function itemInvokedHandler(e) {
e.detail.itemPromise.done(function (invokedItem) {
myEdit();
});
};
});
The problem is that everytime I click on the listview myEdit() is run and propagates within the listview. I was wondering how to do it once and stop invoking listview until I am done with myEdit? Is there a simpler way to handle such a situation as this?
Simple yet hard to see when you have a mind block and forget some of the basics (yes yes I'm still learning):
var testtrue = true;
WinJS.UI.processAll(root).then(function () {
var listview = document.querySelector('#myNotePad').winControl;
listview.addEventListener("iteminvoked", itemInvokedHandler,false);
function itemInvokedHandler(e) {
e.detail.itemPromise.done(function (invokedItem) {
if (testtrue === true){
myEdit();
}
});
};
});
In myEdit:
function myEdit() {
var theelem = document.querySelector(".win-selected #myNotes");
var gestureObject = new MSGesture();
gestureObject.target = theelem;
theelem.gestureObject = gestureObject;
theelem.addEventListener("pointerdown", pointerDown, false);
theelem.addEventListener("MSGestureHold", gestureHold, false);
function pointerDown(e) {
e.preventDefault();
e.target.gestureObject.addPointer(e.pointerId);
}
function gestureHold(e) {
if (e.detail === e.MSGESTURE_FLAG_BEGIN && test === true) {
e.preventDefault();
editNotes();
} else {
}
console.log(e);
}
theelem.addEventListener("contextmenu", function (e) {
e.preventDefault();}, false); //Preventing system menu
};
function editNotes() {
//The Code I wish to execute
return test = false;
};
What I needed was a conditional statement so that it would run if true and not if false. That same test needed to be done in the gestureHold otherwise it would continue to fire myEdit on the invoked item because of the way the gesture is attached to the item the first time it is run.

Scope of variable in DOJO when created from within function

In a DOJO widget there is code in the postCreate and destroy method to create/start and stop a timer like you can see below. Depending on the value in a drop down box the timer is started or stopped. This works fine so far.
postCreate: function() {
var deferred = this.own(<...some action...>)[0];
deferred.then(
lang.hitch(this, function(result) {
this.t = new dojox.timing.Timer(result.autoRefreshInterval * 1000);
this.t.onTick = lang.hitch(this, function() {
console.info("get new data");
});
this.t.onStart = function() {
console.info("starting timer");
};
this.t.onStop = function() {
console.info("timer stopped");
};
})
);
this.selectAutoRefresh.on("change", lang.hitch(this, function(value) {
if (value == "Automatic") {
this.t.start();
} else {
this.t.stop();
}
}));
},
When leaving the page the timer is still active so I want to stop it when I leave the page using DOJOs destroy() method.
destroy: function() {
this.t.stop();
},
This however throws a this.t.stop is not a function exception. It seems like this.t is not created in the context of the widget although I use lang.hitch(this...
What am I missing here?
I solved that by just renaming the variable t to refreshTimer. Maybe t is some kind of reserved variable in Dojo?

Custom image toggle button in ReactJS

I have this ReactJS code to show a custom image button that toggles between 2 different images for ON and OFF state. Is there a simpler way to do this? I was hoping CSS might be less lines of code, but wasn't able to find a simple example.
The code below passes state up from <MyIconButton> to <MyPartyCatButton> then to <MyHomeView>. My app will have 4 of these custom buttons on the home screen, which is why I factored out <MyIconButton>.
btw - this is for a mobile App and I read (and noticed this myself) it's really slow using checkboxes on mobile browsers; that's why I chose to try this without using checkboxes.
ReactJS code
var MyIconButton = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
console.log("INSIDE: MyIconButton handleSubmit");
// Change button's state ON/OFF,
// then sends state up the food chain via
// this.props.updateFilter( b_buttonOn ).
var b_buttonOn = false;
if (this.props.pressed === true) {
b_buttonOn = false;
}
else {
b_buttonOn = true;
}
// updateFilter is a 'pointer' to a method in the calling React component.
this.props.updateFilter( b_buttonOn );
},
render: function() {
// Show On or Off image.
// ** I could use ? : inside the JSX/HTML but prefer long form to make it explicitly obvious.
var buttonImg = "";
if (this.props.pressed === true) {
buttonImg = this.props.onpic;
}
else {
buttonImg = this.props.offpic;
}
return (
<div>
<form onSubmit={this.handleSubmit}>
<input type="image" src={buttonImg}></input>
</form>
</div>
);
}
});
// <MyPartyCatButton> Doesn't have it's own state,
// passes state of <MyIconButton>
// straight through to <MyHomeView>.
var MyPartyCatButton = React.createClass({
render: function() {
return (
<MyIconButton pressed={this.props.pressed} updateFilter={this.props.updateFilter} onpic="static/images/icon1.jpeg" offpic="static/images/off-icon.jpg"/>
);
}
});
//
// Main App view
var MyHomeView = React.createClass({
getInitialState: function() {
// This is where I'll eventually get data from the server.
return {
b_MyPartyCat: true
};
},
updatePartyCategory: function(value) {
// Eventually will write value to the server.
this.setState( {b_MyPartyCat: value} );
console.log("INSIDE: MyHomeView() updatePartyCategory() " + this.state.b_MyPartyCat );
},
render: function() {
return (
<div>
<MyPartyCatButton pressed={this.state.b_MyPartyCat} updateFilter={this.updatePartyCategory}/>
</div>
// Eventually will have 3 other categories i.e. Books, Skateboards, Trees !
);
}
});
if you update the coponent 'pressed' prop dynamically (like you did), simply
var MyIconButton= React.createClass({
render: function(){
var pic= this.props.pressed? this.props.onpic : this.props.offpic
return <img
src={pic}
onClick={this.props.tuggleSelection} //updateFilter is wierd name
/>
}
})
(EDIT: this way, on MyPartyCatButton component, you can pass function to handle 'tuggleSelection' event. event function argument is an event object, but you have the button state allready in the wrapper state (the old one, so you should invert it). your code will be something like that:
render: function(){
return <MyIconButton pressed={this.state.PartyCatPressed} tuggleSelection={this.updatePartyCategory} />
}
updatePartyCategory: function(e){
this.setState(
{PartyCatPressed: !this.state.PartyCatPressed} //this invert PartyCatPressed value
);
console.log("INSIDE: MyHomeView() updatePartyCategory() " + this.state.b_MyPartyCat )
}
)
but if you don't, use prop for defult value:
var MyIconButton= React.createClass({
getInitialState: function(){
return {pressed: this.props.defultPressed}
},
handleClick: function(){
this.setState({pressed: !this.state.pressed})
},
render: function(){
var pic= this.state.pressed? this.props.onpic : this.props.offpic
return <img
src={pic}
onClick={this.handleClick}
/>
}
})

Making sure my form isn't being submitted multiple times with jquery show/hide

So when someone hits Reply, I am attempting to pop-up a form to type your response. Once the form is submitted, it disappears until the next time you hit Reply.
This is working except after the 1st time, I am submitting the information twice. If I do it a third time, the form submits three times. Essentially what is happening is the previous form doesn't seem to be resetting after I hide it again.
I checked this website/google and have tried using reset() but it didn't work. Below is the code:
$(document).on('click', '.secretfeed button', function () {
var message_id = $(this).attr('name');
$(".comment_box").show();
$("#m_id").val(message_id);
var value = document.getElementById("m_id").value;
$('#comment_form').submit(function (e) {
e.preventDefault();
var commentData = $(this).serialize();
$.post('../../process_comment.php', commentData, processData);
function processData(data) {
//$('comment_form').reset()
$(".comment_box").hide();
$('#comment_form')[0].reset();
RefreshFeed();
}
});
});
Rather than initializing the submit function on every click, move it outside the click function. jQuery may be creating an instance of it for each click.
$('#comment_form').submit(function (e) {
e.preventDefault();
var commentData = $(this).serialize();
$.post('../../process_comment.php', commentData, processData);
function processData(data) {
//$('comment_form').reset()
$(".comment_box").hide();
$('#comment_form')[0].reset();
RefreshFeed();
}
});
$(document).on('click', '.secretfeed button', function () {
var message_id = $(this).attr('name');
$(".comment_box").show();
$("#m_id").val(message_id);
var value = $("#m_id").val();
});
The alternative is to unbind the click function before reusing it.
We want a reusable way to handle the state. We will save the state of the button in a boolean which gets turned on and off depending on the status of the request. The pattern is the following:
var isSending = false;
function onSubmit() {
isSending = true;
// Send data
}
function onComplete() {
// done sending data
isSending = false;
}
if (!isSending) {
onSubmit();
}
// When data sending is finished:
onComplete();
The above can be encapsulated in a more functional way that uses promises to manage the state. (jQuery AJAX functions all return a promise-like object):
function oneAtATimeFunction(promisedFunction) {
var pendingPromise;
function reset() { pendingPromise = null; }
return function() {
if (pendingPromise) { return pendingPromise; }
pendingPromise = promisedFunction.apply(promisedFunction, arguments)
.always(reset);
return pendingPromise;
}
}
function submitForm() {
return $.ajax({
url: '/foo',
method: 'POST',
data: { data: 'from form' }
});
}
$('#submit-button').on('click', oneAtATimeFunction(submitForm));
Adding a little flare to the UI We can add a way to turn on and off the submit button. First we will define a helper function to handle the on and off state:
function buttonEnable(enabled) {
$('#submit-button').attr('disabled', !enabled);
}
buttonEnable(false); // disable the button
buttonEnable(true); // enable the button
Putting it all together:
function onClick() {
buttonEnable(false);
return onSubmit()
.always($.proxy(buttonEnable, null, true));
// The above is also the same as:
// .always(function() { buttonEnable(true); });
}
$('#submit-button').on('click', oneAtATimeFunction(onClick));
To see this in action here is a JSBin example.

Categories

Resources