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.
Related
What is the way to catch anytime a view is rendered?
Not only when switching views, but also when clicking today / prev / next?
I need to clear an array of unique event titles after (or before) each render is complete.
So, similar to eventAllRender which was removed starting v4.
Currently using .click event for all buttons, which does the trick, but I was hoping there was something really linked to the actual rendering.
calendar.render();
$('.fc-button').click( () => {
console.log("do something")
})
https://fullcalendar.io/docs/datesSet
Called after the calendar’s date range has been initially set or
changed in some way and the DOM has been updated.
datesSet: function(info) {
// ...
}
Im trying to use registerHelper to respond to a click event on my page.
i seem to be having difficulty getting the page to perform a function based on a click event.
The function below runs when the page renders.
Template.registerHelper('deletetask', function () {
Tasksdb.remove(this._id);
how do i get it to run on a click event? I have tried something like:
Template.registerHelper('deletetask', 'click.delete' : function () {
Tasksdb.remove(this._id);
it just errors out.I think my syntax is off or i have to do it some other way.
Thanks
Template helpers return values for display. Template events are designed for, you guessed it, handling events.
Template.myTemplate.events({
'click .delete': function(ev){
Tasksdb.remove(this._id);
}
});
Note that this will be the data context corresponding to the instance of myTemplate that was clicked on.
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.
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.
I have an UpdatePanel with a repeater in it that is re-bound after a user adds an item to it via a modal popup.
When they click the button to add a new row to the repeater the code-behind looks something like this:
protected void lbtnAddOption_Click(object sender, EventArgs e)
{
SelectedOption = new Option()
{
Account = txtAddOptionAccountNumber.Text,
Margin = chkAddOptionMargin.Checked,
Symbol = txtAddOptionSymbol.Text,
Usymbol = txtAddOptionUsymbol.Text,
};
Presenter.OnAddOption(); // Insert the new item
RefreshOptions(); // Pull down and re-bind all the items
mpeAddOptionDialog.Hide(); // Hide the modal
// ... Make call to jQuery scrollTo() method here?
}
This works fine and the new row will show up quickly via the UpdatePanel.
However, there are often hundreds of rows and where the new one is added is based on the current sorting column used.
So, I wanted to take this as a chance to use the sweet jQuery ScrollTo plugin. I know that if I give it the ID of my overflowed container div and the ID of an element within it, it will smoothly scroll straight to the users newly added row.
However, there are two problems:
I need to find the appropriate row so I can snag the ClientID for it.
I need to execute the jQuery snippet from my code-behind that will cause my newly updated repeater to scroll to the right row.
I've solved #1. I have a reliable method that will produce the newly added row's ClientID.
However, problem #2 is proving to be tricky. I know I can just call ScriptManager.RegisterStartupScript() form my code-behind and it will execute the JavaScript on my page.
The problem I'm having is that it seems that it is executing that piece of JavaScript before (I'm guessing) the newly refreshed DOM elements have fully loaded. So, even though I am passing in the appropriate jQuery line to scroll to the element I want, it is erroring out for me because it can't find that element yet.
Here is the line I'm using at the end of the method I posted above:
string clientID = getClientIdOfNewRow();
ScriptManager.RegisterStartupScript(this, typeof(Page), "ScrollScript", String.Format("$(\"#optionContainer\").scrollTo(\"{0}\", 800);", clientID), true);
What do I need to do so I can ensure that this line of JavaScript isn't called until the page with the UpdatePanel is truly ready?
If the stuff you need to process is in the update panel, then you need to run your JS once that panel is loaded. I use add_endRequest for that. This below is hacked from something rather more complex. It runs once on document ready, but installs the "end ajax" handler which is triggered every time your update panel is updated. And by the time it fires, it's all there for you.
var prm = Sys.WebForms.PageRequestManager.getInstance();
jQuery(document).ready(function () {
prm.add_endRequest(EndRequestHandler);
});
function EndRequestHandler(sender, args) {
// do whatever you need to do with the stuff in the update panel.
}
Obviously you can inject that from code-behind if you want.
You can use the Sys.Application.load event which is raised after all scripts have been loaded and the objects in the application have been created and initialized.
So your code would be:
string clientID = getClientIdOfNewRow();
ScriptManager.RegisterStartupScript(this, typeof(Page)
,"ScrollScript"
,String.Format("Sys.Application.add_load(function(){{$(\"#optionContainer\").scrollTo(\"{0}\", 800);}});"
, clientID)
, true);