简体   繁体   中英

Show/ hide divs based on URL Parameter

The code below shows and hides divs based on URL Parameter. However, the URL parameter is going to show multiple items instead of just one (apples, oranges). With the current code that doesn't work. It will display nothing. Instead I need it to show if it includes "apples" then show apple div. If it includes "oranges", also show oranges. This one is beyond me and I need some help configuring it. Thanks in advance for any help!

The script I am using is below. Like I said, the URL Parameter I will be using will be variations on "apples, oranges, bananas"

<script type="text/javascript">
    // Parse the URL parameter
    function getParameterByName(name, url) {
        if (!url) url = window.location.href;
        name = name.replace(/[\[\]]/g, "\\$&");
        var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, " "));
    }
    // Give the parameter a variable name
    var dynamicContent = getParameterByName('dc');

     $(document).ready(function() {

        // Check if the URL parameter is apples
        if (dynamicContent == 'apples') {
            $('#apples').show();
        } 
        // Check if the URL parameter is oranges
        else if (dynamicContent == 'oranges') {
            $('#oranges').show();
        } 
        // Check if the URL parameter is bananas
        else if (dynamicContent == 'bananas') {
            $('#bananas').show();
        } 
        // Check if the URL parmeter is empty or not defined, display default content
        else {
            $('#default-content').show();
        }
    });
</script>
  1. The modern way:

    new URL(" http://example.com/aa/bb/ ")

Returns an object with properties hostname and pathname, along with a few others.

The first argument is a relative or absolute URL; if it's relative, then you need to specify the second argument (the base URL). For example, for a URL relative to the current page:

new URL("/aa/bb/", location)

In addition to browsers, this API is also available in Node.js since v7, through require('url').URL

  1. You can also use parse_url() function from Locutus project (former php.js).

Code:

parse_url('http://username:password@hostname/path?arg=value#anchor');

Result:

{
  scheme: 'http',
  host: 'hostname',
  user: 'username',
  pass: 'password',
  path: '/path',
  query: 'arg=value',
  fragment: 'anchor'
}

Once it is parsed correctly, it should work the way you have used it. Hope this helps..

Keeping the first part of your code the same (up to the document.ready line) here's how you change the part that displays the divs for each param:

$(document).ready(function() {
  if (dynamicContent) {
    dynamicContent.split('\n').forEach(function(param) {
      $('#' + param).show();
    });
  } else {
    $('#default-content').show();
  }
});

With a url like example.com/?dc=apples%0Aoranges this would show the div with id #apples and the div with id #oranges

The key here is how you handle multiple items in your dc parameter.

First, as @Shlomo's answer indicated, there is a better way to get the parameter value, by using the URL object instead of a RegExp . This would change your function getParameterByName(name, url) method to be like this:

 function getParameterByName(name, url) { let u = new URL(url); return u.searchParams.get('dc'); } // try a call let urlString = 'https://example.com?dc=apples%0Aoranges'; console.log( getParameterByName('dc', urlString) ); 

This is so simple you can do away with the method and just inline it.
What it gets you is the String apples(linefeed)oranges == apples\ oranges
so you will want to split that string to get the components you want: apples and orangesstring.split('\\n') which will give you an array: ["apples", "oranges"]

Now when you act in your $(document).ready(...) you will want to check every element in the array.

 let urlString = 'https://example.com?dc=apples%0Aoranges'; $(document).ready(function() { const url = new URL(urlString) const dc = url.searchParams.get('dc') console.log(dc); const fruits = dc.split('\\n'); console.log(fruits); fruits.forEach(function(f) { // Check if the URL parameter is apples if (f == 'apples') { $('#apples').show(); } // Check if the URL parameter is oranges else if (f == 'oranges') { $('#oranges').show(); } // Check if the URL parameter is bananas else if (f == 'bananas') { $('#bananas').show(); } // Check if the URL parameter is empty or not defined, display default content else { $('#default-content').show(); } }); }); 
 .fruit { display: none; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="fruit" id="default-content">No fruits have been chosen</div> <div class="fruit" id="apples">apples</div> <div class="fruit" id="oranges">oranges</div> <div class="fruit" id="bananas">bananas</div> 

There are more improvements that can be made to this, for example the url , dc , and fruits assignments can be combined as a on-liner, and I may edit to show some of the improvements as time permits.


Edits

I've removed the comma — your first comment had comma-space, second comment just a newline, but I had left the comma in.

As @Elian's answer demonstrates, if your id= values exactly match the dc values you don't have to bother with the if() tests, you can use the dc value directly in the selector for your .show() — that was one of the improvements I implied.

Here is code that has that improvement, plus combining the steps and eliminating the intermediate variables. It also uses the Javascript ES6 arrow function in place of the function(f) parameter to the forEach :

 let urlString = 'https://example.com?dc=bananas%0Aoranges'; $(document).ready(function() { try { const fruits = new URL(urlString) .searchParams.get('dc') .split('\\n'); console.log(fruits); fruits.forEach(f => $('#'+f).show()); } // If there is no `dc` value, the .split above will cause an error. // Catch it and show the default content. catch (err) { $('#default-content').show(); } }); 
 .fruit { display: none; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="fruit" id="default-content">No fruits have been chosen</div> <div class="fruit" id="apples">apples</div> <div class="fruit" id="oranges">oranges</div> <div class="fruit" id="bananas">bananas</div> 


Temporary (would be a comment but needs formatting)

Go to the page where your javascript is running — the one that has the query string ?dc=apples%0Aoranges ... go there however you would normally get there, by doing whatever you need in jotform.
On that page open your browser developer tools and type the following into your browser console:

let u = new URL(window.location.href);
let args = u.searchParams.get('dc');
let vals = [];
for (let i=0; i<args.length; i++) {
    vals.push(args.charCodeAt(i));
}

Now you have an array named vals ... just type that variable name into the console and it should display the contents of the array, which will be the numeric values of all the characters in the parameter value for dc=

vals

You should get a display that looks something like this:

(14) [97, 112, 112, 108, 101, 115, 10, 111, 114, 97, 110, 103, 101, 115]  #in Chrome
-or-
Array(14) [ 97, 112, 112, 108, 101, 115, 10, 111, 114, 97, … ] #in Firefox

Post it in a comment here using back-ticks to make it code.
(this output is when dc === 'apples\ oranges' )
This will show what actual characters are in the string, and therefore what to split on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM