jQuery .load() interfering with shopping cart function - php

I've been struggling for 2 hours now, searching all over for a solution to this.
I'm working with a Zen-Cart installation, and I've decided to thrown on some dynamic banners. Basically I use jQuery.get() to load a URL from banner1.php - banner1.php has an array of a few urls (which are product pages), and it echoes out a random url from the array.
Once the random URL is loaded by jQuery, I then use the jQuery.load() function to load the image of the product, the price of the product and the name of the product.
All this works absolutely fine, but the problem is that it seems the load() function is interfering with my Zen-Cart "redirect" function. Say if you are viewing a product, let's call it "Product A" - and you decide to log in from that page by clicking the "Login" button - what happens is that you are taken to the Login page, you enter your login details, and hit "Submit". The standard outcome is that if you are logged in successfully, you are taken back to the "Product A" page. But with my little dynamic jQuery banner concoction, instead of redirecting back the "Product A", it loads one of the pages that the jQuery.load() used to generate the random banner. I have 3 banners, each dynamically loading a random url, but here is an example of Banner 1:
<script type="text/javascript">
$.get("banner1.php", function(getbannerlink1) {
$( document ).ready(function() {
$("#banner1").load(getbannerlink1+ " #globalproductimage");
$('#banner1name').load(getbannerlink1+ " #productName", function(result) {
var banner1text = $('#banner1name').html();
banner1text = jQuery(banner1text).text();
$("#banner1name").html(banner1text);
});
$('#banner1price').load(getbannerlink1+ " #productPrices", function(result) {
var banner1prices = $('#banner1price').html();
banner1prices = jQuery(banner1prices ).text();
$("#banner1price").html(banner1prices );
});
var bannerlink1 = $("<a>").attr("href", getbannerlink1);
$("#banner1name").wrap(bannerlink1);
$("#banner1price").wrap(bannerlink1);
$("#banner1").wrap(bannerlink1);
});
});
</script>
The thing is I'm not too concerned about the wrongful redirection once a customer logs in, the problem also occurs most disappointingly when the customer once to actually Checkout. For instance, if they were to have products in their shopping basket, click the Checkout button, which then asks them to login, and once they login, instead of continuing with the standard shopping cart function of taking them to the first step of the checkout process, it redirects them to one of the pages that the dynamic banner has loaded. I don't know how to sort this out, I tried some weird things to no avail. For the sake of reference, this might be needed, this is the Zen-Cart function that handles redirection after a login:
if (sizeof($_SESSION['navigation']->snapshot) > 0) {
// $back = sizeof($_SESSION['navigation']->path)-2;
//if (isset($_SESSION['navigation']->path[$back]['page'])) {
// if (sizeof($_SESSION['navigation']->path)-2 > 0) {
$origin_href = zen_href_link($_SESSION['navigation']->snapshot['page'], zen_array_to_string($_SESSION['navigation']->snapshot['get'], array(zen_session_name())), $_SESSION['navigation']->snapshot['mode']);
// $origin_href = zen_back_link_only(true);
$_SESSION['navigation']->clear_snapshot();
zen_redirect($origin_href);
} else {
zen_redirect(zen_href_link(FILENAME_DEFAULT, '', $request_type));
}
Please help! Perhaps there is an easier way I should be doing this :/
I noticed that the page it loads is always the last banner that jQuery.load() loaded. Like I mentioned there are 3 banners in total, so if Banner 2's price was the last one to load, that's the URL that's loaded in the redirection.
Edit:
banner1.php (this simply generates a random url from an array, but currently for testing purposes I only have one URL in the array):
<?php
$strings = array('http://example.com/index.php?main_page=product_info&cPath=3&products_id=104');
echo $strings[array_rand($strings)];
?>

It appears that the banner page is setting the snapshot href. I assume you are including some of the Zen cart libraries in your banner urls that are setting the Session navigation snapshot. You maybe able to set something to ignore your url for the snapshot.
Adding the banner code may help solve this issue.
Although I would not recommend it, you could add logic to not redirect to certain pages after login.

Related

PHP print message when a div is present on specific page

