Angular.js filter premade html element - html-lists

I was playing with angular.js the other day and I found this filter function, that angular.js provides for us.
<div class="container-fluid">
<div class="row-fluid">
<div class="span2">
<!--Sidebar content-->
Search: <input ng-model="query">
</div>
<div class="span10">
<!--Body content-->
<ul class="phones">
<li ng-repeat="phone in phones | filter:query">
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul>
</div>
</div>
</div>
My question is: Can I use angular.js filter on premade html elements, somehing like this.
<div class="container-fluid">
<div class="row-fluid">
<div class="span2">
<!--Sidebar content-->
Search: <input ng-model="query">
</div>
<div class="span10">
<!--Body content-->
<ul class="phones" ng-filter:query>
<li>First element</li>
<li>Second elementy/li>
<li>Third element</li>
</ul>
</div>
</div>
</div>
Thank you for your answers!

For this kind of DOM manipulation/filtering, Angular directives ngSwitch or ngShow/ngHide are normally used.
<ul class="phones" ng-switch on="query">
<li ng-switch-when="Nexus S">First element</li>
The above would look for an exact match though (so it is not as nice as #tosh's directive). ng-switch is often used with a select drop-down, where the possible values are fixed/known.
ngShow/ngHide are probably a better match for what you are trying to do. An in-line expression or $scope function can be used to determine whether to show an element:
<li ngShow="some expression using query">First element</li>
<li ngShow="myFilter()">First element</li>
function MyCtrl($scope) {
$scope.myFilter = function() {
if($scope.query ...) { // could use RegExp() here like #tosh
return true
}
return false
}
The above does not require jQuery.

No. Your first example uses a filter - called "filter"! A filter can form part of an Angular binding expression. It is placed after a pipe character, and applies a "filter function" to the part of the expression that came before the pipe. Some filters also take additional parameters, to the right of a colon. The filter called "filter" acts on an Array (the part before the pipe, in this case phones) passing each item through a check determined by the parameter to the right of the colon. In your case, using a string variable called query, it returns an Array with any items from phones that contain the string in query.
Other examples of filters in Angular include currency, date, uppercase and orderBy. They all take an input (for example a string) returning another value (for example the uppercase version of the string) and in some cases additional configuration parameters (such as a date or currency format, or field to order by). But they only work with an input that is some value in the "data model", not directly on the content of a DOM node.
Your second example attempts to use a directive called "ngFilter". A directive is an extension to standard HTML syntax, and can be expressed as hyphenated attributes (as in this case), data- attributes (data-ng-filter), namespaced attributes (ng:filter), css classes, etc. Angular's default directives have the prefix "ng". But there is no such directive as "ngFilter" in Angular. Your example will load fine, but there will be no effect on the DOM processing from adding this non-existent directive.

I do not think that is part of the default directive, but
that's interesting task.
I tried to implement with a custom directive. http://plnkr.co/edit/TOGbtq
app.directive('ngFilter', function() {
return {
link: function(scope, element, attr) {
scope.$watch(attr.ngFilter, function(q){
$(element).children().each(function(i,a){
$(a).toggle((new RegExp(q)).test($(a).text()));
});
});
}
};
});

Related

Cypress: How to click on a array-list element if matching text found

I want to add an item in cart with a matching text like 'cashews'. I tried below code but .click() function is giving error as "bind and event handler to the click javascript event"
cy.get('.products').find('.product').each(($e1, index, $list) => {
const textveg = $e1.find('h4.product-name').text() {
if (textveg.includes('Cashews')) {
$e1.find('.button').click();
}
}
})
can someone suggest what can be the possible reason that .click() method is not identified by cypress. I am using cypress version 7
How you do this depends on the structure of the HTML.
It looks like you may have this sort of hierarchy
<div class="products">
<div class="product">
<h4 class="product-name">Almonds</h4>
<button>Add to cart</button>
</div>
<div class="product">
<h4 class="product-name">Cashews</h4>
<button>Add to cart</button>
</div>
</div>
Take the product section containing the text you want, and within that find the products <button>.
Your test might be
cy.contains('.product', 'Cashews') // pick the <div class="product"> with required text
.find('button') // inside the product, find it's button
.click()
You can use .filter() to find your element and click it:
cy.get('h4.product-name').filter(':contains("Cashews")').click()

odoo xpath add existing element inside element

I am trying to add existing division of Odoo product template in a new division. for that, I can do the "replace" of the whole division. and add my custom division.
for example, here is default Odoo template section with the div.
<section t-attf-class="container mt8 oe_website_sale" id="product_detail">
<div class="row" id="odoo_default_row">
</div>
</section>
and I wanted to add odoo_default_row div in my custom div element. like
<section t-attf-class="container mt8 oe_website_sale" id="product_detail">
<div id="my_custom_div">
<div class="row" id="odoo_default_row">
</div>
</div>
</section>
what is the best way to add existing division in the custom division despite using xpath replace?
We can replace whole div element using "replace" attribute. With these, we can freely design custom div element.
Try with following code:
<div id="odoo_default_row" position="replace">
<!-- Design your div element as per your requirement-->
</div>
NOTE:
As per my understanding with your situation is that "inside" attribute will not work.

How can I make custom class HTML divisions using AsciiDoctor?

I am beginning with AsciiDoctor and I want to output HTML. I've been trying to figure out how to create custom class in divisions, I searched google, manuals etc. and couldn't find a solution. What I want to do is simply write something like this:
Type the word [userinput]#asciidoc# into the search bar.
Which generates HTML
<span class="userinput">asciidoc</span>
but I want to have div tags instead of span. Is there any way to do it or should I just use something like
+++<div class="userinput">asciidoc</span>+++ ?
I think what you need is called "role" in Asciidoctor.
This example:
This is some text.
[.userinput]
Type the word asciidoc into the search bar.
This is some text.
Produces:
<div class="paragraph">
<p>This is some text.</p>
</div>
<div class="paragraph userinput">
<p>Type the word asciidoc into the search bar.</p>
</div>
<div class="paragraph">
<p>This is some text.</p>
</div>
You have now a css selector div.userinput for the concerned div.
See 13.5. Setting attributes on an element in the Asciidoctor User Manual (you can also search for "role").
You may want to use an open block for that purpose:
Type the following commands:
[.userinput]
--
command1
command1
--
Producing:
<div class="paragraph">
<p>Type the following commands:</p>
</div>
<div class="openblock userinput">
<div class="content">
<div class="paragraph">
<p>command1</p>
</div>
<div class="paragraph">
<p>command1</p>
</div>
</div>
</div>
The advantage is it can wrap any other block and is not limited to only one paragraph like the other answer.
For slightly different use cases, you may also consider defining a custom style.

HTML5, Razor. How do I get different styling for the header element?

I am new to HTML5.
This code returns a parser error on the if statement. I do not know if it will work anyway, so how do I fix the if statement and how do I get this to work?
<div class="page">
#if (Constants.EnvironmentSetting.ToUpper() == "LIVE"){
<header>
} else {
<header class="headerTest">
}
<div id="title">
#Content.Image("MulalleyLogoSmall.jpg", "float:left;padding:10px 10px 0 10px", Url)
<div class="head" style="float:left;padding-top:4px;">Instruction To Open Contract (ITOC)</div>
</div>
<div id="logindisplay">
#Html.Partial("_LogOnUserControl")
</div>
<nav>
#Html.Partial("_MenuItems")
</nav>
</header>
<section>
#RenderBody()
</section>
</div>
You don't need to put the curly brace on its own line.
What happens if you change it to this?
#if (Constants.EnvironmentSetting.ToUpper() == "LIVE"){
#:<header>
} else {
#:<header class="headerTest">
}
The #: tells the Razor parser that the rest of the line should be taken as markup and not C# code.
You have to place the { on its own line in Razor
#if (Constants.EnvironmentSetting.ToUpper() == "LIVE"){
should be
#if (Constants.EnvironmentSetting.ToUpper() == "LIVE")
{
Otherwise, that portion of the code should work.
On a side note, it's better to use
Constants.EnvironmentSettings.Equals("LIVE",
StringComparison.CurrentCultureIgnoreCase);
The ToUpper method is often used to convert a string to uppercase so that it can be used in a case-insensitive comparison. A better method to perform case-insensitive comparison is to call a string comparison method that has a StringComparison parameter whose value you set to StringComparison.CurrentCultureIgnoreCase for a culture-sensitive, case-insensitive comparison.
http://msdn.microsoft.com/en-us/library/ewdd6aed.aspx

xPath strange behaviour - selecting ALL elements even if [1] set

today I stumbled upon a very interesting case (at least for me). I am messing around with Selenium and xPath and tried to get some elements, but got a strange behaviour:
<div class="resultcontainer">
<div class="info">
<div class="title">
<a>
some text
</a>
</div>
</div>
</div>
<div class="resultcontainer">
<div class="info">
<div class="title">
<a>
some other text
</a>
</div>
</div>
</div>
<div class="resultcontainer">
<div class="info">
<div class="title">
<a>
some even unrelated text
</a>
</div>
</div>
</div>
This is my data.
When i run the following xPath query:
//div[#class="title"][1]/a
I get as a result ALL instead of only the first one. But if I query:
//div[#class="resultcontainer"][1]/div[#class="info"]/div[#class="title"]/a
I get only the first , not all.
Is there some divine reason behind that?
Best regards,
bisko
I think you want
(//div[#class="title"])[1]/a
This:
//div[#class="title"][1]/a
selects all (<a> elements that are children of) <div> elements that have a #class of 'title', that are the first children of their parents (in this context). Which means: it selects all of them.
The working XPath selects all <div> elements that have a #class of 'title' - and of those it takes the first one.
The predicates (the expressions in square brackets []) are applied to each element that matched the preceding location step (i.e. "//div") individually. To apply a predicate to a filtered set of nodes, you need to make the grouping clear with parentheses.
Consequently, this:
//div[1][#class="title"]/a
would select all <div> elements, take the first one, and then filter it down futher by checking the #class value. Also not what you want. ;-)

Resources