Why variable is undefined inside foreach function? - javascript

I have this jQuery function were I create a table:
function propertyView(values) {
// build the table
var frame = '<fieldset id = "propertiesValueArea" style="border: solid 1px #6b6b6b;">';
var content = frame + smallHeader + '<table data-role="table" id="propertiesList"><thead><tr></tr></thead>';
$.each($(values), function () {
var data1 = this.RealValue.FieldValue;
var data2 = this.RealValue.Id;
//create tables row
content += '<tr data-id=' + this.Id + '>';
content += '<td style="vertical-align: inherit;text-align:center;"><label for="">' + this.FieldName + '</label></td>';
if (this.FieldValue.indexOf(',') > -1) {
content += '<td style="text-align:center;"><select>';
this.FieldValue.split(',').forEach(function (item) {
if (data1 === item) //Here data1 is undefined!!!
{
content += '<option selected="selected" value="">' + item + '</option>';
}
else {
content += '<option value="">' + item + '</option>';
}
})
content += '</select></td>';
}
else {
content += '<td style="text-align:center;"><input type="text" id="propFieldName" data-id="' + this.Id + '" value="' + congiValue(this.FieldValue, this.RealValue) + '"/>';
}
content += '</tr>';
});
content += '</table>';
content += '</fieldset>'
return content;
}
Inside outter each function I create 2 variables:
var data1 = this.RealValue.FieldValue;
var data2 = this.RealValue.Id;
I try to create this variable inside inner each:
if (data1 === item) //Here data1 is undefined!!!
But on this row I get this error:
Uncaught ReferenceError: data1 is not defined
Any idea why data1 is undefined?

It can be undefined only because this.RealValue.FieldValue or this.RealValue is undefined

It looks like
var data1 = this.RealValue.FieldValue; //it's value is undefined
this.FieldValue //it's value is undefined
try to
console.log(this.FieldValue)
console.log(data1)
After that you can easily found where you are getting an error and why. Else everything looks fine with your code.

I have encountered similar problem before. It took me several hours to discover the problem. Now that aside there some things which is not clear here.
is the value coming from another function's operation? If
this.RealValue.FieldValue;
is coming from e.g. a result of maybe another function then you would need to use async/await to ensure that the function completes its operation and there is data in this.RealValue.FieldValue before you move on to the next line of code.
Maybe the this.RealValue.FieldValue itself does not have any thing assigned to it outside of the function itself.
In order to help you we would need a complete code. If you think your code is too private then you can go through it by trying what #Negi Rox said earlier.
Put console.log(this.RealValue.FieldValue) at various strategic locations in your code to determine when it was assigned a value.

Related

Confusing behaviour on passing object as parameter to a method called from Table created in Javascript

