Referencing input in specific form - javascript

I'm catching data-async of form created using twitter bootstrap in following manner:
$('form[data-async]').live('submit', function(event) {
var $form = $(this);
var $target = $($form.attr('data-target'));
var target_id = $target[0].id;
....
}
I'd like to reference input with name "username" in the form in question... I tried $form.username, $form['username'], but to no avail, and I couldn't find how to get the input. I know I can use
$('#formid input[name=bla]')
but since I've already got form object, I'd like to use that if possible.
Thanks

You can use .find():
var $input = $form.find('input[name=bla]');
edit — commenter Jack points out that there's also the HTML5 "elements" property of the form DOM element. That lets you get to inputs by name or id, or by numeric index.
var input = this.elements['bla'];
Access by name is complicated by the fact that the mechanism also considers element "id" properties (in fact those take precedence, I think).

Inside your submit handler, the username input field can be referenced simply by:
this.elements['username']
No need for fancy jQuery :)
Update
Didn't realize elements is a fairly recent addition. Before that you could use:
this.username
Update 2
A shimmed version would look like this:
var field = this.elements ? this.elements['username'] : this.username;

You can use the form object as context with selector to find the elements within context.
Syntax: jQuery( selector [ , context ] )
$('input[name=bla]', $form );
You can use this as it represents your form.
$('form[data-async]').live('submit', function(event) {
$('input[name=bla]', this ); // this is your form
})

Related

problem with use of val() in jQuery sometimes failing and setting elements with array id's

