How to access an HTML element that is dynamically filled with values? - javascript

I've read lots of stackoverflow questions with no luck. My problem is, I have an HTML page in which I have
<select id="myid"></select>
and there, there's a Firebase command that retrieves names of values i need, and put it inside the <option> like HERE:
reference.on("child_added", function (childSnapshot){
var key = childSnapshot.key;
var opt = document.createElement('option');
opt.textContent = key;
document.getElementById('myid').appendChild(opt);
});
Now, i need to somehow access these values, that by the way are correctly appearing in both HTML and my site, however:
var val = document.getElementById('myid').value;
console.log(val);
It always returns blank in console. I don't know how else can I access it. Whenever I type those values in <option> by myself in HTML, everything works as it should and console returns the names that are in database.
#edit: as far as i tried to crack it, it seems to do with the fact that javascript cannot access elements, that for javascript itself aren't yet loaded, but i tried doing window.onload and other similar ones and they don't help.

You can use AngularJS, with directive $scope.watch, i will write a simple example of how to use and the link of documentation, if you have any question talk back to me!
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
AngularJS Documentation
I hope help with this :)

Related

Extract an Page Variant Value with Javascript

I am not a javascript expert at all and expect this to be a fairly simple task.
I am trying to grab the value from a hidden field on my page called pageVariant so I can store it as a value inside of Google Tag Manager. I just don't know how to write the javascript.
This is the code I have tried, but know it is not right. Any help here would be appreciated.
function() {
var capturedText = document.querySelector("#lp-pom-form-162 > form > input[type=hidden]:nth-child(2)");
return capturedText; }
First of all provide a name to your function.
Then use the code mentioned below:
function inputText() {
var capturedText = document.querySelector("input[name='pageVariant']").value;
return capturedText;
}

Need debugging/outside advice. Angular not working

