Update an element that already has a plugin - zurb-foundation

Zurb Foundation 6.5.3
I have an accordion menu which needs to be updated via ajax after the initial page load. So initially the menu contains 2 items, then $(document).foundation(); is called. Later after an ajax response is received elements are added (and potentially removed/replaced) within the menu.
I would like to be able to re-use the same elements however, I can't update the plugin to re-style the changed elements. I've tried:
$("#my-menu").foundation(); which doesn't work and shows the error:
Tried to initialize accordion-menu on an element that already has a Foundation plugin.
Foundation.reflow(menu, 'accordion'); which doesn't work.
menu.foundation('reflow'); which doesn't work and shows the error:
Uncaught ReferenceError: We're sorry, 'reflow' is not an available method for AccordionMenu.
I have made it work by destroying and removing the existing menu, re-creating the whole thing, then calling $("#my-menu").foundation(); however this isn't ideal in my opinion.

I found that my issue was due to no one solution working in all 3 cases:
foundation has not yet been initialised
foundation is initialised and the entire element has been replaced since
foundation is initialised and the element has been updated since
Unless someone has a better answer, I solved using this approach:
// this can happen before, or after code creates the menu
$(document).foundation();
console.log("foundation run");
__foundationRun = true;
...
function foundationUpdate(el) {
if (__foundationRun) {
if (el.data('zfPlugin'))
// already initialised, update it
Foundation.reInit(el);
else
// new element, initialise it
el.foundation();
}
// else leave for foundation initialise
}
....
// ... do updates (modify or replace entirely) and then:
foundationUpdate($("#my-menu"));

Related

emberjs get('lastObject') bug?

I'm looping through an array using Ember.Array#lastObject property:
while (last = this.get('clickViews.lastObject')) {
// perform some actions to last
this.get('clickViews').removeObject(last);
}
When all objects from the clickViews array have been removed, this.get('clickViews.lastObject') still returns an object. Is there something wrong with how I'm getting 'lastObject' or removing objects from array?
Maybe you should do it this way. See here for a working jsbin.
while (this.get('clickViews.lastObject') !== undefined) {
// perform some actions to last
this.get('clickViews').removeObject(this.get('clickViews.lastObject'));
}
Hope it helps.
This seems to be a cacheing problem with multiple versions of emberjs loaded within the browser window context, as similar to the answer to this question: emberjs getEach method does not work as expected
I resolved problem by clearing browser history and rails precompiled tmp files.

"Cannot call method 'destroy' of undefined" in arrayWillChange

I have what I think is a pretty standard array/template relationship setup, but when I push a new item into the array I get the above mentioned Cannot call method 'destroy' of undefined error in the arrayWillChange method of the Ember source:
for (idx = start + removedCount - 1; idx >= start; idx--) {
childView = childViews[idx];
if (removingAll) { childView.removedFromDOM = true; }
childView.destroy(); <-- childView is undefined
}
I have never had this issue before. This doesn't happen when I remove an item from the array. Only on addition. Below is a link for a JSBin where I tried to duplicate the issue. The error doesn't get thrown but the template doesn't update either.
http://jsbin.com/asemul/2
EDIT:
You're calling array.push instead of array.pushObject -- the latter is an Ember.js method that is binding aware, which means it will automatically update bindings for you. The handlebars template helper {{#each filters}} is a binding to the filters array of the controller, and the template needs to know to update when the underlying array is updated. push doesn't tell the binding to update, but pushObject does.
Here's a working example (all I did was change push to pushObject): http://jsbin.com/asemul/6/
This is a pretty common mistake -- usually, I find that if my templates aren't synchronized with the underlying object, it's because something's wrong with the bindings, so that's where I start looking.
END EDIT
I don't think you should be setting removedFromDOM directly -- try using childView.remove() followed by destroy().
I'm not sure what the context is, but have you looked at ContainerView or CollectionView? Both of those views have support for arrays of child views and may accomplish what you're looking to do both more robustly and with less code.

Playing with Ember.Object.reopen(), why I have those results?

