Dynamically add option with jquery and update html source - javascript

I have two listbox, A & B:
when I double click on an item of A , the item will be added in List B. And i have done this. List B visually show the value, but when I go to the view source of the page, I dont see new <option>.
This is my List A options.
This is my List B options (before and after addition and it remains same whatever items added. this is my problem.):
It should have one <option>. like
<option value="VSNR">VSNR</option>
what is my code is :
$('#lstXLSCol').on('dblclick', function () {
var item = $('#lstXLSCol').find(":selected").text();
var newOption = { item: item };
$('option:selected', this).remove();
$.each(newOption, function (val, text) {
if (text != "")
$('#lstXLSSelectedCol').append(new Option(text, val));
});
});
EDIT 1 :
I have found it pressing F12 in IE. but the values are like below:
but, i wanted to insert the value same as text. What should be changed in my jquery code?

you can not see them. The source is just used to build the initial DOM that represents the document. Dynamically created elements are only inserted in the DOM.
But you can analyse such elements with a DOM viewer like Safari’s WebInspector or the Firefox extionsion Firebug. Firefox can also show source code that represents such dynamically created elements by selecting that element an choosing View Selection Source in the context menu.
See this

take out the space between params and :last
$('#lstXLSSelectedCol:last').html('<option value=\''+item+'\'>'+item+'</option><option>');

$('#lstXLSSelectedCol:last').live('change', function () {
var option_selected = $('option:selected', this).val();
$('#lstXLSSelectedCol:last').append($('<option>', {
value: option_selected
}).text(option_selected));
});

You won't see dynamically added elements in the source of your page.
Use your browser's console to inspect the DOM.
Normally it's enough to right click on the element and select "inspect" from the context menu, otherwise see this link for how to access your browser's console.

Related

Located element in a dropdown list but can not click on it

There is a dropdown list I want to click, it has four options when expanded. With my code, I can click and expand this dropdown list, but unable to click on the option (value = '100').
This is the HTML code for the elements I want to click before the dropdown list is expanded:
This is the HTML code for the elements I want to click after the dropdown list is expanded:
Below is my code:
//#FunctionName : Display100ResultsPerPage
//#Description : A function that chooses to display 100 results per page instead of 10
//#Parameters : PageObj: page that displays items
//#Returns : None
//#Version : v1.0
function Display100ResultsPerPage ( PageObj )
{
var localPageObj = PageObj;
var display100ItemsPerPageOptionCssSelector = "div[class='per-page-section'] select option[value='100']";
var displayNItemsPerPageDropdownListCssSelector = "div[class='per-page-section'] select";
localPageObj.QuerySelector(displayNItemsPerPageDropdownListCssSelector).Click();
aqUtils.Delay(500);
localPageObj.QuerySelector(display100ItemsPerPageOptionCssSelector).Click();
}
My code manages to:
Clicks and expands the dropdown list, but unable to click on the (100) option.
If I add an additional line in my code:
Log.Message(localPageObj.QuerySelector(display100ItemsPerPageOptionCssSelector).getAttribute('value'));
I got a logging message saying "100", which means my code can successfully locate this (100) option but why can not I click on it?
Many thanks
I have tried the following approach:
localPageObj.contentDocument.Script.jQuery("div[class='per-page-section'] select").find("option").css("z-index","999", "position", "relative");
option elements have changed into:
By index, I tried to click on the last option (value = '100'), but still not working.
Inspect the element by right clicking on it, if the inspector takes you to a different element I think you need to give dropdown list a "z-index" and remember that z-index works only when you specify position to relative or absolute. that should solve the problem, I believe.

Changes to selected element in scope won't be persisted in array of available elements