So, my instructor thought it would be a great idea to throw in local storage and all that great nonsense the second week into learning Angular JS and basically told us to copy her code but change the names (as if that's learning). But anyways I have no idea how to work with angular js except for a few concepts and I need help finding the issues in my code. Any input would help. So far it looks as if the information from the form isn't being inputed to the html where it will be displayed. Here is my js fiddle. Any input is greatly appreciated
http://jsfiddle.net/g3tg5L15/1/
var app = angular.module('myApp', []);
app.controller("EmployeeController", function($scope, DataService){
$scope.empInfo = DataService.getEmpInfo();
$scope.newempInfo = {};
$scope.addNewEmpInfo = function(){
DataService.saveEmpInfo($scope.newempInfo.employee, $scope.newempInfo.street,
$scope.newempInfo.city,$scope.newempInfo.state, $scope.newempInfo.zip);
$scope.newempInfo = {};
};
$scope.removeEmpInformation = function(index){
DataService.removeEmpInfo(index);
};
$scope.clearInfo = function(){
DataService.destroyLocalStorage();
};
});
angular.module('myApp').service("DataService", function(){
var empInfoArray = [];
this.getEmpInfo = function(){
var employeeInfoArray = JSON.parse(localStorage.getItem("employeeInformationLS")) || [];
var empInfoArray = employeeInfoArray;
return empInfoArray;
};
this.saveEmpInfo = function(aName, aStreet, aState, aCity, aZip){
var savedEmpInfo = {employee : aName, street : aStreet, state : aState, city : aCity, zip : aZip};
empInfoArray.push(savedEmpInfo);
localStorage.setItem("employeeInformationLS", JSON.stringify(empInfoArray));
};
this.removeEmpInfo = function(aIndex){
empInfoArray.splice(aIndex, 1);
localStorage.setItem("employeeInformationLS", JSON.stringify(empInfoArray));
};
this.destroyLocalStorage = function(){
empInfoArray.splice(0);
localStorage.clear();
};
});
The main reason for the lack of response and debugging ability is due to AngularJS not loading correctly. For it to load you must change the dropdown in the left menu bar of jsFiddle from onLoad to No wrap - in <body> to load Angular correctly (as shown in the following screenshot).
The following surmises the issues I observed when debugging the code.
The getEmpInfo function within the DataService returns a new array each time it is called which prevents Angular from effectively monitoring it for changes. Instead of this function checking localStorage each time it is called it should just return the local array. The array can be simply loaded from localStorage when the service is first initialized.
The following update to the fiddle demonstrates this http://jsfiddle.net/g3tg5L15/6/. The changes implemented are as follows:
Change the dropdown in the menu bar of jsFiddle from onLoad to No
wrap - in <body> to load Angular correctly.
Added ng-click to 'Add Entry' button in HTML
<!-- Added ng-click to call addNewEmpInfo function on scope -->
<button ng-click='addNewEmpInfo()'>Add Entry</button>
Amended text on employeeInfo header to employee name rather than being hard coded value and added ng-click to remove in HTML.
<!-- Amended to add.employee rather than hardcoded value -->
<h3>{{add.employee}}</h3>
<!-- Added ng-click to call removeEmpInformation function on scope -->
<button ng-click='removeEmpInformation($index)'>X</button>
Amended the DataService to load from localStorage when it is initialized rather than initializing as an empty array.
var empInfoArray = JSON.parse(localStorage.getItem("employeeInformationLS")) || [];
Amend the getEmpInfo object to just return the local Array
this.getEmpInfo = function(){
return empInfoArray;
};
If necessary you can also watch for events triggered when localStorage changes, as included in the above fiddle. This will pick up changes from different tabs / windows if multiple are open. To monitor for these you must:
Include the services $window and $timeout in the DataService
angular.module('myApp').service("DataService", function($window, $timeout){
Add a trigger when a storage change occurs.
//Watch for storage events indicating changes to storage
angular.element($window).on('storage', function(event) {
//Check if the storage change was for our key
if (event.key === 'employeeInformationLS') {
//In a timeout (i.e. on next digest) update the array
//This could be done in a smarter way rather than clearing
//and rebuilding the entire array
$timeout(function(){
empInfoArray.splice(0);
var newArr = JSON.parse(localStorage.getItem("employeeInformationLS")) || [];
for (var i=0; i<newArr.length; i++){
empInfoArray.push(newArr[i]);
}
});
}
});

CQ5 AEM: how to get a component by name within a dialog using javascript

I know this will probably a simple question, but I'm new to CQ5 and AEM in general.
I have a cq:Widget node which is a simple textfield.
<rowtitlevalue
jcr:primaryType="cq:Widget"
fieldLabel="Row Title Value"
name="./rowtitlevalue"
xtype="textfield"
disabled="true"/>
Now at the moment within my JavaScript, I'm currently accessing it via
var textfield = panel.findByType('textfield')[1];
which works fine (there's another textfield before this one, hence the 1 in the array.
MY QUESTION:
how do I look for this field using it's NAME attribute within my javascript.
Any help would be appreciated.
Also, I'm using this object to run the following:
if (show != undefined) {
textfield.enable();
textfield.show();
}
else if (show == undefined) {
textfield.disable();
textfield.hide();
}
The JavaScript is located within the Component Based ClientLibs.
And this is the Listener that I have under the checkbox that defines the value of SHOW within the javascript (which is working fine).
<listeners
jcr:primaryType="nt:unstructured"
loadcontent="function(field,rec,path){Ejst.toggleRowTitle(field);}"
selectionchanged="function(field,value){Ejst.toggleRowTitle(field);}"/>
Please let me know if you see any problems with this.
Appreciate it in advance
The CQ.Dialog API defines the getField( String name) method which returns a field with the given name. In case more than one field with the same name exists, it returns an array of those fields.
Thus finding parent of xtype dialog instead of panel as shown below would solve this.
Ejst.toggleRowTitle = function(checkbox) {
var dlg = checkbox.findParentByType('dialog');
var rowTitleField = dlg.getField('./rowtitlevalue');
// perform required operation on rowTitleField
}
i did something like that a few days ago and my solution was to make a js file on the same level of the component and with the same name of the component with the information that i need.
Something like this:
The file will be called rowtitlevalue.js and the content would be:
"use strict";
use(function() {
var data = {};
data.rowtitlevalueData = properties.get("rowtitlevalue");
//more properties if needed...
return {
data: data
}
});
then where i need to use it in javascript, i need the following tags:
<sly data-sly-use.data="rowtitlevalue.js">
<script type="text/javascript">
var myVariable = ${data.rowtitlevalueData};
</script>
</sly>

How to make variable accessible within jQuery .each() function?

This is and example of a frequent dilemma: how to make markup accessible inide this .each()?
I'm more interested in learning how to access outer variables from within a closure than I am in this specific issue. I could fix this problem by assigning markup from inside the each function, but I'd rather learn a more elegant way to handle this kind of problem.
// hide form & display markup
function assessmentResults(){
// get assessment responses
var markup = parseForm();
// show assessment results to user
$('#cps-assess-form fieldset').each( function() {
var q = $(this).find('.fieldset-wrapper');
var i = 0;
// hide form questions
q.slideUp();
// insert markup
$('<div>'+markup[i]+'</div>').insertAfter(q);
i++;
});
}
Read the docs, it already has an index!
.each( function(index, Element) )
No need for i
$('#cps-assess-form fieldset').each( function(index) {
var q = $(this).find('.fieldset-wrapper').slideUp();
$('<div/>').html(markup[index]).insertAfter(q);
});
The reason why yours is failing is the i is inside of the function so it is reset every iteration. You would need to move it outside of the function for it to work.

Variable not updating in script string, yet it updates

Very confused here.
I have a search box which reads a list of school names from my database. When I select a school, the id (from the db) gets put in a hidden textbox.
I also have a search box which reads a list of courses from my database. However, I made the query so that it only reads the courses from the selected school.
It does that, in theory.
I was planning to pass the school id, which I grab from the hidden box, to the search script which in turn passes it to my database query. However, the variable I put my school id in doesn't seem to be updating.. yet it does. Let me explain.
I come on the page. The school for my test account has id 1. The id number in my hidden box is indeed 1. I search for a school which I know has some courses assigned to it: the id number in the box changes to 3.
I have a JS variable called school_id which I declared outside of my $(document).ready. I assume that means it's global (that's what I got taught even though SO told me once it isn't really the correct way to do this. Still have to look into that). I wrote a function which updates this variable when the school search box loses focus:
$("#school").blur(function() {
school_id = $("#school_id").val();
});
A quick javascript:alert(school_id); in my browser bar also shows the updated variable: it is now 3 instead of 1.
Onto the search script part of my page (excerpt of the script):
script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&"
As you can see, I pass the school_id variable to the script here. However, what seems to be happening is that it always passes '1', the default variable when the page loads. It simply ignores the updated variable. Does this string get parsed when the page loads? In other words, as soon as the page loads, does it actually say &id=1? That's the only idea I can come up with why it would always pass '1'.
Is there a way to make this variable update in my script string? Or what would be the best way to solve this? I'm probably missing out on something very simple here again, as usual. Thanks a lot.
EDIT
Updated per request. I added a function getTheString as was suggest and I use the value of this function to get the URL. Still doesn't work though, it still seems to be concatenating before I get a chance to update the var. HOWEVER, with this code, my ajax log says id:[object HTMLInputElement], instead of id:1. Not sure what that means.
<script type="text/javascript">
var school_id;
$(document).ready(function() {
$("#school").blur(function() {
school_id = $("#school_id").val();
});
// zoekfunctie
var scholen = {
script:"/profiel/search_school?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:6,
callback: function (obj) { document.getElementById('school_id').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('school', scholen);
var richtingen = {
script: getTheString(),
varname:"input",
json:true,
shownoresults:true,
maxresults:6
};
var as_json2 = new bsn.AutoSuggest('studierichting', richtingen);
});
function getTheString() {
return "/profiel/search_richting?json=true&limit=6&id=" + school_id + "&";
}
</script>
This is because the URL is static, it is not updated as the ID changes.
You should update the URL as part of the code you wrote to get the ID:
$("#school").blur(function() {
school_id = $("#school_id").val();
// update URL here ...
});
Aren't you concatenating script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&" before the event is fired and the var updated?
Okay. So the problem was my third party plug-in instead of the code I wrote. I fixed this by editing the code of the autoSuggest plugin so it now includes my id field in the AJAX request.
var url = this.oP.script+this.oP.varname+"="+encodeURIComponent(this.sInp)+"&id="+ $("#school_id").val();
Thanks to everyone who tried to help me out!

Categories