Why is this variable not in scope in coffee script? - coffeescript

I'm using the dashing framework to create a widget. Basically it uses sinatra, batman, and coffee script to create a dashboard.
My code is based off of this widget
I have the following code
coffee script
class Dashing.Countdown extends Dashing.Widget
ready: ->
setInterval(#startCountdown, 500)
startCountdown: =>
color_available
current_timestamp = Math.round(new Date().getTime()/1000)
end_timestamp = Math.round( Date.parse($(#node).find(".more-info").html())/1000 )
seconds_until_end = end_timestamp - current_timestamp
if #get('title') > 'Busy'
# #set('title', 'herpin the derpin')
color_available = true
else
color_available = false
...truncated for readability
#accessor 'isAvailable', ->
true
html
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
<div
data-id="pomodoro"
data-view="Countdown"
data-title="Herp the Derp"
data-end=""
data-addclass-available='isAvailable'>
</div>
</li>
</ul>
</div>
If the accessor 'isAvailable' function returns true, then the 'available' css class is applied which changes the color of the div from red to blue as expected.
However, if I change the accessor function from 'true' to a variable, it says it is undefined.
....
#accessor 'isAvailable', ->
color_available?
From my hours of research on google and stack overflow, It seems like the problem is a scope issue.
I have tried changing every instances of the color_available variable to the global scope with no luck.
#color_available
I've also tried adding color_available to the window
window.color_available = color_available
Can anyone point out why color_available is undefined? I'm brand new to javascript / coffeescript and I"m in a bit over my head.
Resources
How do I define global variables in CoffeeScript?
https://donatstudios.com/CoffeeScript-Madness
Update
I forgot to mention, that I have tried the following approaches to initialize the variable.
startCountdown: =>
color_available
startCountdown: =>
#color_available
color_available
startCountdown: =>
color_available = null
startCountdown: =>

Using #accessor is putting it literally on the prototype object so it would be shared And of course if you add it to every instance of the class, you probably don't want it to be the same for every instance of the class. My guess is that Batman is adding this for you as an instance method, so you should just be able to set it wherever it might make sense to do so:
myInstance = new Dashing.Countdown()
myInstance.isAvailable() #=> true
myInstance.isAvailable = -> false
myInstance.isAvailable() #=> false
maybe? I'd try that. FWIW, you can do do this in pure coffeescript pretty easily without using the #accessor stuff.
class Dashing.Countdown extends Dashing.Widget
constructor: ({#colorAvailable})->
#colorAvailable ?= -> false
isAvailable: #colorAvailable
myInstance = new Dashing.Countdown(colorAvailable: -> true)
myInstance.isAvailable() #=> true
myInstance = new Dashing.Countdown()
myInstance.isAvailable() #=> false

Related

nsubstitute mock method with other arguments Unity

I have a code where I call a method e.g. MyMock.Create(true). I want to replace every call with true to false, when I am testing it in PlayMode. How to do that? I spend hours and I am just starting with NSubstitute so probably it is something quite easy...
Inside visual studio (crtrl + f) find & replace MyMock.Create(true) with MyMock.Create(false) for the whole project. Alternatively you could switch true with false inside the Create method like this
bool tmp = true;
if (param==true)
tmp = false
else
tmp = true
.....
Use tmp instead of the given parameter of the Method MyMock.Create

How to use Optional in Netlogo Extensions

I want to create a netlogo primitive that may receive a boolean or may not. Therefore I want make possible to the user that he uses the primitive of these two ways:
1:
ask Walkers [
qlearningextension:learning
]
2:
ask Walkers [
qlearningextension:learning true
]
I tried to do that with OptionalType, but I could not make it. Is it possible to do what I want? If so, how can I do it?
So OptionalType unfortunately only works with CommandBlockType. For a good example of how that works, check out the sample-scala extension (maybe that's where you saw a reference to it in the first pace). OptionalType will not work with BooleanType.
There is a secondary option, that's a little hacky. You can use RepeatableType along with setting defaultOption and minimumOption in your syntax (so NetLogo knows that 0 arguments is okay/expected). Scala code example:
object RepeatableTypeTest extends api.Command {
override def getSyntax =
commandSyntax(
right = List(BooleanType | RepeatableType),
defaultOption = Some(0),
minimumOption = Some(0)
)
def perform(args: Array[api.Argument], context: api.Context) {
println(args.length)
if (args.length > 0) {
val ref = args(0).getBoolean
println(ref)
} else {
println("No argument given!")
}
}
}
Then you just have to wrap calls with the boolean argument in parenthesis, so NetLogo knows you're not starting a new command (it expects the defaultOption without the parens):
to test
sample-scala:rep-bool
(sample-scala:rep-bool true)
(sample-scala:rep-bool false)
(sample-scala:rep-bool false true false true false)
end
The problem with this, as you can see in the example, is if your users want to they can provide extra useless booleans: (sample-scala:rep-bool false true false false true false false). If your code ignores them they won't have an effect, but they could be confusing or weird to extension users.

SugarCRM 6.5 CE: how to remove button in detailview according to a condition

I'm trying to remove buttons in detail view of a Lead if it is alredy converted.
I saw a similar question and it use javascript to hide buttons. I'm trying to obtain same result via php.
This is my view.detail.php in custom\modules\Leads\views\ folder
class LeadsViewDetail extends ViewDetail {
function __construct(){
parent::__construct();
}
function preDisplay() {
parent::preDisplay();
if($this->bean->converted==1) {
echo "hide";
foreach ($this->dv->defs['templateMeta']['form']['buttons'] as $key => $value) {
unset($this->dv->defs['templateMeta']['form']['buttons'][$key]);
}
} else {
echo "show";
}
}
}
Using this code, after a Quick Repair & Rebuilt, I see "hide" or "show" correctly according to the Lead status but buttons are not updated correctly.
If I open a converted Lead after QR&R, I will never see the buttons.
If I open a unconverted Lead after QR&R, I will see the buttons all times.
I'm stuck with this situation. Can anyone explain me where is the problem? How I can solve it?
Every help is very appreciated.
You can probably handle this without extending the ViewDetail by using Smarty logic ("customCode") in custom/modules/Leads/metadata/detailviewdefs.php. It looks like the Convert button is already only rendered when the user has Edit privileges, so it's not a big deal to add one more condition to it...
$viewdefs['Leads']['DetailView']['templateMeta']['form]['buttons'][] = array('customCode' => '
{if $bean->aclAccess("edit") && $bean->converted}
<input title="{$MOD.LBL_CONVERTLEAD_TITLE}"
accessKey="{$MOD.LBL_CONVERTLEAD_BUTTON_KEY}"
type="button"
class="button"
name="convert"
value="{$MOD.LBL_CONVERTLEAD}"
onClick="document.location=\'index.php?module=Leads&action=ConvertLead&record={$fields.id.value}\'" />
{/if}');
Alternatively, if you do have several conditions and they'd get too messy or difficult for Smarty logic to be reasonable, we can combine a small amount of Smarty Logic with the extended ViewDetail.
This except of custom/modules/Leads/metadata/detailviewdefs.php is actually the out-of-the-box file from SugarCRM CE 6.5.24, where it looks like they've actually tried to make this customization easier by supplying a Smarty var $DISABLE_CONVERT_ACTION. For reference, it simply needs the global config variable disable_convert_lead to be set and enabled, but I suspect that this was a relatively new feature not included in earlier versions. Still, it's a good example of using the View to set a simple Smarty variable that we can pivot on:
<?php
$viewdefs['Leads']['DetailView'] = array (
'templateMeta' => array (
'form' => array (
'buttons' => array (
'EDIT',
'DUPLICATE',
'DELETE',
array (
'customCode' => '{if $bean->aclAccess("edit") && !$DISABLE_CONVERT_ACTION}<input title="{$MOD.LBL_CONVERTLEAD_TITLE}" accessKey="{$MOD.LBL_CONVERTLEAD_BUTTON_KEY}" type="button" class="button" onClick="document.location=\'index.php?module=Leads&action=ConvertLead&record={$fields.id.value}\'" name="convert" value="{$MOD.LBL_CONVERTLEAD}">{/if}',
//Bug#51778: The custom code will be replaced with sugar_html. customCode will be deplicated.
'sugar_html' => array(
'type' => 'button',
'value' => '{$MOD.LBL_CONVERTLEAD}',
'htmlOptions' => array(
'title' => '{$MOD.LBL_CONVERTLEAD_TITLE}',
'accessKey' => '{$MOD.LBL_CONVERTLEAD_BUTTON_KEY}',
'class' => 'button',
'onClick' => 'document.location=\'index.php?module=Leads&action=ConvertLead&record={$fields.id.value}\'',
'name' => 'convert',
'id' => 'convert_lead_button',
),
'template' => '{if $bean->aclAccess("edit") && !$DISABLE_CONVERT_ACTION}[CONTENT]{/if}',
),
),
We can combine this $DISABLE_CONVERT_ACTION reference with a custom/modules/Leads/views/view.detail.php like the following to set it based on whatever condition we want:
<?php
require_once('modules/Leads/views/view.detail.php');
class CustomLeadsViewDetail extends LeadsViewDetail {
/*
* while we might normally like to call parent::display() in this method to
* best emulate what the parnts will do, we instead here copy-and-paste the
* parent methods' content because LeadsViewDetail::display() will set the
* DISABLE_CONVERT_ACTION Smarty var differently than we want.
*/
public function display(){
global $sugar_config;
// Example One: Disable Conversion when status is Converted
$disableConvert = ($this->bean->status == 'Converted');
// Example Two: Disable Conversion when there is at lead one related Call
// where the status is Held
$disableConvert = FALSE;
$this->bean->load_relationships('calls');
foreach($this->bean->calls->getBeans() as $call){
if($call->status == 'Held'){
$disableConvert = TRUE;
break; // exit foreach()
}
}
// Example Three: Disable Conversion if the User is in a specific Role, e.g.
// Interns who are great for data entry in Leads but shouldn't be making
// actual sales
global $current_user;
$disableConvert = $current_user->check_role_membership('No Lead Conversions');
// In any of the above examples, once we have $disableConvert set up
// as we want, let the Smarty template know.
$this->ss->assign("DISABLE_CONVERT_ACTION", $disableConvert);
// copied from ViewDetail::display();
if(empty($this->bean->id)) {
sugar_die($GLOBALS['app_strings']['ERROR_NO_RECORD']);
}
$this->dv->process();
echo $this->dv->display();
}
}

Lift - how to get default value of select using WiringUI

I have an issue with getting default value of select dropdown.
i have fruits val:
val fruits = List("apple", "banana", "other")
and i render a tr with:
<tr id={ theLine.guid }>
<td>
{
SHtml.ajaxSelect(fruits, Full(fruits(0)),
s => {
mutateLine(theLine.guid) {
l => Line(l.guid, l.name, s, l.note)
}
Noop
})
}
</td>
(...)
on page html is rendered correctly with option selected="selected", but when i try to save it to DB i get empty value of fruit. if i change option to 'other' and then i select it back to 'apple', it saves right value.
i add also a println function to addLine to see what values are in this vector, and there is empty value if i dont change fruit option, so i suppose that it is not problem when i process lines to save it to DB.
can you help me with this?
thanks
Gerard
Before you change your select option, you are not triggering the event that calls your function. The function is bound to onChange and that only gets fired when the value changes.
To fix, you could either: Start with an option like "Select a value". This would require the user to change the item, but is the only way to trigger the onchange.
If you don't want to do that, you could add a button and add your logic to a button click handler that would get called when submitted. Something like this should help - you'll need to bind it to your output, either inline as you provided, or via CSS Selectors:
var selected = Full(fruits(0))
SHtml.ajaxSelect(fruits, selected,
s => {
selected = Full(s)
Noop
})
SHtml.ajaxSubmit("Submit", () => {
mutateLine(theLine.guid) {
l => Line(l.guid, l.name, selected, l.note)
}
})

Can't get query results outside the function

I have this class in which i try to initialize array attributes with query results:
class data
minute: []
hour: []
constructor: () ->
findMin = events.find({"aggr":"minute"}).sort({$natural:-1}).limit(120)
findHour = events.find({"aggr":"hour"}).sort({$natural:-1}).limit(14)
findMin.execFind (errMin, resMin) ->
for recMin in resMin
#minute.push recMin
findHour.execFind (errH, resH) ->
for recH in resH
#hour.push recH
So i call smth = new data() and console.log smth and get an empty attributes and an error about undefined not having 'push' method. While i can understand an error i cant get why my arrays are empty. Dont get me wrong - i know this error causes them to be empty, but i tried several kinds of variants. And ive read about acync and callbacks, but still don't have a clue how to use callbacks not to 'alert' smth, but to use it afterwards. If you could help me with that or with some links that could - i would appreciate it SO much.
You have two issues. The one that is causing the error you are observing is that '#' inside of your two callbacks is not bound to your data instance, so you need to use =>. Secondly, and as pointed out by #AaronDufour, your hour and minute arrays are declared at the class level so they will be shared between every instance of data, which I doubt is what you want, so you need to move them into your constructor.
class data
constructor: () ->
#minute = []
#hour = []
findMin = events.find({"aggr":"minute"}).sort({$natural:-1}).limit(120)
findHour = events.find({"aggr":"hour"}).sort({$natural:-1}).limit(14)
findMin.execFind (errMin, resMin) =>
for recMin in resMin
#minute.push recMin
findHour.execFind (errH, resH) =>
for recH in resH
#hour.push recH
I assume you want minute and hour to be instance variables? They must be initialized in the constructor. The way you're doing it now, they're on the prototype, so it won't work properly. Try this:
class data
constructor: () ->
#minute = []
#hour = []
findMin = events.find({"aggr":"minute"}).sort({$natural:-1}).limit(120)
findHour = events.find({"aggr":"hour"}).sort({$natural:-1}).limit(14)
findMin.execFind (errMin, resMin) =>
for recMin in resMin
#minute.push recMin
findHour.execFind (errH, resH) =>
for recH in resH
#hour.push recH