I am trying to print a message (link) through PHP if a div is present on a page. Basically the div is present on some product pages on an ecommerce website, while it is not present on other product pages. The ecommerce is a Woocommerce and that's why I am using Woo hooks in the code.
Basically I get nothing in return (even when visiting pages where the div is present). What am I missing?
add_filter('woocommerce_before_add_to_cart_button', 'size_guide_display', 15);
function size_guide_display() {
$sizeguide = $html->find("div#tab-SizeChart_tab");
if ($sizeguide) :
echo 'Storleksguide';
endif;
}
I'll be very happy for any reply :-) Pretty novice with PHP.
Thanks!
Due to the information you've provided I guess using JavaScript on the client-side would be your way to go.
document.addEventListener("DOMContentLoaded", () => {
const sizeChartTabEle = document.querySelector("div#tab-SizeChart_tab")
const storleksGuideLinkEle = document.createElement("a")
storleksGuideLinkEle.title = "Storleksguide"
storleksGuideLinkEle.href = "#tab-SizeChart_tab"
storleksGuideLinkEle.classList.add("size_guide_link")
storleksGuideLinkEle.innerText = "Storleksguide"
sizeChartTabEle?.append(storleksGuideLinkEle)
})
This code creates an event listener DOMContentLoaded (see this StackOverflow answer to learn more about it, speaking very basic - it waits for your contents being loaded) and executes the part in the curly brackets.
Your div#tab-SizeChart_tab is queried and afterwards appended by a newly created a element storleksGuideLinkEle.
If you make sure this code is only executed on pages that you need it, this should do the job.

codeigniter - how to redirect to default index page when user submits form that's embedded in menu

