I have a service that is making an API call, grabbing a path to a JSON file, and then running that through a proxy to get around CORS and then returning a value to my controller, I can get it to console.log()but am unable to update anything in my HTML when the function is ran, I have tried $scope.$apply but got a digest error. Also tried using $scope.$applyAsync()
My Service
mywow.service('auctionService', function($http) {
this.getData = function(realmName) {
return $http.get('https://us.api.battle.net/wow/auction/data/' + realmName + '?locale=en_US&apikey=xxxx').
then(function(response) {
var urlToJsonFileUncut = response.data.files[0].url;
urlToJsonFile = urlToJsonFileUncut.slice(7);
console.log("URL to JSON file: " + urlToJsonFile);
return $http.get('http://localhost:1337/' + urlToJsonFile).
then(function(response) {
console.log("Response from Service: " + response.data.realms[0].name);
return response.data.realms[0].name;
});
});
}
});
My Controller
//Auction controller
mywow.controller('auctionCtrl', function($scope, $firebaseArray, auctionService, $timeout, $q) {
var self = this;
self.realms = loadAll();
self.selectedItem = null;
self.searchText = null;
self.querySearch = querySearch;
$scope.test = "waiting for you to choose!"; //here is where I assigned test
//search
function querySearch(query) {
var results = query ? self.realms.filter(createFilterFor(query)) : self.realms;
var deferred = $q.defer();
$timeout(function() { deferred.resolve(results); }, Math.random() * 1000, false);
return deferred.promise;
};
//get all of the realms
function loadAll() {
var allRealms = "Wyrmrest Accord, Ysera, Ysondre, Zangarmarsh, Zul'jin, Zuluhed";
return allRealms.split(/, +/g).map(function(realm) {
return {
value: realm.toLowerCase(),
display: realm
};
});
};
//chnage realm to lowercase
function createFilterFor(query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(realm) {
return (realm.value.indexOf(lowercaseQuery) === 0);
};
};
//send realm name to auction service and run the call
function Init(realmNameFromGo) {
auctionService.getData(realmNameFromGo).then(function(data) {
console.log("From controller: " + data);
$scope.realmName = data;
});
};
//Go button
$scope.realmGo = function() {
Init(self.selectedItem.value);
};
});
My HTML
<div ng-controller="auctionCtrl as ctrl" layout="column" ng-cloak>
<md-content class="md-padding">
<form ng-submit="$event.preventDefault()" name="realmNameSelection">
<p>Please select a realm to begin API queries</p>
<div layout-gt-sm="row">
<md-autocomplete flex="45" required
md-input-name="autocompleteField"
md-no-cache="ctrl.noCache"
md-selected-item="ctrl.selectedItem"
md-search-text="ctrl.searchText"
md-items="item in ctrl.querySearch(ctrl.searchText)"
md-item-text="item.display"
md-floating-label="Realm"
md-require-match
>
<md-item-template>
<span md-highlight-text="ctrl.searchText">{{item.display}}</span>
</md-item-template>
<div ng-messages="searchForm.autocompleteField.$error" ng-if="searchForm.autocompleteField.$touched">
<div ng-message="md-required">Please type, then select an existing realm.</div>
<div ng-message="md-require-match">Please select an existing state.</div>
</div>
</md-autocomplete>
<md-button class="md-raised md-primary" ng-disabled="realmNameSelection.$invalid" ng-click="realmGo()">GO!</md-button>
</div>
</form>
</md-content>
</div>
<p>{{test}}</p>
<p>Selected Realm: {{ realmName }}</p>
<div layout="row">
<div flex="25" hide-sm hide-xs>
<md-content flex layout-align="center center">
<p>Lorem ipsum dolor sit amet, ne quod novum mei. Sea omnium invenire mediocrem at, in lobortis conclusionemque nam. Ne deleniti appetere reprimique pro, inani labitur disputationi te sed. At vix sale omnesque, id pro labitur reformidans accommodare, cum labores honestatis eu. Nec quem lucilius in, eam praesent reformidans no. Sed laudem aliquam ne.</p>
</md-content>
</div>
<div flex="50" hide-sm hide-xs>
<md-content flex layout-align="right">
<p>Lorem ipsum dolor sit amet, ne quod novum mei. Sea omnium invenire mediocrem at, in lobortis conclusionemque nam. Ne deleniti appetere reprimique pro, inani labitur disputationi te sed. At vix sale omnesque, id pro labitur reformidans accommodare, cum labores honestatis eu. Nec quem lucilius in, eam praesent reformidans no. Sed laudem aliquam ne.</p>
</md-content>
</div>
</div>
Related
I've managed to get the cookie consent banner to work, where the cookies aren't set when the page loads. Only once the user clicks on the "Accept" button, the cookies will set and show up within the dev tool Application. Once the "Accept" button has been clicked, the banner is hidden, but only temporarily. Because when I refresh the page, or click on a different page, the cookie consent banner shows up again, even though User has already accepted cookies.
I've tried out a bunch of stuff, and am stuck on how I can keep the banner hidden, after user has accepted the cookies.
Note: I have a custom cookie made and use the Google Tag Manager/Google Analytics cookies.
I would appreciate any help on this! Thank you!
HEAD SCRIPTS
<head>
<!-- Cookie Consent Banner -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {dataLayer.push(arguments);}
gtag('consent', 'default', { 'ad_storage': 'denied', 'analytics_storage': 'denied' });
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TAG_ID');
</script>
<script>
function consentGranted() {
gtag('consent', 'update', { 'ad_storage': 'granted', 'analytics_storage': 'granted' });};
</script>
<script>
function dismissCookieBanner() {
gtag('consent', 'update', { 'ad_storage': 'denied', 'analytics_storage': 'denied' });};
</script>
<!-- Cookie Consent Banner -->
</head>
HTML
<div role="region" aria-label="cookie-consent-banner" id="cookie-banner">
<div class="cookie-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</div>
<div class="cookie-buttons">
<button type="button" class="accept-cookies" onclick="consentGranted()">Accept</button>
<button type="button" class="dismiss-cookies" onclick="dismissCookieBanner()">Dismiss</button>
</div>
</div>
JAVASCRIPT
function consentGranted() {
var cookieConsentBanner = $('#cookie-banner');
if ( cookieConsentBanner.length ) {
if ( Cookies.get('CUSTOM_COOKIE') != 'true' ) {
var acceptCookieButton= cookieConsentBanner.find('.cookie-buttons .accept-cookies');
acceptCookieButton.on('click', function() {
Cookies.set( 'CUSTOM_COOKIE', 'true', { expires: 365 } );
cookieConsentBanner.remove();
});
};
};
};
function dismissCookieBanner() {
var cookieConsentBanner = $('#cookie-banner');
var dismissCookieBanner= cookieConsentBanner.find('.cookie-buttons .dismiss-cookies');
dismissCookieBanner.on('click', function() {
cookieConsentBanner.remove();
});
};
I would recommend using localStorage to store the cookie consent data, and then once the page loads, put the banner onscreen if no answer was given, else, not place it. Example:
function consentGranted() {
localStorage.setItem('consent', true)
var cookieConsentBanner = $('#cookie-banner');
if ( cookieConsentBanner.length ) {
if ( Cookies.get('CUSTOM_COOKIE') != 'true' ) {
var acceptCookieButton= cookieConsentBanner.find('.cookie-buttons .accept-cookies');
acceptCookieButton.on('click', function() {
Cookies.set( 'CUSTOM_COOKIE', 'true', { expires: 365 } );
cookieConsentBanner.remove();
});
};
};
};
function dismissCookieBanner() {
localStorage.setItem('consent', false)
var cookieConsentBanner = $('#cookie-banner');
var dismissCookieBanner= cookieConsentBanner.find('.cookie-buttons .dismiss-cookies');
dismissCookieBanner.on('click', function() {
cookieConsentBanner.remove();
});
};
document.getElementById('cookie-banner').hidden = localStorage.getItem('consent') != null
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<head>
<!-- Cookie Consent Banner -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {dataLayer.push(arguments);}
gtag('consent', 'default', { 'ad_storage': 'denied', 'analytics_storage': 'denied' });
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TAG_ID');
</script>
<script>
function consentGranted() {
gtag('consent', 'update', { 'ad_storage': 'granted', 'analytics_storage': 'granted' });};
</script>
<script>
function dismissCookieBanner() {
gtag('consent', 'update', { 'ad_storage': 'denied', 'analytics_storage': 'denied' });};
</script>
<!-- Cookie Consent Banner -->
</head>
<h1>My site</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Dui vivamus arcu felis bibendum ut tristique et egestas quis. Nunc consequat interdum varius sit amet. Ac odio tempor orci dapibus. Eu consequat ac felis donec et odio pellentesque diam. Faucibus nisl tincidunt eget nullam. Aenean et tortor at risus viverra adipiscing at in. Lacinia at quis risus sed vulputate odio ut enim. Sagittis eu volutpat odio facilisis mauris sit amet massa. Maecenas volutpat blandit aliquam etiam erat velit scelerisque. Vitae tempus quam pellentesque nec nam. Vitae proin sagittis nisl rhoncus mattis rhoncus urna.
</p>
<div role="region" aria-label="cookie-consent-banner" id="cookie-banner">
<div class="cookie-text">Do you accept the cookie policy?</div>
<div class="cookie-buttons">
<button type="button" class="accept-cookies" onclick="consentGranted()">Accept</button>
<button type="button" class="dismiss-cookies" onclick="dismissCookieBanner()">Dismiss</button>
</div>
</div>
JSFiddle
Here my search is working but I am a newbie and doesn't know how to use the npm...I am using HTML with VueJS to implement this and successsfully created the search filter but couldn't implement the highlight filter..Some leads are markjs.io that is used and some other custom vuejs filters but couldn't implement them.
class Post {
constructor(title, link, author, img, course, coursel, cours, coursl, cour, courl, cou, coul, co, col) {
this.title = title;
this.link = link;
this.author = author;
this.img = img;
this.course = course;
this.coursel = coursel;
this.cours = cours;
this.coursl = coursl;
this.cour = cour;
this.courl = courl;
this.cou = cou;
this.coul = coul;
this.co = co;
this.col = col;
}
}
const app = new Vue({
el: "#app",
data: {
search: "",
postList: [
new Post("abc", null, "xyz", "wqw", "qwe", "", " ", null, " ", null, " ", null, " ", null, );
]
},
computed: {
filteredList() {
return this.postList.filter(post => {
return post.title.toLowerCase().includes(this.search.toLowerCase()) ||
post.author.toLowerCase().includes(this.search.toLowerCase()) ||
post.course.toLowerCase().includes(this.search.toLowerCase()) ||
post.cours.toLowerCase().includes(this.search.toLowerCase()) ||
post.cour.toLowerCase().includes(this.search.toLowerCase()) ||
post.cou.toLowerCase().includes(this.search.toLowerCase()) ||
post.co.toLowerCase().includes(this.search.toLowerCase());
});
}
}
});
Here is the HTML code I am using
<div id="app">
<div class="search-wrapper">
<input type="text" v-model="search" placeholder="Search"
onfocus="if(this.value==this.defaultValue)this.value=''"
onblur="if(this.value=='')this.value=this.defaultValue" />
</div>
<div class="wrapper">
<div class="col-lg-12 col-md-4 card" v-for="post in filteredList">
<a v-bind:href="post.link" target="_blank">
<img v-bind:src="post.img"/>
<div style="line-height:20%;">
<br>
</div>
<font size="2">{{ post.author }}</font>
<div class="brmedium"></div>
<font size="5"><b><i><em>{{ post.title }}</em></i></b></font>
<a v-bind:href="post.coursel" title="View Credential" target="_blank"><font size="3">{{ post.course }}</font></a>
<a v-bind:href="post.coursl" title="View Credential" target="_blank"><font size="3">{{ post.cours }}</font></a>
<a v-bind:href="post.courl" title="View Credential" target="_blank"><font size="3">{{ post.cour }}</font></a>
<a v-bind:href="post.coul" title="View Credential" target="_blank"><font size="3">{{ post.cou }}</font></a>
<a v-bind:href="post.col" title="View Credential" target="_blank"><font size="3">{{ post.co }}</font></a>
</a>
</div>
</div>
</div>
<template>
<div>
<input v-model="text" #input="input" />
<p id="x">
Lorem ipsum dolor sit āmet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
clita kasd gubergren, nò sea takimata sanctus est Lorem ipsum dolor sit
amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
nonumy eirmod tempor invidunt ut labore et
</p>
</div>
</template>
<script>
/*eslint-disable */
export default {
data() {
return {
t: String(""),
text: String(""),
};
},
mounted() {
this.t = document.querySelector("#x").innerText;
},
methods: {
input() {
document.querySelector("#x").innerHTML = this.t.replaceAll(
this.text,
`<span class='h'>${this.text}</span>`
);
},
},
};
</script>
<style>
.h {
background: red;
}
</style>
Simple highligh searching this might help you
Good day everyone,
i am trying to change value of each element inside body by using pure js without any framework.
for example, you open console insert js and it changes all the values in each element of body into other symbols.
So basically i can get all the visible words on the website for user without any html markdowns.
like:
<li>This is text</li>
t->p
h->s
i->e
s->l
e->o
x->z
will be
<li>Psel el pozp</li>
so, don't know how to loop through each elements value.
this is what i tried
var elems = document.body.getElementsByTagName("*");
for (i = 0; i < elems.length; i += 1) {
if (elems[i].innerHTML.indexOf('<script') != -1){
console.log(elems[i]);
} else {
continue;
}
}
function validate(element){
if(element.indexOf('<div') == -1){
return false;
} else if(element.indexOf('<script') == -1){
return false;
} else {
return true;
}
}
but cannot get it to work.
updated:
i think it is my bad. i didnt say that i need to change the values on fly. i mean if i insert the code in console, it should loop through each element, get it value, change values by replacing each letter into another letter, then put the value back instead of the old one. eventually it looks on the web different. thank you in advance.
so i need the code to loop through each element, get its value, do something with it and then put it back.
in bold is what i cannot do. thank you to everyone in advance.
First, in your for loop, add the call to validate. Then in validate, add the text replacement:
var elems = document.body.getElementsByTagName("*");
for (i = 0; i < elems.length; i += 1) {
if (elems[i].innerHTML.indexOf('<script') != -1){
console.log(elems[i]);
} else {
validate(elems[i]);
}
}
function validate(element){
if(element.indexOf('<div') == -1){
return false;
} else if(element.indexOf('<script') == -1){
return false;
} else {
element.innerText = element.innerText.replace("t", "p"); //Add the others as well
}
}
.textContent & .innerText
"So basically I can get all the visible words on the website for user without any HTML markdown." ✱
✱Upper case and grammatical corrections are mine
Text can be extracted from HTML easily just by using .textContent or .innerText properties. There are some significant differences between results and minor inconsistency of standards, see links above and demo below.
Demo
Run the demo and click the Results link or scroll to the very bottom
var content = document.getElementById('content');
var tC = document.getElementById('textContent');
tC.textContent = content.textContent;
var iT = document.getElementById('innerText');
iT.innerText = content.innerText;
<!DOCTYPE html>
<html>
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet">
<style>
html {
scroll-behavior: smooth
}
</style>
</head>
<body>
<div id='content' class='container'>
<header id='top' class='container'>
<hgroup class='row'>
<h1>Home</h1>
</hgroup>
<nav class='row'>
<ul class='nav col-12'>
<li class='p-2'><a href='#a0'>Section 1</a></li>
<li class='p-2'><a href='#a1'>Section 2</a></li>
<li class='p-2'><a href='#a2'>Section 3</a></li>
<li class='p-2'><a href='#a3'>Article</a></li>
<li class='p-2'><a href='#a4'>Results</a></li>
</ul>
</nav>
</header>
<hr>
<main class='container'>
<section id='a0' class='row'>
<article class='col-12'>
<h2>Section I</h2>
<p>Lorem ipsum dolor sit amet, eos nonumy omittam ex. No dicant tibique accusamus pri, sed omnis posidonium ad. In sea dico honestatis, ex repudiare reprimique delicatissimi mea. Sit dicta moderatius ad, natum convenire usu ei. Est no graece laboramus
deterruisset. </p>
</article>
</section>
<section id='a1' class='row'>
<article class='col-12'>
<h2>Section II</h2>
<p>Mundi nemore iisque in nec. An dolorum intellegat conclusionemque eos, ad labore omittam mel. Te nam wisi omittam patrioque, oporteat honestatis intellegebat cu mei. Odio cibo omittantur te sed.</p>
</article>
</section>
<section id='a2' class='row'>
<article class='col-12'>
<h2>Section III</h2>
<p>Alii commodo ne sea, eu pro legimus signiferumque. At mei nisl facete adolescens, et mel eleifend voluptatibus. Qui ei wisi sonet noster, est solum posidonium scribentur et, sea nobis verear ut. Nemore admodum usu ne.</p>
</article>
</section>
<hr>
<section id='a3' class='row'>
<article class='col-12'>
<h2>Article</h2>
<p>Lorem ipsum dolor sit amet, quot erroribus voluptatum in pri. Fabulas vocibus insolens his ex. Vide laboramus ius et, at sit adhuc doctus luptatum, et sit dicat inani democritum. His liber blandit pericula id, an fugit reformidans neglegentur
cum. Indoctum intellegat et pro, sed fabulas ocurreret eu. Nam ut fabulas inciderint, iracundia conceptam ne vix, quo offendit inimicus torquatos in.</p>
<div class='row'>
<aside class='col-4 float-left'>
<blockquote>
<p>Duo illum assum discere ne, sed cu posse alterum accusam. Cum an error pertinacia, aperiam deleniti</p>
</blockquote>
</aside>
<p class='col-8'>Ut has elit labores, ex animal delectus efficiendi eos. Id soleat accusamus mel, sint deterruisset his an. Civibus fabellas interpretaris vis ea, dicat aperiri nec ut. Et posidonium dissentias ius, essent quodsi no nam. Mei graece prompta
quaestio et, pri no voluptua atomorum. Pri id putant graecis. Autem prompta nostrud ut mei, mea ut facilisis expetenda intellegebat.</p>
</div>
<div class='row'>
<p class='col-12'>Quo dolor commune albucius ea, ad novum senserit mediocritatem pro, te nisl quidam intellegam nam. Audire omittam in sea, per veniam noster ne. Duo illum assum discere ne, sed cu posse alterum accusam. Cum an error pertinacia, aperiam deleniti
sedcu. Pri ut facilisi hendrerit reformidans, id qui modus libris deseruisse, cum primis moderatius ut.</p>
</div>
</article>
</section>
</main>
<hr>
<footer class='container'>
<nav class='row'>
<ul class='nav col-12'>
<li><a href='#top'>HOME</a></li>
</ul>
</nav>
</footer>
</div>
<!--End of #content-->
<hr>
<hr>
<section id='a4' class='container'>
<h2>Results</h2>
<div class='container'>
<div class='row'>
<h3><code>textContent</code></h3>
<div id='textContent' class='col-10'></div>
</div>
<hr>
<div class='row'>
<h3><code>innerText</code></h3>
<div id='innerText' class='col-10'></div>
</div>
</div>
</section>
<script>
</script>
</body>
</html>
Your code as you have posted does not call the validate function so I will totally ignore that. Your stated objective is really not super clear however I will put an attempt to loop through some elements with something similar to what you have.
For my code, I add a class to everything that is not skipped; that is where you would do your processing; call your function etc. i.e. el.classList.add("show-processors");
Note:skipList an the function filterBySkipCheck are the key parts here.
function doSomething(el) {
const showplace = document.getElementById('actions-display')
.getElementsByClassName('showme')[0];
showplace.innerText = showplace.innerText + el.innerText;
const textContentOutput = document.getElementById('textContentOutput');
const innerTextOutput = document.getElementById('innerTextOutput');
textContentOutput.innerHTML = el.textContent;
innerTextOutput.innerHTML = el.innerText;
}
function hasParentWithMatchingSelector(target, selector) {
return [...document.querySelectorAll(selector)].some(el =>
el !== target && el.contains(target)
);
}
function hasMatchingSelector(target, selector) {
return [...document.querySelectorAll(selector)].some(el =>
el === target
);
}
function hasClass(element, classname) {
return element.classList.contains(classname);;
}
function hasSelfOrParentWithClass(element, classname) {
if (element.classList.contains(classname)) return true;
return element.parentNode && hasSelfOrParentWithClass(element.parentNode, classname);
}
function hasParentWithClass(element, classname) {
return hasParentWithMatchingSelector(element, '.' + classname);
}
function filterBySkipCheck(el, index, myarr, skipList) {
let isSkipped = false;
// process each item in skip list
skipList.forEach(function(skip) {
if (!isSkipped && skip.matchType === 'tag') {
isSkipped = el.tagName === skip.match;
}
if (!isSkipped && skip.matchType === 'skipclass') {
isSkipped = hasClass(el, skip.match);
}
if (!isSkipped && skip.matchType === 'selector') {
isSkipped = hasMatchingSelector(el, skip.match);
}
if (!isSkipped && skip.matchType === 'parentselector') {
isSkipped = hasParentWithMatchingSelector(el, skip.match);
}
if (!isSkipped && skip.matchType === 'element') {
isSkipped = el === skip.match;
}
});
return isSkipped;
}
function processAllElements(elements, skipL) {
// filter for stuff to skip
const filteredElements = [...elements].filter(function(el, index, myarr) {
return filterBySkipCheck(el, index, myarr, skipL);
});
// this answers the question, how to process/loop through all but also how to filter
for (let i = 0; i < elements.length; i += 1) {
let el = elements[i];
let isSkipped = filteredElements.includes(elements[i]);
let shouldProcess = !isSkipped;
if (shouldProcess) {
el.classList.add("show-processors");
}
}
}
let skipList = [{
match: "SECTION",
matchType: "tag"
}, {
match: "SCRIPT",
matchType: "tag"
}, {
match: "STYLE",
matchType: "tag"
}, {
match: "skipme-also",
matchType: "skipclass"
}, {
match: ".skipme",
matchType: "selector"
}, {
match: ".skipme",
matchType: "parentselector"
}, {
match: document.getElementById('second-skip'),
matchType: "element"
}];
let elementsInScope = document.body.getElementsByTagName("*");
processAllElements(elementsInScope, skipList);
.show-processors {
border: solid 1px red;
}
.show-skippers {
border: solid 1px green;
}
<script>
var myfriend = "pluto";
</script>
<div>first</div>
<div id='second-skip'>second</div>
<div>nested one
<div>nested inner
<div>nested granchild</div>
</div>
</div>
<div>container for list
<ul>in the list
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
</div>
<div>testlink
<button type="button">button</button>
<span>span1</span><span>spanner2</span>
</div>
<section>test section to skip</section>
<div class="skipme-also">I am skipped</div>
<div class="skipme">skip me by class</div>
<div>I contain paragraphs
<p>Happy day</p>
<p>Happy day2</p>
<p>Happy day3</p>after paragraphs
</div>
<div id="actions-display" class="skipme">I just show stuff
<button id="test-button" type="text">Click to test</button>
<div class="showme"></div>
<h3>Result of textContent:</h3>
<textarea id="textContentOutput" rows="6" cols="30" readonly>...</textarea>
<h3>Result of innerText:</h3>
<textarea id="innerTextOutput" rows="6" cols="30" readonly>...</textarea> JavaScript
</div>
I am having trouble with CasperJS. I load the page for our site, then try to click on the signup button. It's supposed to open a modal, but nothing happens. It works in actual browsers, and very similar functionality works in other tests on other pages.
What could I be doing wrong? What else would help you, the wider internet, help me?
casperjs --version: 1.1.0-beta3
phantomjs --version: 1.9.7
Casper test snippet:
casper.then(function() {
casper.open(DOMAIN);
});
// wait added for debugging.
casper.then(function() {
casper.wait(2500);
});
// many different ways of trying to click and debug:
casper.then(function() {
casper.click('[data-js="company-search-view-jobs-button-reg"]');
var x = casper.evaluate(function() {
var f = $("[data-js='company-search-view-jobs-button-reg']");
f.click();
var q = document.getElementById("foo");
q.click();
$('#foo').click();
return $("[data-js='company-search-view-jobs-button-reg']")[0].innerHTML;
});
// this prints the expected text, so it is definitely on the right page.
casper.echo(x);
});
//waiting in case it was slow for some reason
casper.then(function() {
casper.wait(2500);
});
// takes a screenshot. uses casper.capture under the hood.
casper.then(function() {
util.screenshot("fff", SCREENSHOT_OPTIONS);
});
From the JS with the click handler:
var $companySearchViewJobsBtnNeedReg = $("[data-js=company-search-view-jobs-button-reg]");
[...]
$companySearchViewJobsBtnNeedReg.on("click", function(e) {
e.preventDefault();
[library code for opening the modal]
The HTML on the page:
<div class="columns xlarge-8">
<div class="company-basic-info__logo left">
<img class="company-basic-info__logo-img" src="/images/logo_placeholder.png" alt="[Standard Values] logo">
</div>
<div class="header-container">
<h1>Standard Values</h1>
<button class="company-basic-info__view-jobs-button" data-cta="viewOpenJobsForCompany" data-js="company-search-view-jobs-button-reg" href="https://[internal url not really important for the question]">Sign Up</button>
</div>
<div class="company-basic-info__description">
<div class="company-basic-info__description-text" data-attr="expandable">Lorem ipsum dolor sit amet, inani labores eligendi ex cum, labitur equidem recteque eam eu. Ignota semper mentitum ad vim, aperiam volumus iracundia ne mea, eu eros movet mel. Sed ea natum elaboraret. Mel modus aliquid reformidans ei, postea putent splendide an eum.
Sanctus indoctum mea id, feugiat placerat mei ea. An scripta epicurei theophrastus has, vis eu illud principes moderatius. Facer velit sed ei, atqui dicta ornatus ea vix, nec soluta populo ei. Quis laudem nec cu, sed viderer theophrastus id.
</div>
<div class="company-basic-info__description-expander" data-attr="expander" style="display: block;">
</div>
</div>
</div>
In my case the problem was this line
casper.options.remoteScripts.push 'http://code.jquery.com/jquery-2.1.4.min.js'
The casperjs Jquery injection overwrited the addEventListeners so they were not working. Remove that line and test if it works. Modify your code to use plain javascript instead of Jquery lib.
THIS HAS BEEN UPDATED, AND IS FUNCTIONAL Thank you #j.wittwer
http://jsfiddle.net/wittwerj/2xjuh/
I am trying to select a row from an array of posts based on ID. The goal behind selecting a single post is to create a single view where users can comment on a specific post.
I am unsure of what the best way to go about this is. I thought about just creating a model but I unsure how to select a single row in order to make that happen. I also would need to then select it with the form controller so that I can send that in the array back to ajax so that it gets posted in the array for that post.
I apologize if the code is messy firefox doesn't seem to like the formating Stack applies.
This is my JS code:(UPDATED)
var myApp = angular.module('myApp', []);
myApp.controller('FrmController', function ($scope, $http) {
$scope.visible = {
post: 1
};
$scope.posts = [{
id: 1,
content: 'Lorem ipsum dolor sit amet, eu laboramus persecuti cum, vel prompta ornatus democritum at, te alia partiendo pri. Ei quo sumo verear. Sed ad elitr aeterno disputationi, solum philosophia ex pro. Tempor essent prodesset in his, ne diam menandri vix, feugiat menandri ad cum.',
comment: ['first!!', 'second!!']
}, {
id: 2,
content: 'Facilisi pertinacia an nec. Veniam nostro commune ei pro, in mazim labores disputationi nec, cu habeo ludus deleniti ius. Id eripuit adolescens vis, mei nemore copiosae referrentur id. Pro ut ubique delicatissimi.',
comment: ['great post!', 'tl;dr', 'interesting']
}, {
id: 3,
content: 'Sed fugit error cu. In cetero albucius insolens pri, an sea velit altera constituto. Et perpetua splendide sed, te vel solum doming contentiones. Pro no omnes ridens liberavisse, ea pri tale cetero laoreet, pro te essent civibus assueverit. Assum essent appareat mei te, duo aeque consulatu et, te mel reque facilisis.',
comment: ['first to comment!']
} ];
$scope.btn_add = function (post, comment) {
if (comment != '') {
var IS_VALID = true;
}
if (IS_VALID) {
console.log("The form was sent");
post.comment.push(comment);
}
}
$scope.remItem = function (post, $index) {
post.comment.splice($index, 1);
}
});
HTML:(UPDATED)
<div ng-controller="FrmController">choose a post ({{visible.post}} is visible)
<ul>
<li ng-repeat="post in posts" style="display: inline; list-style-type: none;">
<input type="button" ng-click="visible.post = post.id" value="{{post.id}}" />
</li>
</ul>
<div ng-repeat="post in posts" ng-if="visible.post == post.id">{{post.content}}
<form>Post your Comment (for post {{post.id}})
<textarea ng-model="txtcomment" placeholder="Your Comment" style='width:550px'></textarea>
<button ng-click='btn_add(post, txtcomment);txtcomment = "";' style='margin-top:10px;'>Post Comment</button>
<h4>Comments</h4>
<ul>
<li ng-repeat="comnt in post.comment">{{ comnt }}<a style="float: right;" href="" ng-click="remItem(post, $index)">x</a>
</li>
</ul>
</form>
</div>
</div>
The simplest way I can think of is to let ng-click set a variable indicating which post is visible/being commented on. Then use that variable in ng-if to show the correct post.
<ul>
<li ng-repeat="post in posts">
<input type="button" ng-click="visible.post = post.id" value="{{post.id}}" />
</li>
</ul>
<div ng-repeat="post in posts" ng-if="visible.post == post.id">{{post.content}}
...
Here is a working demo: http://jsfiddle.net/wittwerj/2xjuh/