I have a project where a form is required for inputs for a week, so for efficiency elsewhere an array of inputs is used (i.e. start[0] etc) this seems to have exacerbated the issue.
The problem is when validating a form where some inputs are given initial values (its an update) jQuery only returns those initial values instead of changed ones unless use of 'this' is feasible. I found to resolve that I had to use:
$(".weekdays").change(function(){
var newval = $(this).attr('value');
$(this).attr('value', newval);
});
Which seems a crazy thing to have to do! Its here I found using $(this).val(newval); always fails except when setting initial values, though its the common given solution?
In the same vein setting check-boxes seems also problematical, using:
var id = $(this).attr('pid');
$("#choice["+id+"]").prop('checked', false);
$("#choiceLabel["+id+"]").css('background-image','url("images/Open.png")');
Always fails, yet reverting to javascript with:
var id = $(this).attr('pid');
document.getElementById("choice["+id+"]").checked = false;
document.getElementById("choiceLabel["+id+"]").style.backgroundImage = 'url("images/Open.png")';
Works fine!
So does jQuery not like inputs with id's in array form? or am I getting things wrong somewhere?
When attempting to select an element with an id that contains special characters, such as [], you have to remember to escape them for jQuery. For instance..
var id = 12;
console.log(
$('#choice\\['+ id +'\\]').get()
);
console.log(
$('#choice[data-something]').get()
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="choice[12]">weee</div>
<div id="choice" data-something>dang!</div>
Otherwise, jQuery will treat them as special characters, in this case, assuming you are trying to find an element that has an id and has an attribute matching your variable value.

Dynamically assign properties to a JS object

I needed to dynamically add properties to an js Object, which I achieved via eval():
$ ->
#Methods
window.add_address = (attributes, id=new Date().getTime())->
$container = $('ul#addresses_list')
$unit = $('<li>')
$.each attributes, (key,value)->
$input = $('<input type="hidden">')
$input.attr 'name', "contact[addresses_attributes][#{id}][#{key}]"
$input.val value
$unit.append $input
$container.append $unit
#Events
#Add address button
$('a#add_address').on 'click', (ev)->
attributes = new Object
$('#address_fields').find('input').each ->
eval("attributes.#{$(this).attr 'id'}='#{$(this).val()}'");
add_address attributes
This works perfect but I feel awkward with the eval(), is there anyway to do this "prettier"? I mean, I searched for alternatives like the Jquery .serializeArray() but it seems to work only with a queried form and I need to get the inputs from that #address_fields div.
Use object['key'] notation
attributes[$(this).attr('id')] = $(this).val();
It's also very efficient to create object using:
var attributes={};
EDIT: Along similar lines can write the jquery methods in same notation
attributes[$(this)['attr']('id')] = $(this)['val']();

How can I make a request to all elements inside a form?

I have a form, with many elements (inputs, selections, checkboxes etc..). How can I apply an action to all elements inside the form without explicitly doing it per element?
Here is my code (in Selenium IDE):
storeEval |
window.document.getElementsByTagName('form')[0].id = 'myForm';
window.document.defaultView.getComputedStyle(window.document.myForm.getElementsByTagName('*')).getPropertyValue('background-color');
| result
I get an error: [error] Threw an exception: document.myForm is undefined
I tried to do this:
storeEval |
window.document.getElementsByTagName('form')[0].id = 'myForm';
window.document.defaultView.getComputedStyle(window.document.getElementById('myForm')).getPropertyValue('background-color');
It works correctly.
When I try to do this:
var myForm = document.getElementsByTagName('form')[0];
var children = myForm.childNodes;
I get an error: [error] Threw an exception: document.myForm is undefined
Try this:
Command: storeEval
Target : myForm = selenium.browserbot.getCurrentWindow().document.getElementsByTagName("form")[0].childNodes; var colors = new Array(); for (i=0; i < myForm.length; i++) { colors[i] = window.document.defaultView.getComputedStyle(myForm[i]).getPropertyValue('background-color')}; colors.join()
Value : result
JavaScript snippet selenium.browserbot.getCurrentWindow() gets the window of your application.
First of all, you need to set an id attribute to your form tag, so you can easily identify it with JavaScript.
For example, if your form id is myForm, you could do this
var children = document.myForm.childNodes;
// or
var children = document.myForm.getElementsByTagName('*');
The first returns the list of direct descendants, while the second returns a list of all descendants.
EDIT: You can identify a form in many other ways than by id, but it could become hard. Try with document.getElementsByTagName('form'). This works well especially if you have only one form in your page.
I'm not sure why would you want to do that, but in order to refer all children tags inside the form tag, you may try the following:
#my_form * {
color: #369
}
Yet if you'd like to only refer form-specific elements there's not that much of them, so you just specify them in a row:
#my_form select, #my_form input, #my_form label, #my_form button {
color: #369
}
Edit. If you want to refer all elements inside a form via javascript, and you're using jQuery framework (which I'd highly recommend), you may just use the same selectors:
$('#my_form *').css( ... )
$('#my_form select, #my_form input, #my_form label, #my_form button').css( ... )

How can I store a value (string) in a web page

