protractor get element link inside nested div - protractor

nested div structure and inside it i have link
like this:
<div>
<div>
<a ng-click>
Now i reached the second div successfully, but I wasn't able to reach the second div and to click it(need to test if the click works)
My structure:
How i select the selected element in the picture and click it? thanks
Can you help? thanks

Just use CSS Attribute Selectors.
var el = element(by.css('a[ng-click="openService()"]'));
// or using the $() shorthand
// var el = $('a[ng-click="openService()"]');
el.click();
If that doesn't work, you can try cssContainingText()
var el = element(by.cssContainingText('a', 'gfd'));
Or it's close relative linkText.
var el = element(by.linkText('gfd'))

Related

How to add child element with class ? through JS

I have an element with the following id="loader-wrap"
<div id="loader-wrap"></div>
I want to add a new div element btw the above parent div automatically including add class "Pin" where ever I have this Id element.
Want this: <div id="loader-wrap"><div class="Pin"></div></div>
Use document.createElement() method:
var pin = document.createElement("div"); // create new div
pin.setAttribute("class", "Pin"); // set class to the div
var loaderWrap = document.getElementById("loader-wrap"); // get the parent element
loaderWrap.appendChild(pin); // append the new div to the parent

more than one caption with featherlight?

i am using featherlight.js for image galleries and used this code for captions:
$.featherlightGallery.prototype.afterContent = function() {
var caption = this.$currentTarget.find('img').attr('alt');
this.$instance.find('.caption').remove();
$('<div class="caption">').text(caption).appendTo(this.$instance.find('.featherlight-content'));
};
now a client wants to add a second caption which contains only copyright-information on the right side of gallery-images. is it possible to have two captions, one named .caption and the second maybe .copyright?
I already tried with "data-caption=" and a simple copy of the above js-initial but it failed.
any ideas?
thank you in advance and merry christmas!
You could use a data attribute.
$.featherlightGallery.prototype.afterContent = function() {
var caption = this.$currentTarget.find('img').attr('alt');
this.$instance.find('.caption').remove();
$('<div class="caption">').text(caption).appendTo(this.$instance.find('.featherlight-content'));
var copyright = this.$currentTarget.find('img').data('copyright');
this.$instance.find('.copyright').remove();
$('<div class="copyright">').text(copyright).appendTo(this.$instance.find('.featherlight-content'));
};
Then in your markup add
<img src="..." alt="my caption text" data-copyright="my copyright text">
and in your css
.copyright {
float: right;
}
or something to suit.
If you need it to be conditional you can check for the defined-ness and/or length of the data-copyright attribute.

Class prefix as selector for each function

