Am unable to add elements to a dropdown list via Javascript.
The below piece of code works in IE and Chrome, but not in firefox.
ddlId.add(new Option("",0));
In firefox, I keep getting an 'Not enough arguments' exception. Any idea on how to resolve it? Thanks
try {
ddlId.add(new Option("",0), null); // standards compliant; doesn't work in IE
} catch(ex) {
ddlId.add(new Option("",0)); // IE only
}
Hm. The idea is, roughly, to go to the Mozilla Developer Center page for select.add() and have a look at the method signature ;-)
Syntax
select.add(newOption, existingOption);
Parameters
newOption An HTMLOptionElement to add to the options collection.
existingOption An existing HTMLOptionElement within the
collection used as a reference point
for inserting the new element; the new
element being inserted before the
referenced element in the collection.
If this parameter is null, the new
element is appended to the end of the
collection.
var opt = document.createElement("option");
var ddlPopulate=document.getElementById("<%=ddlPopulate.ClientId %>");
opt.text="firstElement";
opt.value="1";
ddlPopulate.options.add (opt);
The select element has as its children an options array. You add or remove options as you would using standard array methods.
Related
I have a table in which I want to extract the text of the active item. I do this with the following code:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active");
console.log(addedWorkout);
addedWorkout = addedWorkout.textContent;
console.log(addedWorkout);
The problem is that I keep getting undefined. I checked the console and it indeed finds the element I want without fail.
I am relatively new to Javascript, but after over an hour of Googling I could not find the issue and I don't understand why. I know that I can get the text element if I hardcore it using the following line:
document.querySelector("#selectiona1").textContent
but not with:
$("#selectiona1").textContent
What is the difference between these 2? I read that textContent is part of the DOM, to my understanding it relates to objects and according to my console i think it is an object. I made some crazy attempts like putting the object I got into the querySelector, but nothing works.
With this line:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active");
you're using jQuery to select the .dropdown-item.active inside #custDropDownMenuA, and when you select with jQuery, you get a jQuery object in response. So, addedWorkout is a jQuery object, and jQuery objects generally do not have the same properties/methods as standard HTMLElements. (querySelector is the vanilla Javascript method to retrieve an element)
Either select the [0]th item in the jQuery collection to get to the first matching element:
var addedWorkout = $("#custDropDownMenuA").find(".dropdown-item.active")[0];
Or use the jQuery method to get the text of the first matching element, which is .text():
var addedWorkoutText = addedWorkout.text();
(note the use of a new variable - you will likely find it easier to read and debug code when you create new variables rather than reassigning old ones, when possible)
Your var 'addedWorkout' is a Jquery object, not a html element.
To show the text use:
addedWorkout.text();
Alternatively, you can change the 'addedWorkout' to a html element by adding the index [0], like this:
addedWorkout[0].textContent;
EDIT:
JSFIDDLE here. I am trying to mirror DESKTOP 1 to MOBILE 1 elements (same for #2) in the fiddle. The error is shown in console.
Got to DESKTOP 1 and select NEW RATE from the list. Have the console opened to see the issue. Thanks!
I get an element from my layout with this command:
var eqTaxSelect = $('table#mob-tab-' + num).find('select.tax_rate').get();
I then try to toggle it:
toggleField($(eqTaxSelect), $(eqTaxSelect).nextElementSibling); <-- FAILS
function toggleField(hideObj, showObj) {
hideObj.style.display = 'none'; <-- FAILS HERE
showObj.style.display = 'inline';
showObj.focus();
}
with:
Uncaught TypeError: Cannot set property 'nextElementSibling' of undefined
What am I doing wrong when assigning the element to my variable? This function works for this inside click event listeners for example.
Thanks!
The HTML I am toggling came from this forum, essentially a select with a hidden input so new entries can be added as well as using an entry from the options list.
What am I doing wrong when assigning the element to my variable?
You are passing jQuery() objects, where toggleField expects DOM elements. jQuery() does not have a .nextElementSibling method. Remove calls to jQuery() at
toggleField($(eqTaxSelect), $(eqTaxSelect).nextElementSibling);
replace with
toggleField(eqTaxSelect, eqTaxSelect.nextElementSibling);
to pass DOM elements to toggleField.
test with
console.log(eqTaxSelect)
see on inspector (CTRL+SHIF+I CHROME). if this is ok,
just do this
toggleField(eqTaxSelect, eqTaxSelect.nextElementSibling)
withouth "$"
The reason why your statement
toggleField(eqTaxSelect, eqTaxSelect.nextElementSibling);
fails is because of the way you are populating the eqTaxSelect
var eqTaxSelect = $('table#mob-tab-' + num).find('select.tax_rate').get();
It should be modified as
var eqTaxSelect = $('table#mob-tab-' + num).find('select.tax_rate').get(0);
reason being, get() without an index returns an array and the way you are operating, you are expecting an single dom element.
jQuery documentation for get()
This is my code.
var arrSelectElements = document.getElementsByTagName( "SELECT" );
for (var i = 0; i < arrSelectElements.length; i++) {
alert(arrSelectElements[i].DataSource); //code to use datasource value
}
It simply gets a list of all select elements in aspx file, and finds out the datasource name. Here is the code that binds the dropdown in C# file.
ddlSubsidiary.Attributes.Add("DataSource", "Subsidiary");
ddlSubsidiary.Attributes.Add("DataMember", "DISubsidiary");
Now, this code in IE works perfect. alert returns the name properly. But in Chrome, it always returns undefined.
Is it by design or am I missing something here?
In order to get the attribute value with the DOM element property in Internet Explorer, you have to use IE8 or older, or to run in compatibility mode (equivalent to IE7). In these old versions, the custom attributes can be retrieved in client code using the expando property with the same name:
var dataSource = ctl.DataSource;
var dataMember = ctl.DataMember;
From what I have read, this technique worked only in Internet Explorer, not in other browsers (HTML Custom Attributes Not Working in Chrome).
Since version 9, it doesn't work in Internet Explorer either. The getAttribute method must be used to get the attribute value in client code:
var dataSource = ctl.getAttribute('DataSource');
var dataMember = ctl.getAttribute('DataMember');
It is hard to say why IE6+ browser returns undefined, but my guess is that the checking event gets executed before the assignment event actually occurred. Quirk mode only uses 1 thread for everything while newer browser uses separate thread for DOM manipulation and render.
javascript with>
var customer=document.getElementById('custList').value;
and that works...
Why does it work BUT...
var customer=(form1.custList.value);
I get an error that form1 is not defined.
Especially why would this work in IE, and Chrome but not Firefox.
It seems just as clearly stated to me, but I am not a script engine
Just trying to understand
if you want to refer to a form object in your page, you may use the 'document.forms' object, that is an array of form objects in the document. suppose we have a form like this:
<form method="post" action="somthing.php" name="myContactForm" id="contact_form">
<input type="text" name="custList" id="custListId" />
</form>
to access the value in a correct way, you might use any of these methods:
first acccess the form, then the element.
var form = document.forms['myContactForm']; // use the 'name' attribute as the array key
// or if this is the first form appeared in the page. otherwise increase the index number to match the position of your target form.
var form = document.forms[0];
// or access the form directly
var form = document.getElementById('contact_form');
// now get the element, from the form. you can access form elements, by using their name attribute as the key in the elemetns array property of the form object.
var cust = form.elements['custList'].value();
or you can access a form element directly, without any form. you can refer any element in the document by its id, directly. no form is needed here.
var cust = document.getElementById('custListId');
all these statements are valid JavaScript that run on IE, firefox, opera, chrome, etc.
however you can refer to a form object in IE, by just calling its 'name' attribute. so this line works in IE (and as you are saying, chrome. I did not know that chrome handles it):
var cust = myContactForm.custList.value();
IE tries to map unknown window level properties (like myContactForm ) to elements by matching to their 'name' attribute.
I believe IE/Chrome/Opera incorrectly interpret id="form1" as name="form1" ( or vice versa? ) to account for legacy markup.
I would not rely on dom 0 level property accessing such as form1.custList and instead use document.getElementById. If it's too long to type, define a method to do it.. eg
function getId( id ) { return document.getElementById(id) }
Because the second idiom is not standard, while getElementById is, so it has to be supported by every browser to say that is javascript compatible.
Also, the second one should be, if I'm not mistaken, document.form1.custList.value.
Internet Explorer did a lot of things in it's own way. By all means, the first way is the correct way (using getElementById).
For backward compatibility many of these "bugs" still work, but you should not use them.
There are still differences between browsers. Using a JavaScript framework (like jQuery) helps a lot here, it is written to work well cross-browser (for the record, your code will be $('#custList').val(); using jQuery)
Internet Explorer stuffs all of your form elements by name into the window object as properties, which is fragile, incompatible, difficult to use with any finesse -- and what makes your second example work. Other browsers simply take the clean route of not implementing that interface at all, leaving you with the proper DOM functions. Or a toolkit. jQuery really is quite nice. ;)
I have an ext combobox which uses a store to suggest values to a user as they type.
An example of which can be found here: combobox example
Is there a way of making it so the suggested text list is rendered to an element in the DOM. Please note I do not mean the "applyTo" config option, as this would render the whole control, including the textbox to the DOM element.
You can use plugin for this, since you can call or even override private methods from within the plugin:
var suggested_text_plugin = {
init: function(o) {
o.onTypeAhead = function() {
// Original code from the sources goes here:
if(this.store.getCount() > 0){
var r = this.store.getAt(0);
var newValue = r.data[this.displayField];
var len = newValue.length;
var selStart = this.getRawValue().length;
if(selStart != len){
this.setRawValue(newValue);
this.selectText(selStart, newValue.length);
}
}
// Your code to display newValue in DOM
......myDom.getEl().update(newValue);
};
}
};
// in combobox code:
var cb = new Ext.form.ComboBox({
....
plugins: suggested_text_plugin,
....
});
I think it's even possible to create a whole chain of methods, calling original method before or after yours, but I haven't tried this yet.
Also, please don't push me hard for using non-standard plugin definition and invocation methodics (undocumented). It's just my way of seeing things.
EDIT:
I think the method chain could be implemented something like that (untested):
....
o.origTypeAhead = new Function(this.onTypeAhead.toSource());
// or just
o.origTypeAhead = this.onTypeAhead;
....
o.onTypeAhead = function() {
// Call original
this.origTypeAhead();
// Display value into your DOM element
...myDom....
};
#qui
Another thing to consider is that initList is not part of the API. That method could disappear or the behavior could change significantly in future releases of Ext. If you never plan on upgrading, then you don't need to worry.
So clarify, you want the selected text to render somewhere besides directly below the text input. Correct?
ComboBox is just a composite of Ext.DataView, a text input, and an optional trigger button. There isn't an official option for what you want and hacking it to make it do what you want would be really painful. So, the easiest course of action (other than finding and using some other library with a component that does exactly what you want) is to build your own with the components above:
Create a text box. You can use an Ext.form.TextField if you want, and observe the keyup event.
Create a DataView bound to your store, rendering to whatever DOM element you want. Depending on what you want, listen to the 'selectionchange' event and take whatever action you need to in response to the selection. e.g., setValue on an Ext.form.Hidden (or plain HTML input type="hidden" element).
In your keyup event listener, call the store's filter method (see doc), passing the field name and the value from the text field. e.g., store.filter('name',new RegEx(value+'.*'))
It's a little more work, but it's a lot shorter than writing your own component from scratch or hacking the ComboBox to behave like you want.
#Thevs
I think you were on the right track.
What I did was override the initList method of Combobox.
Ext.override(Ext.form.ComboBox, {
initList : function(){
If you look at the code you can see the bit where it renders the list of suggestions to a dataview. So just set the apply to the dom element you want:
this.view = new Ext.DataView({
//applyTo: this.innerList,
applyTo: "contentbox",
#qui
Ok. I thought you want an extra DOM field (in addition to existing combo field).
But your solution would override a method in the ComboBox class, isn't it? That would lead to all your combo-boxes would render to the same DOM. Using a plugin would override only one particular instance.