Reactively add class after Session changes - meteor

I have a Session named dropdownVisible.
Session.setDefault('dropdownVisible', false)
I have the following template / event
template(name="authUser")
a(id="user-link") User Link
if dropdownVisible
.dropdown-container
p This is a dropdown
Template.authUser.events
'click #user-link': ->
if Session.equals('dropdownVisible',false)
Session.set('dropdownVisible', true)
else
Session.closeDropdown()
Whenever I click on #user-link the dropdown will toggle open/close. This works fine.
Now I am trying to add an extra class to the dropdown container whenever it's rendered.
So I have
Template.loggedOut.rendered = ->
$('.dropdown-container').addClass("test")
This adds the class the first time when it's rendered, but not after that. I suspect it has something to do with reactivity. I tried wrapping it in a Tracker.autorun function but that doesn't work. How can I have the addClass be invoked every time my dropdown opens.
** EDIT
I used the addClass example, but in actually I want to animate the dropdown using _uihooks. I just used the addClass example to make the example simpler as it is probably a similar issue to that I'm facing with the uihooks.
Template.loggedOut.rendered = ->
#find('.parent-of-dropdown-container')._uihooks =
insertElement: (node, next) ->
$(node).addClass("animate").insertBefore(next)

Seems to me that this should do it, no?
Template.authUser.events
'click #user-link': ->
if Session.equals('dropdownVisible',false)
Session.set('dropdownVisible', true)
$('.dropdown-container').addClass("test")
else
Session.closeDropdown()

Ok I found the problem.
The 'next' argument as defined in the insertElement function is the DOM element positioned right after the inserted element ('node'). In this example, there was none, as 'node' (.dropdown-container) was the only element inside the wrapping container. Hence it never got inserted.

Related

Is it possible to load AppMaker DropDowns with an Option Text and and Value?

I've been able to set the options on an AppMaker DropDown by doing this sort of thing:
google.script.run
.withSuccessHandler(function(oA){app.pages.Notes.descendants.Dropdown1.options=oA;})
.getSelectOptions();//oA is just an array
But I'd like to know how to do load different values in the options and value like we can do it in javascript with something like this:
function updateSelect(vA){
var select = document.getElementById("sel1");
select.options.length = 0;
for(var i=0;i<vA.length;i++)
{
select.options[i] = new Option(vA[i].option,vA[i].value);
}
}
And I tried this by trying to get a hold of the dom element as follows:
var elem=app.pages.myPage.descendants.myDropDown.getElement();
elem.options.length=0;//always gives me an error because options doesn't seem to exist in that object.
So for now I've been using the standard HTML dom elements in an AppMaker Html widget and that works okay as long as your select is on the first page. If it's not on the first page I have found that the onChange event can't load Widgets on pages that are not visible. It is interesting to note however that you can change the contents of HTML widgets even if they are on other non visible pages.
Anyway the simple question is how can one load one thing into value and another thing into option text in an AppMaker DropDown Widget?
<option value="value">text</option>
If you have a predefined array for your options and values you could do the following for your onAttach Event of your dropdown:
var options = ['one thing','two thing','three thing'];
var names = ['another one thing','another two thing','another three thing'];
widget.options = options;
widget.names = names;
In this case the values that would get recorded would be the options array, but the items that would be displayed would be from the names array. Hope this gets you on the right path.

Attach drop event to a ui-hook instance

