While building a carousel module for Joomla I am having 2 JavaScript issues I can't get fixed. I've been trying for 2 days. Hopefully someone here can point out what I am doing wrong.
I can't get a boolean from a string "0" or string "1"
And I can't JSON.parse() to convert an object string to a JavaScript object
The situation:
To be able to have multiple instances on 1 page I am passing each modules individual settings (via php) to 1 object in my javascript file. Each module is 1 key value pair inside the object, the value being its own settings object. Basicly, this is how the JS recieves it:
const moduleSettings = {
"103":{"items":3,"margin":5,"loop":"1","center":"0","responsive":"{0:{items:1}}"},
"105":{"items":3,"margin":5,"loop":"0","center":"1","responsive":"{0:{items:2}}"}
};
Next I need to loop over each module to initialize the settings. This is done on ready using jQuery.
jQuery(document).ready(function() {
// Loop over each module
const modules = Object.keys(moduleSettings);
for (const id of modules) {
const target = "carousel-" + id;
const params = moduleSettings[id];
// Callback to evaluate true/false params
function eval(singleParam) {
return params[singleParam] === "1";
};
// Initialize carousel
jQuery(target).owlCarousel({
items: params.items,
margin: params.margin,
loop: eval("loop"),
center: eval("center"),
responsive: JSON.parse(params.responsive)
});
};
});
The carousel properties items & margin are numbers. No problem there, but these are recieved as numbers from the start.
The problem:
The properties loop & center should return a boolean, based on the callback function eval(). But they just return the string "0" or "1".
The property responsive should return an object. But this still remains a string object "{...}".
The console error:
The first problem above does not block functionallity. It works, but I want to understand why my values are not booleans.
The second problem however causes console error and make the carousel not work. This is only IF responsive is not an empty string. When responsive is an empty string, it works. But I need the responsive setting.
I've been looking for the cause of this issue for 2 days now. It's getting frustrating. Any pointers would be most helpfull. Thanks!
instead of using eval function use can you below
jQuery(target).owlCarousel({
items: params.items,
margin: params.margin,
loop: !!params.loop,
center: !!params.center,
responsive: JSON.parse(params.responsive)
});
For the second issue, you need to change the structure from your server side code to generate this module settings JSON. The responsive object is not a proper JSON. its should be like
responsive: {items:1} or responsive: [{items:1}]
If you can post that code then I can tell you the change need to made there.
In the example you've provided, you're not evaluating the params field by name provided as a singleParam argument, but the actual params.singleParam field, which is undefined. To fetch field by it's name use brackets syntax: params[singleParam].
Related
How to write localStorage script which will remember the value of turning odometer...so that each time the user visits the site again , the odometer will resume on the value on which odometer was at when the user left the site? I'm beginner in javascript so please understand...
This is my code: https://jsfiddle.net/aht87opr/17/
I've found the following code which might help with my case: http://jsfiddle.net/Jonathan_Ironman/Hn7jc/
$('button').click(function() {
var mefedron = myOdometer.get();
$('#value').text(mefedron);
});
Nicely done on the odometer, looks good. Local storage is simple.
To set local storage:
localStorage.setItem("key", "value");
To get local storage:
var number = localStorage.getItem("key");
Be sure to try getting the local storage first so you can handle any null errors.
Get and Set
localStorage has a few ways to get and set values to the browser. The simplest is treating it like a regular object.
localStorage.distance = 55;
you can then retrieve the value by accessing the property name you created earlier.
console.log(localStorage.distance); // "55"
Strings are stored, parse the string
Notice that localStorage.distance was set as a number but when accessed was a string. If you only need to store a number you could pass the string through a function like parseInt().
console.log(parseInt(localStorage.distance)); // 55
Another solution is to use JSON
create an object model of your odometer.
var odometer = { distance: 55, timeForOilChange: false };
Then write to the localStorage passing your model through JSON.stringify
localStorage.odometer = JSON.stringify(odometer);
and read the value back out using JSON.parse
console.log(JSON.parse(localStorage.odometer));
// { distance: 55, timeForOilChange: false }
I am using MeteorJS and trying to get the value of a field from MongoDB and assign to a variable. But when want to print to console, it gives all the time 'undefined'. It works fine in HTML template, but i need to store the value in a var in .js file.
var num = ButtonsList.find({_id:'ZcLkjSwNGTpgHkoeq'});
var n = num.button1;
console.log("button number is: "+n);
The code below works fine by the way, if i want them to output in the browser. It outputs the buttons numbers in html using {{}} namespace. But as I said, i need to store the values in variables.
ButtonsList = new Meteor.Collection('list');
Template.theList.helpers({
'buttons': function(){
//return ButtonsList.find().fetch();
return ButtonsList.find('ZcLkjSwNGTpgHkoeq');
}
});
ButtonsList.find() returns a cursor.
ButtonsList.find().fetch() returns an array of buttons.
ButtonsList.findOne() returns will return a single button.
ButtonsList.findOne().fieldName will return the field fieldName of the button that was found.
The reason it works with the {{#each}} template block helper is that each blocks know how to iterate over cursors.
Your using Find , doesnt that mean your getting multiple reccords back? Shouldnt you be using FindOne instead? otherwise youll get an array of objects which means youd have to use num[i].button1 to get to the value.
I'm using the Chap Links Timeline Library http://almende.github.io/chap-links-library/js/timeline/doc/ and find it very useful. However I need to stack the events in a special order.
I tried to use the customStackOrder() function without any success so far.
How can I access custom data fields in this function?
My data elements look like:
data.push({
start: new Date( msg.timestamp ),
content: msg.text,
stackOrder: msg.level
});
and
function customStackOrder(A,B) {
return A.stackOrder - B.stackOrder
}
But A.stackOrder and B.stackOrder is undefined.
How can I access custom data fields in this function?
The Timeline does just ignores custom fields, and there is no easy way to access them. Usable item properties in the function customStackOrder are the actual position and size (left, right, width, height) and timestamps (start and optionally end).
If you really want to do this, you will have to apply an inefficient hack. This is not officially supported and I don't recommend it:
From the items passed to the sorting function you will have to determine their table index: var indexA = mytimeline.items.indexOf(itemA)
Read the data of this item from your original data table: var dataA = data[indexA].
Read your custom field from this: var stackOrderA = dataA.stackOrder
Edit:
Another trick could be: if you don't use the field className, you could misuse this to hold the value of your stackOrder field. Just ensure the values cannot collide with some actual css.
I am teaching myself jquery and json for work. I have been making great progress, but now got myself very confused. My ultimate goal is to be able to parse json from a text file I have and then store them as javascript objects so I can do more stuff with it.
This is what I have done. I have the following data in json format (created from a java class I wrote). Please note that data.json looks like this:
{"Time": 15,
"Distance": 20,
"Position":[{"x":5,"y":10},
{"x":15,"y":20}]}
I formatted the above in this question to be easier to read by being on separate lines, but the raw file contains it all on one line.
I used the following code in a script:
$(document).ready(function(){
console.log("ready!");
$.getJSON('data.json', function(key,val)
{
alert(val.Time);
alert(val.Distance);
alert(val.Position);
});
});
But what it outputs is three "undefined" alerts. Why? My ultimate goal is to store Time, Distance, and the Position as javascript objects so I can draw them on a graph I made in html. However, I am obviously no way close to that because my alerts are not reading/parsing json objects right.
So I changed it to as follows, on a hunch:
$(document).ready(function(){
console.log("ready!");
$.getJSON('data.json', function(key,val)
{
alert(key.Time);
alert(key.Distance);
alert(key.Position);
});
});
Well, these is mostly promising in that I get the following alerts:
Alert 1 Output: 15,
Alert 2 Output: 20,
Alert 3 Output: [Object Object], [Object Object]
Okay, I am closer, but now very confused. Shouldn't the key be giving me alert output "Time", "Distance", and "Position" and val be "15", "20", and "[Object Object], [Object Object]". I thought json kind of works like a hashtable. Hmmmm.
Also, do I need to do a .each(key, val) to parse my list called Position? Because obviously Object Object is not going to help me much. I basically want to save this list Position as a javascript obj like
myList = [[5, 10], [15,20]]
Anyway, that is my thinking. I thank you for your time. I will upvote anyone who replies and helps me out. This is important to me.
Regards,
GeekyOmega
I'm not sure what you're trying to do with your function(key,val) { ... }, but this isn't how jQuery's getJSON works at all. The callback function for getJSON takes three parameters, data, textStatus and jqXHR. I suspect you will find that the data parameter is essentially the javascript object you wanted to build, except with fields 'x' and 'y' rather than each nested array. To get the data out, I'd do something like:
for (var i = 0; i < data.Position.length; i ++)
do_something_with (data.Position[i].x, data.Position[i].y);
key and val as you have them are misnamed. The first parameter to the $.getJSON() callback is the JSON object. See the API Doc example where the callback function is just passed a parameter called data.
[Object Object] is the default toString() for objects in javascript. To get the values of your object array, you can iterate data.Position and access the x and y properties of each object in the array.
Edit to respond to your comment:
You could always change the Position property in your JSON to be generated as an array of arrays instead of an array of objects.
Or, on the client side, you could do something like this:
var points = [];
$.each(data.Position, function(item) {
points.push([item.x, item.y]);
});
Re-read your key names. Words like route and travelTime appear in your code but not in your JSON.
Try this:
$(document).ready(function(){
console.log("ready!");
$.getJSON('data.json', function(key)
{
console.log(key.Time);
console.log(key.Distance);
console.log(key.Position[0]);
});
});
when you create a class user javascript,you can write var pepole={name:"smith",code:"YQ001",println:function(code,name){document.write(this.name+":"+this.code+"<br/>")}};,json is a class for javascript,but there is no method it's only attribute
Not very familiar with JSON data and how to create it using JavaScript.this is what i am trying
i have created two JS variables
var json={};
var json1={};
i have some certain loops to iterate data and loops like
for(firstLoop){
key=outerKey;
for(innerLook){
innerKey=innerkey;
for(lastloop){
jsonValues= create values in a java variable
}
json[innerKey]=jsonValues;
}
json1[outerKey]=JSON.stringify(json);
}
Doing this i am getting following output
Required: "{"Center":"radio_Required_Center_0,radio_Required_Center_1,","Left":"radio_Required_Left_0,"}"
which is not a valid JSON format.My idea id to create a outer-key say Required and than an inner one's in my case Center and Left
so that i can iterate each value with respect to key Center (i can break the string based on ')
i am not sure how to create correct structure and i don't want to do it on server side which can be done easily.
any solution or hint will really be helpful.
Edit
var data= JSON.stringify(json1);
giving following output
{"Required":"{\"Center\":\"radio_Required_Center_0,radio_Required_Center_1,\",\"Left\":\"radio_Required_Left_0,\"}"}
which is valid JSON data, now i need to execute some code based on the data in the JSON and here are my requirements
Fetch the outer-key (Required or there can be other also).
Fetch all values under the key Center and Left
Create array from the value retrieved from step 2 (split based on ",").
Loop through the values obtained from step 3 and execute the logic.
My real challenge is at step number 2 and 3 where i need to fetch the keys and its associated values and those key and not predefined so i can not access them based on there name.
I am thinking of a way to get key and its values without hard coding key names and execute my logic.
is it possible in by this approach or not?
If you're using a modern version of Javascript, it comes with JSON functions built-in.
var jsonString = JSON.stringify(jsobject);
...to convert a JS object into a JSON string.
(See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify)
and
var jsOject = JSON.parse(jsomString);
...to convert back in the other direction.
(see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse)
The only time you need to worry about this not being built-in is if you're using an old browser - for example, older versions of IE. However, in this case, there are polyfill libraries like this one that you can load which will implement the above syntax for you.
If you're just trying to compose one big JSON object, you don't need to stringify one JSON object before adding it to another... So instead of doing JSON.stringify(json) you can just do json1[outerKey]=json
for(firstLoop){
key=outerKey;
for(innerLook){
innerKey=innerkey;
for(lastloop){
jsonValues= create values in a java variable
}
json[innerKey]=jsonValues;
}
json1[outerKey]=json;
}
try jsonlint.com to validate your JSON
This is valid:
{
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
This is valid too:
{
"Required": {
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
}
This isn't:
Required: {
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
using JSON.stringify() is the right way of converting javascript objects to JSON string format. However if you want to put it in a variable you should do that first, later in the last step you convert to JSON string.
var output = { "Required": yourpreviousjsonvar },
jsonString = JSON.strinify(output);
EDIT:
You need to process the data first you probably won't even need the JSON string if I understand you right. (=> if however you already got a string you need it parsed first. Do it using JSON.parse(yourjsonstring))
Fetch the outer-key (Required or there can be other also).
Fetch all values under the key Center and Left
Create array from the value retrieved from step 2 (split based on ",").
Loop through the values obtained from step 3 and execute the logic.
having this as variable:
var a = {
"Required": {
"Center": "radio_Required_Center_0,radio_Required_Center_1,",
"Left": "radio_Required_Left_0,"
}
}
// step 1
console.log(a.Required);
// step 2
console.log(a.Required.Center);
console.log(a.Required.Left);
// step 3
var center = a.Required.Center.split(',');
var left = a.Required.Left.split(',');
// step 4
for(var i = 0; i<center.length; i++){
console.log("doing somthing with", center[i]);
}
Here is a fiddle => use Chrome/safari/Opera's developpertools and check the console to check the output. Or use firebug (in firefox) Or IE9 or greater (F12).
Use native Javascript toSource :
var obj= new Object();
var obj1= new Object();
for(firstLoop){
key=outerKey;
for(innerLook){
innerKey=innerkey;
for(lastloop){
jsonValues= create values in a java variable
}
obj.innerKey=jsonValues;
}
obj1.outerKey=obj;
}
json = obj.toSource();
json1 = obj1.toSource();