I'm have a table with buttons in each row. On every button click I want to pass that row's data to a method. I've done the following
HTML
<body>
<div>
<button onclick="load()" >Click</button>
<table id="roleTable">
<thead>
<tr>
<td>EnterpriseId</td>
<td>Role</td>
<td>UserId</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</body>
Javascript
function load() {
var data = JSON.parse(sessionStorage.getItem("loginInfo"));
var html = "";
for (var i = 0; i < data.length; i++) {
html += "<tr><td>" + data[i].ENTERPRISE_ID + "</td>";
html += "<td><button type='button' onclick='loadSegment(data[" + i + "])'>...</button></td>";
html += "<td>" + data[i].USER_ID + "</td></tr>";
}
document.getElementById('roleTable').getElementsByTagName("TBODY")[0].innerHTML = html;
}
function loadSegment(o) {
alert('reading obj');
alert(JSON.stringify(o));
}
The problem is when I click on the button with given code, nothing happens.
But if I move the code of load() function out, the loadSegment method gets called and I'm able to use the object as I want.
Working JS
//function load() { // Commented the function call
var data = JSON.parse(sessionStorage.getItem("loginInfo"));
var html = "";
for (var i = 0; i < data.length; i++) {
html += "<tr><td>" + data[i].ENTERPRISE_ID + "</td>";
html += "<td><button type='button' onclick='loadSegment(data[" + i + "])'>...</button></td>";
html += "<td>" + data[i].USER_ID + "</td></tr>";
}
document.getElementById('roleTable').getElementsByTagName("TBODY")[0].innerHTML = html;
//}
function loadSegment(o) {
alert('reading obj');
alert(JSON.stringify(o));
}
I don't understand why through the second code the method is reachable but not from the first code. If I don't pass object as parameter in the first code then it is able to reach to the loadSegment() function.
Can anybody please help me understand what is the exact issue her. And how can I achieve the function call from the first JS code.
Update
JSON string
[{"USER_ID":"UID00007","ENTERPRISE_ID":"admin1","ROLE":"ADMIN"},
{"USER_ID":"UID00008","ENTERPRISE_ID":"admin2","ROLE":"TESTER"},
{"USER_ID":"UID00009","ENTERPRISE_ID":"admin3","ROLE":"REVIEWER"},
{"USER_ID":"UID00010","ENTERPRISE_ID":"admin4","ROLE":"PMO"},
{"USER_ID":"UID00011","ENTERPRISE_ID":"admin5","ROLE":"MANAGER"},
{"USER_ID":"UID00012","ENTERPRISE_ID":"admin6","ROLE":"DEVELOPER"},
{"USER_ID":"UID00013","ENTERPRISE_ID":"admin7","ROLE":"DBA"}]
In the first example, the data variable exists only within the scope of the load function:
function load() {
var data = JSON.parse(sessionStorage.getItem("loginInfo"));
//...
}
And then you try to reference it outside of that function:
onclick='loadSegment(data[0])'
It doesn't exist at this point, so you can't reference it. By contrast, in the second example you create the data variable in global scope, so it exists on the window object and can be referenced anywhere.
To encapsulate the data variable within that function, you'll need to supply the HTML you're creating with all of the information it needs to call the loadSegment function, not just an index reference. Maybe serialize the whole value into the function call? Maybe put values on data-* attributes? Maybe move all the code into the function except the data variable and keep that on window scope? You have options, depending on what you're trying to achieve overall.
Side note: You might not want to create something called load on the window object (or any other DOM object). If not actual problems, that could cause confusion with other code.
Changing the functionName will help
function loadfun()
{
var data = JSON.parse(sessionStorage.getItem("loginInfo"));
var html = "";
for (var i = 0; i < data.length; i++) {
html += "<tr><td>" + data[i].ENTERPRISE_ID + "</td>";
html += "<td><button type='button' onclick='loadSegment(data[" + i + "])'>...</button></td>";
html += "<td>" + data[i].USER_ID + "</td></tr>";
}
document.getElementById('roleTable').getElementsByTagName("TBODY")[0].innerHTML = html;
}
function loadSegment(o) {
alert('reading obj');
alert(JSON.stringify(o));
}

Jquery loop once or show data once in array of data

I am using $.get() request to fetch data from Laravel controller and getting array of data in Javascript.
function getSpots1(){
var spots = $('#event-spots1');
spots.empty();
spots.html('<p><i class="uk-icon-refresh uk-icon-medium uk-icon-spin"></i></p>');
var event_id = $("#event-event_id").val();
var event_date = $("#event-date").val();
var code = '';
console.log(event_date);
$.get("/1/users/spots/" + event_id + "/" + event_date + "/date", function(data) {
spots.empty();
console.log(data);
code += '<label for="event_time" class="uk-form-label">Select Time</label><select class="uk-width-1-1" name="event_time" id="event-time">';
$.each(data.spots, function(index, value)
{
code += '<option value="' + value.event_time + '">' + value.event_time + '</option>';
});
code += '</select><p class="uk-form-help-block uk-text-muted">The spot you\'re booking</p>';
code += '</br><div class="uk-margin-bottom"><label for="event_time" class="uk-form-label">Price</label>';
$.each(data.spots, function(index, value)
{
code += '<input type="text" class="uk-width-1-1" value="' + value.price + '" disabled />';
});
spots.append(code);
getSpots2();
});
}
I have $.each() jquery method to loop through array of Data. but for second $.each() method, I just need to loop once. I get value.price Multiple times depending on the loop length. For first $.each I need a loop because I have select input field.
Is there a another method instead of $.each to loop once through data variable? I am new and haven't really coded Jquery or Javascript before.
Well you could just get the first object in data.spots like for example data.spots[0].event_time and then you don't have to loop at all.
Less recommended, you could just put a return false; at the end of a loop like for example:
$.each(data.spots, function(index, value)
{
code += '<input type="text" class="uk-width-1-1" value="' + value.price + '" disabled />';
return false;
});
which immediately stops the loop.

