I have a while loop in my php page which sets a different id for every button and form through a counter variable. Every button has to open a different form (they each have different default information preselected, this is for a prescription renewal ability). I can get this to work by having in my javascript a click function for every id which calls a show on the right form. But, obviously this is not scalable, and so it cannot adapt to the amount of prescriptions I have. Looking through the web, I saw people using classes and the id starts with solutions to this problem. However, when I use this solution, the buttons open all the forms... not the desired behavior. Currently my javascript function is the following:
$('[id^="add-renew-link"]').click(function () {
$('[id^="add-renew-form"]').show();
});
Like mentioned above, the function does get called by all different IDs button. That code however opens all the forms every time one of the buttons get click. IDs are actually of the form add-renew-form0, add-renew-form1, add-renew-form2... (same pattern for add-renew-link). Forms and links with the same number at the end are meant to be linked. Does anybody know how I can achieve this? Thanks a lot!!
You can't have multiple DOM elements with the same ID. What you can do here is to assign classes for the elements:
<div class="add-renew-link"></div> <div class="add-renew-form"></div>
And then use .each
$('.add-renew-link').each( function(x){
$(this).click(function(){
$(".add-renew-form:eq("+x+")").show();
});
});
You can check out the JSFiddle here.
You're close. The $('[id^="add-renew-form"]').show(); is going to match ALL ELEMENTS that start w/ "add-renew-form" as the id, so that's why you're experiencing all forms being shown when clicking any link/button.
You can use a regex to pull the number from the end of the id to find a match on the associated form as below:
$('a[id^="add-renew-link"]').click(function() {
var idx = $(this).attr("id").match(/\d+$/)[0]; // Pull index number from id
$("#add-renew-form" + idx).show();
});
This jsbin has a full working example.
http://jsbin.com/xicuwi/1/edit
Try, using the .each() method:
$('[id^="add-renew-link"]').each(function(i){
var ths = $(this);
(function(i){
ths.click(function(){
$('#add-renew-form'+i).show();
}
})(i);
});
Related
I am working on one table, where I have created one button which I am using in different rows and tables based on some condition.
I have one scenario where I need to show the button to some specific users, I have implemented the condition however I am not able get the path of the button, I can hide the cell but in that case complete cell is removed from the table which is not looking good, please help me to get the path of the button, so that I can hide it, here is the code I am using:
totalrows = document.getElementById("DEVmyTable").rows.length;
for(i = 0;i<totalrows; i++){
if(actualusernamevalue == currentusernamevalue){
table.rows[i].cells[6].style.display = "";
}
if(actualusernamevalue != currentusernamevalue){
table.rows[i].cells[6].style.display = "none";
}
}
Here in Cells[6] my button is present which I am created dynamically like this:
row = document.getElementById("DEVFirstrow");
var w = row.insertCell(6);
w.innerHTML = '<button onclick="Releaseentry(this)"type="button"
id="release" class="btn btn-primary release">Release</button>';
I have not added the complete code here, but based on the ids I am using this code in different table and rows.
in this code I have hidden the cell, for hiding the button I am not able to get the path, and that is what I am looking for.
You actually style the cell based on table.rows[i].cells[6].style.display and not its content. You choose the 6th cell and style it.Another mistake you make is that you use id in the button while the button is used in multiple rows which makes the id useless as it should be unique.
What I would do is simply use the class of the buttons and then based on the checks you have decide what the button should do using jquery, so:
if(actualusernamevalue == currentusernamevalue){
$('.release').show();
}
if(actualusernamevalue != currentusernamevalue){
$('.release').hide();
}
If I understand well what you are trying to do at least. The simpler solution, the better solution!
EDIT: By the way, you should keep in mind that if someone wants to find the button when you play with the display property in both ways, they can always find it through the source code. If someone inspects the element and changes the CSS manually they will be able to see the button, so it's always important to have back end validation too for cases like this.
I think I have got my solution finally, Thanks #natan for your help.
table.rows[i].cells[6].getElementsByTagName('button')[0].style.display = "none";
table.rows[i].cells[6].getElementsByTagName('button')[0].style.display = "";
I should have used this code.
I currently have made a way so the user can add another text field to the form by pressing on a 'add_another' div, this uses basic JS so when the user presses on the div 'add_another' the div 'author_2' is toggled.
I would like to make it so that when the user presses on the 'add_another' div for a second time it shows 'author_3' div, and when they press 'add_another' again, it then shows 'author_4'. I have put all the CSS and HTML divs in place to support this, I am just trying to adapt my code so it shows one div after another, rather then toggling a single div.
Here is my JS:
<script>
$(document).ready(function() {
$('.add_another').on('click', function(){
$('.author_2').toggle();
});
});
</script>
I have tried altering this code, however with no luck.
I haven't added my HTML as it is just 4 divs, 'author_1' 'author_2' ... 3...4
Thankyou for your help
There are two solutions to Your problem.
First one - use static code
It means the max author count is 4 and if user gets to 4, this is it.
If so - You need to store the number of authors already shown.
var authors_shown = 1;
$(document).ready(function() {
$('.add_another').on('click', function(){
authors_shown++;
if (!$('.author_'+authors_shown).is(":visible")) {
$('.author_'+authors_shown).toggle();
}
});
});
But there is also a second - more dynamic option.
What if user wants to input 10 or 20 authors? You don't want to pre render all that html code and hide it. You should clone the div and change its id or if the (HTML) code (for another author) is not too long, you can render it within JS code.
var div = document.getElementById('div_id'),
clone = div.cloneNode(true); // true means clone all childNodes and all event handlers
clone.id = "some_id";
document.body.appendChild(clone);
If it's a form, then change names of input fields to array as author_firstname[]
Also You can store number of added authors in another hidden field (so you know how long to loop the form fields on the server side.
The second option is a bit more complex and longer, but way more dynamic.
You should make another div when clicked on add_another:
something like this:
<script>
$(document).ready(function() {
$('.add_another').on('click', function(){
$('<div><input type="text" name="name[]" /></div>').appendTo('.your_container');
});
});
</script>
as you see, input's name has [] which means you should treat with the inputs as an array.
let me know if you got any further questions
good luck.
I'm trying to create form for printing with dynamically generated inputs.
Contents of the fields is shown later in PreviewDiv.
It works fine as long as I specify where they should be, for example:
$('#Prw_CapacityA_1').text($('#CapacityA_1').val());
$('#Prw_CapacityB_1').text($('#CapacityB_1').val());
$('#Prw_CapacityC_1').text($('#CapacityC_1').val());
But if the user creates 100 fields this would be a lot of code to write.
There must be other methods to fix this dynamically, for example:
$('#Prw_CapacityA_'+ counter).text($('#CapacityA_'+ counter).val());
Here's the js fiddle
You could try using attribute starts with selector to select the elements starting with the specific id's and then loop through them using the each() function.
There is no need to have html within your preview table. You can generate it when the user clicks on preview. Modified fiddle
$('#PreviewButton').click(function(){
var capB = $('td input[id^=CapacityB_]');
var capC = $('td input[id^=CapacityC_]');
var table = $("#AddFieldsToPreviewDiv");
table.empty(); //build table everytime user previews so that previously appended values are removed
table.append('<tr><td>ID</td><td>Text 1</td><td>Text 2</td><td>Text 3</td></tr>');
$('td input[id^=CapacityA_]').each(function(i){
table.append('<tr><td>#'+(i + 1)
+'</td><td>'+$(this).val()
+'</td><td>'+$(capB[i]).val()
+'</td><td>'+$(capC[i]).val()
+'</td></tr>');
});
// Show PreviewDiv and hide FormDiv if PreviewButton clicked
$('#PreviewDiv').show();
$('#FormDiv').hide();
});
You could try giving them a unique class (Normally I'd suggest ID but you're using one) say a class of "getinfo"
You could then try the .each() function
https://api.jquery.com/each/
$( ".getinfo" ).each(function( index ) {
var text = $(this).val();
alert(text);
});
This will make an alert box for every element it finds with the class 'getinfo' and then retrieve the value and display it, I hope this gives you a better idea.
If the amount of inputs can change from one page load to the next then you need to use a loop, rather than pulling all the values by 'hand', More code will help better understand what you're trying to achieve and from what.
I have a dynamic form that you can add elements. Like, you type a name, and then if you have to write a new name, you click on 'Add Name', and another textbox appears.
Their names are names[]. I can process those inputs with PHP on the server-side. However, I want to make a calculation with those inputs, like writing all of them on the page as the user types.
However, because those inputs, those textboxes are created dynamically, Javascript only selects the first textbox with the name name[].
Let me make it clear. This way it'll be better. I got a textbox. I input age in there. If I want to enter a new age, I click 'Add Age' button, and a new input box pops out. I write the new age value. And as I type, on a 3rd textbox, the average of those age values get printed. But because of those input boxes, with names ages[] are created on the execution time (not the compile time, I'm not sure these are the appropriate words for those. Probably not, because nothing is compiling? - or is it?), I can't process them.
What must I do to solve this problem?
I used both
$('input[name=ages\\[\\]]').change(function(){
console.log('1');
});
and
$('input[name=ages\\[\\]]').on('input', function() {
console.log('2');
});
but it didn't work.
Thanks in advance.
There's no need to escape the square brackets (though you should enclose the whole field name in double quotes). This works for me:
$('input[name="names[]"]').on('change', function(){
console.log($(this).val());
});
Here's a jsfiddle demonstrating: http://jsfiddle.net/t7J5t/
Your problem is actually probably related to the fact that you're adding the fields dynamically. The way you're using your selector will only work on the fields that already exist. Fields that are added after that selector will not be picked up. What you want to do, then, is put the selector inside the .on, like this:
$('.container').on('change', 'input[name="names[]"]', function(){
console.log($(this).val());
});
This will bind the listener to the container, not the fields (just make sure your fields get added inside of the container; you can call it whatever you want).
Incidentally, there's no reason you have to restrict yourself from using the name attribute of fields when using jQuery selectors. For example, you could use a class:
<div class="container">
<input class="age" name="ages[]">
<input class="age" name="ages[]">
<!-- ... as many more as needed, added dynamically is OK ... -->
</div>
<script>
$(document).ready(function(){
$('.container').on('change', 'input.age', function(){
console.log($(this).val());
});
});
</script>
Here's a sample of it in action, where you can dynamically add fields, and it calculates the average:
http://jsfiddle.net/t7J5t/1/
Try to use:
$(document).on('change', 'input[name=ages\\[\\]]', function() {
console.log('2');
});
I have 2 pages using jQuery Mobile framework.
One is called types.html, where I have a list of checkboxes.
The other is called products.html, where I whant to show the products regarding the types selected in the page types.html.
So, my question is: how can I pass these checked values to next page?
Thanks in advance.
[UPDATED]
This is the solution, as #Ved suggested. It worked! :)
var chk_types = [];
$('.chk_types:checked').each(function() {
chk_types.push($(this).attr("value"));
});
localStorage.setItem("chk_types",chk_types);
$('#form').submit();
On types.html store all selected value store in array variable
localStorage.setItem("checkboxvalue", array_variable);
On products.html on pageshow even OR document.ready event
localStorage.getItem("checkboxvalue");