Im attempting to produce a dynamic url containing multiple javascript variables but i only want to include them if they contain information.
These variables are essentially filters which will be used to Select from a MYSQL databse so they take form of "column=value".
The url i am trying to produce will need to be in the format of
page.php?column1=value1&column2=value2.... etc.
i am struggling to work out how to include only the variables that contain info and then how to insert the required "&" between each variable.
The current code is below and currently contains just the two variabls but the aim is to have as many as 5.
var jsedibility = "";
function chosenEdibility(choice){
jsedibility = choice;
}
var jsfrequency = "";
function chosenFrequency(choice2){
jsfrequency = choice2;
}
function setFilters(){
window.location='search.php?' + jsedibility+"&"+jsfrequency;
}
i am then using "onClick=setFilters()" assigned to a button to load the relevant page.
How can i set this up so that the URL is produced dynamically, only containing the variables that have data in them and also to add the required "&" between each variable.
Massively appreciate any help :)
I would make an array of the variables then use join().
var filters = [];
Use an if statement to check that they are not empty strings.
if (jsedibility != ""){ filters.push(jsedibility) }
var filtersString = filters.join('&');
Then in your setFilters(),
window.location.assign('./' + filtersString)
This works with any number of variables.
// mockup data object
const obj = {
jsedibility: '',
jsfrequency: '',
jsvar1: '',
jsvar2: '',
jsvar3: ''
}
// setting object values
function setObjVal(obj) {
obj.jsedibility = 'choice1'
obj.jsfrequency = 'choice2'
}
// creating the filter string
function setFilters(obj) {
return Object.values(obj).filter(val => val !== '').join('&')
}
document.getElementById('setFilters').addEventListener('click', function(e) {
setObjVal(obj)
console.log(setFilters(obj))
})
<button id="setFilters">Filters</button>
Or another with an array:
// mockup data
const choice = 'ch1'
const choice2 = 'ch2'
const array = []
var jsedibility = "";
function chosenEdibility(choice) {
jsedibility = choice;
}
var jsfrequency = "";
function chosenFrequency(choice2) {
jsfrequency = choice2;
}
// showing that it can be filtered out
var noValue = "";
function chosenNoValue(choice3) {
noValue = choice3;
}
chosenEdibility(choice)
chosenNoValue('') // empty value
chosenFrequency(choice2)
document.getElementById('setFilters').addEventListener('click', function(e) {
array.push(jsedibility)
array.push(noValue)
array.push(jsfrequency)
// string filtered for not empty values
const filterString = array.filter(el => el !== '').join('&')
console.log(filterString)
})
<button id="setFilters">Filters</button>
Related
Have an array which is being compiled based on user input selection (checkbox and radio buttons)
This is being compiled using an input on change function.
The array is then used to check if values in the array match data attributes referenced within each card, and those which match, show the respective card.
This is working fine.
I am now trying to get the same functionality, but instead of being based on user input, the result is being compiled based on user query string (string is also compiled from the user input - effectively saving a query for using to return to page with results without having to enter the checkbox values again). This function has a lot of if true, push which I would like to re-use instead of re-write. I have simplified here.
Problem I am having is using the same function I built for show/hide the card based on user input with the query string.
// Set Globals:
var arr = []
function buildResults() {
// Build query based on input values and push into array:
$("input").on("change", function() {
var arr = [];
$(":checkbox").each(function() {
if ($(this).is(":checked")) {
arr.push($(this).val());
}
});
$(":radio").each(function() {
if ($(this).is(":checked")) {
arr.push($(this).val());
}
});
console.log(arr);
// Join array using unique string
var vals = arr.join("--");
// Set URL to pin query to and begin pushing values to string:
var urlBegin = "https://thisisatest/?results=";
var str = vals;
$("#val").text(urlBegin + vals);
$("#query").text(vals);
$("#copyTarget").val(urlBegin + vals);
userSelection = arr;
resRec();
});
}
buildResults();
function resRec() {
// Show div based on user checkbox values:
var user = userSelection;
var dataRec = [];
var recordResultCount = 0;
console.log(user);
var first = user.includes("123");
if (first == true) {
dataRec.push(123456);
}
var recordResults = [...new Set(dataRec)];
recordResultCount = recordResults.length;
console.log(recordResultCount);
// Show only the records needed:
$(".card").each(function() {
var recordFound = $.inArray($(this).data("recordid"), dataRec);
if (recordFound === -1) {
$(this).parent().addClass("destroy");
} else {
$(this).removeClass("destroy");
}
});
}
function resQuery() {
var urlQuery = window.location.href.match(/results=(.+)/)[1];
console.log(urlQuery);
user = urlQuery;
}
// If user enters page via unique query only, and not from page start:
$(function() {
if (window.location.pathname == "https://thisisatest/?results=") {
// reuse resRec() here, but using urlQuery and not userSelection;
var user = resQuery();
resRec();
// and show only the cards which match the results built from query
}
});
resQuery();
Function reuse is still new to me, and while I think my logic is on the correct path, I am still getting resRec() not defined.
Thank you.
I have this String:
['TEST1-560', '{"data":[{"price":0.0815,"volume":0.2,"car":"BLUE"}],"isMasterFrame":false}']
I want to get the keys 'TEST1-560' which is always fist and "car" value.
Do you know how I can implement this?
This is a very, very scuffed code, but it should work for your purpose if you have a string and you want to go through it. This can definitely be shortened and optimized, but assuming you have the same structure it will be fine.:
// Your data
var z = `['TEST1-560', '{"data":[{"price":0.0815,"volume":0.2,"car":"BLUE"}],"isMasterFrame":false}']`;
var testName = z.substring(2).split("'")[0];
var dividedVar = z.split(",");
for (var ind in dividedVar) {
if (dividedVar[ind].split(":")[0] === '"car"') {
var car = dividedVar[ind].split(":")[1].split("}")[0].substring(1,dividedVar[ind].split(":")[1].split("}")[0].length-1);
console.log(car)
}
}
console.log(testName);
output:
BLUE
TEST1-560
In a real application, you don't need to log the results, you can simply use the variables testName,car. You can also put this in a function if you want to handle many data, e.g.:
function parseData(z) {
var testName = z.substring(2).split("'")[0];
var dividedVar = z.split(",");
for (var ind in dividedVar) {
if (dividedVar[ind].split(":")[0] === '"car"') {
var car = dividedVar[ind].split(":")[1].split("}")[0].substring(1, dividedVar[ind].split(":")[1].split("}")[0].length - 1);
}
}
return [testName, car]
}
This will return the variables values in an array you can use
const arr = ['TEST1-560', '{"data":[{"price":0.0815,"volume":0.2,"car":"BLUE"}],"isMasterFrame":false}']
const testValue = arr[0];
const carValue = JSON.parse(arr[1]).data[0].car;
console.log(testValue);
console.log('-----------');
console.log(carValue);
If your structure is always the same, your data can be extracted like above.
so basically i want to make a phone contacts app, and i try to save the saved contact to local storage
so this is the function when the save button clicked
saveContact(name, number){
//To check if the name input or phone input is not blank
if(nameInput.value == '' || phoneInput.value == ''){
info.style.display = 'block'
}
const firstLetter = name[0].toUpperCase()
const getContact = localStorage.getItem(firstLetter)
const storedObject = {
[name]:number
}
//If contact's first letter exists in localstorage
if (getContact){
const oldData = [JSON.parse(localStorage.getItem(firstLetter))]
oldData.push([storedObject])
const oldDataString = JSON.stringify(oldData)
localStorage.setItem(firstLetter, oldDataString)
const finalOldData = []
//i do a looping here to push each contact's object to a new array which is finalOldData
//but it doesn't work well. it doesn't actually add a new object to the array instead of replacing the old object with a new one
oldData.forEach(e => {
finalOldData.push(e[0])
})
const finalOldDataString = JSON.stringify(finalOldData)
localStorage.setItem(firstLetter, finalOldDataString)
}
//If contact's first letter doesn't exist in localstorage
else{
const storedObjectString = JSON.stringify([storedObject])
localStorage.setItem(firstLetter, storedObjectString)
this.clearSave()
}
}
so the issue is when i try to add a contact which its first letter exist in local storage and make it as a list
//and this is the result i want
Storage
A: "[{\"amber\":\"1242134\"},{\"annie\":\"123421\"}]"
length: 1
You can consider the code below, it is working as expected.
Changes
const oldData = [JSON.parse(localStorage.getItem(firstLetter))]
No need to put the result from JSON.parse into an array, it already is an array and also you can use the variable getContact instead of calling getItem again on localStorage.
oldData.push([storedObject])
No need to push an array into oldData, simply push storedObject.
I've removed the initial check for making testing easy, you can add it back.
function saveContact(name, number) {
if (!name || !number) {
return;
}
const firstLetter = name[0].toUpperCase();
const getContact = localStorage.getItem(firstLetter);
const storedObject = { [name]: number };
if (getContact) {
const oldData = JSON.parse(getContact);
oldData.push(storedObject);
const oldDataString = JSON.stringify(oldData);
localStorage.setItem(firstLetter, oldDataString);
} else {
const storedObjectString = JSON.stringify([storedObject]);
localStorage.setItem(firstLetter, storedObjectString);
}
}
Is there a way to programmatically check whether a filter with a given name exists?
I developed a directive to process page content based on a string input, I want it to react differently in case a certain part of the string corresponds to a filter that exists in my system. For example I have a localize filter:
// Somewhere in the code
var myInput = 'localize';
// Somewhere else
var contentToProcess = 'my content';
var result = '';
if ($filter.hasOwnProperty(myInput)) // TODO: this is the part I'm trying to figure out
result = $filter(myInput)(contentToProcess);
else
result = 'something else';
Jonathan's answers is also acceptable, but I wanted to find a way to check if a filter exists without using a try catch.
You can see if a filter exists like this:
return $injector.has(filterName + 'Filter');
The 'Filter' suffix is added by angular internally, so you must remember to add it or you will always return false
Solution
This seems to work for me.
var getFilterIfExists = function(filterName){
try {
return $filter(filterName);
} catch (e){
return null;
}
};
Then you can do a simple if check on the return value.
// Somewhere in the code
var myInput = 'localize';
var filter = getFilterIfExists(myInput);
if (filter) { // Check if this is filter name or a filter string
value = filter(value);
}
Bonus
If you are looking to parse apart a filter string for example 'currency:"USD$":0' you can use the following
var value; // the value to run the filter on
// Get the filter params out using a regex
var re = /([^:]*):([^:]*):?([\s\S]+)?/;
var matches;
if ((matches = re.exec(myInput)) !== null) {
// View your result using the matches-variable.
// eg matches[0] etc.
value = $filter(matches[1])(value, matches[2], matches[3]);
}
Pull it all together
Wish there was a more elegant way of doing this with angular however there doesn't seem to be.
// Somewhere in the code
var myInput = 'localize';
var value; // the value to run the filter on
var getFilterIfExists = function(filterName){
try {
return $filter(filterName);
} catch (e){
return null;
}
};
var filter = getFilterIfExists(this.col.cellFilter);
if (filter) { // Check if this is filter name or a filter string
value = filter(value);
} else {
// Get the filter params out using a regex
// Test out this regex here https://regex101.com/r/rC5eR5/2
var re = /([^:]*):([^:]*):?([\s\S]+)?/;
var matches;
if ((matches = re.exec(myInput)) !== null) {
// View your result using the matches-variable.
// eg matches[0] etc.
value = $filter(matches[1])(value, matches[2], matches[3]);
}
}
You can just do this:
var filter = $filter(myInput);
if (filter)
result = filter(contentToProcess);
else
result = 'something else';
Undefined and null values are treated as false in JS, so this should work in your case.
I'm trying to extract a URL from an array using JS but my code doesn't seem to be returning anything.
Would appreciate any help!
var pages = [
"www.facebook.com|Facebook",
"www.twitter.com|Twitter",
"www.google.co.uk|Google"
];
function url1_m1(pages, pattern) {
var URL = '' // variable ready to accept URL
for (var i = 0; i < pages[i].length; i++) {
// for each character in the chosen page
if (pages[i].substr(i, 4) == "www.") {
// check to see if a URL is there
while (pages[i].substr(i, 1) != "|") {
// if so then lets assemble the URL up to the colon
URL = URL + pages[i].substr(i, 1);
i++;
}
}
}
return (URL);
// let the user know the result
}
alert(url1_m1(pages, "twitter")); // should return www.twitter.com
In your case you can use this:
var page = "www.facebook.com|Facebook";
alert(page.match(/^[^|]+/)[0]);
You can see this here
It's just example of usage RegExp above. Full your code is:
var pages = [
"www.facebook.com|Facebook",
"www.twitter.com|Twitter",
"www.google.co.uk|Google"
];
var parseUrl = function(url){
return url.match(/^(www\.[^|]+)+/)[0];
};
var getUrl = function(param){
param = param.toLowerCase();
var page = _(pages).detect(function(page){
return page.toLowerCase().search(param)+1 !== 0;
});
return parseUrl(page);
};
alert(getUrl('twitter'));
You can test it here
In my code I have used Underscore library. You can replace it by standard for or while loops for find some array item.
And of course improve my code by some validations - for example, for undefined value, or if values in array are incorrect or something else.
Good luck!
Im not sure exactly what you are trying to do, but you could use split() function
var pair = pages[i].split("|");
var url = pair[0], title=pair[1];