Search Not Working In Dynamic Bootstrap Multiselect

I'm using
http://davidstutz.github.io/bootstrap-multiselect/ for creating bootstrap multiselect controls in my webpage.
The below fiddle link with static data is what I want to achieve using dynamic data:
https://jsfiddle.net/DROCKS/mrmLrsad/4/
//please refer the fiddle
The search option works fine in case the values of the select box are static, but if they are dynamically created, the multiselect gets created. However the search filter is not working in this case. However the my code is similar to the fiddle below, the only difference being that the search filter part doesn't work in my actual code, but works in this fiddle.
fiddle link with dynamic data.
https://jsfiddle.net/DROCKS/mrmLrsad/5/
//please refer the fiddle
This is my code.
HTML code
<select id="lstFieldList" ></select>
jQuery code [Updated]:
function uncheckFields(field_id)
{
$('#' + field_id).multiselect('deselectAll', true);
}
//json_obj is the value from the fiddle.
createMultiSelectBox(json_obj);
//this function creates the multiselect
function createMultiSelectBox(json_obj)
{
var element_String = "";
var default_ele_set = 0;
var def_element_first = "1"; //if the first Y flag should be considered
var def_element_last = "n"; //if the last Y flag should be considered
var def_element = def_element_first; //change the value here to toggle between default selection
var tmp = [];
for (var key in json_obj)
{
var val = json_obj[key];
//alert("Key: " + key);
var chk_box_ctr = 0;
var element;
for(var child_key in val)
{
//alert("key: " + child_key + "\nvalue: " + val[child_key]);
var default_value = child_key.split(",")[7];
//alert("default_value: " + default_value);
if(!chk_box_ctr)
{
g_max_PageSize = child_key.split(",")[8];
//alert("g_max_PageSize: " + g_max_PageSize);
}
if(def_element == def_element_first)
{
if(default_value == "Y" && !default_ele_set)
{
//element_String += '<option value="' + child_key + '" selected="selected">' + val[child_key] + '</option>';
element = {"label": val[child_key],"value":child_key};
}
else
{
//element_String += '<option value="' + child_key + '">' + val[child_key] + '</option>';
element = {"label": val[child_key],"value":child_key};
}
}
else
{
if(default_value == "Y")
{
//element_String += '<option value="' + child_key + '" selected="selected">' + val[child_key] + '</option>';
element = {"label": val[child_key],"value":child_key};
}
else
{
//element_String += '<option value="' + child_key + '">' + val[child_key] + '</option>';
element = {"label": val[child_key],"value":child_key};
}
}
tmp.push(element);
}
if(def_element == def_element_last)
{
uncheckFields('lstFieldList');
}
}
//$('#lstFieldList').append(element_String);
//$('#lstFieldList').multiselect('rebuild');
$("#lstFieldList").multiselect('dataprovider', tmp);
$('#lstFieldList').multiselect({
maxHeight: 200,
buttonWidth:"100%",
enableFiltering:true,
enableCaseInsensitiveFiltering:true,
/*maxHeight: 200,
enableCaseInsensitiveFiltering: true,
//enableFiltering: true,
onChange: function(option, checked, select) {
alert('Changed option ' + $(option).val() + '.' + "\nchecked: " + checked + "\nselect: " + select);
if(checked)
{
//uncheckFields('lstFieldList');
}
else
{
uncheckFields('lstFieldList');
}
}*/
});
var elem = $('#lstFieldList').next();
elem.attr('class',(elem.attr('class') + ' open'));
}
What could be the problem? because the same code is present in both the files.
Any help would be appreciated.
Thanks in advance.
create an array var tmp = [];
create a json like this while looping for option
element = {"label": this.Name,"value":this.id};
and push each element to tmp
tmp.push(element);
and pass this tmp array to multi select
$("#lstFieldList").multiselect('dataprovider', tmp);
and add multiselect to dropdown by
$("#lstFieldList").multiselect({
maxHeight: 260,
buttonWidth:"100%",
enableFiltering:true,
enableCaseInsensitiveFiltering:true,
});
I actually found out what was causing the unusual behavior in the code related to the bootstrap multiselect plugin. The code given to me by Anoop was right, I also tried various different codes related to the same plugin in the past months, but I later drop the idea to use the plugin.
Then lately last week while reworking on the same code, I identified that I had included some js script files in my html page. So I tried commenting out each include statement for the files in my html to identify which one was causing the issue. So on doing so I reached at a particular js file.
Once the file was identified, I just needed to find out which function was causing the problem to the suggestion logic of the plugin. So to identify this, I kept on commenting/removing the functions till I arrived to the function that caused the issue. There was a code related to window.setTimeout. It was due to this function that the existing suggestion logic was not working as the code was coming into this block. So I later added some flagging logic to avoid running this function in my case.
Thanks a lot all for your inputs.....

