I am turning a React.js component into a Common.js module using module.exports and am having an issue accessing "this" in the context of the component element from one of it's methods.
Below is the entire component. I have placed a comment above the line where the problem occurs. I did try a less verbose example at first but I do not think it was sufficient to explain the issue.
var React = require('react');
var GSAP = require('gsap');
var Psychedelicon = React.createClass({
cycleColors: function() {
var touchPlatforms = ['iPhone', 'iPad', 'iPod', 'Android', 'Linux armv7l', 'WinCE'];
isTouch = false;
iDevice = false;
isDroid = false;
plat = navigator.platform;
if(plat === 'iPhone' || plat === 'iPad' || plat === 'iPod') {
isTouch = true;
iDevice = true;
}
else if (plat === 'Linux armv7l' || plat === 'Android') {
isTouch = true;
isDroid = true;
}
else {
for (var i = 0; i < touchPlatforms.length; i++) {
if (plat === touchPlatforms[i]) {
isTouch = true;
break;
}
else {
isTouch = false;
}
}
}
var isIE = false
if (navigator.userAgent.toLowerCase().indexOf('msie') > -1 || navigator.userAgent.toLowerCase().indexOf('trident') > -1) {
isIE = true
}
var isFF = false
if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
isFF = true
}
if(!isTouch) {
var ColorSwirl = function(colorSet,defaultColor,time) {
var storedResult;
var randomColor = function(theArray) {
var result = theArray[Math.floor(Math.random() * (theArray.length))];
if(result === storedResult){
return(defaultColor)
}
else {
storedResult = result;
return(result);
}
}
var theLuckyColors = {top:randomColor(colorSet),bottom:randomColor(colorSet)};
var swirl = function(){
//!!!!On this line the problem occurs onUpdateParams must reference the element accepting the execution event (onMouseEneter)
TweenLite.to(theLuckyColors, time, {colorProps:{top:randomColor(colorSet), bottom:randomColor(colorSet)}, onUpdate:colorize, onUpdateParams:[this],onComplete:swirl});
}
gradients
var colorize = function(el) {
if(isIE) {
TweenLite.set(el, {
backgroundImage:'-ms-radial-gradient(center,circle cover,' + theLuckyColors.top + ' 0%, ' + theLuckyColors.bottom + ' 100%)'
});
}
else if(isFF) {
TweenLite.set(el, {
backgroundImage:'-moz-radial-gradient(center,circle cover,' + theLuckyColors.top + ' 0%, ' + theLuckyColors.bottom + ' 100%)'
});
}
else {
TweenLite.set(el, {
backgroundImage:'radial-gradient(circle,' + theLuckyColors.top + ', ' + theLuckyColors.bottom + ')',
backgroundImage:'-webkit-radial-gradient(circle,' + theLuckyColors.top + ', ' + theLuckyColors.bottom + ')'
});
}
}
swirl();
}
ColorSwirl(['red','green','#4B0082','#9F00FF','yellow','orange'],'blue',.15);
}
},
stopTheCycle: function() {
},
render: function() {
return (
<a className="psychedelicon" href={this.props.href} target={this.props.target} onMouseEnter={this.cycleColors} onMouseLeave={this.stopTheCycle}>
<i className={"fa fa-" + this.props.icon}></i>
</a>
)
}
});
module.exports = Psychedelicon;
So far I have tried to bind "this" to the the element receiving the event:
onMouseEnter={this.cycleColors.bind(this)}
and I got: `'You are binding a component method to the component. React does this for you automatically in a high-performance way, so you can safely remove this call.'
I also tried:
onMouseEnter={this.cycleColors.call(Psychedelicon)}
and
onMouseEnter={this.cycleColors.bind(Psychedelicon)}
which both produced no error but did not work
I know that the function otherwise works because when I change
onUpdateParams:[this]
to
onUpdateParams:['.psychedelicon']
The component produces the desired behavior, except that it effects all of the components at the same time (which I need to avoid hence needing to use "this").
I must be missing something. Any help is appreciated.
So I was able to solve my own problem. Here is the code that did the trick:
var React = require('react');
var GSAP = require('gsap');
var $ = require('jquery')
var Psychedelicon = React.createClass({
componentDidMount: function() {
var that = React.findDOMNode(this.refs.psicon);
$(that).hover(function() {
//detect device type for Psychedelicon
var touchPlatforms = ['iPhone', 'iPad', 'iPod', 'Android', 'Linux armv7l', 'WinCE'];
isTouch = false;
iDevice = false;
isDroid = false;
plat = navigator.platform;
if(plat === 'iPhone' || plat === 'iPad' || plat === 'iPod') {
isTouch = true;
iDevice = true;
}
else if (plat === 'Linux armv7l' || plat === 'Android') {
isTouch = true;
isDroid = true;
}
else {
for (var i = 0; i < touchPlatforms.length; i++) {
if (plat === touchPlatforms[i]) {
isTouch = true;
break;
}
else {
isTouch = false;
}
}
}
//sniff the for ie
var isIE = false
if (navigator.userAgent.toLowerCase().indexOf('msie') > -1 || navigator.userAgent.toLowerCase().indexOf('trident') > -1) {
isIE = true
}
//sniff for firefox
var isFF = false
if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
isFF = true
}
//Begin ColorSwirl on non-touch devices
if(!isTouch) {
//Define the Color Sets
var ColorSwirl = function(colorSet,defaultColor,time) {
//Pick random color. If the color is the same as the previous one pick blue instead.
var storedResult;
var randomColor = function(theArray) {
var result = theArray[Math.floor(Math.random() * (theArray.length))];
if(result === storedResult){
return(defaultColor)
}
else {
storedResult = result;
return(result)
}
}
//Pick our colors for the initial state
var theLuckyColors = {top:randomColor(colorSet),bottom:randomColor(colorSet)};
//Start swirling
$(that).addClass('swirling');
var swirl = function(){
if($(that).hasClass('swirling')) {
TweenLite.to(theLuckyColors, time, {colorProps:{top:randomColor(colorSet), bottom:randomColor(colorSet)}, onUpdate:colorize, onUpdateParams:[that],onComplete:swirl});
}
}
//Detect Browser and Pass Psychedelicon the appropriate radial gradients
var colorize = function(el) {
if(isIE) {
TweenLite.set(el, {
backgroundImage:'-ms-radial-gradient(center,circle cover,' + theLuckyColors.top + ' 0%, ' + theLuckyColors.bottom + ' 100%)'
});
}
else if(isFF) {
TweenLite.set(el, {
backgroundImage:'-moz-radial-gradient(center,circle cover,' + theLuckyColors.top + ' 0%, ' + theLuckyColors.bottom + ' 100%)'
});
}
else {
TweenLite.set(el, {
backgroundImage:'radial-gradient(circle,' + theLuckyColors.top + ', ' + theLuckyColors.bottom + ')',
backgroundImage:'-webkit-radial-gradient(circle,' + theLuckyColors.top + ', ' + theLuckyColors.bottom + ')'
});
}
}
swirl();
}
ColorSwirl(['red','green','#4B0082','#9F00FF','yellow','orange'],'blue',.15);
}
},function() {
var theLuckyColors = {top:'#FFFFFF',bottom:'#FFFFFF'};
var stopNow = function(time){
$(that).removeClass('swirling');
TweenLite.to(theLuckyColors, time, {colorProps:{top:'#FFFFFF', bottom:'#FFFFFF'}, onUpdate:whiteWash, onUpdateParams:[that]});
}
var whiteWash = function(el) {
TweenLite.set(el, {
backgroundImage:'-ms-radial-gradient(center,circle cover,#FFFFFF 0%, #FFFFFF 100%)',
backgroundImage:'-moz-radial-gradient(center,circle cover,#FFFFFF 0%, #FFFFFF 100%)',
backgroundImage:'radial-gradient(circle,#FFFFFF,#FFFFFF)',
backgroundImage:'-webkit-radial-gradient(circle,#FFFFFF,#FFFFFF)'
});
}
stopNow(.15);
});
},
render: function() {
return (
<a className="psychedelicon" ref="psicon" href={this.props.href} target={this.props.target} onMouseEnter={this.cycleColors} onMouseLeave={this.stopTheCycle}>
<i className={"fa fa-" + this.props.icon}></i>
</a>
)
}
})
module.exports = Psychedelicon;
Here is how I got from the problem to the solution:
When I was unable to produce a result by using "call" as was suggested by #Alexander O'Mara, i required jQuery to speed up testing and added the variable
var that = $(this)
to the component's outermost scope, so that I could access the component itself from the scope of the inner functions like so:
//Note that onUpdateParams now references "that" which is equal to "this" in the scope of the actual component.
TweenLite.to(theLuckyColors, time, {colorProps:{top:randomColor(colorSet), bottom:randomColor(colorSet)}, onUpdate:colorize, onUpdateParams:[that],onComplete:swirl});
this failed again so I logged the value of "this" to the console and saw that I was actually referencing the component's constructor and not the rendered output!
I had a look at the docs again and saw that I could reference the rendered output on every render instance by using a reactjs attribute called "refs". I needed only to give the rendered element a "ref" attribute:
render: function() {
return (
<a className="psychedelicon" ref="psicon" href={this.props.href} target={this.props.target} onMouseEnter={this.cycleColors} onMouseLeave={this.stopTheCycle}>
<i className={"fa fa-" + this.props.icon}></i>
</a>
)
}
and reference the ref in my method, which I decided to run out of "componentDidMount" instead.
var that = React.findDOMNode(this.refs.psicon);
Now, everytime I reference "that" I am referencing the rendered element itself (pretty impresive considering it's re-rendering every .15 seconds on mouseover) and everything is peachy!
UPDATE: This answer does not apply to React, but was in response to a more-general previous version of the question.
This looks like another argument for not using the onclick attribute, but you could use the call or apply method, and pass this as the first argument.
<div id="foo" onClick="Module.addClass.call(this)"></div>
However you might want to consider using addEventListener or jQuery's event delegation instead.
Related
on page load I run this function to hide long quoted posts into a clickable link to prevent huge comments on my site:
function hide_long_quotes()
{
$('.comments .comment_quote').each(function(i)
{
var actual_text = $(this).text();
var content = $(this).outerHTML();
if(actual_text.length > showChar)
{
var cite = $(this).find('cite span.username').first().text();
var cite_link = '';
if (cite.length > 0)
{
cite_link = 'from ' + cite;
}
var html = '<span class="morecontent">' + content + '</span>' + moretext + cite_link + '<br />';
$(this).replaceWith(html);
}
if (i+1 === quote_count) // this will be executed at the end of the loop
{
// deal with being linked to a comment, so we can put the window to the correct scroll position, since it will be different due to hidden quotes making the page smaller
if(window.location.hash)
{
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if (hash.indexOf("r") >= 0)
{
$('#'+hash)[0].scrollIntoView();
}
}
}
});
}
The problem is that when I reload ".comments" through ajax/load the above function no longer works:
function paginate_comments(page, article_id)
{
var url = "/includes/ajax/post_comment.php";
var current_url = window.location.href;
var host = window.location.host;
if(current_url.indexOf(host + '/admin.php?module=reviewqueue') != -1 || current_url.indexOf(host + '/admin.php?module=articles&view=Submitted') != -1 || current_url.indexOf(host + '/admin.php?module=articles&view=Submitted') != -1)
{
var area = 'admin';
}
else
{
var area = 'normal';
}
$('.comments').load(url, {'type':'reload', 'article_id': article_id, 'page': page, 'area': area}, function()
{
$(".lb-container").show();
$('.box.comments').get(0).scrollIntoView();
hide_long_quotes();
});
}
Not sure why it doesn't work, as the function is being called in the completed callback part of the load function?
What about giving the element collection to that function:
function hide_long_quotes(var comments = false)
{ /* for the case that you don't pass a collection to the function, maybe in the first call when the page is loaded */
comments = comments ? comments : $('.comments .comment_quote');
comments.each(function(i)
{
...
}
function paginate_comments(page, article_id)
{
...
$('.comments').load(
url,
{
'type':'reload',
'article_id': article_id,
'page': page,
'area': area
},
function()
{
$(".lb-container").show();
$('.box.comments').get(0).scrollIntoView();
hide_long_quotes($('.comments .comment_quote'));
}
);
}
I'm new to Nativescript (used to be a Corona/Lua developer) and I need to create a function (similar to a RuntimeEventListener in Lua) that constantly gets user location and updates a dashboard with speed and altitude, for example.
My current code gets this info only when a button is pressed (which does not make sense for the kind of app I am trying to build). Question is, how to create and invoke such listener/function?
I am coding in Javascript and below it is my current code:
var Observable = require("data/observable").Observable;
var frames = require("ui/frame");
var orientation = require('nativescript-orientation');
orientation.enableRotation(); // The screen will rotate
console.log(orientation.getOrientation()); // Returns the enum DeviceOrientation value
var dialogs = require("ui/dialogs");
// Get geo coordinates
var geolocation = require("nativescript-geolocation");
if (!geolocation.isEnabled()) {
geolocation.enableLocationRequest();
}
/*
var watchID
watchId = geolocation.watchLocation(
function (loc) {
if (loc) {
console.log("(watchid) Received location: " + loc);
}
},
function(e){
console.log("(watchid) Error: " + e.message);
},
{desiredAccuracy: 3, updateDistance: 10, minimumUpdateTime : 1000 * 20}); // should update every 20 sec according to google documentation this is not so sure.
*/
//variables for the dashboard and the Origin
var originLoc //holds the lat,long of the starting point
var originHeading = "NNW"
var originTime = "0"
var originDistance = "0"
var mySpeed = "0"
var myDuration = "00:00"
var myDistance = "0"
var myAltitude = "0";
var myDirection;
var butAction = "START" //button action when it starts
var fbMeasurement = "imperial";
//Sets the right heading of the compass (if landscape, subtracts 90 degrees)
function headingCompass(args) {
var compassHead = "";
if (args>12 && args<=34) {
compassHead = "NNE";
} else if (args>34 && args<=57) {
compassHead = "NE";
} else if (args>57 && args<=80) {
compassHead = "ENE";
} else if (args>80 && args<=102) {
compassHead = "E";
} else if (args>102 && args<=124) {
compassHead = "ESE";
} else if (args>124 && args<=147) {
compassHead = "SE";
} else if (args>147 && args<=170) {
compassHead = "SSE";
} else if (args>170 && args<=192) {
compassHead = "S";
} else if (args>192 && args<=215) {
compassHead = "SSW";
} else if (args>215 && args<=237) {
compassHead = "SW";
} else if (args>237 && args<=260) {
compassHead = "WSW";
} else if (args>260 && args<=282) {
compassHead = "W";
} else if (args>282 && args<=305) {
compassHead = "WNW";
} else if (args>305 && args<=327) {
compassHead = "NW";
} else if (args>327 && args<=350) {
compassHead = "NNW";
} else {
compassHead = "N";
}
return compassHead;
}
//Gets current location when app starts
var geolocation = require("nativescript-geolocation");
if (!geolocation.isEnabled()) {
geolocation.enableLocationRequest();
}
var location = geolocation.getCurrentLocation({desiredAccuracy: 3, updateDistance: 10, maximumAge: 20000, timeout: 20000}).
then(function(loc) {
if (loc) {
console.log("Current location is: " + loc);
originLoc = loc;
if (fbMeasurement === "imperial") {
myAltitude = parseInt(loc.altitude * 3.28084);
mySpeed = (loc.speed * 2.23694).toFixed(1);
} else {
mySpeed = loc.speed.toFixed(1);
myAltitude = parseInt(loc.altitude);
}
myDirection = headingCompass(loc.direction)
}
}, function(e){
console.log("Error: " + e.message);
});
function createViewModel() {
var viewModel = new Observable();
viewModel.originHeading = originHeading;
viewModel.originTime = originTime;
viewModel.originDistance = originDistance;
viewModel.mySpeed = mySpeed;
viewModel.myDuration = myDuration;
viewModel.myDistance = myDistance;
viewModel.myAltitude = myAltitude;
viewModel.butAction = butAction;
//STARTs
var watchid;
viewModel.onTapStart = function(args) {
if (butAction==="START") {
//change button color to RED
var btn = args.object;
btn.backgroundColor = "#FF0000";
//change button text to "STOP"
this.set("butAction","STOP");
butAction = "STOP";
watchId = geolocation.watchLocation(
function (loc) {
if (loc) {
console.log("Received location: " + loc);
if (fbMeasurement === "imperial") {
myAltitude = parseInt(loc.altitude * 3.28084);
mySpeed = (loc.speed * 2.23694).toFixed(1);
} else {
mySpeed = loc.speed.toFixed(1);
myAltitude = parseInt(loc.altitude);
}
myDirection = headingCompass(loc.direction);
}
},
function(e){
console.log("Error: " + e.message);
},
{desiredAccuracy: 3, updateDistance: 10, minimumUpdateTime : 1000 * 1}); // should update every 20 sec according to google documentation this is not so sure.
} else {
//change button color to GREEN
var btn = args.object;
btn.backgroundColor = "#00FF00";
//change button text to "START"
this.set("butAction","START")
butAction = "START";
if (watchId) {
geolocation.clearWatch(watchId);
}
}
this.set("myAltitude",myAltitude);
this.set("mySpeed",mySpeed);
this.set("myDistance",myDirection);
}
return viewModel;
}
exports.createViewModel = createViewModel;
The watchlocation method is, in fact, a listener and will update your location when it is changed (based on this arguments). However, you will need to use some observable properties to update the info and reuse it where and when needed. Also, keep in mind that in Android the location is sometimes triggered after some distance (in my case approx. 100 steps gave the difference in the fourth sign after the dot).
If you are familiar with MVVM pattern this is the one used on regular basis in NativeScript applications.Here you can find the article for Data Binding in NativeScript.
So basically just execute your watch function (e.g. using loaded event for your Page) and then watch for changes in the Observable model (e.g. create Observable property latitude and use the updated info when and where needed)
e.g.
vm = new Observable();
vm.set("altitude", someDefaultValue);
vm.set("longitude", someDefaultValue);
geolocation.watchLocation(function(loc) {
vm.set("altitude", loc.altitude);
vm.set("longitude", loc.longitude);
console.log(vm.get("altitude")); // Observable model updated
console.log(vm.get("longitude"));
})
I am creating an inventory for object, When I pick object it stores in inventory but my display line (Press E to pick up) still showing.
method ONGUI, I think making some problem,
Here is code of FPS pickup.
#pragma strict
var InstructionBoxSkin : GUISkin;
var ButtonToPress : KeyCode = KeyCode.E;
var PickUpDistance = 1.7f;
private var canPickUp = false;
private var theItem : Item;
private var thePlayer : Transform;
private var dist = 9999f;
#script AddComponentMenu ("Inventory/Items/First Person Pick Up")
#script RequireComponent(Item)
function Awake ()
{
theItem = (GetComponent(Item));
if (InstructionBoxSkin == null)
{
InstructionBoxSkin = Resources.Load("OtherSkin", GUISkin);
}
}
function RetrievePlayer (theInv : Inventory)
{
thePlayer = theInv.transform.parent;
}
function OnGUI ()
{
//This is where we draw a box telling the Player how to pick up the item.
//
GUI.skin = InstructionBoxSkin;
GUI.color = Color(1, 1, 1, 0.7);
if (canPickUp == true)
{
if (transform.name.Length <= 1)
{
GUI.Box (Rect (Screen.width*0.5-(165*0.5), 200, 165, 22), "Press E to pick up " + transform.name + ".");
}
else
{
GUI.Box (Rect (Screen.width*0.5-(185*0.5), 200, 185, 22), "Press E to pick up " + transform.name + ".");
}
}
}
function Update ()
{
if (thePlayer != null)
{
dist = Vector3.Distance(thePlayer.position, transform.position);
if (dist <= PickUpDistance)
{
canPickUp = true;
}
else
{
canPickUp = false;
}
//This is where we allow the player to press the ButtonToPress to pick up the item.
if (Input.GetKeyDown(ButtonToPress) && canPickUp == true)
{
theItem.PickUpItem();
}
}
}
function OnDrawGizmosSelected ()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere (transform.position, PickUpDistance);
}
What could be the reason?
It looks like canPickUp is never set to false.
Does changing:
if (Input.GetKeyDown(ButtonToPress) && canPickUp == true)
{
theItem.PickUpItem();
canPickUp = false;
}
resolve the issue?
The question is very simple but also a bit theoretical.
Let's imagine you have a long JQuery script which modifies and animate the graphics of the web site. It's objective is to handle the UI. The UI has to be responsive so the real need for this JQuery is to mix some state of visualization (sportlist visible / not visible) with some need due to Responsive UI.
Thinking from an MVC / AngularJS point of view. How should a programmer handle that?
How to refactor JS / JQuery code to implement separation of concerns described by MVC / AngularJS?
I provide an example of JQuery code to speak over something concrete.
$.noConflict();
jQuery(document).ready(function ($) {
/*variables*/
var sliderMenuVisible = false;
/*dom object variables*/
var $document = $(document);
var $window = $(window);
var $pageHost = $(".page-host");
var $sportsList = $("#sports-list");
var $mainBody = $("#mainBody");
var $toTopButtonContainer = $('#to-top-button-container');
/*eventHandlers*/
var displayError = function (form, error) {
$("#error").html(error).removeClass("hidden");
};
var calculatePageLayout = function () {
$pageHost.height($(window).height());
if ($window.width() > 697) {
$sportsList.removeAttr("style");
$mainBody
.removeAttr("style")
.unbind('touchmove')
.removeClass('stop-scroll');
if ($(".betslip-access-button")[0]) {
$(".betslip-access-button").fadeIn(500);
}
sliderMenuVisible = false;
} else {
$(".betslip-access-button").fadeOut(500);
}
};
var formSubmitHandler = function (e) {
var $form = $(this);
// We check if jQuery.validator exists on the form
if (!$form.valid || $form.valid()) {
$.post($form.attr("action"), $form.serializeArray())
.done(function (json) {
json = json || {};
// In case of success, we redirect to the provided URL or the same page.
if (json.success) {
window.location = json.redirect || location.href;
} else if (json.error) {
displayError($form, json.error);
}
})
.error(function () {
displayError($form, "Login service not available, please try again later.");
});
}
// Prevent the normal behavior since we opened the dialog
e.preventDefault();
};
//preliminary functions//
$window.on("load", calculatePageLayout);
$window.on("resize", calculatePageLayout);
//$(document).on("click","a",function (event) {
// event.preventDefault();
// window.location = $(this).attr("href");
//});
/*evet listeners*/
$("#login-form").submit(formSubmitHandler);
$("section.navigation").on("shown hidden", ".collapse", function (e) {
var $icon = $(this).parent().children("button").children("i").first();
if (!$icon.hasClass("icon-spin")) {
if (e.type === "shown") {
$icon.removeClass("icon-caret-right").addClass("icon-caret-down");
} else {
$icon.removeClass("icon-caret-down").addClass("icon-caret-right");
}
}
toggleBackToTopButton();
e.stopPropagation();
});
$(".collapse[data-src]").on("show", function () {
var $this = $(this);
if (!$this.data("loaded")) {
var $icon = $this.parent().children("button").children("i").first();
$icon.removeClass("icon-caret-right icon-caret-down").addClass("icon-refresh icon-spin");
console.log("added class - " + $icon.parent().html());
$this.load($this.data("src"), function () {
$this.data("loaded", true);
$icon.removeClass("icon-refresh icon-spin icon-caret-right").addClass("icon-caret-down");
console.log("removed class - " + $icon.parent().html());
});
}
toggleBackToTopButton();
});
$("#sports-list-button").on("click", function (e)
{
if (!sliderMenuVisible)
{
$sportsList.animate({ left: "0" }, 500);
$mainBody.animate({ left: "85%" }, 500)
.bind('touchmove', function (e2) { e2.preventDefault(); })
.addClass('stop-scroll');
$(".betslip-access-button").fadeOut(500);
sliderMenuVisible = true;
}
else
{
$sportsList.animate({ left: "-85%" }, 500).removeAttr("style");
$mainBody.animate({ left: "0" }, 500).removeAttr("style")
.unbind('touchmove').removeClass('stop-scroll');
$(".betslip-access-button").fadeIn(500);
sliderMenuVisible = false;
}
e.preventDefault();
});
$mainBody.on("click", function (e) {
if (sliderMenuVisible) {
$sportsList.animate({ left: "-85%" }, 500).removeAttr("style");
$mainBody.animate({ left: "0" }, 500)
.removeAttr("style")
.unbind('touchmove')
.removeClass('stop-scroll');
$(".betslip-access-button").fadeIn(500);
sliderMenuVisible = false;
e.stopPropagation();
e.preventDefault();
}
});
$document.on("click", "div.event-info", function () {
if (!sliderMenuVisible) {
var url = $(this).data("url");
if (url) {
window.location = url;
}
}
});
function whatDecimalSeparator() {
var n = 1.1;
n = n.toLocaleString().substring(1, 2);
return n;
}
function getValue(textBox) {
var value = textBox.val();
var separator = whatDecimalSeparator();
var old = separator == "," ? "." : ",";
var converted = parseFloat(value.replace(old, separator));
return converted;
}
$(document).on("click", "a.selection", function (e) {
if (sliderMenuVisible) {
return;
}
var $this = $(this);
var isLive = $this.data("live");
var url = "/" + _language + "/BetSlip/Add/" + $this.data("selection") + "?odds=" + $this.data("odds") + "&live=" + isLive;
var urlHoveringBtn = "/" + _language + '/BetSlip/AddHoveringButton/' + $this.data("selection") + "?odds=" + $this.data("odds") + "&live=" + isLive;
$.ajax(urlHoveringBtn).done(function (dataBtn) {
if ($(".betslip-access-button").length == 0 && dataBtn.length > 0) {
$("body").append(dataBtn);
}
});
$.ajax(url).done(function (data) {
if ($(".betslip-access").length == 0 && data.length > 0) {
$(".navbar").append(data);
$pageHost.addClass("betslipLinkInHeader");
var placeBetText = $("#live-betslip-popup").data("placebettext");
var continueText = $("#live-betslip-popup").data("continuetext");
var useQuickBetLive = $("#live-betslip-popup").data("usequickbetlive").toLowerCase() == "true";
var useQuickBetPrematch = $("#live-betslip-popup").data("usequickbetprematch").toLowerCase() == "true";
if ((isLive && useQuickBetLive) || (!isLive && useQuickBetPrematch)) {
var dialog = $("#live-betslip-popup").dialog({
modal: true,
dialogClass: "fixed-dialog"
});
dialog.dialog("option", "buttons", [
{
text: placeBetText,
click: function () {
var placeBetUrl = "/" + _language + "/BetSlip/QuickBet?amount=" + getValue($("#live-betslip-popup-amount")) + "&live=" + $this.data("live");
window.location = placeBetUrl;
}
},
{
text: continueText,
click: function () {
dialog.dialog("close");
}
}
]);
}
}
if (data.length > 0) {
$this.addClass("in-betslip");
}
});
e.preventDefault();
});
$(document).on("click", "a.selection.in-betslip", function (e) {
if (sliderMenuVisible) {
return;
}
var $this = $(this);
var isLive = $this.data("live");
var url = "/" + _language + "/BetSlip/RemoveAjax/" + $this.data("selection") + "?odds=" + $this.data("odds") + "&live=" + isLive;
$.ajax(url).done(function (data) {
if (data.success) {
$this.removeClass("in-betslip");
if (data.selections == 0) {
$(".betslip-access").remove();
$(".betslip-access-button").remove();
$(".page-host").removeClass("betslipLinkInHeader");
}
}
});
e.preventDefault();
});
$("section.betslip .total-stake button.live-betslip-popup-plusminus").click(function (e) {
if (sliderMenuVisible) {
return;
}
e.preventDefault();
var action = $(this).data("action");
var amount = parseFloat($(this).data("amount"));
if (!isNumeric(amount)) amount = 1;
var totalStake = $("#live-betslip-popup-amount").val();
if (isNumeric(totalStake)) {
totalStake = parseFloat(totalStake);
} else {
totalStake = 0;
}
if (action == "decrease") {
if (totalStake < 1.21) {
totalStake = 1.21;
}
totalStake -= amount;
} else if (action == "increase") {
totalStake += amount;
}
$("#live-betslip-popup-amount").val(totalStake);
});
toggleBackToTopButton();
function toggleBackToTopButton() {
isScrollable() ? $toTopButtonContainer.show() : $toTopButtonContainer.hide();
}
$("#to-top-button").on("click", function () { $("#mainBody").animate({ scrollTop: 0 }); });
function isScrollable() {
return $("section.navigation").height() > $(window).height() + 93;
}
var isNumeric = function (string) {
return !isNaN(string) && isFinite(string) && string != "";
};
function enableQuickBet() {
}
});
My steps in such cases are:
First of all write (at least) one controller
Replace all eventhandler with ng-directives (ng-click most of all)
Pull the view state out of the controller with ng-style and ng-class. In most of all cases ng-show and ng-hide will be sufficed
If there is code that will be used more than once, consider writing a directive.
And code that has nothing todo with the view state - put the code in a service
write unit tests (i guess there is no one until now:) )
How to enable the maximize and restore button of the popup window using Javascript?
You have to open a popup like this:
window.open('url', 'windowname', 'location=0, status=0, resizable=1, scrollbars=1, width=400, height=400');
The trick is to make the window resizable. Search for the window.open() function documentation.
Using the code I pasted on the bottom, you can emulate these buttons by creating them in your website interface.
To maximise: save the current position with Namespace.outerPositionGet() and size with Namespace.outerSizeGet(), then do Namespace.outerPositionSet({left:0,top:0}) and Namespace.outerSizeSet({width:window.screen.availWidth, height:window.screen.availHeight}).
To restore: just set position and size which were saved when maximising.
var Namespace = (function() {
var N, W, framePosition, frameChrome, setFramePosition, setFrameChrome;
N = {};
W = window;
setFramePosition = function() {
var tmp0;
if (typeof framePosition !== 'undefined') {
return;
}
tmp0 = {
top : W.screenTop,
left : W.screenLeft
};
W.moveTo(tmp0.left, tmp0.top);
framePosition = {
top : tmp0.top - W.screenTop,
left : tmp0.left - W.screenLeft
};
W.moveTo(tmp0.left + framePosition.left, tmp0.top + framePosition.top);
};
setFrameChrome = function() {
var tmp0, tmp1;
if (typeof frameChrome !== 'undefined') {
return;
}
tmp0 = N.innerSizeGet();
W.resizeTo(tmp0.width, tmp0.height);
tmp1 = N.innerSizeGet();
frameChrome = {
width : tmp0.width - tmp1.width,
height : tmp0.height - tmp1.height
};
W.resizeTo(tmp0.width + tmp1.width, tmp0.height + tmp1.height);
};
N.outerPositionSet = function(position) {
W.moveTo(position.left, position.top);
};
N.outerPositionGet = function() {
if (typeof W.screenTop !== 'undefined') {
setFramePosition();
N.outerPositionGet = function() {
return {
top : W.screenTop + framePosition.top,
left : W.screenLeft + framePosition.left
};
};
} else if (typeof W.screenY !== 'undefined') {
N.outerPositionGet = function() {
return {
top : W.screenY,
left : W.screenX
};
};
} else {
N.outerPositionGet = function() {
return {
top : 0,
left : 0
};
};
}
return N.outerPositionGet();
};
N.outerSizeSet = function(size) {
W.resizeTo(size.width, size.height);
};
N.outerSizeGet = function() {
if (W.outerWidth) {
N.outerSizeGet = function() {
return {
width : W.outerWidth,
height : W.outerHeight
};
};
} else {
setFrameChrome();
N.outerSizeGet = function() {
var size;
size = N.innerSizeGet();
size.width += frameChrome.width;
size.height += frameChrome.height;
return size;
};
}
return N.outerSizeGet();
};
N.innerSizeSet = function(size) {
setFrameChrome();
N.innerSizeSet = function(size) {
W.resizeTo(size.width + frameChrome.width, size.height + frameChrome.height);
};
N.innerSizeSet(size);
};
N.innerSizeGet = function() {
if (typeof W.innerHeight === 'number') {
N.innerSizeGet = function() {
return {
width : W.innerWidth,
height : W.innerHeight
};
};
return N.innerSizeGet();
}
var isDocumentElementHeightOff, node;
isDocumentElementHeightOff = function() {
var div, r;
div = W.document.createElement('div');
div.style.height = "2500px";
W.document.body.insertBefore(div, W.document.body.firstChild);
r = W.document.documentElement.clientHeight > 2400;
W.document.body.removeChild(div);
return r;
};
if (typeof W.document.clientWidth === 'number') {
node = W.document;
} else if ((W.document.documentElement && W.document.documentElement.clientWidth === 0) || isDocumentElementHeightOff()) {
node = W.document.body;
} else if (W.document.documentElement.clientHeight > 0) {
node = W.document.documentElement;
}
N.innerSizeGet = function() {
return {
width : node.clientWidth,
height : node.clientHeight
};
};
return N.innerSizeGet();
};
return N;
})();
I'm assuming you're talking about the alert popup? This can't be done with standard JavaScript.
You best solution would be to try using some of the many popup solutions that have been developed for the various JavaScript frameworks (e.g. jQuery), and seeing if you can tailor this to your particular use.
try this also. its working for me...
window.open('fileURL','status=1,directories=1,menubar=0,toolbar=0,
scrollbars=1,titlebar=0,dialog=1)
You can't, sorry - at least, not universally. The popup is implementation-dependent and there aren't any standard JavaScript methods for controlling it in the manner you describe.