I am having some issues getting my JS to work right. I am trying to select an option from a dropdown which then calls this function. The function is being called properly (type is set to 'truck' and id is set to 5). I want to then use the data returned to populate several fields. The alert() I added to test gives me "undefined".
Here is my JS:
function getDueDates(type, id) {
$.getJSON("loadVehicle.php",
{
id: id,
type: type
},
function(data) {
alert( "TEST: " + data.year);
$("#inspection_due").val(data.inspection_due);
$("#short_due").val(data.short_due);
$("#full_due").val(data.full_due);
}
)};
When I check the loadVehicle page manually (with id=5, type=truck) I get:
[{"truck_id":"5","status":"A","truck_number":"21","year":"1999","make":"Freightliner","model":"Classic","engine":"Detroit","vin_number":"1FUPCSZB2XPA16977","transmission_number":"","tire_size":"","inspection_due":"2009-04-30","short_due":"0000-00-00","full_due":"0000-00-00","comments":"Caf Inc Truck","web_id":"b963940bfd96528f7fd57c08628221f0","last_update":"2009-03-09 16:26:28"}]
But in the page the alert comes up with "TEST: undefined"
You need data[0].year since you are getting an array containing a single object.
Try data[0].year.
It looks like your loadVehicle.php is returning an array of objects not just one object.
Related
I am a beginner and using $.get to retrieve data from a rest API such as:
[{"id":"1","url":"http:\/\/123.456.78.910\/workforce\/images\/item1.jpg","price":"99","description":"Mobile Phone"},
{"id":"2","url":"http:\/\/123.456.78.910\/workforce\/images\/item2.jpg","price":"98","description":"Laptop"}
{"id":"3","url":"http:\/\/123.456.78.910\/workforce\/images\/item3.jpg","price":"92","description":"Console"}] }
$.get('http://xxxxxxxxxxx,
function (data) {
var obj = $.parseJSON(data);
So from what I understand I have retrieved the data from the REST API and parsed it so it is stored in a variable called obj.
My question is, how do I access and use each unique record in the obj variable?
Each record has it's own picture (item1.jpg, item2.jpg etc).
Whem my app loads I want it to show the item1.jpg image, and I want to be able to navigate to the other item pictures using buttons (previous / next).
I also want the description and price to be displayed underneath in some text input fields.
What I have figured so far is that I should:
Iterate through the obj variable, and store each record into an array.
Upon app initialisation I can set the default value for the image placeholder to array[index0].url, and set the description and price fields.
I can then set the previous and next buttons to array[currentIndex-1] or array[currentIndex+1].
Would this be the best way to do it?
Or can I just do this without using an array and manipulate the obj.data directly?
Thanks!!!
I may not be understanding what exactly what you want to do but I think I have the gist. If you just want to show the picture then the array of just images probably wouldn't be a bad idea. However, it looks like the Jason you're getting is already in an array. You can just use array index notation to get to what you want.
ie)
var arr = //your json response ;
var current = 0; //sets currently displayed object to the first in the array
var setCurrent = function () {
var image = arr[current]["url"];
}
You can then modify current however you want (on click on arrow iterate up/down, etc) then call the setCurrent function to set your image the the one you want. Hope that helps!
You can use the response you have from $.get() directly.
It is an array of objects.
You can use it like this:
console.log(data[2].description);
// outputs: "Console"
I've made a CodePen demo where it has a 4th object with a real image url to show you how to use the url info...
EDIT
Just in case you wouldn't know this:
You can use the response inside the scope of the $.get() callback...
You can not use it straith after the $.get() outside the callback since $.get() is asynchronous.
You can use it in some other handler wich will happen after the response is received.
var getResponse;
$.get('http://xxxxxxxxxxx', function (data) {
getResponse = data;
console.log(data[2].description);
// outputs: "Console"
console.log(getResponse[2].description);
// outputs: "Console"
});
console.log(getResponse[2].description);
// outputs: "Undefined"
// But since this handler will be triggered long after the response is obtained:
$("#somebutton").click(function(){
console.log(getResponse[2].description);
// outputs: "console"
});
In order for your page javascript to be able to access the data retrieved from your ajax request, you'll need to assign it to some variable which exists outside the callback function.
You will need to wait until the ajax request has been processed before you can read the array. So you might want to set the actual default image to be something that doesn't rely on the ajax request (a local image).
Here's a simple approach
// fake testing ajax func
function fakeget (url, callback) {
setTimeout(callback(JSON.stringify([
{"id":"1","url":"http:\/\/123.456.78.910\/workforce\/images\/item1.jpg","price":"99","description":"Mobile Phone"}, {"id":"2","url":"http:\/\/123.456.78.910\/workforce\/images\/item2.jpg","price":"98","description":"Laptop"},
{"id":"3","url":"http:\/\/123.456.78.910\/workforce\/images\/item3.jpg","price":"92","description":"Console"}
])), 1000);
}
// real code starts here
// global variables for ajax callback and setImg func to update
var imageData, currentImg;
// change this back to $.get for real
fakeget('http://xxxxxxxxxxx',
function (data) {
imageData = $.parseJSON(data);
setImg(0);
}
);
function setImg(index) {
// turns negative indices into expected "wraparound" index
currentImg = (index % imageData.length + imageData.length) % imageData.length;
var r = imageData[currentImg];
$("#theImg").attr('src', r.url);
$('#theDescription').text(r.price + " " + r.description);
}
$("#prev").click(function () {
setImg(currentImg - 1);
});
$("#next").click(function () {
setImg(currentImg + 1);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img id='theImg' src='somedefault.jpg'>
<div id='theDescription'></div>
</div>
<button id='prev'>Prev</button>
<button id='next'>Next</button>
Few observations :
Your JSON Object is not a valid JSON.
No need to parse it again your data is already a JSON Object.
Working fiddle
var data = [{"id":"1","url":"http:\/\/123.456.78.910\/workforce\/images\/item1.jpg","price":"99","description":"Mobile Phone"},{"id":"2","url":"http:\/\/123.456.78.910\/workforce\/images\/item2.jpg","price":"98","description":"Laptop"}, {"id":"3","url":"http:\/\/123.456.78.910\/workforce\/images\/item3.jpg","price":"92","description":"Console"}];
for (var i in data) {
var imgUrl = data[i].url;
console.log(imgUrl);
}
Practicing some JS by creating a basic app integrated with TaffyDB. It stores medical codes. I've tried searching for a solution to this but can't seem to get it working.
Goal: On click of button, JS function is called passing the innerHTML value into the TaffyDB query which searches by "code". It then alerts() the user with the description of that code.
Problem: I keep getting "undefined" when calling the function.
TaffyDB snippet:
diagnosisCodes = TAFFY([
{code_id:'C001', code:'460', description:'Acute Nasopharyngitis(Common Cold)'},
{code_id:'C002', code:'708.2', description:'Urticaria Due to Cold and Heat'},
{code_id:'C003', code:'778.2', description:'Cold Injury Syndrome of Newborn'},
{code_id:'C004', code:'975.6', description:'Poisoning by Anti-Common Cold Drugs'},
]);
HTML snippet:
<h2 class='code_categories' id='diagnosis_title'>Diagnosis Codes</h2>
<div id='diagnoses_COLD'>
<h4 id='column_titles'>Cold-Related</h4>
<button id='button' onclick="testing()">460</button>
JS Function:
function testing() {
//grab element value:
var obj = document.getElementById('button').innerHTML.value;
//pass element value into TaffyDB query:
var dxDesc = diagnosisCodes({code:obj}).first().description;
//'alert' description of the code
alert(dxDesc);
}
This function returns 'undefined'. However, var obj is correctly assigned a string value. Also, the query works fine when passing a function parameter. For example, this alerts with the correct description:
function getDxDesc(name) {
var obj2 = diagnosisCodes({code:name}).first().description;
alert(obj2);
}
My problem is getting the entire thing to work in unison.
.value is used to get the value of a user input. Just use .innerHTML by itself:
var obj = document.getElementById('button').innerHTML;
DEMO
I have a Select2 auto-complete input (built via SonataAdmin), but cannot for the life of me figure out how to programmatically set it to a known key/value pair.
There's a JS Fiddle here that shows roughly what I have. What I want to know is what function I can attach to the button so that
the Select2 field shows the text "NEW VALUE" to the user, and
the Select2 field will submit a value of "1" when the form is sent to the server
I have tried all sorts of combinations of jQuery and Select2 data and val methods, called against various inputs on the page, but nothing seems to work... surely there's some way to do this?
-- Edit --
The accepted answer below is very useful, helps shed some light on the right way to initialise the selection and explains what initSelection is for.
Having said that, it seems that my biggest mistake here was the way I was trying to trigger the change.
I was using:
$(element).select2('data', newObject).trigger('change');
But this results in an empty add object inside select2's change event.
If, instead, you use:
$(element).select2('data', newObject, true);
then the code works as it should, with the newObject available in select2's change event and the values being set correctly.
I hope this extra information helps somebody else!
Note this was tested with version 4+
I was finally able to make progress after finding this discussion: https://groups.google.com/forum/#!topic/select2/TOh3T0yqYr4
The last comment notes a method that I was able to use successfully.
Example:
$("#selectelement").select2("trigger", "select", {
data: { id: "5" }
});
This seems to be enough information for it to match the ajax data, and set the value correctly. This helped immensely with Custom Data Adapters.
Note: For multi select, execute the above code for each item, like this :
// for each initially selected ids, execute the above code to add the id to the selection.
[{id: 5, text: 'op5'}, {id: 10, text: 'op10'}].forEach(option => {
$("#selectelement").select2("trigger", "select", {data: { id: option.id, text: option.text }});
})
Note: The Question and this Answer are for Select2 v3. Select2 v4 has a very different API than v3.
I think the problem is the initSelection function. Are you using that function to set the initial value? I know the Select2 documentation makes it sound like that is it's purpose, but it also says "Essentially this is an id->object mapping function," and that is not how you have implemented it.
For some reason the call to .trigger('change') causes the initSelection function to get called, which changes the selected value back to "ENABLED_FROM_JS".
Try getting rid of the initSelection function and instead set the initial value using:
autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});
jsfiddle
Note: The OP has supplied the formatResult and formatSelection options. As supplied, those callback functions expect the items to have a "label" property, rather than a "text" property. For most users, it should be:
autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});
More info on the initSelection function:
If you search through the Select2 documentation for "initSelection", you will see that it is used when the element has an initial value and when the element's .val() function is called. That is because those values consist of only an id and Select2 needs the entire data object (partly so it can display the correct label).
If the Select2 control was displaying a static list, the initSelection function would be easy to write (and it seems like Select2 could supply it for you). In that case, the initSelection function would just have to look up the id in the data list and return the corresponding data object. (I say "return" here, but it doesn't really return the data object; it passes it to a callback function.)
In your case, you probably don't need to supply the initSelection function since your element does not have an initial value (in the html) and you are not going to call its .val() method. Just keep using the .select2('data', ...) method to set values programmatically.
If you were to supply an initSelection function for an autocomplete (that uses ajax), it would probably need to make an ajax call to build the data object.
To set initial values you need to add the necessary options tag to the select element with jQuery, then define these options as selected with select2's val method and finally trigger select2's 'change' event.
1.-$('#selectElement').append('<option value=someID>optionText</option>');
2.-$('#selectElement').select2('val', someID, true);
The third boolean argument tells select2 to trigger the change event.
For more info, see https://github.com/select2/select2/issues/3057
Be carreful, there is a mistake in "validated" comment.
autocompleteInput.select2('data', {id:103, label:'ENABLED_FROM_JS'});
The correct way is
autocompleteInput.select2('data', {id:103, text:'ENABLED_FROM_JS'});
Use text instead of label
With Select2 version 4+, there is actually nothing special you need to do. Standard jQuery with a 'change' event trigger at the end will work.
var $select = $("#field");
var items = {id: 1, text: "Name"}; // From AJAX etc
var data = $select.val() || []; // If you want to merge with existing
$(items).each(function () {
if(!$select.find("option[value='" + this.id + "']").length) {
$select.append(new Option(this.text, this.id, true, true));
}
data.push(this.id);
});
$select.val(data).trigger('change'); // Standard event notifies select2
There is a basic example in the Select2 documentation:
https://select2.org/programmatic-control/add-select-clear-items
from their examples
https://select2.github.io/examples.html
Programmatic access:
var $example = $(".js-example-programmatic").select2();
var $exampleMulti = $(".js-example-programmatic-multi").select2();
$(".js-programmatic-set-val").on("click", function () { $example.val("CA").trigger("change"); });
$(".js-programmatic-open").on("click", function () { $example.select2("open"); });
$(".js-programmatic-close").on("click", function () { $example.select2("close"); });
$(".js-programmatic-init").on("click", function () { $example.select2(); });
$(".js-programmatic-destroy").on("click", function () { $example.select2("destroy"); });
$(".js-programmatic-multi-set-val").on("click", function () { $exampleMulti.val(["CA", "AL"]).trigger("change"); });
$(".js-programmatic-multi-clear").on("click", function () { $exampleMulti.val(null).trigger("change"); });
All you have to do is set the value and then execute: $ ('#myselect').select2 (); or $ ('select').select2 ();.
And everything is updated very well.
If you remove the .trigger('change') from your fiddle it logs Object {id: 1, label: "NEW VALUE"} (need to click twice since the logging is before the value change). Is that what you're looking for?
When using select2 with multiple option, use this construction:
$(element).select2("data", $(element).select2("data").concat(newObject), true);
jqueryselect2multiplesetconcatenation
this is it:
$("#tag").select2('data', { id:8, title: "Hello!"});
FOR VERSION 3.5.3
$(".select2").select2('data',{id:taskid,text:taskname}).trigger('change');
Based on John S' answer . Just the the above will work however only if while initializing the select2 the initSelection option is not initialized.
$(".select2").select2({
//some setup
})
For those still using version 3.5 or even higher ones. Please be sure how you reference select2.js to your page. If you are using async or defer load. This plug-in might behave differently.
Thought to mention.
In my situation I was able to render the preselected option into the HTML server side with PHP.
During my page load, I already knew the option value, so my <select name="team_search"></select> became the following;
<select name="team_search">
<?php echo !empty($preselected_team)
? '<option selected="selected" value="'. $preselected_team->ID .'">' . $preselected_team->team_name . '</option>'
: null ?>
</select>';
As you can see, when I have a $preselected_team available I render in an option with the selected attribute, value and label set. And, if I don't have a value then not option is rendered.
This approach may not always be possible (and in the case of the OP is not mentioned), but it does come with the added benefit of being ready on page load ahead of JavaScript execution.
Append a new option with id and text
let $newOption = $("<option selected='selected'></option>").val(1).text('New Text goes here');
$("#selector").append($newOption).trigger('change');
I have an object containing share counts for various social metrics. The object looks like this:
Object{
delicious: 0,
facebook: {
comments: 0,
likes: 0,
shares: 0,
total: 0,
},
linkedIn: 1,
pinterest: 0,
twitter: 9
}
Here is some testing code I am using to try to access my object:
console.log(bg.results);
console.log(bg.results["facebook"]);
console.log(bg.results.facebook);
Object.keys(bg.results).forEach(function(key){
console.log(bg.results);
console.log(key + "->" + bg.results[key]);
});
The object above is what I am seeing in the console, so I know that the fields in bg.results contain data. The problem is, when I try to access any of these fields using either dot syntax or by using object["key"] I get an empty string as the result. I searched and could not find anyone else experiencing the same problem. Does anyone have any ideas why this may be happening?
Some additional info:
My code is being run within the context of a chrome extension. I'm accessing this object from a popup page, and the object's data is being supplied from my background page.
Thank you for your assistance.
UPDATE
Something funny is going on with how Chrome is handling my code. The data in bg.results is supplied by a function on my background page called update. In my program there are two ways that update is called depending on the user's settings. When update() is called from within the context of my background page, everything works fine and behaves as expected. When update() is called from my popup page, I get empty strings when I try to access any fields.
This seems like a bug very particular to how chrome extensions are handled, so any input from experts in this sort of thing would be awesome. Thanks for the help everyone!
1.) your code should work. facebook is an object itself so you need to think about that, and maybe use a recursive function!
2.) why dont you just loop over your objects properties with the for-in-loop?
for(key in bg.results) {
console.log(key);
}
3.) example recursive function
function recursiveExample(obj) {
var current;
for(key in obj) {
current = obj[key];
if(typeof current === 'object' && !Array.isArray(current)) {
recursiveExample(current);
}
console.log("key: " + key + " - value" + current);
}
}
I've concluded that my values were not completely loaded into the results object when I was trying to access them. I can only speculate as to why I could see the values when I printed the results object to the console (and could not access them at that point) but was not able to access them until later. Below is the solution I used for this problem.
function checkLoaded(results){
var isLoaded = true;
$.each(results, function(key, value){
if(value === "" || value === undefined){
isLoaded = false;
}
});
setTimeout(function(){
if(!isLoaded){
checkLoaded(results);
}
else{
displayHandler(results);
}
}, 500);
}
If anyone knows why I could see the values in the console but could not access them, I'd appreciate an explanation. But otherwise, if anyone else encounters a problem like this, try setting up a delay to make sure that your values are completely loaded into your collection.
This is just a guess (since you haven't posted any of the relevant data-loading code), but I suspect you may be doing something like this:
chrome.extension.sendMessage({myAction: "update"}, function(response) {
bg.results = response;
});
// we try to use bg.results, but the sendMessage callback won't be run until later on
Object.keys(bg.results).forEach(function(key){
console.log(bg.results);
console.log(key + "->" + bg.results[key]);
});
The ansychronous callback passed to sendMessage runs after the current function stack has cleared (i.e., once the JavaScript thread has run out of other things to do), so bg.results = response won't happen until after you try to use it. Instead, use the results inside the callback:
chrome.extension.sendMessage({myAction: "update"}, function(response) {
bg.results = response;
// now it works, because this code is inside the callback
Object.keys(bg.results).forEach(function(key){
console.log(bg.results);
console.log(key + "->" + bg.results[key]);
});
});
Maybe you don't actually use chrome.extension.sendMessage, but you must be using some asynchronous operation (maybe Ajax, maybe another Chrome API call). I don't know what that method is for certain, since you didn't post any of your data-loading code.
I've got a "LocalStore" object for storing data locally. It's based around a Lawnchair object.
var LocalStore = function(name) {
var that = this;
that.name = name;
that.lawnchair = Lawnchair({ name: that.name }, function(store) {
this.before('save', function(record){
console.log("saving " + that.name);
console.log(record);
});
this.after('save', function(record){
console.log("saved " + that.name);
console.log(record);
that.getData(function(records){
console.log("now it's this");
console.log(records);
});
});
});
that.getData = function(callback) {
that.lawnchair.get(that.name, callback);
};
};
LocalStore is then extended with _.extend(from the Underscore.js library) with this method:
save: function(collection, callback) {
this.lawnchair.save({ key:this.name, value: collection }, function(record) {
callback(record);
});
}
This code is used to update a Backbone.js Collection object to Lawnchair. The first time "save" runs for my Users Collection it saves correctly and shows that the object is a simple key/value pair where value is an Array.
Later in my code when a User selects a Default Project, I modify the Users Collection and call "save" again with an updated "defaultProjectId" on the User. The code runs error free, but the after('save') code for Lawnchair runs and shows me that:
- The record object returned is a key/value pair where value is a full Backbone.js Collection with the defaultProjectId property set correctly.
- The getData method that grabs the latest from the Database still shows as a key/value pair with value a simple Array and defaultProjectId is set incorrectly.
I'm at a loss as what to do. It should just be simply calling "lawnchair.save" updates the record, but it just doesn't do it.
Could you try this jsfiddle?
http://jsfiddle.net/QUgtg/1/
I have recreated your code. Instead of a backbone collection, I am passing in an array of objects. This seems to work. You can see the logging output in Firebug.
I have used my own extend code to add the save(). Though honestly, I don't see why you would want to do it that way, instead of just adding a property to the prototype. Your code may differ in that aspect.
If what I have posted works on your end, could you modify that code to show what are you doing differently? If possible, recreate the issue on jsfiddle...