inline if else statements in jQuery

I have a jQuery function that is executed by two different buttons.
$("#btnSearch, #btnDirectorSearch").click(function () {
Part of the html that this function builds depends on which button was hit. I am using data- attributes to store my variables like this:
var div = $(this).data("str");
And the html string I am building depends on what value the variable "div" is. Is there a way to do an inline if/else statement in jQuery?
if div = "choice1" {
html += '<tr data-str = "str1" data-dataItem = "dataItem1" data-result-title = "' + name + '" data-result-id="' + sel + '">';
} else {
html += '<tr data-str = "str2" data-dataItem = "dataItem2" data-result-title = "' + name + '" data-result-id="' + sel + '">';
}
That seems cumbersome and I'm hoping there is a better jQuery way of doing this.
Thanks!
you have a syntax error
if div = "choice1"
should be
if (div == "choice1")
Anyway, the pattern you're looking for is:
div == "choice1" ? <code for true> : <code for false>
you can use condition ? code when true: code when false
but i would suggest you to stick with curley braces only, as it looks better and easier to debug.
one more thing , do it as below
if(div==="choice1"){
}
else{
}
use ===
Since it's only the number that changes in the output, you could do this:
var num = div == "choice1" ? 1 : 2;
html += '<tr data-str="str'+num+'" data-dataItem="dataItem'+num+'" data-result-title="'+name+'" data-result-id="' + sel + '">';
If your choices are limited, you could add a small lookup array:
var choices = {
choice1: {
str: "str1",
data: "dataItem1"
},
choice2: { ... }
};
html += '<tr data-str="' + choices[div].str
+ '" data-dataItem="' + choices[div].data
+ '" data-result-title="' + name + ... etc;

Javascript selected item value not pulling correctly

I'm doing a select box with a list of items(dynamically created from an XML created by a webservice), and I'm unable to pull the selected value correctly. Here is what is happening.
What I'm sending:
onchange="changeFunction(this.options[this.selectedIndex].value)"
What I'm receiving:
function (a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!=
I'm the only thing I'm using is some self built functions and jQuery.
Any help would be superb.
Edit: here is the change function. All it is intended to do is build a form populated with values for given selected item.
function changeFunction(selection) {
console.log(selection);
$('#right').empty();
var addNewFields = 'these will be the fields';
$('#right').append(addNewFields);
}
Here is the select in question:
<select class="userSelection" id="userSelection" size="10" style="width:150px;" onchange="changeFunction(this.options[this.selectedIndex].value)"></select>
This is literally all the code in the html part of it. It's being populated via ajax, and there are 2 divs, one for left, containing the select, and one for right, containing the content for the user.
Just for giggles, here is the code creating the options:
var optionTag = '<option value="' + $(this).find('optionID').text + '" >' + $(this).find('optionName').text() + '</option>';
$('#userSelection').append(optionTag);
var optionTag = '<option value="' + $(this).find('optionID').text + '" >' + $(this).find('optionName').text() + '</option>';
should be:
var optionTag = '<option value="' + $(this).find('optionID').text() + '" >' + $(this).find('optionName').text() + '</option>';
Notice that $(this).find('optionID').text should be $(this).find('optionID').text().
or even better, to avoid this soup:
var optionTag = $('<option/>', {
value: $(this).find('optionID').text(),
html: $(this).find('optionName').text()
});
When you set the event handler of a DOM object to a function it get passed an event object as it's argument.
selectBox.onchange = function(event) {
changeFn(this.options[this.selectedIndex].value);
};

Categories

Resources