How to duplicate a data-bound function in a view element to which the un-editable script does not apply bindings? - mvvm

I am a beginner to knockout and I work on a platform where only the VIEWs (called Templates) are editable - ViewModels are not editable nor even readable (except for reading the minimized code in dev tools).
I am trying to move a button from one template to another. However, the button uses a data-bound function, and each template has bindings applied (using element Id) from a different ViewModel (javascript file).
See Graphic
Ideas so far
⚡ Changing target template's main div's id was a bad idea.
⬜ Wrap new button in div with same id as source template?
SO seems to have concensus that duplicate id's are bad.
Would the 2 ViewModels interfere with each other?
If so, can the main one be "paused" or cleared only for that new element?
⬜ Should I try to recreate that part of the ViewModel in a <script> tag within the target template?
This is daunting, because I don't know js and the minimized
file I can see in devtools is long and does not look simple.
Something else?
Thank you.
EDIT: Adding the HTML button only <button data-bind="click: toggleResponsiveDesign">Old UI</button>, displays a button, but clicking it does nothing. Dev tools console gives error on page load (and a jQuery.Deferred exception warning referencing the error):
Uncaught ReferenceError: Unable to process binding "click: function(){return toggleResponsiveDesign }"
Message: toggleResponsiveDesign is not defined
 at click (eval at parseBindingsString (CoreApp.js?v=v2011.0.1.1:394), :3:58)
 at CoreApp.js?v=v2011.0.1.1:394
 at init (CoreApp.js?v=v2011.0.1.1:394)
 at init (CoreApp.js?v=v2011.0.1.1:394)
 at CoreApp.js?v=v2011.0.1.1:394
 at Object.G (CoreApp.js?v=v2011.0.1.1:394)
 at CoreApp.js?v=v2011.0.1.1:394
 at Object.D (CoreApp.js?v=v2011.0.1.1:394)
 at h (CoreApp.js?v=v2011.0.1.1:394)
 at l (CoreApp.js?v=v2011.0.1.1:394)

based on your screenshots you might be able to get the clickhandler to work, as the viewmodel of Userpersonalisationapp.js is bound to variable r you could change your buttons databind in headerapp template to
<button data-bind="click: r.toggleResponsiveDesign">
It may be that you have to add () to it to make the function run as it is not applied to header template
<button data-bind="click: r.toggleResponsiveDesign()">
I would give it a try

I don't think it can be done. If your graphic is accurate, you're working with two totally separate viewmodels that aren't in any way connected or aware of each other. If the viewmodels were nested, accessing one from the other would be pretty trivial, but that appears not to be the case here.
This is what components are for, actually. Usually you'd call applyBindings once for your entire application, and the rest would be divided into components, which gives you a way of sharing data and methods between them. The way your app is structured right now, you just can't do that. That, and your apparent inability to edit or even get a good look the viewmodels really puzzles me. Whoever though that was a good idea?

Related

"Clicking" on a not visible element

So my current situation is that I am trying to click on a marker based in a Google Maps window on a webpage. I have successfully located the markers in two manners: element.all(by.css('.angular-google-map-marker')) and element.all(by.repeater('m in map.markers')).
I have proven that I am obtaining the correct elements by changing the location on the Google Map and using count() to retrieve the number of markers present which returns the correct number in every case.
However, when I try to do for example element.all(by.css('.angular-google-map-marker')).first().click(), I receive the following error:
Failed: element not visible
HTML section
<div ng-transclude="" style="display: none">
<span class="angular-google-map-marker" ng-transclude="" ng-repeat="m in map.markers" options="m.options" coords="m.coords" idkey="m.id" click="onMarkerClick"></span>
<span class="angular-google-maps-window" ng-transclude="" coords="activeMarker.coords" options="windowMapOptions" show="windowMapOptions.show" closeclick="closeInfoWindow" templateurl="'gMapInfoWindow.html'" templateparameter="activeMarker"></span>
</div>
Normally elements that trigger some event due to clicking have an attribute like ng-click= foo(), however the markers above only use click= foo(). In addition if you look the line with the div tag, it says display: none, which might explain the visibility error.
My Question: Is there a way to activate the effect of an attribute like click= foo() without clicking on the element directly?
Aside from trying to make an element visible and then clicking, you can attempt clicking "via JavaScript" (there are some differences though - WebDriver click() vs JavaScript click()):
var marker = $('.angular-google-map-marker');
browser.executeScript("arguments[0].click();", marker.getWebElement());
First of all be sure that you can interact with the element when it is visible, you can do this from within the DevTools of your browser, make it visible by adding a display:block. Then check that if you change the value of the selectbox, the value can also be used with Angular Binding.
If so, you can easily make the element visible with Protractor by injecting a piece of Javascript in the page with the following command:
browser.executeScript('document.querySelector("div").style.display = "block"');
This results in a promise, so be aware of that!