I am able to do this using an ID prefix as the selector, but I need to be able to do it with classes instead. It's an each function for opening up different modal windows on the same page. I need to avoid using ID names because I have some modal windows that will have multiple links on the same page, and when using IDs, only the first link will work.
So here's the function as it works with IDs:
$('div[id^=ssfamodal-help-]').each(function() {
var sfx = this.id,
mdl = $(this),
lnk = $('.link-' + sfx),
cls = $('.ssfamodal-close'),
con = $('.ssfamodal-content');
lnk.click(function(){
mdl.show();
});
cls.click(function(){
mdl.hide();
});
mdl.click(function() {
mdl.hide();
});
con.click(function() {
return false;
});
});
and I'm trying to change it to classes instead, like:
$('div[class^=ssfamodal-help-]').each(function() {
var sfx = this.attr('class'),
etc.
But I cannot get it to work without using IDs. Is it possible?
EDIT Fixed error with semi-colon at end of Vars, and updated Fiddle with the fix. Still not working though.
Here's a Fiddle
** UPDATE **
To be clearer, I need to be able to refer to the same modal more than once on the same page. E.g.:
MODAL 1
MODAL 2
MODAL 3
MODAL 4
LINK TO MODAL 1
LINK TO MODAL 2
LINK TO MODAL 3
LINK TO MODAL 4
OTHER STUFF
LINK TO MODAL 1
LINK TO MODAL 4
LINK TO MODAL 3
OTHER STUFF
LINK TO MODAL 2
ETC.
When using classes get rid of the ID habit :
className1, className2, className3 ... etc
simply use
className
HTML:
<div class="ssfamodal-help-base ssfamodal-backdrop">
<div id="help-content" class="ssfamodal-content">
<span class="ssfamodal-close">[x]</span>
Howdy
</div>
</div>
<div class="ssfamodal-help-base ssfamodal-backdrop">
<div id="help-content" class="ssfamodal-content">
<span class="ssfamodal-close">[x]</span>
Howdy Ho
</div>
</div>
<span class="link-ssfamodal-help-base">One</span>
<span class="link-ssfamodal-help-base">Two</span>
LIVE DEMO
var $btn = $('.link-ssfamodal-help-base'),
$mod = $('.ssfamodal-help-base'),
$X = $('.ssfamodal-close');
$btn.click(function(i) {
var i = $('[class^="link-"]').index(this); // all .link-** but get the index of this!
// Why that?! cause if you only do:
// var i = $('.link-ssfamodal-help-base').index();
// you'll get // 2
// cause that element, inside a parent is the 3rd element
// but retargeting it's index using $('className').index(this);
// you'll get the correct index for that class name!
$('.ssfamodal-help-base').eq(i).show() // Show the referenced element by .eq()
.siblings('.ssfamodal-help-base').hide(); // hide all other elements (with same class)
});
$X.click(function(){
$(this).closest('.ssfamodal-help-base').hide();
});
From the DOCS:
http://api.jquery.com/eq/
http://api.jquery.com/index/
http://api.jquery.com/closest/
Here I created a quite basic example on how you can create a jQuery plugin of your own to handle modals: http://jsbin.com/ulUPIje/1/edit
feel free to use and abuse.
The problem is that class attributes can consist of many classes, rather than IDs which only have one value. One solution, which isn't exactly clean, but seems to work is the following.
$('div').filter(function () {
var classes = $(this).attr('class').split(/\s+/);
for (var i = 0; i < classes.length; i++)
if (classes[i].indexOf('ssfamodal-help-') == 0)
return true;
return false;
}).each(function() {
// code
});
jsFiddle
Or, equivalently
$('div').filter(function () {
return $(this).attr('class').split(/\s+/).some(function (e) {
return e.indexOf('ssfamodal-help-') == 0;
});
}).each(function() {
// code
});
jsFiddle
If there is one-to-one relationship between the modal helps and the modal links which it appears there is...can simplfy needing to match class values by using indexing.
For this reason you don't need unique class names, rather they just overcomplicate things. Following assumes classes stay unique however
var $helps=$('div[id^=ssfamodal-help-]');
var $help_links=$('div[id^=link-ssfamodal-help-]');
$help_links.click(function(){
var linkIndex= $help_links.index(this);
$helps.hide().eq( linkIndex ).show();
});
/* not sure if this is what's wanted, but appeared original code had it*/
$helps.click(function(){
$(this).hide()
})
/* close buttons using traverse*/
$('.ssfamodal-close').click(function(){
$(this).closest('div[id^=ssfamodal-help-]' ).hide();
});
Also believe that this code is a little more readable than original apporach
DEMO
Can you try this,
$('div[class^=ssfamodal-help-]').each(function() {
var sfx = $(this).attr('class');
console.log(sfx);
/*console log:
ssfamodal-help-base ssfamodal-backdrop
ssfamodal-help-base2 ssfamodal-backdrop
*/
});
Demo: http://jsfiddle.net/xAssR/51/
why don't you write like
$('div.classname').each(function() {
// you can write your desired code here
var sfx = this.attr('class');
var aa= this.attr('id');
});
or
$('.classname').each(function() {
// you can write your desired code here
var sfx = this.attr('class');
var aa= this.attr('id');
});
where classname is the name of the class used for the div in html
Thanks.

getting class attr in jquery

I have some divs that are generated dynamically with content. I add the content id to the class for the div like so:
<div class="div-1"></div>
<div class="div-3"></div>
<div class="div-6"></div>
<div class="div-8"></div>
How do I select the id for a div because I need it as a param to send via ajax. e.g. I need to get the 1 when I click on the 1st div, 3 when I click on 2nd and so on
var id = $(this).attr('class').replace('div-', '');
Or even simple
var id = this.className.replace('div-', '');
Where this points to the dom element you click on inside the click handler.
//Here instead of document it is better to specify a parent container of all divs
$(document).on('click', '[class^="div-"]', function(){
var id = this.className.replace('div-', '');
});
Try this, and remember changing "div" for your selector:
$(document).on("click", "div", function() {
var class_elem = $(this).attr("class").split("-");
var n = class_elem[1]; // This is your number
});
The correct jQuery syntax is:
$("div").click( function() {
var id = $(this).attr('class').replace('div-', '');
});

XHTML DOM - How to split a tag on IE?

Let's assume I have a part of an html document containing the following code (basic structure) :
<p>
<span class="1">This is my first content</span>
<span class="2">This is my second content</span>
</p>
I'd like to allow the user to select a part of the text and apply a new class to it.
Let's say the user selects "is my first" in the first span, and applies class "3".
I'd like to have the following result :
<p>
<span class="1">This </span>
<span class="3">is my first</span>
<span class="1"> content</span>
<span class="2">This is my second content</span>
</p>
I've managed to do this on Firefox by using the execCommand "InsertHTML", but I can't find a way to do this in IE (before IE9)
The only result I have is a nested span element, like below :
<p>
<span class="1">This <span class="3">is my first</span> content</span>
<span class="2">This is my second content</span>
</p>
Do you have any idea of how I could achieve this ?
Any help would be much appreciated !
By the way, if this looks too simple to you, how would you handle the case of a user selecting a portion of text that spans over 2 or more spans ? over 2 or more ps ?
you can get the selected segment using selection range. I would recommend using rangy, which is a cross browser range module.
Here's some "untested" code using jQuery and Rangy to hopefully point you in the right direction, for your first case:
var splitTag=function(class){
var sel = rangy.getSelection();
// this is your selection, in your example "is my first"
var r0 = sel.getRangeAt(0);
// create a new range
var r1 = rangy.createRange();
// this would be your <p>
var p = r0.endContainer.parentNode;
// set the new range to start at the end of your phrase and to end at <p>
r1.setStart(r0.endContainer, r0.endOffset);
r1.setEnd(p, p.length-1);
// extract the content of your first selection "is my first"
var r0Txt=r0.toHtml();
// make it into an span, with class set to "class argument" which would be 3
var newContent=$("<span/>").html(r0Txt).attr("class", class);
r0.deleteContents();
// insert the new node before r1
r1.insertNode(newContent[0]);
sel.removeAllRanges();
}
this should get you the result for your first situation. for selections across multiple paragraphs, here's a modification of the code:
var splitTag=function(class){
var sel = rangy.getSelection();
var r0 = sel.getRangeAt(0);
var r1 = rangy.createRange();
var p = r0.endContainer.parentNode;
r1.setStart(r0.endContainer, r0.endOffset);
r1.setEnd(p, p.length-1);
var r0Txt=r0.toHtml();
if(!r0.startContainer===r0.endContainer){
// the selection spans multiple dom's
// set the class of all spans in the highlight to 3
var newContent=$(r0Txt).find("span").attr("class",class);
}else{
var newContent=$("<span/>").html(r0Txt).attr("class", class);
}
r0.deleteContents();
r1.insertNode(newContent[0]);
sel.removeAllRanges();
}