I have an HTML page in which a hidden div becomes visible when a button is clicked. Something like this:
$('#display').click(function(){
$('#itemList').removeClass('hide');
...
})
On another page, there is a link which when clicked takes the user back to the earlier page, and the element with id='itemList' on that page has to become visible. The code is something like this:
<a href='firstHTML.php'> View items</a>
I am not sure what else to add to the code to make the other page appear with the previously hidden element visible. Can somebody help please?
One of the most probable solution is localStorage .Where as you may also implement Cookies or string query to pass value to other page.
I am showing the use of localstorage , you may store the id in localStorage on click of anchor as below
<a href='firstHTML.php' data-showId='itemList'> View items</a>
Now bind event on anchor
$("[data-showId]").bind('click',function(){
var idToShow=$(this).attr('data-showId');
if(idToShow)
store('visibleId', idToShow);
});
Now all you need to define these functions .
function setup() {
var tmp = get('visibleId');
if (tmp)
showDiv(tmp);
}
function showDiv(cls) {
$("#"+cls).removeClass('hide');
}
function get(name) {
if (typeof (Storage) !== "undefined") {
return localStorage.getItem(name);
} else {
window.alert('Please use a modern browser to properly view this template!');
}
}
function store(name, val) {
if (typeof (Storage) !== "undefined") {
localStorage.setItem(name, val);
} else {
window.alert('Please use a modern browser to properly view this template!');
}
}
Now call setup() on dom ready..
First of all, I would use the jQuery function to hide/show the List instead of using an own CSS class for it:
$('#display').click(function(){
$('#itemList').show();
...
})
Then a possible approach for your problem could be to use a get Parameter for this, for example:
<a href='firstHTML.php?list=show'> View items</a>
And with jQuery
Create a helperfunction (Taken from Get url parameter jquery Or How to Get Query String Values In js):
$.urlParam = function(name) {
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (results==null){
return null;
}else{
return results[1] || 0;
}
}
Read out the property:
var listStatus = $.urlParam('list');
Unhide the list in case it should be shown:
$( document ).ready(function() {
if(listStatus == 'show') {
$('#itemList').show();
}
});
Related
Here's the problem. I'm making a callback to the server that receives an MVC partial page. It's been working great, it calls the success function and all that. However, I'm calling a function after which iterates through specific elements:
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(...)
Inside this, I'm checking for a specific attribute (custom one using data-) which is also working great; however; the iterator never finishes. No error messages are given, the program doesn't hold up. It just quits.
Here's the function with the iterator
function HideShow() {
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(function () {
if (IsDataYesNoHide(this)) {
$(this).collapse("show");
}
else
$(this).collapse("hide");
});
alert("test");
}
Here's the function called in that, "IsDataYesNoHide":
function IsDataYesNoHide(element) {
var $element = $(element);
var datayesnohide = $element.attr("data-yes-no-hide");
if (datayesnohide !== undefined) {
var array = datayesnohide.split(";");
var returnAnswer = true;
for (var i in array) {
var answer = array[i].split("=")[1];
returnAnswer = returnAnswer && (answer.toLowerCase() === "true");
}
return returnAnswer;
}
else {
return false;
}
}
This is the way the attribute appears
data-yes-no-hide="pKanban_Val=true;pTwoBoxSystem_Val=true;"
EDIT: Per request, here is the jquery $.post
$.post(path + conPath + '/GrabDetails', $.param({ data: dataArr }, true), function (data) {
ToggleLoader(false); //Page load finished so the spinner should stop
if (data !== "") { //if we got anything back of if there wasn't a ghost record
$container.find(".container").first().append(data); //add the content
var $changes = $("#Changes"); //grab the changes
var $details = $("#details"); //grab the current
SplitPage($container, $details, $changes); //Just CSS changes
MoveApproveReject($changes); //Moves buttons to the left of the screen
MarkAsDifferent($changes, $details) //Adds the data- attribute and colors differences
}
else {
$(".Details .modal-content").removeClass("extra-wide"); //Normal page
$(".Details input[type=radio]").each(function () {
CheckOptionalFields(this);
});
}
HideShow(); //Hide or show fields by business logic
});
For a while, I thought the jquery collapse was breaking, but putting the simple alert('test') showed me what was happening. It just was never finishing.
Are there specific lengths of time a callback function can be called from a jquery postback? I'm loading everything in modal views which would indicate "oh maybe jquery is included twice", but I've already had that problem for other things and have made sure that it only ever includes once. As in the include is only once in the entire app and the layout is only applied to the main page.
I'm open to any possibilities.
Thanks!
~Brandon
Found the problem. I had a variable that was sometimes being set as undefined cause it to silently crash. I have no idea why there was no error message.
I have a WordPress site that lists custom post type items in isotope layout. Every item has a favorite button. Once you favorite it, a star will be highlighted via CSS. When you go to that item, I want to be able to see that this item has been favorited.
I just realized that the script I have doesn't store the ID of that button so it doesn't show it on a singular page, just to the page where it was favorited. Here's the script:
if (typeof(localStorage) == 'undefined') {
document.getElementById("result").innerHTML =
'Your browser does not support HTML5 localStorage. Try upgrading.';
} else {
$(".grid-item").each(function(i, el) {
if (localStorage['fav' + i] == 'addfave') {
$(this).addClass('addfave');
}
});
}
$(document).ready( function() {
// ADD FAVE
$( ".fav" ).click(function(e) {
e.preventDefault();
var $item = $(this).closest('.grid-item');
var index = $('.grid-item').index($item);
//localStorage.removeItem('background');
$item.toggleClass('addfave');
if ($item.hasClass('addfave')) {
console.log(index)
localStorage.setItem('fav' + index, 'addfave');
} else {
localStorage.removeItem('fav' + index);
if (localStorage['fav' + i] == null) {
}
}
});
});
My button looks like this and I display the star in the span tag using CSS
<span></span>
you already have an post id in your link id so no need to redo that, you simply had to change from identifying grid items using their index number to using the post id.
if (typeof(localStorage) == 'undefined') {
document.getElementById("result").innerHTML =
'Your browser does not support HTML5 localStorage. Try upgrading.';
} else {
console.log(localStorage);
$(".fav").each(function(i, el) {
if (localStorage[el.id] == 'addfave') {
$(this).closest('.grid-item').addClass('addfave');
}
});
}
$(document).ready( function() {
// ADD FAVE
$( ".fav" ).click(function(e) {
e.preventDefault();
var $item = $(this).closest('.grid-item');
var index = this.id;
//localStorage.removeItem('background');
$item.toggleClass('addfave');
if ($item.hasClass('addfave')) {
localStorage.setItem( index, 'addfave');
} else {
localStorage.removeItem(index);
}
});
});
To demonstrate have a look at the jsfiddle below, its not very exciting but it will turn red when favorited, you can add in more grid-items and change the order, it will favorite the correct item.
https://jsfiddle.net/a71b4zd8/6/
Now i dont know where you mean by singular page, but im assuming on a single page template. The function above will not be suitable for marking a favorite on that page. I don't know your html structure, but a typical id used to uniquely identify the page might be post-{$postif}
You should allow for this when creating the script to check the post ids off against each other.
This calls for some script localization. Where you enqueue your scripts you can do something like:
global $post;
wp_localize_script( 'main-js', 'my_object', array( 'post_id' => $post->ID ) );
main-js should be the name of the script before which you want the localized script content to be output.
Then in your javascript file you can access this object and its post_id property and do what you want with the value like so:
var post_id = my_object.post_id;
I have this main page that loads another php file on onchange event of the dropdown. I use this to load the page:
function get_value(){
if($("#dropdwn").val()=="0"){
//load nothing
}else{
$('#txtval').val($("#dropdown").val());
$('#load_page').html('<p align="center"><br/><img src="images/popuploader.gif" /><br/><br/></p>');
$('#load_page').load('load_xml.php');
}
}
For now I put the value of dropdown on the textbox but will also try to get the value of dropdown.
The problem is on the second php file that loads on the main page. I can't get the value of $txtval=$_POST['txtval'] when I use this. I will need the value for if else condition.
First you need to sent the parameter to the resource load_xml.php.
function get_value() {
if ($("#dropdwn").val() == "0") {
//load nothing
} else {
var val = $("#dropdown").val();
$('#txtval').val(val);
$('#load_page').html('<p align="center"><br/><img src="images/popuploader.gif" /><br/><br/></p>');
$('#load_page').load('load_xml.php?txtval=' + val);
}
}
The the load method uses a GET request, not a POST method.
$txtval=$_GET['txtval']
If you want to sent a POST method, then use the syntax
function get_value() {
if ($("#dropdwn").val() == "0") {
//load nothing
} else {
var val = $("#dropdown").val();
$('#txtval').val(val);
$('#load_page').html('<p align="center"><br/><img src="images/popuploader.gif" /><br/><br/></p>');
$('#load_page').load('load_xml.php?', {
txtval: val
});
}
}
then
$txtval=$_POST['txtval']
Trying to automate some testing for some analytics tracking code, and I'm running into issues when I try passing links into the each() method.
I copied a lot of this from stackoverflow - how to follow all links in casperjs, but I don't need return the href of the link; I need to return the link itself (so I can click it). I keep getting this error: each() only works with arrays. Am I not returning an array?
UPDATE:
For each anchor tag that has .myClass, click it, then return requested parameters from casper.options.onResourceReceived e.g. event category, event action, etc. I may or may not have to cancel the navigation the happens after the click; I simply only need to review the request, and do not need the follow page to load.
Testing steps:
click link that has .myClass
look at request parameters
cancel the click to prevent it from going to the next page.
I'm new to javascript and casper.js, so I apologize if I'm misinterpreting.
ANOTHER UPDATE:
I've updated the code to instead return an array of classes. There are a few sketchy bits of code in this though (see comments inline).
However, I'm now having issues canceling the navigation after the click. .Clear() canceled all js. Anyway to prevent default action happening after click? Like e.preventDefault();?
var casper = require('casper').create({
verbose: true,
logLevel: 'debug'
});
casper.options.onResourceReceived = function(arg1, response) {
if (response.url.indexOf('t=event') > -1) {
var query = decodeURI(response.url);
var data = query.split('&');
var result = {};
for (var i = 0; i < data.length; i++) {
var item = data[i].split('=');
result[item[0]] = item[1];
}
console.log('EVENT CATEGORY = ' + result.ec + '\n' +
'EVENT ACTION = ' + result.ea + '\n' +
'EVENT LABEL = ' + decodeURIComponent(result.el) + '\n' +
'REQUEST STATUS = ' + response.status
);
}
};
var links;
//var myClass = '.myClass';
casper.start('http://www.leupold.com', function getLinks() {
links = this.evaluate(function() {
var links = document.querySelectorAll('.myClass');
// having issues when I attempted to pass in myClass var.
links = Array.prototype.map.call(links, function(link) {
// seems like a sketchy way to get a class. what happens if there are multiple classes?
return link.getAttribute('class');
});
return links;
});
});
casper.waitForSelector('.myClass', function() {
this.echo('selector is here');
//this.echo(this.getCurrentUrl());
//this.echo(JSON.stringify(links));
this.each(links, function(self, link) {
self.echo('this is a class : ' + link);
// again this is horrible
self.click('.' + link);
});
});
casper.run(function() {
this.exit();
});
There are two problems that you're dealing with.
1. Select elements based on class
Usually a class is used multiple times. So when you first select elements based on this class, you will get elements that have that class, but it is not guaranteed that this will be unique. See for example this selection of element that you may select by .myClass:
myClass
myClass myClass2
myClass myClass3
myClass
myClass myClass3
When you later iterate over those class names, you've got a problem, because 4 and 5 can never be clicked using casper.click("." + links[i].replace(" ", ".")) (you need to additionally replace spaces with dots). casper.click only clicks the first occurrence of the specific selector. That is why I used createXPathFromElement taken from stijn de ryck to find the unique XPath expression for every element inside the page context.
You can then click the correct element via the unique XPath like this
casper.click(x(xpathFromPageContext[i]));
2. Cancelling navigation
This may depend on what your page actually is.
Note: I use the casper.test property which is the Tester module. You get access to it by invoking casper like this: casperjs test script.js.
Note: There is also the casper.waitForResource function. Have a look at it.
2.1 Web 1.0
When a click means a new page will be loaded, you may add an event handler to the page.resource.requested event. You can then abort() the request without resetting the page back to the startURL.
var resourceAborted = false;
casper.on('page.resource.requested', function(requestData, request){
if (requestData.url.match(/someURLMatching/)) {
// you can also check requestData.headers which is an array of objects:
// [{name: "header name", value: "some value"}]
casper.test.pass("resource passed");
} else {
casper.test.fail("resource failed");
}
if (requestData.url != startURL) {
request.abort();
}
resourceAborted = true;
});
and in the test flow:
casper.each(links, function(self, link){
self.thenClick(x(link));
self.waitFor(function check(){
return resourceAborted;
});
self.then(function(){
resourceAborted = false; // reset state
});
});
2.2 Single page application
There may be so many event handlers attached, that it is quite hard to prevent them all. An easier way (at least for me) is to
get all the unique element paths,
iterate over the list and do every time the following:
Open the original page again (basically a reset for every link)
do the click on the current XPath
This is basically what I do in this answer.
Since single page apps don't load pages. The navigation.requested and page.resource.requested will not be triggered. You need the resource.requested event if you want to check some API call:
var clickPassed = -1;
casper.on('resource.requested', function(requestData, request){
if (requestData.url.match(/someURLMatching/)) {
// you can also check requestData.headers which is an array of objects:
// [{name: "header name", value: "some value"}]
clickPassed = true;
} else {
clickPassed = false;
}
});
and in the test flow:
casper.each(links, function(self, link){
self.thenOpen(startURL);
self.thenClick(x(link));
self.waitFor(function check(){
return clickPassed !== -1;
}, function then(){
casper.test.assert(clickPassed);
clickPassed = -1;
}, function onTimeout(){
casper.test.fail("Resource timeout");
});
});
I'm working on ajax search.ajax function is called on onblur event.below is sample code.
function search_ajax(sh_val,sh_act)
{
....some search code.....
window.location.hash = sh_val+'#'+sh_act;
}
I have made one other function for restore the serch using hash value from url when click on browser back or forward button.this work well for back and forward button.
$(window).bind( 'hashchange', function(e) {
var page=location.hash.slice(1)
if (page!="" && page!="p")
{
search_ajax(page,'catsh');
}
return false;
});
but i am facing issue when i am search ajax search function is called twice. $(window).bind( 'hashchange') is also called when i am searching.is there any way to call the above function only for browser back and forward button or any other solution ?
how can i resolve this issue?
I would appreciate anykind of help..
maybe I don't understand well, but why did you bind hashchange function to window??? It doesn't make any sence. I have similar searching function in my own apps. It is not that complicated. My search function is (lets say) same as yours:
function search_ajax(sh_val,sh_act)
{
....some search code.....
window.location.hash = sh_val+'#'+sh_act;
}
The another one is performed once per page load:
(function() {
var page=location.hash.slice(1)
if (page!="" && page!="p")
{
search_ajax(page,'catsh');
}
return false;
})();
So, if you click search button, then search function is called. Hash is changed. One step into browser history is added.
Then another search, another step in history is added.
Then back button. Page loaded again, so annonymous function is performed. Hash is detected, so search is performed. And hash is changed, but becouse hash is same as before, so link is same, then no duplicite step is added into history.
You could use a semaphore:
var searching = false;
function search_ajax(sh_val, sh_act) {
searching = true;
....some search code.....
window.location.hash = sh_val + '#' + sh_act;
searching = false;
}
$(window).bind('hashchange', function (e) {
if (searching)
return false;
var page = location.hash.slice(1);
if (page != "" && page != "p") {
search_ajax(page, 'catsh');
}
return false;
});