I am using the gwendall:ui-hooks' package and it works fine.(rendered with animation as expected on an event that changes the inside "find()" reactive var.).
My problem is that I didn't find a way to re render the template after dropping an element (part of drag and drop events). I get the method callback after the drop and I can see the sortId was replaced as expected, but the whole list is not rendered again sorted as expected.
So my question is if I can somehow add a "drop" event to the uihooks instance, so i can re build the template as in insert?
Thanks.
Ok, that's an option:
Session.setDefault('isDropped', false);
//event on drop:
Session.set('isDropped', true);
//on the uihooks helper:
move: function(node, next, tpl) {
if(Session.get('isDropped')){
$(node)...... ;
Session.set('isDropped', false);
Thanks.

Adding attribute to TinyMCE node with attr not working

I'm developing a WordPress plugin that adds a button to TinyMCE, which lets you add an id attribute to the selected element. I have the button displaying, and when it is clicked it runs my function, which I'll call "idFunc" for this demo and it looks like this:
function idFunc() {
// Make sure editor has focus.
editor.focus();
// Get currently selected node
var selectednode = editor.selection.getNode();
// Set the id attribute on the node
selectednode.attr("id","newid");
}
With idFunc() written as above, nothing happens when I click my button. If I change the last line to an alert like this:
function idFunc() {
editor.focus();
var selectednode = editor.selection.getNode();
// Alert with the selected node
alert(selectednode);
}
I get an alert as expected, which says:
The page at mytestingdomain.com says: [object HTMLParagraphElement]
If I have my caret in a div instead of a p element, it says:
The page at mytestingdomain.com says: [object HTMLDivElement]
So I know I'm close, but the attr() function isn't adding any attributes to any elements in the TinyMCE editor.
What am I doing wrong?
The solution to this is easy.
editor.selection.getNode() gives you the common ancestor node (not a jQuery object).
To set the id attribute on the node you may call one of the following commands:
selectednode.setAttribute("id","newid");
or
selectednode.id = "newid";
or using jQuery
$(selectednode).attr("id","newid");

Add selectedItemCls to First Item of DataView ExtJS

I have ExtJS Dataview with following template for its Items.
<div class="item-container">
<div class="{itemCls}"></div>
<span class="item-title">{title}</span>
</div>
Now, I have set selectedItemCls config with value item-selected, which is styled accordingly in my stylesheet. When I click on items in dataview, it works fine, and selected item is highlighted. But I want to have first item of my dataview be selected by default (and thus having item-selected class already added to it).
I tried to play around the dataview component in its afterrender event but I couldn't add active class to first item.
Update
Note that I want to maintain that toggle behavior of class, so when dataview is rendered and user clicks on other item, first item (on which tab-selected was added programmatically) is no longer highlighted and clicked item gets tab-selected class.
So far, I tried calling dataview.selModel.select(dataview.Store.getAt(0)) within afterrender event, and surprisingly, it works while debugging (breaking execution in afterrender event and proceeding step-by-step) but it throws Uncaught TypeError: Cannot call method 'addCls' of null if I try it without DevTools open. I believe it is due to event bubbling since select() also fires itemclick and selectionchange events internally (I might be wrong though).
P.S. Using Chrome for debugging.
How to attain this?
Try this:
new Ext.XTemplate(
'<tpl for=".">',
'<div class="item-container {[xindex === 1 ? "item-selected" : ""]}">',
'<div class="{itemCls}"></div>',
'<span class="item-title">{title}</span>',
'</div>'
'</tpl>,
)
You could also try this:
listeners: {
afterrender: function(dv) {
dv.selModel.select(dv.store.getAt(0));
}
}
After hacking around for more than an hour, I found the fix!
When using afterrender event, where DataView is technically not fully rendered on UI, calling select() will fire itemclick event but there's nothing on UI, so it would lead to the TypeError I was getting (I'm still not 100% sure if this is the exact reason for TypeError I got).
So I have two possible fixes for this, where I'd prefer 2nd fix.
Option - 1
Make called to select() deferred by a few Milliseconds.
listeners: {
afterrender: function(dv) {
Ext.defer(function() {
dv.selModel.select(dv.store.getAt(0));
}, 10); // Some small number for delay will do.
}
}
Option - 2 (Recommended)
Use viewready event instead of afterrender.
listeners: {
viewready: function(dv) {
dv.selModel.select(dv.store.getAt(0));
}
}
I've used 2nd option and it works perfectly, however, any better suggestion is welcome.

dynamically initializing a child component at run time

In a current Flex project, i have an issue where a certain child component must be initialized and ready when the user clicks a button. the button is a mouseClick Event.
//mouseClick Event
protected function tableSearch_searchClickHandler(event:MouseEvent):void
{
parentXml = event.xmlNode;
if(classifierInfo)
classifierInfo.variables = parentXml;
else //initialize it dynamically..but how?
{};
}
in the function the component (classifierInfo) is checked to see if it is initialized and ready== that is, it is not null. then the variables property is populated with the parentXml value else, if it is not ready, [i want to initialize it dynamically] but do not know how.
does any one know how i could fill up the else statement such that the classifierInfo component is initialized dynamically? Is this even possible?
you have to try to initialize the object and add it to the correct parent UI Object if it is a visual component.
classifierInfo = new WhateverClass();
classifierInfo.somePropertySet
...
yourUIComponent.addElement(classifierInfo);
Is it that what you are trying to do?

Resources