Disable component editing in CQ/AEM

I've got a variety of situations where I have a component A which uses cq:include to include component B. Both A and B are editable and have dialogs. However, when B is included in A, I'd like to disable direct editing of component B - I'll manage the authoring through A's dialog. I've seen a couple methods that accomplish this. The first is
<% IncludeOptions.getOptions(request, true).forceSameContext(true); %>
and the second is
<% slingRequest.setAttribute(ComponentContext.BYPASS_COMPONENT_HANDLING_ON_INCLUDE_ATTRIBUTE, true); %>
<% slingRequest.removeAttribute(ComponentContext.BYPASS_COMPONENT_HANDLING_ON_INCLUDE_ATTRIBUTE); %>
My understanding is that the first forces the child component into the parent's editing context, and the second just creates no editing context for the child at all. But I'm not sure what the difference really means. As far as I can tell, the only major difference is that the first one only affects the next component include, while the second one affects all includes between the two lines. There's also a minor difference in the markup generated. But beyond that, the dialogs seem to behave the same way. It's possible that my POC is just too simple to see the differences...are there values in a cq:EditConfig node that would be affected? Some other difference?
Thanks
You can also just swtich off edit mode for an include with the WCMMode:
<%WCMMode prevMode = WCMMode.DISABLED.toRequest(request);%>
<cq:include path="b" resourceType="B" />
<%prevMode.toRequest(request);%>
This will render B like it would be rendered on a publish server without any edit functionality.

AngularJS - Wrapping nested <select> in a <div> in a form makes its control not be bind anymore

I'm doing a kind of select2 but with much less functionality and we want the form that is above to know about this Control (so we can use $dirty and $invalid).
But I've noted that if you wrap the select that is in the directive's HTML with a div, the $dirty and $invalid of that control stop working. Any idea why ?
Try it out on this http://plnkr.co/edit/UV425G2SMcqRYeX2N4qw?p=preview, go to the select.html file and turn
<select class='form-control' ng-model='selectedval' ng-attr-name='{{name}}' ng-options='item as item.name for item in options' required><option value=''>-- select --</option></select>
into
<div>
<select class='form-control' ng-model='selectedval' ng-attr-name='{{name}}' ng-options='item as item.name for item in options' required><option value=''>-- select --</option></select>
</div>
Ok I asked this as well in https://github.com/angular/angular.js/issues/6862 and got this answer by #caitp:
So your test case is actually running an old version of angular, which
A) does not support the ng-attr-* directives, and B) has a broken
isolate scope implementation.
This is still broken, but in different ways, using angular 1.2.15. You
have a priority issue with the ng-attr-name directive, regardless of
where the control is, and so it gets added to the form
control with the name you aren't expecting.
The reason this "works" with 1.0.8 and without wrapping it in a div,
is because with replace: true in your directive, we merge the
attributes from the directive's compile node (which does contain
name="...") into the root node of the template, so you're sort of
accidentally taking advantage of a poorly documented behaviour of the
compiler, in that case.
Unfortunately, there isn't really a good way to have dynamic form
control names yet (and this is really the root of the problem you're
having), there are a number of PRs adding support for this, and I've
written a hack to decorate the ngModel controller to make this work
(although it might not work anymore, depending on if the new
$interpolate api landed yet or not), you can see that at
http://plnkr.co/edit/hSMzWC?p=preview
So, Matias has an alternative solution for this, it's not clear which
one is going to land --- but in any case, that's about what your issue
is.
In the future it would be good to ask about these on
http://webchat.freenode.net/?channels=angularjs or
https://groups.google.com/forum/#!forum/angular to get answers to
these kinds of support questions (this is not a bug, per se, although
the "issue" you're seeing might be documented better, so PRs welcome
for clarifying that in the compiler docs).

