Homemade NavBar. environment contains lists with the dropdown elements defined like this:
{
title: 'Overview', isDropped: false, Links: [
{linkTitle: 'What is Hunter', linkRoute: '/whatishunter'},
{linkTitle: 'What is a Hard Problem', linkRoute: '/hardproblem'},
{linkTitle: 'Real World Applications', linkRoute: '/realapps'},
{linkTitle: 'Using Hunter', linkRoute: '/usingHunter'}
]
},
The navbar html loops (ngFor) for each dropdown in that section of the navbar; added leftdropdown is dropped to show what's happening:
<div class="positionLeft" [ngStyle]="{'z-index': '2', 'height': '50px'}">
<div *ngFor="let leftdropdown of barContents.leftMenus">
<app-navdropdown [title]="[leftdropdown.title]" [isDropped]="[leftdropdown.isDropped]"
[links]="[leftdropdown.links]"></app-navdropdown>
added leftdropdown isdropped = {{leftdropdown.isDropped}}
</div>
The "leftdropdown" elements are from the environment list above. The component.ts is:
And it's trivial HTML is (with extra diagnostic text):
So when the application runs we see the output html as:
Note the debug console here:
And just to be sure, I can manually change isDropped to true and the "if block" is displayed.
The obvious error is that *ngIf is inverting the isDropped expression ????
Any clues as to what must be a misunderstanding or simple syntax error?
Thanks for your time and advice.
Chuck (Yogi)
Thanks for the various comments; I finally realized that MY confusion about square brackets was regarding the left or right of the expression. Using (or not using) square brackets on the left changes how the right side is evaluated. (I thought they needed to be applied to the right side - WRONG.)
After carefully (and repeatedly) reviewing the property binding documentation in angular.io, the above became clear to me.
Thanks to everyone who added notes.
Related
The below screenshot shows how my iron-data-table element looks when it first loads. Notice the data is missing and the headers are not fully formatted (the width seems to be too small to show the column header labels).
However, if I enter a character in the filter fields or click one of the sort buttons, the iron-data-table seems to re-draw itself and it looks fine. The columns and headers render properly and the data populates the table as expected.
This problem started when I added some directories to my file structure nested my iron-data-table inside neon-animated-pages. I double checked and all my imports are loading correctly. But I suspect that, somehow, there is a slight delay in fetching the data and somehow the table might be trying to render before the data arrives and not refreshing after the data arrives.
So I tried to add the following function. But to no avail. There is no render() method for iron-data-table.
<iron-data-table id="grid" ...
....
attached: function() {
this.async(function() {
this.$$('#grid').render();
}.bind(this), 500);
},
What could be causing this behavior? And what should I try next?
Edit
This plunk demonstrates the desired iron-data-table behavior.
This plunk demonstrates my problem behavior. (Not finished yet. Currently in progress.)
The configuration is approximately as follows.
parent-el.html
<neon-animated-pages>
...
<container-el...>...</container-el>
</neon-animated-pages>
container-el.html
<child-el ...>...</child-el>
child-el.html
<iron-data-table ...></iron-data-table>
Edit 2
Based on #SauliTähkäpää's comment, I tried the following fix unsuccessfully.
parent-el.html
<neon-animated-pages id="animator" ...>
...
<container-el...>...</container-el>
</neon-animated-pages>
...
attached: function() {
this.async(function() {
this.$.animator.notifyResize();
}.bind(this), 50);
},
Not that familiar with neon-animated-pages but by looking at the docs, it should call notifyResize() on selected pages as long as they extend iron-resizable-behavior.
So I think your options are either to make sure <container-element> and other elements in the tree are extending iron-resizable-behavior OR override the resizerShouldNotify to notify the grid directly. See more here: https://elements.polymer-project.org/elements/neon-animation?active=neon-animated-pages#method-resizerShouldNotify
To explicate for anyone who follows this question later...
Per #SauliTähkäpää's accepted answer, I successfully added the following code to each element in the chain (i.e., beginning with the element containing neon-animated-pages and ending with the element containing iron-data-table — in this example, that would be parent-el, container-el, and child-el).
parent-el.html, container-el.html, child-el.html.
<link rel="import" href="path/to/bower_components/iron-resizable-behavior/iron-resizable-behavior.html">
...
behaviors: [
Polymer.IronResizableBehavior,
],
Hello I've been struggling with a should be simple select with capybara. This is what I'm after on my page :
<a title="Activity" class="" href="/changes">Activity <span class="badge">1</span></a>
I need to assert that there is a span.badge with value 1 inside activity a tag.
Before I posted this, printed the page contents and did a save_and_open_page and this content is there.
This is what I tried (which seemed most promising cant even find a tag) :
find(:xpath, "//a[contains(.,'Activity')]")
find(:xpath, "//a[contains(#title, \"Activity\")]")
find(:xpath, "//a[#title='Activity']")
find(:xpath, "//a", :text => /reActivity /i)
And so many other things not worth mentioning, how would you do this?
Question update:
I forgot to mention that this html is actually hidden initially on the page as it is part of a sub menu. So adding Capybara.ignore_hidden_elements = false works but it kind of sux to add this global config to your test, any other ideas?
If I'm understanding what you're trying to do you can use a css selector for this, which will be easier to read than XPath
find('a[title=Activity] span.badge', text: '1', visible: :all)
Assuming the elements are visible on the page that should find what you want. To assert on that if using RSpec something like the following with work
expect(page).to have_css('a[title=Activity] span.badge', text: '1', visible: :all)
if i understood correctly
//a[#title="Activity" and span[#class="badge" and . = 1]]
Someone was able to so quickly help me with a problem I'd spent hours and hours on, that I'm hoping I'll get lucky and someone can point me in the right direction on this one, too.
I didn't see anyone else with quite my issue here - and I'm new to working with WP templates instead of plain old HTML/CSS/JS stuff.
Basically - on a site we did (www.opted.org) with a purchased WP theme - I can't get the mobile version collapsible menu to stop defaulting on page load to the last item in the Main Menu.
So instead of something that makes sense - like About ASCO, or even being able to add "Select Page" - the drop down shows "-- past issues"
I don't care how I fix it really, but the client just doesn't want that page to be the default. I tried adding an extra menu item at the end called "Select Page" with an href='#' and using CSS to hide it on screens above 480px - but I couldn't get it to work no matter how I tried to refer to it.
I feel like this should be easy - but I don't know where to set the selected LI among the many WP files.
Thanks!!
I had a look at the plugin.js file on the site www.opted.org.
On line 22, there is 'header' : false // Boolean: Show header instead of the active item
and on line 41 there is jQuery('<option/>').text('Navigation')
Try setting line 22 to true, and text('Navigation') to your 'Select Page' if you prefer that over the text 'Navigation'
Or, according to the tinynav.js page (http://tinynav.viljamis.com/), you can customize that as an option like this:
$("#nav").tinyNav({
active: 'selected', // String: Set the "active" class
header: 'Navigation', // String: Specify text for "header" and show header instead of the active item
label: '' // String: Sets the <label> text for the <select> (if not set, no label will be added)
});
In your main.js file, your calling it on line 14. You should add that header: 'Navigation', option there.
It's hard to answer this question without knowing how the theme you are using works. However, you can certainly change the selected attribute using javascript.
Here's the code you would use to set it to 'About Asco' using jQuery:
jQuery('.tinynav').val('/about-asco/')
alternatively (a little clearer, but more verbose):
jQuery('.tinynav option:first').prop('selected', true);
Chrome 24 has a new way of outputting objects in console.log().
For example, console.log($("p")); on this jsFiddle example outputs this insanity:
▼[<p>, <p>, <p>, prevObject: jQuery.fn.jQuery.init[1], context: #document, selector: "p"]
► 0: <p>
► 1: <p>
► 2: <p>
► context: #document
length: 3
► prevObject: jQuery.fn.jQuery.init[1]
selector: "p"
► __proto__: Object[0]
I can see that it puts the collection of DOM elements at the beginning. But if you try to expand even a simple <p> tag that is mostly empty, it throws up all over you:
▼ 0: <p>
accessKey: ""
align: ""
► attributes: NamedNodeMap
...
[stopping here for sanity's sake]
So how do I use all this information? My first instinct is to tame it down to how it used to look, but on second thought, there really is a lot of info in there that I might want to have access to. But I'm having a hard time understanding what I'm looking at. Much of it looks like jQuery values. Is this a list of every jQuery value that the object has (or doesn't have)?
Then there's the whole issue of the ► context: thing and the ► __proto__: thing. Once you start drilling down in __proto__ you will never stop. I think it goes infinitely down!
How can I begin to learn how to use this new output?
EDIT:
I actually just realized that I'm still using Chrome 23, this isn't something that was introduced in 24. Someone in this thread said it was a Chrome 24 issue, but maybe it's new in 23? At any rate, I only just recently started noticing this on jQuery objects.
EDIT 2: If you're just looking for how to log the old way, try this: (hat tip)
console.log.apply(console, $("div"));
In your demo fiddle, you are logging NodeLists or HTMLCollections. Each of the elements within a NodeList is represented as a numeric index 0, 1, 2, etc. 0 being the first in the NodeList if any elements exist in it.
When you expand the Elements you see all available properties of an HTML Element as defined in DOM Core 3 specification. Refer here for more information about this http://domenlightenment.com/#3.2 and for a list of all properties and their purposes go here: https://developer.mozilla.org/en-US/docs/DOM/element. None of this is new in Chrome.
What is new in the latest Chrome version is the top level logged object, so if you just opened the console and typed:
console.log(window)
Which for me when I just did it logged a preview of what the expanded window object it provides when logging it. So for example, you should see something like:
Window {is_minor: 5, bmi_ie6: false, careers_adselector: "div.hireme, div#hireme"...}
Other NodeLists properties listed below the Elements of the list:
context - the context of the selection - http://domenlightenment.com/#4.4
length - the number of Elements in the HTMLCollection
selector - the selector used to select the Element or NodeList
__proto__ - An Object's __proto__ property references the same object as its internal [[Prototype]] (often referred to as "the prototype"), which may be an object or null (in the case of Object.prototype.__proto__). For more info on this refer to: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/proto
I modified the fiddle slightly and should show the preview of the objects when you view the console http://jsfiddle.net/jaredwilli/H3YWq/2/
You can't really get rid of any of these things either, they're a part of the DOM and will exist always otherwise the NodeType of what you're looking at will be something other than an ElementNode.
I'm just as annoyed as you are with this change. I know this isn't ideal, but it will hopefully help you a little bit.
console.log($('p')[0]);
You may have seen that solution before, and then found it didn't work if you were in a loop for instance:
$('p').each(function(){
console.log($(this)[0]);
});
That doesn't end up giving you the result you were used to either, so I had to use ['context'] instead of [0] like this:
$('p').each(function(){
console.log($(this)['context']);
});
Again, I'm looking for a better solution myself, but I thought I'd share with you what I've found.
You want first element so use [0]
As another option, check out Firebug in Firefox. I know, I love chrome too and use it every day, but Firebug is a great plugin and I've never had an issue with it.
Is it possible to force the sitemap control to render the menu when the current action is not listed in the MVC.sitemap file?
I have a simple top nav. When the current action is in the sitemap, the call to .Menu() will render the correct <ul><li>.. data. However, if I got to a page that is not in the sitemap such as /Home/Login, then it will not render any html at all (not even a comment, just empty space). This isn't an [authorize] issue; the menu is fine when i'm in '/Home/Index'.
It seems like it should render what was requested, but just not set the IsCurrentNode and IsNodeInPath properties. Here is the call I am making
<div id="main-nav">
#Html.MvcSiteMap().Menu(0, true, true, 1)
</div>
The Mvc.sitemap file:
<mvcSiteMapNode title="Home" controller="Home" action="Index">
<mvcSiteMapNode title="Form New Human" controller="Person" action="Create"/>
<!-- there is no mvcSiteMapNode for "Home" "Login" -->
</mvcSiteMapNode>
Found the way around it. It apparently isn't a built in extension method, or at least I couldn't find one. You could call Html.MvcSitemap().Menu(Html.MvcSiteMap.Provider.RootNode,...) but I didn't want to instantiate the helper twice.
<div id="main-nav">
#{
var sm = Html.MvcSiteMap();
#sm.Menu(sm.Provider.RootNode, true, true, 2); // 2 levels (home, plus main nav)
}
</div>
Looking around in the disassembly seems to show that it works a little like this:
You really need a starting node
If you don't give it one, it tries to find one based on the current node
plus restrictions (forward searching, depth restrictions, etc)
if you want nodes from level 1, you have to know what level you are on
Since that returns null, starting node is null, which means the helper writes an empty string
There may be a combination of tricks, or an overload or two, which can be finagled into doing this, but I can't find it right now. This works for my needs (simple top menu). There has to be a simpler way to do this, something with wild cards, or route based, with a closest match thing going on. I figured menus were a fairly standard part of a web app, and this would be covered :)