I'm having trouble traversing a newly appended DOM element with jQuery - javascript

I have a form that I want to be used to add entries. Once an entry is added, the original form should be reset to prepare it for the next entry, and the saved form should be duplicated prior to resetting and appended onto a div for 'storedEntries.' This much is working (for the most part), but Im having trouble accessing the newly created form... I need to change the value attribute of the submit button from 'add' to 'edit' so properly communicate what clicking that button should do. heres my form:
<div class="newTruck">
<form id="addNewTruck" class='updateschedule' action="javascript:sub(sTime.value, eTime.value, lat.value, lng.value, street.value);">
<b style="color:green;">Opening at: </b>
<input id="sTime" name="sTime" title="Opening time" value="Click to set opening time" class="datetimepicker"/>
<b style="color:red;">Closing at: </b>
<input id="eTime" name= "eTime" title="Closing time" value="Click to set closing time" class="datetimepicker"/>
<label for='street'>Address</label>
<input type='text' name='street' id='street' class='text' autocomplete='off'/>
<input id='submit' class='submit' style="cursor: pointer; cursor: hand;" type="submit" value='Add new stop'/>
<div id='suggests' class='auto_complete' style='display:none'></div>
<input type='hidden' name='lat' id='lat'/>
<input type='hidden' name='lng' id='lng'/>
</form>
</div>
ive tried using a hundred different selectors with jquery to no avail... heres my script as it stands:
function cloneAndClear(){
var id = name+now;
$j("#addNewTruck").clone(true).attr("id",id).appendTo(".scheduledTrucks");
$j('#'+id).filter('#submit').attr('value', 'Edit');
$j("#addNewTruck")[0].reset();
createPickers();
}
the element is properly cloned and inserted into the div, but i cant find a way to access this element... the third line in the script never works.
Another problem i am having is that the 'values' in the cloned form revert back to the value in the source of the html rather than what the user inputs.
advice on how to solve either of these issues is greatly appreciated!

I think you want to use find not filter
$j('#'+id).find('#submit')
That should work in practice, though you've got problems there because there are multiple elements with the same id. I'd change your HTML to use classes, or in this specific case, you don't need either:
$j('#' + id).find(":submit")

have you tried using .val()? and instead of .filter(), use .find()
$j('#'+id).find(':submit').val('Edit');

nickf solution works. (just wrote a piece of code to check that). Do check the definition of filter in jquery documentation.
Reduce the set of matched elements to those that match the selector or pass the function's test.
You have use find in this case. Also as nick mentioned having multiple elements with same id is troublesome, especially when you are doing dom manipulation. Better go with appropriate classes.

Related

How can I use setAttribute on an input without an ID or class attribute?

I have a search input tag that is being added by a jQuery plug-in:
<input type="search" />
Note that this does not have an ID, CLASS, or NAME. I need the search input tag to look like this:
<input type="search" name="myname" />
A simple solution is for me to update the jQuery plug-in. However, I do not want to do this as it will cause challenges when I upgrade this plug-in in the future.
This JavaScript works properly and adds the name attribute:
$(document).ready(function() {
document.getElementsByTagName("input")[0].setAttribute("name", "myname");
});
The problem is that the "[0]" in this function relies on the search input being the first input field in the form. I do not think this solution is sustainable.
There are other inputs in the form. This is the only one with the type attribute equal to "search." Is there a way to identify it by this attribute? Or, is there another solution you propose?
Thank you for your time!
You can use the document.querySelector:
document.querySelector("input[type='search']")
Below is an example (you can inspect the output to see name attribute):
document.querySelector("input[type=search]").setAttribute("name", "myname");
<input type="search" value="foo" />
<input type="bar" value="bar" />
You can target a selection by anything. So, the selector input[type="search"]' will work.
If you want to apply this to all input's of type search, this is good enough, and you get all of them in here:
$('input[type="search"]')
This works without jQuery too:
document.querySelectorAll('input[type="search"]')
A more targeted approach would be
document.querySelectorAll('div.filter input[type="search"]')

Merging search terms from 2 separate input fields

So I have javascript code to prepend "tag:" or "vendor:" before every search term, but I wanted to hide that from the user, so I created a hidden input field to send the code but it's not properly prepending the "tag:" and "vendor:" before every word. and instead inputs the entire string, then the search terms.
<form method="get" action="/search" id="search-home">
<button type="submit" value="search"></button>
<input type="hidden" name="type" value="product" />
<input type="hidden" name="q" class="searchtext" />
<input type="text" name="red" placeholder="Search"/>
</form>
<script>
$(document).on('submit','#search-home',function(){
var searchtext = $('.searchtext').val();
$('.searchtext').val("tag:"+searchtext+"* OR vendor:"+searchtext+"*");
});
</script>
Here's what the Url looks like with the code
http://zzz.co/search?type=product&q=tag%3A+OR+vendor%3A&red=tote#fullscreen=true&search=home
Here's what it's supposed to look like.
http://zzz.co/search?type=product&q=tag%3Atote+OR+vendor%3Atote#fullscreen=true&search=home
You're getting an empty value and inserting it here:
$(document).on('submit','#search-home',function(){
var searchtext = $('.searchtext').val(); // <- HERE
$('.searchtext').val("tag:"+searchtext+"* OR vendor:"+searchtext+"*");
});
What you should be doing is getting the user given query, which is the input you named "red".
$(document).on('submit','#search-home',function(){
var searchtext = $('input[name="red"]').val();
$('.searchtext').val("tag:"+searchtext+"* OR vendor:"+searchtext+"*");
});
With the above fix, your URL will look similar to:
http://zzz.co/search?type=product&q=q=tag%3Atote+OR+vendor%3Atote&red=tote.
I do not know where you're getting your hashbang(#) from, but I would assume it will append at the end as before.
If you want to get rid of the red=tote part, you have a few options. Emptying the value via $('input[name="red"]').val(''); will make it appear in your url as red=. If you want it gone entirely, you should use $('input[name="red"].remove();.
I would also advise having your "on" hook attached to the form, not the entire document. This is just a good practice to avoid using unnecessary resources as this hook will bubble every time a form is submitted, regardless of the selector. Instead, consider:
$('form#search-home').on('submit', 'button[type="submit"]', function() { ... };
That way it will only bubble when a submit event happens on that specific form, greatly reducing the possible instances those resources are used.

Making jquery function to work across multiple forms. (Making Jquery DRY)

I've created a simple js function called from a button-onclick to do something straight forward, submit the data 'selected' and open a new tab. This was a single use case, worked fine for this one case. But NOW, as I'm scripting out more and more widgets within my feature, (tabs presenting different tools, within the same DOM). I'm finding way harder to keep the DRY.
I want to set up the forms to have same general inputs, get which form it is by the form id, serialize and let the controller deal with the rest. Knowing the form id will allow some exceptions to some forms, if needed. Each attempt has me banging my head on my desk.
Why are no forms being executed?
And if I get one form working, why isn't the other? [Similar code sample with '.change']
How do I get this ideal code to work across all the forms
OldCode:
JS
function doaction(){
alert("I work perfectly");
}
HTML
<form id='form_w'>
<input type='hidden' name="action" />
<input type='text' name="term"></input>
<input type='button' onclick="doaction()"/>
</form>
Ideal Code:
jQuery
//$('form.results').submit(function(e){ //DIDNT WORK
$('.rbutton').click(function(e){ // NOT WORKING EITHER
alert("This alert doesnt exist");
var form_id = e.target.id;
// gather data
// submit data via ajax
// update the dom by adding another tab/widget.
});
HTML
<form id='form_tab_id1' class="results">
<input type='hidden' name="A_action" />
<input type='text' name="term"></input>
<input type='button' class='rbutton'/>
</form>
<form id='form_tab_id2' class="results">
<input type='hidden' name="A_action" />
<input type='text' name="term"></input>
<input type='button' class='rbutton'/>
</form>
<form id='form_tab_id3' class="results">
<input type='hidden' name="B_action" />
<input type='text' name="term"></input>
<input type='button' class='rbutton'/>
</form>
Essentially, a user posted a solution. I am greatful he did. It pointed me in the right direction. [It was removed for whatever Reason that may be. But thanks George.]
His Solution was the following.
JQuery
$('.rbutton').click(function(){
var form = $(this).closest('form');
}
After juggling with so many variations, my code was drifting into an unstable code set. I honestly didn't know how to go about this; JQuery is prolly my sworn enemy. But knowing that the code George posted should be working, and wasn't, it kind of pointed me into other factors that I didn't consider. [I didn't take into consideration the code was being executed before the tabs with the '.rbutton' element were being populated.]
The Solution that helped me make this a more DRY principle was the following JQuery;
JQuery
$(document).on('click','.rbutton',function(){
var form = $(this).closest('form');
// Actions that are needed to be performed
}
Reason why this helps, or at least with my code, it binds this function to any element with the class '.rbutton' including new instances. As i mentioned above,these buttons were created after the jQuery was being executed; So nothing was being binded essentially. The following will do the binding to newly created elements, as if tho there was an active listener doing the additional binding over the document even after the code had been executed.

How to prevent checking checkbox when added dynamically to a div?

so I've been struggling with this issue.
I want to add a checkbox into a div dynamically by clicking a button. Let's say I already have 2 checkboxes in the div, then I uncheck those 2. When I click the button, the checkboxes become 3 (which is what I want), but all those 3 will be checked. What I want is when I add a checkbox, the other checkbox(s)' checked state remain the same as before.
Here is my code (http://jsfiddle.net/gr2o47wt/4/):
HTML:
<div id="chkbox_container">
<input type="checkbox" checked>Check<br />
</div>
<input type="button" value="Add CheckBox" onClick="addCheckBox();">
JavaScript:
function addCheckBox() {
txt = "<input type=\"checkbox\" checked>Check<br />";
document.getElementById('chkbox_container').innerHTML += txt;
}
Thanks in advance for your answers! :)
You can use insertAdjacentHTML() rather than manipulating the innerHTML:
<input type="button" value="Add CheckBox"
onClick="document.getElementById('chkbox_container').insertAdjacentHTML('beforeend','<input type=\'checkbox\' checked=\'checked\' />Check<br />');">
JS Fiddle demo.
The problem you had was that the original HTML (as returned by innerHTML) is from the source of the page, not the DOM; and therefore the checked/unchecked nature of the checkbox originally in place was restored.
insertAdjacentHTML() simply adds the HTML string in the specified place ('beforeend' in this case).
More or less as an aside, it's worth trying, where possible, to keep your event-handling outside of your HTML elements; and binding those event-handlers in the JavaScript itself. This makes for somewhat easier maintainability, and would lead to code like the following:
// note that I gave the button an 'id' for simplicity:
var button = document.getElementById('addCheckboxes');
button.addEventListener('click', function () {
document.getElementById('chkbox_container').insertAdjacentHTML('beforeend', '<input type=\'checkbox\' checked=\'checked\' />Check<br />');
});
JS Fiddle demo.
Finally, some of your HTML is invalid (or at least erroneous), an <input /> is a void element, it can have no descendants; therefore it either has no closing tag (just: <input>) or self-closes (<input />).
Further, the text beside the checkboxes is a little misleading, usually with an HTML form the text beside the <input /> will focus that input; that's achieved by using a <label> element to associate the text with the control, for example:
<label><input type="checkbox" /> click</label>
JS Fiddle demo.
Or:
<input type="checkbox" id="inputElementID" />
<label for="inputElementID">click</label>
But this latter form does require the dynamic generation of ids (which is a little beyond the scope of this question).
References:
insertAdjacentHTML().

Javascript get values of multiple text fields

I have a dynamic web page where the content may contain between 1 and 10 links, provided in text boxes, similar to the following:
<input size="50" id="link" value="http://Something.Something" type="text">
<input size="50" id="link" value="http://SomethingElse.Something" type="text">
I need javascript to be able to read all of the links, and be able to manipulate the data (store in array, output to screen, etc)
I know that I can read a single id using the following
var link = document.getElementById('link');
Which will return the first match - but, how can I do a loop or obtain all the values for all the links, bearing in mind that the number of links cannot be determined beforehand?
P.S. I have tried using getElementsByTagName('input') but there are more inputs on the page, which means it's getting more results than I'd like it to get.
You can make them all have names and search by name.
<input name="vrow" value="0" type="text"/>
<input name="vrow" value="0" type="text"/>
<input name="vrow" value="0" type="text"/>
<input name="vrow" value="0" type="text"/>
Then you can get it with:
var vrows = document.getElementsByName("vrow");
alert(vrows.length);
Give them all a common class and access using document.getElementsByClassName('class').
IDs should be unique for each element. You could use document.getElementsByClassName or document.querySelectorAll(".class"); and then use the class name (assuming relatively modern browser). Or use document.getElementsByTagName() and then iterate through the elements comparing with the class.
Attach a jQuery lib and you will be able to do something like:
$('input[type=text]').each(function(i, val){
alert($(this).val());
});

Categories