I would like to store the value of something on my web page for later use by
some javascript functions. I thought of doing something like this where I have
a div with an id of CategoryID and then put the value in that as HTML.
<div id="CategoryID"></div>
$('#categories > li > a').click(function (e) {
e.preventDefault();
$('#CategoryID').html = $(this).attr('data-value')
refreshGrid('Reference');
});
Then later inside functions such as refreshGrid (and some other functions), I could get the value like this:
var categoryID = $('#CategoryID').val();
Does this seem like a good way to store a temporary variable? How about with
HTML5, is there some way to store values without having to put them inside a
div or something like that. All I need is to have a value that is stored in some
way on the page.
One more question. If I store the value is this the correct way to do it:
$('#CategoryID').html = $(this).attr('data-value')
Please use HiddenField for storing variable using jquery just like this:
var tempvalue= $(this).attr('data-value');
$('#my-hidden-field').val(tempvalue);
Hope this is helpful for you.
Use hidden fields on your web-page. For instance.
<INPUT TYPE=HIDDEN NAME="customerId" VALUE="1234567">
And then use .val in JQuery to work with these values.
I'm sometimes using hidden inputs for this purpose depending on the specific case.
<input type="hidden" name="CategoryID" id="CategoryID" />
Then retrieve it just like this:
var categoryID = $('#CategoryID').val();
I use inputs since i feel html which isn't markup for the page shouldn't be there.
Sometimes the easiest thing is to just output the variable from the server into script.
Example with ASP.NET:
<script type="text/javascript">
//<!--
var categoryID = <%= <output value from server goes here> %>;
//-->
</script>
You should try using the localStorage API introduced in HTML5 if you're keen on that otherwise storing it in hidden fields are the way to go.
var idForStorage = $('#CategoryID').val();
window.localStorage.setItem('keyToId', idForStorage);
and to fetch it from localStorage
var fetchedId = window.localStorage.getItem('keyToId');
Note: the localstorage only stores values as Strings, remember that! :)
Also, if you want to be older browser compliant, don't forget to check if localStorage exists and implement a different solution.
Something along the lines of
if(typeof(window.localStorage) !== 'undefined'){
//set item or do whatever
} else {
//implement other solution or throw an exception
}
Good luck!
Just a thought but have you considered storing the value in a javascript variable? If you are only using it in javascript why bother putting it in a hidden field or an element at all?
Just declare you variable in the global scope if your not using namespacing/modules but if you are you can store it in the scope of the module that uses it.
Only considerations with this approach is the variable will be reset on page refresh but if you arnt using the value on the server, just in script then that should be ok.
In general I'd only use a hidden input if the server needed to be able to read it.
EDIT
In reposone to the comments, if you are using your javascript sensibly which includes the use of namespaceing then this approach works with a certain amount of elegance over cluttering up your markup with "variable holders"
A very quick scaffold for namespacing.....
in a file called MyProject.Global.js
//This function is truly global
function namespace(namespaceString) {
var parts = namespaceString.split('.'),
parent = window,
currentPart = '';
for (var i = 0, length = parts.length; i < length; i++) {
currentPart = parts[i];
parent[currentPart] = parent[currentPart] || {};
parent = parent[currentPart];
}
return parent;
}
in a file called MyProject.MyPage.Ui.js
namespace('MyProject.MyPage');
MyProject.MyPage.Ui = function () {
var self = this;
self.settings = {};
function init(options) {
$.extend(self.settings, options);
//any init code goes here, eg bind elements
setValue();
};
};
//this is considered a "private" function
function setValue(){
$('#categories > li > a').click(function (e) {
e.preventDefault();
self.settings.myValue = $(this).attr('data-value');
refreshGrid('Reference');
});
}
function getValue(){
return self.settings.myValue;
}
//any function within this return are considered "public"
return {
init: init,
getValue: getValue
};
};
finally in your page...
$(document).ready(function () {
var ui = new MyProject.MyPage.Ui();
ui.init();
}
then at any point you can get hold of your value using...
MyProject.MyPage.getValue()
The function val() gets the value of an element. But only inputs have values, therefore you should use a hidden input to store the data:
<input id="CategoryId" type="hidden" />
But generelly you can access any attribute as described below. Just be aware that attr() is old and the new function name is prop() -> see Comment for correct explanation regarding attr() and prop()
One more question. If I store the value is this the correct way to do it:
The easier way to use Data- attributes with jQuery is to use the .data() method.
<body id="CategoryData" data-value1="someone" data-value2="sometwo">
....
alert( $("#CategoryData").data('value1') ); // popup with text: someone
alert( $("#CategoryData").data('value2') ); // popup with text: sometwo
Personally, I would rather store all the data associated with items in a wrapper Div or other elements and use jquery.data.
<table data-locationid="1">
<tr data-personid="1">
<td>Jon</td>
<td>Doe</td>
</tr>
<tr data-personid="2">
<td>Jane</td>
<td>Doe</td>
</tr>
</table>
HTML5 data-* Attributes
As of jQuery 1.4.3 HTML 5 data- attributes will be automatically pulled in to jQuery's data object. The treatment of attributes with embedded dashes was changed in jQuery 1.6 to conform to the W3C HTML5 specification.
For browser compatibility, its wiser to use hidden field as suggested by others. But for exploratory reasons, if you would like to use HTML5 it offers WebStorage. For more information please look at http://sixrevisions.com/html/introduction-web-storage/
Also, there is a framework called Lawnchair the offers solution for html5 mobile apps that need a lightweight, adaptive, simple and elegant persistence solution.
There are three ways to store the values as you wish:
Cookies: the good old way. It is supported everywhere but is more suited for values that need to be kept over different pages and it has other limits (such as size, number of entries, etc).
SessionStorage: not supported everywhere, but there are shims. It allows you to store a value that will last for a session only. Example:
sessionStorage.setItem('key', 'value')
sessionStorage.getItem('key', 'value')
This accepts strings only as keys and values. If you want to store objects, you can use JSON.stringify to store them, and retrieve them later with JSON.parse.
LocalStorage: the brother of sessionStorage, but it has no time limit. It allows you to store datas with the same API as sessionStorage and it's kept over time.
If you want to store the value in one part of your JavaScript for access from another part I'd just use a variable:
var categoryID = null; // set some kind of default
$('#categories > li > a').click(function (e) {
e.preventDefault();
categoryID = $(this).attr('data-value');
refreshGrid('Reference');
});
Then later when you need the value just access categoryID directly.
One more question. If I store the value is this the correct way to do it
If you did want to set the value as the content of your div element you'd use jQuery's .html() method or the non-jQuery .innerHTML property:
$('#CategoryID').html( $(this).attr('data-value') );
// or
$("#CategoryID")[0].innerHTML = $(this).attr('data-value');
But if you don't want to use a variable you'd be better off using a hidden input as mentioned in other answers rather than a div.

How can I dynamically construct a document element string using a variable in Javascript?

This is driving me nuts, and I'm sure it's both possible and surely simple to do.
I have a page with a whole bunch of dynamically created forms on it. In one of my functions, I need to access one of those forms, so I pass the name of the form in a variable.
Then I need to access the name of that form using the document tree.
However, when I put in the variable, it assumes the name of the variable is the name of the form.
So this does not work:
function myAwesomeFunction(nameOfForm)
{
var selection = document.nameOfForm.nameOfInput.selectedIndex;
}
So I looked around the net and saw that I need to use bracket notation, but this doesn't work either:
function myAwesomeFunction(nameOfForm)
{
var selection = document[nameOfForm].nameOfInput.selectedIndex;
}
I also tried with some quotation action:
function myAwesomeFunction(nameOfForm)
{
var selection = document['nameOfForm'].nameOfInput.selectedIndex;
}
... but no joy.
So, where am I going wrong?
For bonus points... what if both the name of the form and the name of the particular input were both dynamic? Then what?
function myAwesomeFunction(nameOfForm, nameOfInput)
{
var selection = document[nameOfForm][nameOfInput].selectedIndex;
}
Look them up in the forms object - this won't work since it is an array and not an object.
use document.getElementsByName
function myAwesomeFunction(nameOfForm, nameOfInput)
{
var selection = document.getElementsByName(nameOfForm)[nameOfInput].selectedIndex;
}
or even better, set an id attribuite on the form and use document.getElementById to find the form
Try using document.getElementById(nameOfForm) (if you have the ID on the form as well)...
If you can include a jQuery reference to your page, you can easily do the following (again assuming you have the ID on the form):
function myAwesomeFunction(nameOfForm, nameOfInput)
{
var form = $("form#" + nameOfForm);
var input = $("#" + nameOfInput + ":input");
var selection = $(input).val();
}
function focusElement(formName, elemName) {
var elem = document.forms[formName].elements[elemName];
}
try this
formname is name of the form and elemname is input label name

Categories