I'm using angularJS 1.5.6 and try to update a value by using a combo box within an object that had already being selected through another combo box. But after switching the source object these changes are lost.
For a better understanding try this JSFiddle.
Within the above example the first combo box just selects an item out of a list of availables:
<select data-ng-model="currentElement"
data-ng-options="element.name for element in elements track by element.id"
data-ng-change="updateDeeperOption()">
</select>
The second combo box works on a second list of available options:
<select data-ng-model="deeperOption"
data-ng-options="option.name for option in availableOptions track by option.value"
data-ng-change="writeDeeperOptionToCurrentElement()">
</select>
The two method, which are being called whenever a change happens are simply updating the data in both directions:
$scope.updateDeeperOption = function() {
$scope.deeperOption = $scope.availableOptions.filter(function (option) {
return option.value === $scope.currentElement.going.deeper.to.myOption; })[0];
};
$scope.writeDeeperOptionToCurrentElement = function() {
$scope.currentElement.going.deeper.to.myOption = $scope.deeperOption.value;
};
The problem comes from writeDeeperOptionToCurrentElement(). It updates the current element (you can see it within the fiddle), but if you switch to another element and back again, the changes are lost.
Any idea, what I made wrong? I think, I'm still missing some fundamental understanding about when objects are copied or just referenced within AngularJS. So any explanation or links would be helpful.
Update:
I isolated the actual problem here and found that if you remove the track by from your first select then the currentElement object gets updated by reference. See: https://jsfiddle.net/tbzggyg1/4/
So instead of this:
<select data-ng-model="currentElement"
data-ng-options="element.name for element in elements track by element.id"
data-ng-change="updateDeeperOption()">
Try this:
<select data-ng-model="currentElement"
data-ng-options="element.name for element in elements"
data-ng-change="updateDeeperOption()">
And here is why: https://docs.angularjs.org/api/ng/directive/ngOptions
... is to use a track by clause, because then ngOptions will track the identity of the item not by reference, but by the result of the track by expression. For example, if your collection items have an id property, you would track by item.id.
Old answer:
It looks like your '$scope.currentElement' object is actually just getting a copy reference from the array, so when you make modifications it doesnt really update the original array (which is what your dropdowns bind to). I tried this and it worked:
$scope.writeDeeperOptionToCurrentElement = function() {
// $scope.currentElement.going.deeper.to.myOption = $scope.deeperOption.value; // old code
var elementRef = $scope.elements.filter(isMatchingElement)[0];
elementRef.going.deeper.to.myOption = "" + $scope.deeperOption.value;
};
function isMatchingElement(e) {
return e.id === $scope.currentElement.id;
}
Also, add this to your template so you can see the entire picture of whats happening:
<tt>{{currentElement}}</tt>
<hr>
<tt>{{elements}}</tt>
Link to fiddle forked: https://jsfiddle.net/t2dvm0a2/
In ng-options each option item is identified by the value you provide in track by.
Had you given your deep value in track by, things would have worked.
<select data-ng-model="currentElement"
data-ng-options="element.name for element in elements track by element.going.deeper.to.myOption"
data-ng-change="updateDeeperOption()">
</select>
Please check the updated fiddle
https://jsfiddle.net/tbzggyg1/3/

Using JQLite How to select an item or items in a select box

I'm attempting to highlight 1 or more items in a select box in a unit test. I'm using Karma, Jasmine, and PhantomJS, AngularJS, JQLite, CoffeeScript.
My list has items ["banana", "apple", "orange"].
I tried setting the value directly:
sourceList = element.find('select').eq(1)
sourceList.val("[banana]").triggerHandler('change');
// Or
sourceList.val("banana").triggerHandler('change');
When I get sourceList.val() it's not set.
I tried triggering events to select it. Note I can't do a "click" event because I have another event fire on click.
sourceList.find('option').eq(0).triggerHandler("active");
sourceList.find('option').eq(0).triggerHandler("focus");
sourceList.find('option').eq(0).triggerHandler("drag");
sourceList.find('option').eq(0).triggerHandler("dragLeave");
I tried using the selectedIndex
sourceList.selectedIndex = 1
None of those seem to highlight or select the item. I'm out of ideas. Has anyone accomplished this?
Here is the method of the directive which I am trying to test:
// Clicks on the add button. Should take all items highlighted and move them over
$scope.add = function(){
var sourceList = $element.find('select').eq(1);
angular.forEach(sourceList.val(), function(val, index){
$scope.selected.push({
text: val
});
});
checkListDupes();
};
This code works when I do it manually in the browser but I can't seem to get my test to highlight some items in the select box before clicking the add button. So when this code executes sourceList.val() is equal to [].
A bit late to the party, but I'll leave it here for anyone else with the same problem.
I don't know how you've built the options for the select box but sourceList.val("banana").triggerHandler('change');
should work fine as long as the value of the option is banana. If you haven't specified a track by on the ng-options, the default values that angular creates will be 'string:'+<option label> so sourceList.val('string:banana').triggerHandler('change'); should do the trick.

Using Jquery, load select options on focus