How to stop MooTools stripping element IDs when clicked in Joomla 2.5.x using the 'modal' class [duplicate]

I have a form in a module that I want to appear in a modal window. Depending on the id the window may be blank, or if it does show any content all classes and ids are removed, so I can't validate or style the form.
Truncated Code:
...
<div id="feedback">
<div class="feedbackinner">
<!-- form module -->
<div id="contact-wrapper">
<!--form elements with ids and classes-->
</div>
<!-- end module -->
</div><!-- end .feedbackinner -->
</div><!-- end #feedback -->
This triggers the modal window without any ids or classes (using Firefox Web Developer outline current elements):
Click for ugly unstyled form that won't validate
This triggers a blank modal window:
Click if you like staring at a blank white box
So most importantly how do I keep all the ids and classes inside the modal window, and why won't calling the parent div work?
( As a work around I moved the form to a component view then called it using handler: 'iframe' instead of clone. I still want to know what's going on with the modal window. )
Thanks!
not seen the code but implications of using Element.clone on an element are apparent. By nature of HTML, id is meant to be unique. This means you are not really supposed to have more than one element with the same id injected into the DOM at the same time.
MooTools mirrors the sentiment correctly by implicitly removing the id from any element it creates a clone of:
https://github.com/mootools/mootools-core/blob/master/Source/Element/Element.js#L860
the .clone method accepts optional arguments which allow you to override stuff:
clone: function(contents, keepid){ - see http://mootools.net/docs/core/Element/Element#Element:clone as well.
cloned elements also lose all the events you may have assigned to them (but cloneEvents can help with that).
I would recommend looking at the squeezebox implementation and double check that the clone is implemented in the intended way. A better practice may be to adopt and re-attach the elements instead - or to copy the whole innerHTML (though this will once again cause non-delegated events to fail).

how to debug JSF/EL

How to debug EL in the JSF page? I'd like to watch variable values, function calls an so on. The best solution would be an eclipse plugin, but any other possibility is better than guessing "Why this expression failed to render correctly?".
Closest what you can get in JSF/Facelets is placing an <ui:debug /> somewhere in the view:
<ui:debug />
Pressing CtrlShiftD should then show a popup window with debug information about the component tree and all available request parameters and request/view/flash/session/application scoped variables. It's basically a representation of the content of all those maps.
The hotkey is by the way configureable by hotkey attribute so that you can choose another whenever it clashes with browser default hotkeys, as it would do in Firefox; CtrlShiftD would by default show the Add bookmarks dialogue. Here's how you could make it to listen on CtrlShiftX instead:
<ui:debug hotkey="x" />
You'd usually also like to hide it in non-development stage, so add a rendered condition like that:
<ui:debug hotkey="x" rendered="#{facesContext.application.projectStage == 'Development'}" />
In the shown debug information, the information provided about scoped variables isn't that great as you would expect. It only shows the Object#toString() outcome of all scoped variables which defaults to com.example.Bean#hashcode. You can't explore their properties and the values of their properties directly like as you could do in debug view of Eclipse's debugger. You'd need to implement toString() on the class accordingly so that as much as possible relevant information is returned (if necessary, you can even let Eclipse autogenerate it by rightclick source code > Source > Generate toString()):
#Override
public String toString() {
return String.format("Bean[prop1=%s,prop2=%s,prop3=%s]", prop1, prop2, prop3);
}
As to method calls, just put a breakpoint on the Java source code the usual way. Eclipse will kick in there as well when EL calls the method. If it's a managed bean, you'll also just see its properties in the Eclipse debugger.
If you are really having problems then if you can get the source for the EL implementation (easy enough for the RI) then you can use Eclipse to set breakpoints in the EL implementation methods. You need to get an understanding of how the EL code works, but it isn't that complicated. Not for the very faint hearted though.
Another possibility would be to create and evaluate the EL programatically. There are examples of how to do this around. You can then use the debugger to fiddle around with what the expression is and what the result is until you've worked out where your problem lies.