How do i make this working?
var makePage = $('<div />').attr('data-role', 'page').attr('id', 'p'+item.id)
.append($('<div>').attr('data-role', 'header')
.append('')
.append('<img src="images/app/logo.png" id="navImg"/>')
.append('<div class="separatore"></div></div>'))
.append($('<div />').attr('data-role', 'main').attr('class', 'ui-content')
.append('<h2 class="hstyle">'+item.name+' '+item.surname+'</h2>')
.append($('<ul />').attr('data-role', 'listview').attr('data-inset', 'true')
if (item.cellulare != '') { .append('<li><img src="images/app/tel.png" class="ui-li-icon">'+item.cellulare+'</li>') }
) // data-role page
); // data-role main
makePage.appendTo($.mobile.pageContainer);
the condition i want is "if variable item is not empty, append this..".
Thanks
Store your new div into a variable if you want to later append new elements onto it. The way you were doing it you were telling the compiler to use the append method of a true value which doesn't exist.
var newDiv = $('<div />').attr('data-role', 'page')
.append($('<div>')
.attr('data-role', 'header');
if (item != '') {
newDiv.append('')
.append('<img src="images/app/logo.png" id="navImg"/>');
}
If you need to append into specific elements you need to append at that level then put that level into the parent. For instance if you were trying to append the image inside the anchor (note your code if it were to be proper code would append all into the first div you created):
$('').append('<img src="images/app/logo.png" id="navImg"/>').appendTo(newDiv);
In your first part it looks like you possibly were intending to create a div and then append another div with a specific data-role, but the way you were doing it would create a div with data-role page, append another div, and then update the parent div's data-role to header. To do it in order you should do:
var newDiv = $('<div />').attr('data-role', 'page');
$('<div>').attr('data-role', 'header').appendTo(newDiv);
Write like this.
if(item != '')
{
//write your code
}
you are mixing code
Related
Is there a way I can traverse through the list, perform click again and then return to the same page again for the next item in list.
cy.get('#collaborators').next().children().each((items) => {
// Here I have to write code to access list element
cy.log(cy.wrap(items))
}
Log gives me a structure like this and am not sure how to access it. Please help as I am new to cypress.
cy.get('#collaborators').next().children().each( (items,index)=>{
cy.wrap(items[index]).click()
}
)
Having a code written like this, is causing DOM element to be detached although it goes to the next page.
var itemsCount = cy.get('#collaborators').next().children().its('length')
Not sure if I can loop over to get to each of the elements this way.
cy.children() enables you to select child elements and use the selector to filter them. In your case, to get the a tag element, you can do something like:
cy.wrap(items).children('a');
I am also new to cypress, but I believe you can access the href attribute with the invoke() command:
invoke() - https://docs.cypress.io/api/commands/invoke
Try something like this:
cy.wrap(items).children('a').invoke('attr', 'href')
.then((url) => {
cy.visit(url);
});
If you evaluate the href attribute before starting the loop, you'll avoid the detached from DOM error.
Essentially, iterate over a string array not an element array.
cy.get('#collaborators').next()
.find('a') // find all <a> within the <ul>
.then($els => [...$els].map((a) => a.href)) // extract the href
.each(href => { // now iterate list of URL strings
cy.visit(href)
cy.pause() // substitute whatever test you need
cy.go('back')
})
Clicking the link
If you prefer to click the link, extract the last part of the href and use it to find the link element inside the loop
cy.get('#collaborators').next()
.find('a')
.then($els => [...$els].map((a) => a.href))
.each(href => {
const slug = href.split('/')[3]
cy.get('#collaborators').next().find(`a[href="/${slug}"]`).click()
const title = slug.replace('~', '')
cy.contains('h2', title)
cy.go('back')
})
I'm using casperjs to scrape a site. I setup a function which stores a string into a variable named images (shown below) and it works great.
images = casper.getElementsAttribute('.search-product-image','src');
I then call that variable in fs so I can export it to a CSV, which also works fine.
casper.then(function() {
var f = fs.open('e36v10.csv', 'w');
f.write(imagessplit + String.fromCharCode(13));
f.close();
});
The issue I just noticed is that not all products have images, so when the scraper hits a product without an image it passes by it obviously. I need it to at least alert me somehow (something as simple as filler text thats says, "no image here") when it passes by a product without an image because what I do is I copy that string (along with may other strings) and organize them into columns within the CSV and it messes up the order of everything without having some sort of filler text ("no image here"). Thanks
Edit
Below is the exact source from the website I am trying to pull from.
A product I can get the image from and my code works fine:
<div class="search-v4-product-image">
<img alt="238692" class="search-product-image" src="http://d5otzd52uv6zz.cloudfront.net/group.jpg">
<p class="image-overlay">Generic</p>
</div>
A product with no image and my scraper passes right by it without alerting me.
<div class="search-v4-product-image"> </div>
First I would do images = casper.getElementsInfo('.search-product-image') which will give you an array of elements matching .search-product-image. Then you can iterate over this array and extract the src attribute from each element with: var src = image.attributes.src
Now that you have the src attribute you can simply check wether it has a value or not. If it does not, then you could assign it to placeholder text.
You can write this functionality for the page context this way:
casper.then(function(){
var imgList = this.evaluate(function(){
var productImages = document.querySelectorAll("div.search-v4-product-image"),
imageList = [];
Array.prototype.forEach.call(productImages, function(div){
if (div.children.length == 0) {
imageList.push({empty: true});
} else {
var img = div.children[0]; // assumes that the image is the first child
imageList.push({empty: false, src: img.src});
}
});
return imageList;
});
var csv = "";
imgList.forEach(function(img){
if (img.empty) {
csv += ";empty";
} else {
csv += img.src+";";
}
});
fs.write('e36v10.csv', csv, 'w');
});
This iterates over all divs and pushes the src to an array. You can check the empty property for every element.
I suspect that the output would be more meaningful if you iterate over all product divs and check it this way. Because then you can also write the product name to the csv.
You could use CSS selectors but then you would need make the :nth-child selection much higher in the hierarchy (product div list). This is because :nth-child only works based on its parent and not over the whole tree.
I have a container div which includes lots of element divs all of which have a unique ID. I then make an ajax call to get more elements and append these to the DOM.
This works using the function below but I need to check that what I append doesn't already exist in the DOM. I've been looking into using each() and possibly remove() or detach() in order to do this, but I am not sure of jQuery syntax and really need some assistance.
function loadMoreItems(url) {
$.get(url, null, function(data) {
var container = $(data).find('#container');
var newItemsHTML = "";
/*-- not sure what to do in between
container.find('.element').remove();
container.each('.element').detach();
--*/
newItemsHTML = $(container).html();
var $newItems = $(newItemsHTML);
$container.isotope('insert', $newItems, true);
}, 'html');
}
<div class="element" id="id_172977"></div>
Assuming all of appended divs has class element you can do
$(".element").each(function() {
container.find("#" + this.id).remove();
});
Demo
I try implement Kendo UI PanelBar (see http://demos.kendoui.com/web/panelbar/images.html) If I open some items (Golf, Swimming) and next click to "Videos Records", I have expanded items. But when I do refresh page (click on some link), all expanded structure is lost.
On KendoUI forum I found, that I can get only possition of selected item and after reload page I must calculate all noded. Is there any way, how can I have expanded items in my situation? If do not need, I don't want to use the html frames.
Best regards,
Peter
Thank you for your answer, was very usefull. I add here code of skeleton of jQuery which remember 1 selected item now. Required add jquery.cookie.js [https://github.com/carhartl/jquery-cookie]
function onSelect(e) {
var item = $(e.item),
index = item.parentsUntil(".k-panelbar", ".k-item").map(function () {
return $(this).index();
}).get().reverse();
index.push(item.index());
$.cookie("KendoUiPanelBarSelectedIndex", index);
//alert(index);
}
var panel = $("#panelbar").kendoPanelBar({
select: onSelect
}).data("kendoPanelBar");
//$("button").click(function () {
// select([0, 2]);
//});
function select(position) {
var ul = panel.element;
for (var i = 0; i < position.length; i++) {
var item = ul.children().eq(position[i]);
if (i != position.length - 1) {
ul = item.children("ul");
if (!ul[0])
ul = item.children().children("ul");
panel.expand(item, false);
} else {
panel.select(item);
}
}
}
// on page ready select value from cookies
$(document).ready(function () {
if ($.cookie("KendoUiPanelBarSelectedIndex") != null) {
//alert($.cookie("KendoUiPanelBarSelectedIndex"));
var numbersArray = $.cookie("KendoUiPanelBarSelectedIndex").split(',');
select(numbersArray);
}
else {
// TEST INIT MESSAGE, ON REAL USE DELETE
alert("DocumenReadyFunction: KendoUiPanelBarSelectedIndex IS NULL");
}
});
The opening of the panels happens on the client. When the page is refreshed, the browser will render the provided markup, which does not include any additional markup for the selected panel.
In order to accomplish this, you will need to somehow store a value indicating the opened panel. The easiest way to accomplish this would be with a cookie (either set by JavaScript or do an AJAX call to the server).
Then, when the panelBar is being rendered, it will use the value in the cookie to set the correct tab as the selected one.
You can use this block to work withe the selected. in this example, i am just expanding the panel item. You can do other things such as saving panel item in your dom for later use or may be saving it somewhere to use it later:
var panelBar = $("#importCvPanelbar").data("kendoPanelBar");
panelBar.bind("select", function(e) {
var itemId = $(e.item)[0].id;
panelBar.expand(itemId);// will expand the selected one
});
I have made a jQuery thing; with will load content without refreshing the page. The code for that is:
$(document).ready(function(){
// initial
$('#content').load('content/index.php');
// handle menu clicks
$('#navBar ul li ').click(function(){
var page = $(this).children('a').attr('href');
$('#content').load('content/'+ page +'.php');
return false;
});
});
Now I want to have a sort of history thing in that, the code for that is:
(function(){
// Bind an event to window.onhashchange that, when the hash changes, gets the
// hash and adds the class "selected" to any matching nav link.
$(window).hashchange( function(){
var hash = location.hash;
// Set the page title based on the hash.
document.title = 'The hash is ' + ( hash.replace( /^#/, '' ) || 'blank' ) + '.';
// Iterate over all nav links, setting the "selected" class as-appropriate.
$('#nav a').each(function(){
var that = $(this);
that[ that.attr( 'href' ) === hash ? 'addClass' : 'removeClass' ]( 'selected' );
});
})
// Since the event is only triggered when the hash changes, we need to trigger
// the event now, to handle the hash the page may have loaded with.
$(window).hashchange();
});
Found on: http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
My Question is: how can i make the second code working with the first?
Since you haven't gotten an answer yet I will write it. You need the plugin jQuery hashchange for the code to run.
https://github.com/cowboy/jquery-hashchange
To implement a cache you could do something like
$('#content').load('content/index.php');
//create a cache object
var cache = {};
// handle menu clicks
$('#navBar ul li ').click(function(){
var page = $(this).children('a').attr('href');
//check if the page was already requested
if(cache[page] === undefined){
//if not fetch the page from the server
$.get('content/'+ page +'.php', function(data){
$('#content').html(data);
//save data in cache
cache[page] = data;
}else{
//use data from cache
$('#content').html(cache[page]);
}
return false;
});
Use History JS. It works for HTML5 pushState and also falls back to HTML 4 hashtags. Also works for keeping the state model when the page is refreshed.