Background Information
I have a php web application that uses a template approach to my pages.
So in other words, I have a header.php, footer.php and a leftnav.php.
Each view in my php app includes all three pages listed above.
So far, so good. Everything works.
As a part of my leftnav.php, I have the following code:
<div class="input-group custom-search-form">
<input type="text" class="form-control" placeholder="Quick Search..." id="searchtext">
<span class="input-group-btn">
<button class="btn btn-default" type="button" id="qsearch">
<i class="fa fa-search"></i>
</button>
</span>
</div>
The idea is to provide the users with a "quick search" option that they can use where ever they are in the application... It always shows up because every page includes the same menu stored in leftnav.php.
Problem
This code works fine ONLY if you launch my app and trigger the search right away. But if you navigate away from the default controller, and then the user tries to run the search... nothing happens because they're not in the default controller.
So for example, here's the default URL when you launch my web app:
http://myserver/testapplication/index.php
From here, you can run the quick search and the dashboard controller kicks in.
But from somewhere else like this:
http://myserver/testapplication/index.php/widgets/addwidget
the search button does nothing.
Question
I don't know how to set up my code so that whenever the user clicks on the search submit button, the first thing that happens in the system redirects to the dashboard controller.
The logic that actually runs the search is in my default controller, called "Dashboard". The controller looks like this:
public function index()
{
$data['main_content'] = "dashboard";
$this->load->view('includes/template',$data);
}
public function quicksearch()
{
//grab search text
$seg3 = $this->uri->segment(3); //hardwaremodel
$searchresults = $this->dashboard_model->quick_search($seg3);
$retval = array();
foreach ( $searchresults as $id => $value )
{
//logic to build results array
array_push($retval, $temp);
}
echo json_encode($retval);
}
}
And the view that includes the logic to display the search results is in the "dashboard.php" file.
$(document).ready(function(){
$(".searchresults").hide();
$('#qsearch').click(function(){
$('#qsearchresults tbody').empty();
var searchstring = $('#searchtext').val();
var searchurl = "<?php echo site_url('dashboard/quicksearch/');?>" + searchstring;
$.ajax({
url:searchurl,
type:'POST',
dataType:'json',
success: function(res) {
if (res.length > 0) {
var htmlstring = "<tr><th>ID</th><th>PH</th><th>Site</th><th>Location</th><th>Department</th><th>Description</th><th>Fax?</th><th>Last Assigned Date</th><th>Score</th></tr>";
for (var key in res) {
tmpurl = "<?php echo site_url('did/getdidbyobjid/')?>";
//bunch of logic to build html string with search results
}
$('#qsearchresults tbody').append(htmlstring);
$('.searchresults').show();
}
},
error: function(xhr, req, err) {
var err = eval("(" + xhr.responseText + ")");
console.log(err.Message);
}
});
});
});
EDIT 1
I tried to put all the javascript that handles the search button click event into a separate js file called qsearch.js.
qsearch.js is now included in the header.php... which in turn in included by all views.
<head>
<script src="<?php echo base_url(); ?>assets/l/js/qsearch.js"></script>
</head>
Test
This works: (because it's launch the default controller Dashboard)
http://myserver/myapp/index.php/
But let's say i go to:
http://myserver/myapp/index.php/reports/dept
the search IS WORKING... but it has no where to display the results.
The javascript that handles the search click event does this in part:
$('#qsearchresults tbody').append(htmlstring);
"htmlstring" contains the results of the search... but not all pages have the html table called qsearchresults.
So I guess I need to know if it's possible to redirect the user to the dashboard controller and then run the search.
If not, no worries. I will redo the code and use a static form inside the leftnav.php menu. But I'm so close, I'd like to leave it as is... if possible
I found this link: How to redirect on another page and pass parameter in url from table?
and I'm trying to see if I can adapt it to my use case.
First of all, the form and ajax will only work if your JS is included on every page (which it appears you are only adding on the dashboard from your description). This is easily achieved in a slight customization to the way your template system works, you do not have to add it to every controller.
However, I would suggest you actually use a form with form_open and a submit button styled in any way that suits. The submit button will then submit to your search controller from any page. Having a dedicated non-ajax search results page allows you to do lots of things very easily, without worrying about loading the same js on every page, and disabling it on pages where you do not have the search.
A dedicated search results page is actually very user freindly. The form_open will also give you xss protection if you have that enabled by adding the hidden xss code that will be updated on every page.
You can read about it here: http://www.codeigniter.com/user_guide/helpers/form_helper.html
One of the benefits is that you can show a more complex result set. For instance for a shop you can show exact matches, suggested matches, matching categories, matching sub-categories etc in a layout that is user friendly and easily understood. You can then develop that page to provide more and more information that you think your visitor wants. Ajax, in this situation, might not be the best answer.
A better use of ajax here might be to create a list of clickable search terms that appears when they start typing, which gives you the benefit of suggesting searches that actually produce good results rather than some of the weird searches users actually do.
I have rattled on a bit here but I hope this helps in some way.
Paul.

Pass Variable to Div with AJAX

ORIGINAL POST: Not sure why I am having such a hard time grasping this but I am creating a page that executes a query to list a set of records per a user. I am wanting to create a div that shows the details of a select record from the list. I am attempting to load that record with the following:
$(document).ready(function(){
// load index page when the page loads
$("#form").load("tm-reserves-form.php");
$("#record").click(function(){
// load home page on click
$("#form").load("tm-reserves-form-test.php?ContactID"+$ContactID);
});
});
Initial form loads but I can not get my .click function to work using the URL parameters.
How can I pass the url parameter from my current query into a div that loads an external page and executes a second query based on that url paramenter (primary id)?
Thanks in advanced for helping me out!
EDIT POST: Found solution, but another issue has arisen.
So I took a crash course this weekend on ajax and I found a working solution here:
$(document).ready(function(){
// load index page when the page loads
$("#form").load("tm-reserves-form.php");
$("#record").click(function(){
// load home page on click
var ContactID = document.getElementById('ContactID').value;
$("#form").load("tm-reserves-form.php", {"ContactID": ContactID});
});
});
So with this example, when the page loads the div form is loaded with a default page. With a click function on the label #record the div #form is than loaded with a parameter of ContactID that is a string value inside of #ContactID. All that seems to work very well (even passes the parameter correctly).
The issue now is that it is only allowing me to pass the first record to my div. Any thoughts on what I need to implement next? I originally thought it was to clear the var but that didn't work either.
The original query parameters are not readily available to a running script. So $ContactID is not resolved to an actual value.
See this page on methods for extracting query parameters from the current page:
Get query string parameters with jQuery
$(document).ready(function(){
// load index page when the page loads
$("#form").load("tm-reserves-form.php");
$("#record").click(function(){
// load home page on click
var ContactID = document.getElementById('ContactID').value;
$("#form").load("tm-reserves-form.php", {"ContactID": ContactID});
});
});
This code solved my initial question, but led to an additional question.

Back Button for a Single Paged Website

I have a single paged website relying heavily on jQuery. As a portfolio, users can click on various designs, in which the jQuery will hide the main page, and reconstruct the design page based on the content returned by a query string.
The problem is, people that would like to go back to the main portfolio page will naturally press the BACK button on their browser, causing them to go back to whatever website they were on previously (e.g. Google Search). When in fact, the intended behaviour is that they return to the main.
My question is, what is the best way to implement a way so that the BACK button functions as if it was on a multipage website. Would it involve implementing my own stack of queries? What is the best option.
Many thanks. The website is here if you'd like to see it in action.
Take a look at the History.js library, handles both modern browsers and has fallbacks for older HTML4 browsers
https://github.com/browserstate/history.js/
In your event handler inside $(".mLink").click(function(){...
Whenever you trigger an scroll, you can add something like this
case "mL0":
$("html, body").stop().animate({ scrollTop: 0}, 1000, 'easeInOutExpo');
History.pushState(null, null, "?home");
break;
case "mL1":
$("html, body").stop().animate({ scrollTop: ($('#filter').offset().top-72) }, 1000, 'easeInOutExpo');
History.pushState(null, null, "?portfolio");
break;
...
Beautiful portfolio site, btw.
How about putting a hash tag in the URL? Something like this?
About
And somewhere in the code there should be a line with this?
<div id="about">
<h2>About/h2>
<!-- More content here -->
</div>
You might want to look into the HTML5 History API. There are lots of tutorials on how to get started with it, but the basic gist is that when you load a new "page" with jQuery, you push it onto the history stack:
// After loading the new page...
window.history.pushState({}, '', 'newpage.html');
This will make the user agent display yoursite.com/newpage.html in the URL bar even though the page was never loaded.
Caniuse reports that history API support is fairly good. The usual suspects (IE 7 and 8) have no support, but there are polyfills available.
The only caveat with the History API (and it's an important one) is this: the page that you pass as the third (optional) argument to history.pushState MUST exist on your server. A user could copy a URL from the URL bar and share it, so the page names must correspond to real pages. The trouble with this is that doesn't really seem like it would work with your site because you don't have separate pages that you're dynamically loading.
It appears to me that your portfolio is one continuous page, so for that I would recommend using hash urls. That is, urls like yoursite.com/#about and yoursite.com/#contact. You can update window.location to include the hash as you load new pages (and the browser won't re-load the page).
window.location = '#new-page-that-was-just-navigated-to';
Or you can just update window.location.hash. You can examine the contents of the hash with javascript when your site loads with this property to determine which page should be displayed.
$(document).ready(function() {
switch(window.location.hash) {
case 'home': // load home
case 'about': // load about
default: // load default page (index)
}
});
Furthermore, you can abstract your JS from your HTML with the HashChange event (polyfill available on the MDN docs page). Instead of doing this:
About
Projects
Contact
<script>
document.getElementById('about').addEventListener('click', function() {
// navigate to about page
}, false);
document.getElementById('projects').addEventListener('click', function() {
// navigate to projects page
}, false);
//etc.
</script>
You can instead do this:
About
Projects
Contact
<script>
window.addEventListener('hashchange', function() {
switch(window.location.hash) {
case 'about': // load page
case 'projects': // load page
case 'contact': // load page
default: // not found
}
}, false);
</script>
The benefits of this are that your links have meaningful hrefs and you don't have to add event listeners to each link on your site. Just assign them a hash and listen for hashchange.
EDIT
Note that this also works with jQuery:
$(window).on('hashchange', function() {
switch(window.location.hash) {
case 'about': // load page
case 'projects': // load page
case 'contact': // load page
default: // not found
}
});
Your content is loading via AJAX in a single div. So it is little bit tough to go back to previous because your content is updated with the new one.
You can use "history.pushState" to change the URL based on the menu entry you click ... you can check this webpage for an example - http://html5.gingerhost.com/.
BACK button usually goes to the previous URL and in AJAX pages URL doesn't update by itself. You can explicitly change the URL using "history.pushState" and BACK will work like you expect it to.
This will also make your site Search Engine friendly

Executing PHP: detecting when a link has been clicked

I've got a bit of a dilemma with some PHP code. The site I'm working on has a "Back to Previous Page" option and I'd like it to behave much like a browser's back button. As it stands right now, I'm using a $_SESSION variable to track what the current and previous pages are. I've also "refresh-proofed" the variables so that I don't end up with both the previous and current pages being the same.
So here's the issue:
With the current implementation, if I go to one page, say "register.php" and then go to "forgot.php", the previous page will be "register.php" which is fine. However, if I click "Back to Previous Page" I'll end up back at "register.php" with the previous page being "forgot.php" which now leaves me with a 2-page loop with going back.
I tried implementing SplQueue to help me keep track of variables and I tried using the dequeue() function in my links to get the last page to show up as the link. The problem comes in when the dequeue is actually called and causes the element to disappear so that if I refresh, the element is no longer in the queue and the link changes. I fixed this by "refresh-proofing" the function that calls the dequeue for me and it works as I would like it to. The problem is now forward-linking. If I direct myself to another page, I don't want the old links to dequeue information.
Ex:
I'm on register.php and my previous page is "forgot.php". The "Back to Previous Page" link accurately shows that "forgot.php" is the page it will direct to, but now it's no longer in the queue, so if I go to another page, say "profile.php" and then use the back button to go back to "register.php", it will no longer show "forgot.php" as the page that you will go to if you hit "Back to Previous Page" again.
So, I guess my question is really how I can make a link call a PHP function without actually calling that function UNTIL the link has been clicked. I've tried having the link point to a JavaScript function, but the JS functions tend to tell me that my queue is empty, which is completely wrong.
As a side note, the pages are a mix of HTML and PHP. The HTML is supplied to me and I've been adding the PHP in to add functionality to fields and to get data from a database. I have no problem using PHP to echo the HTML links if I have to, and if it can be done in HTML with a small <?php someCode(); ?>, that's fine too.
I thank you for your time to try and help me out.
EDIT:
So to try and clarify a bit, I have a structure that is currently tracking pages that the user has already been to as they visit them. It creates a mini history of the pages. My issue is that I have code like this:
Back To Previous Page
And I don't know what "somelink" is since it will change depending on your history. I know I can do something like:
Back To Previous Page
If I do anything like the above, the function is executed as the page is being displayed, so it makes it difficult to use an array_pop() or a dequeue() but again, the PHP will be executed as soon as the page is displayed. What I'm looking for is a way to display the link and then remove it from the history if and only if the "Back to Previous Page" link is clicked. As of right now, I'm storing an array in $_SESSION as was suggested below and since it's an array, I can show the last element in the array as the link, so the only real problem is to find a way to remove elements from the array when the link is clicked.
EDIT 2:
I've been scouring the internet and decided upon using JavaScript with AJAX to call a PHP file. This allows me to us an onClick on the links I have so that I can control when I array_pop from my $_SESSION['links'] variable.
I don't think my AJAX is actually doing anything sadly, so the code I'm using is below.
<script src="js/jquery-1.4.2.min.js" type="text/javascript">
function dequeue()
{
$.ajax({
type: "POST",
url: "common.php",
data: {action: "rem"},
success: function(output) {
alert(output);
}
});
}
</script>
and the PHP is
switch($_POST['action'])
{
case "rem":
array_pop($_SESSION['links']);
break;
default:
if(isset($_SESSION['current']) && $_SESSION['current'] != $_SERVER['REQUEST_URI'])
{
array_push($_SESSION['links'], $_SESSION['current']);
}
$_SESSION['current'] = $_SERVER['REQUEST_URI'];
break;
}
As far as I can tell, this will allow me to add a link to the history in the session variable unless I'm clicking on the "Back to Previous Page" link since that link will have the "rem" code. I'm also a bit suspicious of the $_SESSION['current'] = $_SERVER['REQUEST_URI']; and where it should be placed.
You can store array in a session and treat the array like a stack (use array_push and array_pop accordingly). When the user hits something but the back button, push the current page to the stack. otherwise, pop it.
I would do it like this if I had to:
$_SESSION["history"] = array();
And within the header of every "rememberable" page:
if(in_array($this_page, $_SESSION["history"])) {
unset($_SESSION["history"][array_search($this_page, $_SESSION["history"])]);
}
array_push($_SESSION["history"], $this_page);
What this does is: "If the page exists in the history, remove it from wherever it is and put it as the last page of the history. If not, just put it as the last page of the history". That way you won't have any loops.

Categories