I was trying to answer this question: emberjs: add routes after app initialize()
I started to play with Ember.Object.reopen(), to understand how it works, and perhaps finding a way of answering the previous question.
I feel a bit puzzled, and don't understand the behavior of this code:
jsfiddle: http://jsfiddle.net/Sly7/FpJwT/
<script type="text/x-handlebars">
<div>{{App.myObj.value}}</div>
<div>{{App.myObj2.value}}</div>
<div>{{App.myObj3.value}}</div>
</script>
App = Em.Application.create({});
App.MyObject = Em.Object.extend({value: 'initial'});
App.set('myObj', App.MyObject.create());
Em.run.later(function(){
App.get('myObj').reopen({
value: "reopenOnInstance"
}); // the template is not updated, 'initial' is still diplayed, but
console.log(App.get('myObj').get('value')); // print 'reopenOnInstance'
App.MyObject.reopen({
value: "reopenOnClass"
});
App.set('myObj2',App.MyObject.create()); // the template is updated and
console.log(App.get('myObj2').get('value')); //print 'reopenOnClass'
App.myObj3 = App.MyObject.create(); // the template is not updated but
console.log(App.myObj3.get('value')); // print 'reopenOnClass'
Em.run.later(function(){
App.get('myObj').set('value', "setWithSetter"); // the template is updated and
console.log(App.get('myObj').get('value')); // print 'setWithSetter'
App.get('myObj2').set('value', "setWithSetter"); // the template is updated and
console.log(App.get('myObj2').get('value')); // print 'setWithSetter'
App.myObj3.set('value', "setWithSetter"); // the template is not updated but
console.log(App.myObj3.get('value')); // print 'setWithSetter'
}, 2000);
},2000);
If someone can explain what is going on, particularly why the templates are sometimes not updated, sometimes updated, and also what's the difference between calling reopen on a class, calling it and on a instance.
Not 100% sure, but I will try and answer you questions.
First lets look at "myObj3". The ember getter/setter methods trigger the updates in the templates (they fire internal events which cause every property/observer to know something happened). Just setting a value by hand does update the value but will not fire these events and hence nothing changes in the UI. Kind of like when you use a Mutable list you use pushObject to make sure the UI updates.
Now lets look at your "reopen". When you reopen on the class it works as you would expect and updates the base class. When you reopen an instance it is actually creating a mixin and shims it on top of the object. This means when you do a "get" ember iterates over the mixin & object for the value to return. It finds that mixin and gets the value before the object; you could actually replace the method with a "return 'foo '+this._super()" on the instance you will get 'foo initial' (think of your object has having layers like an onion). If you have a group of mixin on top of your object you will have a hard time finding the correct value if you set something directly (but "get" will work perfectly). This leads to the general rule that you should always use "set" instead of a direct reference.
Side note: You can call "getPath" instead of "get" and you can use the relative or absolute path. Such as App.getPath('myObj2.value') which will make the code a little easier to manage. Goes for "setPath" also.
Lastly: The last value prints because you did change the value (it is in there) but the trigger for ember to update the ui never fired because you never called set on "myObj3" object.
EDIT: In the lastest version of ember it looks like the reopen on an instance does do a merge-down on the object (if that key already exists). The mixin only will wrap if you are adding new content.

Flex 4.5 List - ensureIndexIsVisible error

In my application I have a list of items which can be changed either by clicking on the list, using a next/previous button or via a menu which allows them to jump between items (mainly for the phone version which doesn't display the list).
I'm using the ensureIndexIsVisible function after the data provider for the list has been populated. However sometimes when I return to this page the application crashes out with the following error:
RangeError: Error #1125: The index 0 is out of range 0.
at spark.layouts.supportClasses::LinearLayoutVector/getMajorSize()[E:\dev\4.y\frameworks\projects\spark\src\spark\layouts\supportClasses\LinearLayoutVector.as:420]
The strange thing is that the index I pass into the function when it crashes isn't 0. It can be 1 or 3 or presumably anything. I can stop the application from crashing if I remove the function call but I need the list to show what question is currently selected.
The actual line that crashes is this:
var block:Block = blockTable[index >> BLOCK_SHIFT]; from a function called getMajorSize
As this has gone unanswered for so long I thought I'd answer it myself back with what I've recently ended up doing.
I managed to get this issue resolved by mainly changing the points where I called the function. i.e. it was being called too early.
However I recently changed over to using a custom function that someone else posted as I found that the ensureIndexIsVisible was often jumping to the wrong position in the list (due to a variety in heights of the items).
The function can be found on this question and is called scrollToIndex:
Scroll to selected item in Flex 4 Spark List component
This error is related to FLEX-28291, which should be fixed in the next version of Apache Flex (probably 4.14).

Changing the Total Number of Recent Files

I'd like the user to be able to edit the number of recent files shown in the File menu of my MFC application. I've used two very good references:
http://www.codeproject.com/KB/menus/changemru.aspx
http://www.microsoft.com/msj/0899/c/c0899.aspx
It involves deleting and recreating the CRecentFileList object stored in CWinApp::m_pRecentFileList. Unfortunately, I find that the menu is not updated properly after replacing the CRecentFileList. See code snippet below:
void CMyWinApp::SetMRUListSize( int size )
{
// size guaranteed to be between 1 and 16
delete m_pRecentFileList ;
LoadStdProfileSettings( size ) ;
}
What can I do to ensure that what is drawn into the File menu is synchronized with m_pRecentFileList after I recreate the object?
My CApp derives from CWinApp. In initInstance, you have this line:
LoadStdProfileSettings(10);
At the end of InitInstance, add this code:
m_pmf->m_pRecentFileList = m_pRecentFileList;
Here m_pmf is my MainFrame class and I created a member CMainFrame::m_pRecentFileList of type CRecentFileList which is in the MFC source file filelist.cpp. m_pRecentFileList on the right is protected and CMainFrame doesn't have access to it from outside InitInstance, but you can make a functional copy here.
At the end of CMainFrame::OnClose, force a registry update by:
m_pRecentFileList->WriteList();
// Force registry update on exit. This doesn't work without forcing.
I don't even have to rebuild m_pRecentFileList, the MRU mechanism updates it correctly. Example: 5 MRU items, the first is moved to another directory and can no longer be found. Stepping through the code in the debugger shows that the bad entry is removed from the list. For some reason, the updated list isn't saved correctly unless I force it as explained above. I originally thought the problem might have something to do with privileges (64-bit Win7), but running the app as admin didn't help.
Some of Microsoft's documentation suggest you should call CWinApp::LoadStdProfileSettings from within InitInstance. This suggests to me that it's something done once during initialisation rather than at run time.
Have you tried fully implementing the second of the two links you provided? My guess is you need to add the second part instead of the call to CWinApp::LoadStdProfileSettings:
m_pRecentFileList = new CRecentFileList(0, strSection, strEntryFormat, nCount);
if(m_pRecentFileList)
{
bReturn = TRUE;
// Reload list of MRU files from registry
m_pRecentFileList->ReadList();
}
[Edit] Apparently m_pRecentFileList points to an CRecentFileList Class . Have you tried calling CRecentFileList::UpdateMenu?
There's another CodeProject example which might help too.