I'm trying to have two lines of headers with context change animation to work together like this:
<h4 class="slideshow__text-content" data-animate id='changetext'>Demo Auction Title</h4>
<script>
var text = ["Various Visual Placeholders", "Featuring: Artist Name #1", "Featuring: Artist Name #2", "Featuring: Curator Name", "May 1 - June 1 2021"];
var counter = 0;
var elem = $("#changetext");
setInterval(change, 3000);
function change() {
elem.fadeOut(function(){
elem.html(text[counter]);
counter++;
if(counter >= text.length) { counter = 1; }
elem.fadeIn();
});
}
</script>
<h1 style="color: white"><div class="slideshow__text-content" data-animate id='auction-heading'>Demo Auction Title</h1>
<script>
var text = ["Various Visual Placeholders", "Featuring: Artist Name #1", "Featuring: Artist Name #2", "Featuring: Curator Name", "May 1 - June 1 2021"];
var counter = 0;
var elem = $("#auction-heading");
setInterval(change, 3000);
function change() {
elem.fadeOut(function(){
elem.html(text[counter]);
counter++;
if(counter >= text.length) { counter = 0; }
elem.fadeIn();
});
}
</script>
Can someone please tell me why only one of them works?
You're using the same variable and function names in both blocks, and they conflict because some of them are in the global scope. If you use non-overlapping names, that should fix it.
Here's the code for it. I may have changed a little more than I needed to, but it is a complete working example and it demonstrates the solution.
<body style="background-color: gray">
<h4 class="slideshow__text-content" data-animate id='changetext'>Demo Auction Title</h4>
<h1 style="color: white"><div class="slideshow__text-content" data-animate id='auction-heading'>Demo Auction Title</h1>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script>
var text1 = ["Various Visual Placeholders", "Featuring: Artist Name #1", "Featuring: Artist Name #2", "Featuring: Curator Name", "May 1 - June 1 2021"];
var text2 = ["Various Visual Placeholders", "Featuring: Artist Name #1", "Featuring: Artist Name #2", "Featuring: Curator Name", "May 1 - June 1 2021"];
var counter1 = 0;
var counter2 = 0;
var elem1 = $("#changetext");
var elem2 = $("#auction-heading");
function change1() {
elem1.fadeOut(function(){
elem1.html(text1[counter1]);
counter1++;
if(counter1 >= text1.length) { counter1 = 0; }
elem1.fadeIn();
});
}
function change2() {
elem2.fadeOut(function(){
elem2.html(text2[counter2]);
counter2++;
if(counter2 >= text2.length) { counter2 = 0; }
elem2.fadeIn();
});
}
setInterval(change1, 3000);
setInterval(change2, 3000);
</script>
</body>
Related
I am trying to implement the example 1 provided by w3c.org. The URL is https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html. It keeps giving me aria undefined error on line (var ex1Combobox = new aria.ListboxCombobox). Here is the code:
<!DOCTYPE html>
<html>
<body>
<label for="ex1-input"
id="ex1-label"
class="combobox-label">
Choice 1 Fruit or Vegetable
</label>
<div class="combobox-wrapper">
<div role="combobox"
aria-expanded="false"
aria-owns="ex1-listbox"
aria-haspopup="listbox"
id="ex1-combobox">
<input type="text"
aria-autocomplete="list"
aria-controls="ex1-listbox"
id="ex1-input">
</div>
<ul aria-labelledby="ex1-label"
role="listbox"
id="ex1-listbox"
class="listbox hidden">
</ul>
</div>
<script>
/*
* This content is licensed according to the W3C Software License at
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
*
* ARIA Combobox Examples
*/
var FRUITS_AND_VEGGIES = [
'Apple',
'Artichoke',
'Asparagus',
'Banana',
'Beets',
'Bell pepper',
'Broccoli',
'Brussels sprout',
'Cabbage',
'Carrot',
'Cauliflower',
'Celery',
'Chard',
'Chicory',
'Corn',
'Cucumber',
'Daikon',
'Date',
'Edamame',
'Eggplant',
'Elderberry',
'Fennel',
'Fig',
'Garlic',
'Grape',
'Honeydew melon',
'Iceberg lettuce',
'Jerusalem artichoke',
'Kale',
'Kiwi',
'Leek',
'Lemon',
'Mango',
'Mangosteen',
'Melon',
'Mushroom',
'Nectarine',
'Okra',
'Olive',
'Onion',
'Orange',
'Parship',
'Pea',
'Pear',
'Pineapple',
'Potato',
'Pumpkin',
'Quince',
'Radish',
'Rhubarb',
'Shallot',
'Spinach',
'Squash',
'Strawberry',
'Sweet potato',
'Tomato',
'Turnip',
'Ugli fruit',
'Victoria plum',
'Watercress',
'Watermelon',
'Yam',
'Zucchini'
];
function searchVeggies (searchString) {
var results = [];
for (var i = 0; i < FRUITS_AND_VEGGIES.length; i++) {
var veggie = FRUITS_AND_VEGGIES[i].toLowerCase();
if (veggie.indexOf(searchString.toLowerCase()) === 0) {
results.push(FRUITS_AND_VEGGIES[i]);
}
}
return results;
}
/**
* #function onload
* #desc Initialize the combobox examples once the page has loaded
*/
window.addEventListener('load', function () {
var ex1Combobox = new aria.ListboxCombobox(
document.getElementById('ex1-combobox'),
document.getElementById('ex1-input'),
document.getElementById('ex1-listbox'),
searchVeggies,
false
);
var ex2Combobox = new aria.ListboxCombobox(
document.getElementById('ex2-combobox'),
document.getElementById('ex2-input'),
document.getElementById('ex2-listbox'),
searchVeggies,
true
);
var ex3Combobox = new aria.ListboxCombobox(
document.getElementById('ex3-combobox'),
document.getElementById('ex3-input'),
document.getElementById('ex3-listbox'),
searchVeggies,
true,
function () {
// on show
document.getElementById('ex3-combobox-arrow')
.setAttribute('aria-label', 'Hide vegetable options');
},
function () {
// on hide
document.getElementById('ex3-combobox-arrow')
.setAttribute('aria-label', 'Show vegetable options');
}
);
document.getElementById('ex3-combobox-arrow').addEventListener(
'click',
function () {
if (ex3Combobox.shown) {
document.getElementById('ex3-input').focus();
ex3Combobox.hideListbox();
}
else {
document.getElementById('ex3-input').focus();
ex3Combobox.updateResults(true);
}
}
);
});
</script>
</body>
</html>
Any help would be appreciated.
I realize that this is an old post, but I have determined why the undefined error is occurring:
There are two js files associated with this example:
ListBox-Combox.js &
ListBox-Combo-example.js
The 'ListBox-Combo-example.js' file has event listeners for all three examples on the page
https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html.
Since you only copied the code for the first example, when the javascript attempts to find the combobox 'ex2-Combobox' it cannot find it so javascript throws an error.
You can comment out these lines in the 'ListBox-Combo-example.js' file:
);
var ex2Combobox = new aria.ListboxCombobox(
document.getElementById('ex2-combobox'),
document.getElementById('ex2-input'),
document.getElementById('ex2-listbox'),
searchVeggies,
true
);
var ex3Combobox = new aria.ListboxCombobox(
document.getElementById('ex3-combobox'),
document.getElementById('ex3-input'),
document.getElementById('ex3-listbox'),
searchVeggies,
true,
and replace with a comma. That should solve the problem.
For a browser (Firefox) addon I need to find ISBN's on certain pages (such as: amazon.com, book.com).
I need to find those DOM elemets containing the ISBN and manipulate them with a link, which sends the ISBN to a REST Webservice for further logic.
Since I'm new to JavaScript I don't have any idea how to get into this because the homepages differ in how they display the ISBN.
This is the current implementation:
var self = require("sdk/self");
// a dummy function, to show how tests work.
// to see how to test this function, look at test/test-index.js
function dummy(text, callback) {
callback(text);
}
exports.dummy = dummy;
var tag = "body"
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;
var button = buttons.ActionButton({
id: "mozilla-link",
label: "Visit Mozilla",
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onClick: handleClick
});
function handleClick(state) {
//tabs.open("http://www.mozilla.org/");
tabs.open("http://www.amazon.com");
}
pageMod.PageMod({
include: "*",
contentScriptFile: data.url("modify-content.js"),
onAttach: function(worker) {
worker.port.emit("getElements", tag);
worker.port.on("gotElement", function(elementContent) {
console.log(elementContent);
});
}
});
This is the modify-content.js
self.port.on("getElements", function(tag) {
var elements = document.getElementsByTagName(tag);
for (var i = 0; i < elements.length; i++) {
var isbn = elements[i].innerText.match("(ISBN[-]*(1[03])*[ ]*(: ){0,1})*(([0-9Xx][- ]*){13}|([0-9Xx][- ]*){10})");
if(isbn != undefined){
//self.port.emit("gotElement", elements[i].innerHTML);
console.log(isbn);
}
self.port.emit("gotElement", elements[i].innerHTML);
}
});
The ISBN's are found. But how do I manipulate the DOM Element surrounding the ISBN?
If I understand your question correctly, you're having trouble translating back from a innerText regexp match, which is a string, to the nearest html element of that match.
The difficult part is that the DOM is a tree. So if a <div> has a <p> which has a <span> which has an ISBN number, all of those elements' innerText will contain that ISBN number. We want to reach the "deepest" element that contains a match, ignoring all of its parents.
One (rather expensive, brute-force) way of doing this, is by recursively looping through your elements, layer by layer.
When there is a match in the innerText, we'll look at every child element.
If none of the children has a match, we return the current element because it's the last known DOM element that had a match
Other than performance, I think there are still edge cases that won't match. For example, if there's a <span> that contains three, comma separated, ISBN numbers. You'll probably have to add one last layer: a layer that creates new elements around each individual string.
var isbnRegExp = new RegExp("(ISBN[-]*(1[03])*[ ]*(: ){0,1})*(([0-9Xx][- ]*){13}|([0-9Xx][- ]*){10})");
var start = document.body;
var findDeepestMatch = function(el, regexp, result) {
result = result || [];
if (regexp.test(el.innerHTML)) {
var childMatches = Array.from(el.children)
.filter(child => regexp.test(child.innerHTML));
// Case 1: there's a match here, but not in any of the children: return el
if (childMatches.length === 0) {
result.push(el);
} else {
childMatches.forEach(child => findDeepestMatch(child, regexp, result));
}
}
return result;
};
console.time("Find results")
var results = findDeepestMatch(start, isbnRegExp);
console.timeEnd("Find results")
var makeISBN = el => {
el.classList.add("isbn");
el.addEventListener("click", () => console.log(el.innerText));
};
results.forEach(makeISBN);
.isbn { color: green; border-radius: 3px; background: rgba(0,255,0,0.2); cursor: pointer; }
<div>
<div>
<ul>
<li>
Some book: <span>978-0451524935</span>
</li>
<li>
Some nested book: <span><strong>ISBN</strong>-978-0451524935</span>
</li>
<li>
Some phone number: <span>0012-34-5678909</span> <code><-- regexp problem?</code>
</li>
<li>
Some email: <span>abc#def.gh</span>
</li>
</ul>
</div>
<div>
Here are no isbn numbers
</div>
Here's one <a><strong>ISBN</strong>-<em>978</em>-0451524935</a>
</div>
I'm trying to implement custom pagination component. This is template.
<div *ngIf="totalItems != 0">
<ul class="pagination">
<li *ngFor="let page of pages" [ngClass]="{'active': currentPage == page.title}">
<a (click)="changePage(page)">{{page.title}}</a>
</li>
</ul>
<select>
<option *ngFor="let size of pageSizes">{{size}}</option>
</select>
</div>
Component code:
#Component({
selector: 'pager',
templateUrl: 'templates/pager.component.html',
styleUrls: ['styles/pager.component.css']
})
export class PagerComponent {
#Input() totalItems: number = 0;
#Input() lastText: string = "»";
#Input() firstText: string = "«";
#Input() nextText: string = "›";
#Input() prevText: string = "‹";
public currentPage: number = 1;
pageSizes: Array<number> = [10, 15, 30];
public currentSize: number = this.pageSizes[0];
#Output() pageChanged = new EventEmitter();
get pages(): Array<IPage> {
var list = new Array<IPage>();
let pageCount = Math.ceil(this.totalItems / this.currentSize);
let start = Math.max(this.currentPage - 1, 1);
let end = Math.min(this.currentPage + 2, pageCount);
list.push({ title: this.firstText, number: 1 });
list.push({ title: this.prevText, number: this.currentPage - 1});
for (let i = start; i <= end; i++) {
list.push({ title: String(i), number: i });
}
list.push({ title: this.nextText, number: this.currentPage + 1});
list.push({ title: this.lastText, number: end});
return list;
}
public changePage(page: IPage) {
this.currentPage = page.number;
this.pageChanged.emit(null);
};
public resetCurrentPage(): void {
this.currentPage = 1;
}
}
I was using simple array of numbers. Then I wanted to add Last/Firts buttons. I wrote interface that contains two properties title and page number. Now click event doesn't work. What's wrong with my code?
I think the problem is function changePage() has an argument of type IPage and you pass a number
public changePage(page: IPage) {
this.currentPage = page.number;
this.pageChanged.emit(null);
};
change it to
public changePage(num: number) {
this.currentPage = num;
this.pageChanged.emit(null);
};
I've fixed it! It's similar to this question. It generated new array each time. So angular can't bind an event to array item.
#Günter Zöchbauer, it should be familiar to you.
I have a simple table (type sap.ui.table.Table) where I allow my users to sort, filter and group elements. However there is no possibility to remove sorting or grouping once it is applied? The filter could be removed by entering no value in the filter, but how do I remove sorting/grouping?
var oTableEmpl = new sap.ui.table.Table({
width : "100%",
visibleRowCount : 20,
selectionMode : sap.ui.table.SelectionMode.Multi,
navigationMode : sap.ui.table.NavigationMode.Scrollbar,
editable : false,
enableCellFilter : true,
enableColumnReordering : true,
enableGrouping : true,
extension : oMatrixLayout,
});
oTableEmpl.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({
text : "Label",
textAlign : sap.ui.core.TextAlign.Center
}),
template : new sap.ui.commons.TextView({
text : "{Value}",
textAlign : sap.ui.core.TextAlign.Center
}),
visible : false,
sortProperty: "Value",
filterProperty: "Value",
}));
This might seem easy, but in the table itself there is no option to remove anything. Does it really have to be removed by programming something?
Yes, there is only way to do this by coding. Basically you need to clear sorters and filters of the ListBinding, and then refresh the DataModel. For grouping, reset the grouping of Table and Column to false, after reset, set grouping of Table back to true.
//set group of table and column to false
oTableEmpl.setEnableGrouping(false);
oTableEmpl.getColumns()[0].setGrouped(false);
var oListBinding = oTableEmpl.getBinding();
oListBinding.aSorters = null;
oListBinding.aFilters = null;
oTableEmpl.getModel().refresh(true);
//after reset, set the enableGrouping back to true
oTableEmpl.setEnableGrouping(true);
I also attached a working code snippet. Please have a check.
<script id='sap-ui-bootstrap' type='text/javascript' src='https://sapui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-libs="sap.m,sap.ui.commons,sap.ui.table,sap.viz" data-sap-ui-theme="sap_bluecrystal"></script>
<script id="view1" type="sapui5/xmlview">
<mvc:View xmlns:core="sap.ui.core" xmlns:layout="sap.ui.commons.layout" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.ui.commons" xmlns:table="sap.ui.table" controllerName="my.own.controller" xmlns:html="http://www.w3.org/1999/xhtml">
<layout:VerticalLayout>
<Button text="Reset" press="onPress" />
<table:Table id="testTable" rows="{/}" enableGrouping="true">
<table:Column sortProperty="abc" sorted="true" visible="true">
<table:label>
<Label text="abc"></Label>
</table:label>
<table:template>
<Label text="{abc}"></Label>
</table:template>
</table:Column>
<table:Column>
<table:label>
<Label text="abc2"></Label>
</table:label>
<table:template>
<Label text="{abc2}"></Label>
</table:template>
</table:Column>
</table:Table>
</layout:VerticalLayout>
</mvc:View>
</script>
<script>
sap.ui.controller("my.own.controller", {
onInit: function() {
var aTableData = [{
abc: 1,
abc2: "a"
}, {
abc: 6,
abc2: "b"
}, {
abc: 6,
abc2: "c"
}, {
abc: 3,
abc2: "g"
}, {
abc: 3,
abc2: "h"
}];
var oTableModel = new sap.ui.model.json.JSONModel();
oTableModel.setData(aTableData);
var oTable = this.getView().byId("testTable");
oTable.setModel(oTableModel);
oTable.sort(oTable.getColumns()[0]);
},
onPress: function() {
var oTable = this.getView().byId("testTable");
//set group of table and column to false
oTable.setEnableGrouping(false);
oTable.getColumns()[0].setGrouped(false);
var oModel = oTable.getModel();
var oListBinding = oTable.getBinding();
oListBinding.aSorters = null;
oListBinding.aFilters = null;
oModel.refresh(true);
//after reset, set the enableGroup back to true
oTable.setEnableGrouping(true);
}
});
var myView = sap.ui.xmlview("myView", {
viewContent: jQuery('#view1').html()
}); //
myView.placeAt('content');
</script>
<body class='sapUiBody'>
<div id='content'></div>
</body>
For openui5 v1.78.7: If you want to delete these Filters from the table:
You can do:
var columns = this.byId("tableId").getColumns();
for (var i = 0, l = columns.length; i < l; i++) {
var isFiltered = columns[i].getFiltered();
if (isFiltered) {
// clear column filter if the filter is set
columns[i].filter("");
}
}
You can clear sort filters with:
var columns = table.getColumns();
var sortedCols = table.getSortedColumns();
for (var i = 0, l = columns.length; i < l; i++) {
if (sortedCols.indexOf(columns[i]) < 0) {
columns[i].setSorted(false);
}
}
Make sure you set back sort on row binding if you had any with:
table.getBinding("rows").sort(new Sorter(sPath, bDescending));
I have an array on my controller
$scope.arr = [......], a
nd in html I want to do
ng-repeat = "item in arr | color:'blue'" //this line works, filter done in the app.filter way.
where color is an attribute of all objects in arr.
How Do I make this color:'blue' customizable and sub in color:'red'?
also if I want to do controller filtering instead of html, what would be the syntax, right now I have
$scope.filteredArr = $filter('color')($scope.arr,'blue');
which is giving error
http://jsfiddle.net/x3azn/YpMKX/
posted fiddle, please remove -1
You can customize color:'blue' with any expression in the format filter:expression, so something like color:myColor would work fine provided a color filter has been defined and myColor exists in the current scope.
In your controller, you can do the same.
$scope.filteredArr = $filter('color')($scope.arr,myColor);
Here is an example based on your jsFiddle example.
Javascript:
angular.module('app', [])
.filter('eyecolor', function () {
return function ( people, color ) {
var arr = [];
for ( var i = people.length; i--; ) {
if ( people[i].eyeColor === color ) {
arr.push( people[i] );
}
}
return arr;
}
})
.controller('ctrl', function ($scope, $filter) {
$scope.desiredColor = 'Brown';
$scope.people = [
{
name: 'Bob',
eyeColor: 'Brown'
}, {
name: 'Katherine',
eyeColor: 'Yellow'
}, {
name: 'Chun',
eyeColor: 'Black'
}
];
$scope.peopleFilter = $filter('eyecolor')( $scope.people, $scope.desiredColor );
});
Html:
<div ng-app="app">
<div ng-controller="ctrl">Color Desired:
<input ng-model="desiredColor" /><br/>
<div ng-repeat="person in people | eyecolor: desiredColor">
HTML filter: {{person.name}} has eye color {{person.eyeColor}}</div>
<div ng-repeat="person in peopleFilter">
Controller filter: {{ person.name }} has eye color {{ person.eyeColor }}</div>
</div>
</div>