PDA

View Full Version : JQuery val/text equivalent



lysy
6 Oct 2009, 2:57 PM
Hi!

I'm looking for an JQuery equivalent of:

$('input:first').val() // getting value from selected element
$('#photos').text() // getting text from selected element

I walk trough Ext Core Manual but probably I miss this information:)

Please excuse my poor English.
Best regards,
Ɓukasz

Animal
6 Oct 2009, 9:34 PM
Anything wrong with using DOM methods directly?

lysy
7 Oct 2009, 12:56 AM
DOM methods are fine for me. I'm just starting to learn Ext and because I'm familiar only with JQuery I was trying to find something similar. So, for input elements setting/getting value should be done with:

Ext.fly('myinput').dom.value
Ext.fly('myinput').dom.value = 'xxxxx'

But what about text nodes? In DOM tree I found two properties:

Ext.fly('foo').dom.innerHTML
Ext.fly('foo').dom.textContent

and both works for me (setting & getting). Is there any difference between those two?

Thanks for your hint with DOM methods!

Animal
7 Oct 2009, 2:17 AM
As a web developer, you should be intimately familiar with the standards to which the Ecmascript (Javascript) DOM implementations aspire: http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html

jQuery brings down the level of expertise required. Resig may think that's a good thing. I think it's a bad thing. People need to serve their apprenticeship and learn the true structure of a web application, and its interactions with the DOM. That document should be your first point of reference at all times, before a jQuery book.

There are subtle differences between the two approaches you give.

innerHTML returns the HTML code within an Element.

textContent (which is non-standard BTW) returns the data values of all the text nodes within that element (See the above document's "Object CharacterData" section)

If it is just a single text node that you have, then treat it as a CharacterData object, and use the appropriate standards-based property.

Condor
7 Oct 2009, 2:32 AM
But what about text nodes? In DOM tree I found two properties:

Ext.fly('foo').dom.innerHTML
Ext.fly('foo').dom.textContent

and both works for me (setting & getting). Is there any difference between those two?

In HTML documents there is no difference (use of innerHTML is preferred), but in XML documents some browsers use textContent and some innerText. So, for XML nodes you should use:

var value = node.textContent || node.innerText;

Animal
7 Oct 2009, 2:37 AM
Here's some extensions to Ext core's CompositeElement class (which is what encapsulates selected elements)



Ext.override(Ext.CompositeElementLite, (function(){

var selType = /select-(one|multiple)/i,
trailSpace = /\s*$/;

function getInputValue(el) {
var i, l, e, one, v, result, st;

if (el.tagName == 'OPTION') {
return (el.attributes.value || {}).specified ? el.value : el.text;
}
if(st = selType.exec(el.type)){
if (st[1] == 'one') {
for (i = 0, l = el.options.length; i < l; i++) {
if ((e = el.options[i]).selected) {
return getInputValue(e);
}
}
} else {
return new Ext.CompositeElementLite(el.options).val();
}
}
return el.value;
}

function getTextValue(el) {
return (el.nodeType == 3)
? el.data.replace(trailSpace, '')
: new Ext.CompositeElementLite(el.childNodes).text();
}

function setTextValue(el, t) {
while (el.hasChildNodes()) {
el.removeChild(el.lastChild);
}
el.appendChild(el.ownerDocument.createTextNode(t));
}

return {
// need this until next release - pulled in from full Ext
fill : function(els){
var me = this;

// Keep reference to last version of self before refill
me.prevObject = new me.constructor(me.elements);

me.elements = [];
me.add(els);
return me;
},

val: function() {
var me = this, i, l = me.elements.length, result;
if (l == 1) {
return getInputValue(me.elements[0]);
}
for (result = [], i = 0; i < l; i++) {
result.push(getInputValue(me.elements[i]));
}
return result;
},

text: function(t) {
var me = this, i, l = me.elements.length, v, el, result;
if (l == 1) {
el = me.elements[0];
if (t !== undefined) setTextValue(el, t);
return getTextValue(el);
}
for (result = [], i = 0; i < l; i++) {
el = me.elements[i];
if (t !== undefined) setTextValue(el, t);
if (v = getTextValue(el)) {
result.push(v);
}
}
return result.join(' ');
},

nextAll: function() {
var els = this.elements, i, l = els.length, n, r = [], ri = -1;
for (i = 0; i < l; i++) {
for (n = els[i].nextSibling; n; n = n.nextSibling) {
r[++ri] = n;
}
}
this.fill(r);
return this;
},

andSelf: function() {
if (this.prevObject) {
this.add(this.prevObject.elements); // add takes an Array. Should it take another Composite???
}
return this;
}
};
})());


So you can do eg:



Ext.getBody().select("input").val()


As with all free code YMMV, not forgetting TANSTAAFL.

mscalora
8 May 2012, 2:08 PM
Is there any reason to prefer




function setTextValue(el, t) {
while (el.hasChildNodes()) {
el.removeChild(el.lastChild);
}
el.appendChild(el.ownerDocument.createTextNode(t));
}

over




function setTextValue(el, t) {
el.innerHTML = Ext.String.htmlEncode(t);
}

which looks a lot cleaner but I suspect Ext.String.htmlEncode is implemented something like:




function encodeHtml(t) {
var el = document.createElement("span");
el.appendChild(document.createTextNode(t));
return el.innerHTML;
}

so how about:




function setTextValue(el, t) {
el.innerHTML = "";
el.appendChild(el.ownerDocument.createTextNode(t));
}
and let the loop happen in native code.

-Mike