I am trying to load options into a select element when the user focuses.
Here is the jquery code I'm using:
$('select').focus(function() {
var $this = $(this);
if (!$this.data('hasitems')) {
var selectedValue = $this.val();
$this.empty()
.append($('<option></option')
.attr('value','')
.text('Loading...'));
// This would usually be the result of an AJAX call
$this.empty()
.data('hasitems','true');
$.each(['a','b','c','d'], function(index,item) {
$this.append($('<option></option>')
.attr('value',item)
.text(item)
.prop('selected', selectedValue == item));
});
}
});
Here is the fiddle:
http://jsfiddle.net/agnnC/
The solution almost works... except in Firefox (and sometimes not in Chrome either, although the fiddle I put together does appear to work).
The problem in Firefox is that when the user clicks on the select element, the currently selected value is not remembered and is changed to one of the new values in the drop down.
Can anyone think of a workaround?
I think the issue is that the selected attribute is not really a property the way you are using it. Per the MDN doc:
selected
If present, this Boolean attribute indicates that the option is
initially selected. If the element is the descendant of
a element whose multiple attribute is not set, only one single
of this element may have the selected attribute.
Note, it talks about "initially selected" only, not real time changes. It also refers to selected only as an attribute, not a property.
The W3C spec for the option element also talks only about pre-selecting an option, not about making live changes using the selected attribute.
Once the select and options are live, the .selectedIndex property on the <select> object controls which option is selected in real time for single selection select elements.
In support of this theory, if you change to setting the saved item with .selectedIndex as shown below, the problem goes away:
$('select').focus(function() {
var $this = $(this);
if (!$this.data('hasitems')) {
var selectedValue = $this.val();
$this.empty()
.append($('<option></option')
.attr('value','')
.text('Loading...'));
// This would usually be the result of an AJAX call
$this.empty()
.data('hasitems','true');
$.each(['a','b','c','d'], function(index,item) {
$this.append($('<option></option>')
.val(item)
.text(item));
if (selectedValue == item) {
$this.prop("selectedIndex", index);
}
});
}
});
Working demo: http://jsfiddle.net/jfriend00/4333d/
Firefox can't change the focus option when select is opening, but you can change before it open, change the event to mousedown it working Fiddle
$('select').mousedown(function() {
// ...
});

How to rebind a Kendo ListView after changing template

I'm attempting to rebind the listview data after changing the template, based on a DropDownList value. I've included a JSFiddle for reference. When I rebind currently the values in the template are undefined.
Thanks!
JSFiddle link
I was thinking the best way to handle it would be in the 'select' or 'change' function:
var cboDetailsCategory = $("#detail").kendoDropDownList({
data: [
"All",
"Customer",
"Location",
"Meter",
"Other"],
select: function (e) {
var template = $("#" + e.item.text()).html();
console.log("template", template);
$("#details").html(template);
},
change: function (e) {
},
please refer to the JSFiddle link and this graphic as a visual
Here is a lengthier workflow:
User completes a name search and clicks a search button.
Name results are populated in a listview, rendered individually as button controls using a template.
User then clicks one of the name results (shown as the button text).
A dropdownlist of categories ('All' <--default , 'Location', 'Customer'...) gives the user the ability to target what subject of data they want to see. 'All' is the default, showing all details about the selected name.
So by default the 'All' template is populated.
If user wants to see the 'Location' details (template) they select it from the dropdownlist.
The template shows but the values are all blank. The only way to populate it is to click the name (button) again.
I want to remove the need for having to re-click the button (name) to populate the template ('Location', etc...).
I have put together a JSFiddle showing the structure. Though due to the data being private and served over secure network I cannot access it.
Refer to JSFiddle:
I believe the issue is that the onclick event grabs the data-uid and passes it to the initial default template (named 'All' but it's not included in code as it's lengthy). When the user changes the dropdownlist (cboDetailsCategory) and selects a new template I lose the data.
Thanks for your help. I'm really stuck on this and it's a current show stopper.
There isn't an officially supported way to change templates, without destroying the listview and rebuilding it. However, if you don't mind poking into into some private api stuff (be warned I can't guarantee that kendo won't break it without telling you) you can do this
var listview = $("#MyListview").getKendoListView();
listview.options.template = templateString;
listview.template = kendo.template(listview.options.template);
//you can change the listview.altTemplate the same way
listview.refresh(); //redraws the elements
if you want to protect against unknown API changes you can do this, which has A LOT more overhead, but no risk of uninformed change (untested!)
var listview = $("#MyListview").getKendoListView(),
options = listview.options;
options.dataSource = listview.dataSource;
listview.destroy();
$("#MyListview").kendoListView(options);
Here's the solution, thanks for everyone's help!
JSFiddle Link
The issue was where I was setting the bind:
$("#list").on("click", ".k-button", function (e) {
var uid = $(e.target).data("uid");
var item = dataSource.getByUid(uid);
var details = dropdown.value();
var template = $("#" + details).html();
$("#details").html(template);
kendo.bind($("#details"), item);
currentData = item;
});

Categories