UPDATE: (2015-10-16) [SOLVED!] -- Fixed with trigger() and by limiting to 50 pins with slice().
Many thanks to Abhas Tandon who offered that by using
$(this).trigger('click');
instead of
$(this).addClass('selected');
it will correctly select the images. I tested with a board consisting of 21 images and it worked perfect! However when trying to move 300+ pins, it failed with this error:
"You can only move 50 Pins at a time."
I then solved that issue by using JavaScript's slice() function to grab only the first 50 images. Tested and it works correctly now. So my limitions are currently that I can only select and move 50 pins at a time, but that's much better than having to pick them one by one by hand!
FINAL WORKING CODE:
function checkAll() {
console.log("Checkboxes count: " + checkBoxes.length);
$.each(checkBoxes, function(i, v) {
console.log("Checkbox #: " + i)// + " = " + v);
$(this).trigger('click');
});
}
var checkBoxes = $("div > div > div.bulkEditPinWrapper > button");
var checkBoxes = checkBoxes.slice(1, 51);
checkAll();
DESCRIPTION OF ISSUE:
I'm having some trouble with a Pinterest interface (?) script (?) I'm developing. I'm a programmer, mostly self-taught, and I think I'm missing some key component of understanding about AJAX possibly? This is the second time I've tried to write a jQuery script to interface with Pinterest. The first one was an attempt to defeat the infinite scroll feature (AKA "load more" button) in order to have all images displayed on one page, from which I could scrape image links and then download them with a browser plugin to backup my Pinterest boards to my computer. My code all worked except it didn't actually end up downloading any images.
Disappointed, I put that on hold to focus on other things. Eventually I revisited my code and did some digging and it should have worked. My research indicated that the CRITICAL FLAW that may have been preventing my program from doing what I wanted was something to with "Pinterest uses AJAX". While I'm aware of the term "Asynchronous JavaScript with XML" and "XMLHttpRequest", I'm not an expert by any stretch at implementing AJAX.
With my latest code, I wrote a -- you would think it would be -- quick little jQuery script to select all images so that I can move them, delete, copy, etc ... The problem is that though checking all the boxes works (You must be in a board and click on "Move" for instance), when I click the "Move" button a second time which should pop-up a modal letting choose which board to move to, all I get is
Oops!
Select the Pins you want to move.
USING:
Chrome 45.0.2454.101
Windows 8.1 64-bit
HOW TO REPRODUCE ISSUES:
Login to your Pinterest account on a laptop or desktop computer.
Choose one of your boards or build a test board from scratch (so you don't loose any of your current pins).
Click "Move" on the top right. This will make transparent checkboxes appear in the upper right of each image. Note: Pinterest shows their unchecked checkboxes WITH a check mark already in them. The way you know a box has been checked is that it retains the checkmark and the box background turns solid (not transparent anymore) red.
In your browser launch your developer tools console (Firefox/Chrome: F12).
Add the below script to your JavaScript console in your browser.
Run the script. If it "worked" you should see all of the checkboxes are now red.
Click the "More" button again. Now you will get the "Select the Pins you want to move." message, indicating that in actuality, the select all did not work.
NOTE: I'm not concerned about pagination at this point, but if anyone wants to address that I'm open to solutions on that issue as well.
SCRIPT TO SELECT ALL IMAGES:
/*
#Repo: EHW-JavaScript-Pinterest-SelectAllImages.
#Creator: Eric Hepperle (CodeSlayer2010/CodeWizard13)
#Date: 10/15/15
#Version: 1.0
#Purpose: Click "Move" in Pinterest board to move pins.
Once checkboxes are visible, run this in an
F12 browser console to automatically check all
visible image pins. You will have success when
the color of all checkboxes turns red. Then
click "Move" again to finish.
#Notes:
2015.10.15
- Created script.
- Checks all checkboxes, but does not allow moving.
*/
function checkAll() {
console.log("Checkboxes count: " + checkBoxes.length);
$.each(checkBoxes, function(i, v) {
console.log("Checkbox #: " + i)// + " = " + v);
$(this).addClass('selected');
});
}
//$(document).ready(function() {
alert('hi');
var checkBoxes = $("div > div > div.bulkEditPinWrapper > button");
checkAll();
//});
WHAT I TRIED TO FIX IT ALREADY:
Googled for solution. I found the following articles. That last one seemed like it might be what I needed, but it did not seem to be focused enough on my issue.
StackOverflow | jQuery to add a class to image links without messing up when the link passes variables
Quora | Pinterest User Feedback: Can you provide options to "select multiple pins and pin them into a board" or "to pin an image into multiple boards at a time"?
StackOverflow | Identify & Extract the title/description of an Image (Data Scraping Pinterest)
StackOverflow | Get all images from a board from a Pinterest web address
Originally tried setting each checkbox's "checked" property to "true", but it did not end up checking the boxes (why??). But,then I observed in a browser console that when I clicked to select an image the "selected" class was applied to that image. So, I used addClass() to apply that class to all checkboxes in my code and I was able to get all the checkboxes to select properly then ... or so it seemed.
I tried the code with a call to $(document).ready, but it gave me the error
"Uncaught ReferenceError: checkBoxes is not defined(…)"
It took me forever to format this ... thanks in advance for your help. I'm happy to clarify if anything was unclear. Also, please let me know if this post belongs in a different forum. Thanks.
I tried triggering click event on each element and it worked perfectly for me. Couldn't try it with scroll because I don't have that many images in my board.
function checkAll() {
console.log("Checkboxes count: " + checkBoxes.length);
$.each(checkBoxes, function(i, v) {
console.log("Checkbox #: " + i) // + " = " + v);
$(this).trigger('click');
});
}
var checkBoxes = $("div > div > div.bulkEditPinWrapper > button");
checkAll();
Let me know if it works for you.
Related
Good afternoon Stack Overflow,
I'm inexperienced when it comes to coding in general and I've been having a problem that's doing my head in!
If you'll allow me to set the scene...
The section of the project I am currently working on involves a user picking items from a warehouse in order to fulfil a shipment and in some cases they have to pick the same item from various locations, when that needs to be done, the small "!" type icon appears next to the item.
The user then can click on the icon and choose which locations they will be retrieving the stock from, they then press confirm on the modal and when it closes it sets the text back to blue and hides the icon.
The part I am having trouble with is that once all the locations have been established, the order needs to be processed and this requires a button to be clicked on, which I only want to appear once all the "!" icons are hidden.
I know there are alot of questions based on for loops and images checks and believe me when I say I've tried hard to figure this out myself and I've tried different approaches:
ShowProcess = false
for (i = 0; i<Picker; i++) {
if ($('#MultiLocIcon'+i).is(':visible')){
ShowProcess = true
}
if (ShowProcess == true) {
$('#ProcessConfirm').show()
};
};
This obviously wouldn't work because its setting the first variable in the list to "true" and will always read it as true, therefore always showing the image, even if the "!" icon still exists in other rows.
I also tried using .each() to test each rows text color of a specific but also had no luck:
var table = $('#RequestedItemsTable');
table.find('tbody > tr').each(function(){
if $('#Desc').css('color') == '#0000FF'){
//do something
I feel like my experience is letting me down as I still have a lot to learn and have a suspicious feeling that the solution is going to be really easy, but then again, its only easy if you know how.
If anyone could take the time to help me with this problem or offer me any advice, I'd be really grateful.
Here is a section of my code which might be useful:
Modal "Confirm" button:
//CONFIRM Button which will submit final picks.
'Confirm': function() {
//Reset the length loop
length = undefined;
//Remove "Multiple Location" icon from the row.
$('#icon'+id).hide();
//Change text colour back to blue to have visual confirmation that item is ready for picking
$('#Desc'+id).css('color', '#0000FF');
$('#QtyReq'+id).css('color', '#0000FF');
$('#QtyinStock'+id).css('color', '#0000FF');
$(this).dialog('close');
The "!" Icon:
<td id= "MultiLocIcon<?=$i;?>"><?if($row->Count_Location > 1)
{?><img src="<?=base_url();?>public/css/images/error.png" alt="LocPick" title="Multiple Locations" style="cursor: pointer;" id= "icon<?=$i;?>" onClick="$.LocPick(<?=$i;?>);"/><?}?></td>
Basically just need to know how my image can show once the loop checks and knows that the "!" icon is hidden from every possible row.
Thank you for your patience.
You'll need to add a second check in your modal logic, perhaps after your .hide():
//Remove "Multiple Location" icon from the row.
$('#icon'+id).hide();
$('img[id^=icon]:visible').length || $('#ProcessConfirm').show();
What this does is combines the :visible pseudo-selector and a regex selector for all img tags with id starting with "icon". This assumes you won't have any other unrelated image tags with an id like "icon*". If the length is 0, it will go ahead and show the #ProcessConfirm element.
simplest solution I would give is to add a class warning to all the table column which has warning icon & then check for visibility of the same.
if($('.warning:visible').length === 0){
//all warning icons are hidden
}
What I would do is based off your HTML, select all the alert icons, and do a :visible psuedo selector on it. This will return all the visible alert icons, if there are none in the array, you know none of them are visible. You will need to identify them with a class, such as .alert:
if( $(".alert:visible").length === 0 ){
// Do your code in here for no visible alert icons!
}
When user clicks confirm on modal you should run a check on how many icons are still visible, and if the amount is 0 then show the button, like this:
// This searchs for every <td> with an id that contains '#MultiLocIcon'
// Then checks if the amount of those which are visible is 0 and do something
if ( $('td[id*=MultiLocIcon]').not(':visible').length === 0 ) {
$('#ProcessConfirm').show()
}
I am working on the responsive design of my website for mobile phones. I have an "img" tag inside of an "a" tag for 3 icons, like this:
<img src="images/webIcon.png" data-attr="webIcon">
On all other screen sizes, when a user hovers over the icon, a description appears, and then disappears again when they mouse-off. But on mobile phones, by the time they scroll down to view the description, it's gone, so I'm changing it to a click event on the "a" tag. I've successfully added the content where I want it when the user clicks on the appropriate icon, but I'm having trouble hiding it when the next icon is clicked, or if they click the same one again.Here is what I have:
$('#mobileServices a').hover(function(e) {
e.preventDefault();
//Grab the corresponding description for the icon
data = $(this).children('img').attr('data-attr');
section = $('#' + data + '').html();
//Plop in the new section containing the description below the icon
$(this).after('<section class=' + data + '>' + section + '</section');
//So I figured perhaps I should store-off the new sections for later use
newSection = $('section.' + data + '');
});
So then I thought: I'll use a simple if statement to check if the newSection is visible, and if it is, hide it (or slide it up, or slideToggle it), but that logic isn't working. I'm getting into the if statement, because I checked it with console.log(s). I tried something like:
if('section:visible') {
newSection.slideToggle();
}
But obviously that doesn't work, because it just slides it down and then up right away. So, now I'm stuck... Any help is greatly appreciated!!!!!
I think your issue may lie with the if statement you're trying to use. You'll want to get the element(s) first, with $('section') and then do .is(":visible");. So, to tie it together:
// Checks for display:[none|block], ignores visible:[true|false]
if($('section').is(":visible")) {
$('section').hide();
}
This will hide all the sections, and should achieve something close to what you're looking for. Then, you can show your new one with newSection.slideToggle() and be good to go.
Ok I made a site a while back and always had issues with the menu system is needed. Basically you click a location on a map, then it displays the list of sub locations in the dropdown menu to the right. These are always their they just chance to display based on the options class.
I have put the site at shiftera.co.uk so you can see it their.
The issue first.
1) IE - The list never filters out, it displays all results all the time regardless of class.
2) Chrome - The dropdown is sometimes squashed showing 1 result and hiding the others you need to use up/down arrows to change, sometimes it shows 3, sometimes 4.
3) Firefox - The list displays in 1 long row, not like a usual dropdown.
I think the issue is more of a css problem or multitude of css problems.
An example of the map link is
Scotland
The dropdown list although not seperated is generated from the database and appears as below
<option value='AB25 1UH' class="Scotland">Aberdeen</option><option value=' WA14 4DW' class="Northwest">Altrincham</option>
As you can see, some have the space before some don't. The dropdown has the id of apick and Im using css below to hide it on load.
#apick { display: none; }
Here is the javascript to display the correct items based on map click.
//<![CDATA[
$(document).ready(function(){
$('.areaselect').on('click', function(event){
$('#apick').css('display','inline');
var id = $(this).attr('id')
$('#apick option').not('.'+id).css('display','none');
$('.'+id).css('display','inline').first().attr('selected','selected');
event.preventDefault();
});
}); //]]>
This has been driving me mad for a long time now, it seem's if i fix 1 issue another 2-3 get created. So I figured i'd try here and see if any brightspark can narrow down my issue.
Updated removing windows load as per change to main website.
The simple answer is that you are setting the style to inline. An <option> tag should not be inline, or have any style like that. The inline style i causing the problems.
Instead add the <option> tags when you need them. Store all the values in a object to add/remove them.
By the way. Remove that window load thing.
Here is the javascript fix:
$(document).ready(function()
{
var options = $('#apick option');
var values = $.map(options, function(option)
{
return option;
});
$('.areaselect')
.on('click', function()
{
var apick = $('#apick').empty();
var id = $(this).attr('id');
var newValues = $.grep(values, function(n, i)
{
return $(n).hasClass(id);
});
apick.append(newValues).show().find('option:first').attr('selected','selected');
return false;
});
});
I am a predominantly PHP developer. I realize in this day and age specialization in one scripting language doesn't cut it, but the fact remains that my skills at JavaScript and jQuery are pretty green. I am a novice at best. I can create my own code but Cross Browser compatibility remains a huge issue with my work in JavaScript.
Anyway, I have a script that filters products according to categories/subcategories. This is how it works: you select a category and the javascript in the background does its thing to filter the subcategories so that the options displayed are the ones pertaining to the parent category- a combination of these two filters the product line.
Here is my code:
function scategories(){
//get the category option value from the category drop down bar
var cat = (document.getElementById('categories').value);
//get all the options from the subcategory drop down bar
var subcat = document.getElementsByClassName('subcategories');
var n=0;
//if the category bar option is set to 0 display everything
if(Number(cat)==0){
Show();
}
//filter the subcategories
while(subcat.item(n)){
//if there is no match b/w the subcategories option and the categories id FILTER
if(Number((subcat.item(n).value).split('|')[1]) != Number(cat) && Number(subcat.item(n).value) != 0){
document.getElementsByClassName('subcategories')
.item(n)
.style
.display="none";
}else{
//else display the subcategory
document.getElementsByClassName('subcategories')
.item(n)
.style
.display="list-item";
}
n++;
}
}
This code is pretty self explanatory I would say. I also have a shiftfocus function that shifts the focus from the current option selected in the subcategory to the default one which is 'none' whenever a new category is picked. This basically resets the subcategory.. here's the code:
function shiftfocus(){
document.getElementsByClassName('subcategories')
.item(0)
.removeAttribute("selected");
document.getElementsByClassName('subcategories')
.item(0)
.setAttribute("selected","selected");
}
Shiftfocus is called onChange and scategories is called onClick.
Problem 1:
1) Firefox: Shiftfocus doesn't shift the focus to the default option even though I can see it adds the 'selected' attribute.
2) Safari: Does not work at all.
EDIT: Problem 2 was the product of a careless mistake. I left open an anchor tag which was
creating havoc in IE. Should have double checked before bothering you
guys. Sorry. Problem 1 still persists.
Problem 2:
I understand none of us developers particularly like internet explorer. But I am willing to believe I have made a mistake here. I have some jQuery that fetches data from a script in another file via the native POST function and appends it to a table with the id "content". This works fine on every browser, except IE. If I try going back to IE 7,8 compatibility mode the results are a little better (the data shows up broken in pieces though) and in IE9 compatibility mode nothing is appended at all! Here's the code:
$.post("bagcontents.php", {
"Bid": $(this).attr('bid')
},
function(data){
$("#content").empty().append(data);
roundNumber();
$('#processorder_hidden').attr('value',currentBid);
});
//append here
<div id="contents" style="overflow:auto;height:345px;padding-right:5px;">
<form name="bag_contents" id="bag_contents" method="post" action="<?php _page ;?>">
<table id="content">
</table>
<input type="hidden" id="bag_contents_hidden" name="bag_contents_hidden" value="1" />
</form>
</div>
Any help will be appreciated. I tried outputting the fetched results with alert, alert(data), and the script is fetching everything just fine. Its the just the append part that fails :|
Here are some suggestions and hope you find them somewhat useful.
Problem: 1
Instead of having the shiftfocus() set the to a specific value, have you tried using .val('') just to clear it out. I can imagine that this will default to the first option.
Problem: 2
This will be hard to debug without knowing what data is coming back from the server. Might be bad formatting or some syntax error on the rendered output.
I'm using 100% pure javascript, tried Jquery but it didn't help. Code not working in FF/Chrome/Safari.
I have built Edit-In-Place functionality where when the user clicks "Edit" (calling external function with onclick - passing in item_id) -- a string of text is hidden to reveal an input with the same string of text in it. (by changing classes) "Edit" is also replaced by "Save". When done editing the string - the user clicks save, and everything reverts back to normal.
AJAX is processing all the updates - but commenting out the AJAX block does not fix it.
I am loading a stream of these objects. The javascript works for all of them - but only updates the DOM, visually anyway for what appears is items before the last 24 hours. The blocks themselves are identical. That is - items that have been added within the last 18-26 hours when I click "Edit", do nothing. BUT if I alert out the class of the element I want to edit it says "editing" (as opposed to "saved") like it is working. (see below) Although this change is never reflected in inspect element.
Code on Page
<input type="text" class="input_field" id="input_254" value="Foo" onkeydown="javascript: if (event.keyCode == 13) { update(254); }" style="display: none; ">
<span class="user_links" id="display_269" style="display:none;">Foo</span> //hidden span that holds the value and acts at the check
<span id="edit_state_269" class="saved" style="display: none;">Foo</span>
<span onclick="update(269)" id="edit_269">Edit</span>
External Javascript
function update(item_id) {
var links_span = document.getElementById('display_' + item_id);
var input_span = document.getElementById('input_' + item_id);
var string_old = document.getElementById('edit_state_' + item_id).innerHTML;
var state_check = document.getElementById('edit_state_' + item_id);
var edit_button = document.getElementById('edit_' + item_id);
if (state_check.getAttribute('class') == 'saved') {
// Hide the links display list and show the input field
links_span.style.display = 'none';
input_span.style.display = 'inline';
// Change the Edit button text and state_check
edit_button.innerHTML = 'Save';
state_check.setAttribute('class','editing');
//alert(state_check.getAttribute('class')); // this alerts "editing" although in DOM it is still "saved" on the blocks that are the problem
If any more details would be helpful - I will provide them.
It is a devil of a problem - with no obvious solution. Would really appreciate any direction you can give!
Solved. As usual it's the little things. The first few blocks were being loaded on page load - and then hidden as the user navigated resulting in duplicate IDs. Javascript naturally selected the one higher on the page - the one that was hidden.