I have an html button with an onclick attribute which runs a jQuery AJAX function pointing to php code.
The php code writes HTML in an output HTML <select> element(the element remains hidden until the javascript runs.)
This is working great to populate the <select> when an "add another" button is clicked.
The problem is it adds one and only one. I want to be able to have a new <select> tag populate with each click of the "add another" button up to a max of 2.
The JS in question:
var genre_dropdown = function genre_dropdown() {
$('.genre_output').css('display', 'block');
$.ajax({
url:'../includes/functions/genre_dropdown.php',
complete: function (response) {
$('.genre_output').html(response.responseText);
},
error: function () {
$('.genre_output').html('Bummer: there was an error!');
}
});
return false;
}
The HTML in question:
<select name="genre_id[]" autocomplete="off" class="genre_output"></select>
<select name="genre_id[]" autocomplete="off" class="genre_output"></select>
<div class="button add-genre-button" onclick="return genre_dropdown();">+ Add Existing Genre</div>
I thought I could include 2 html <select> elements for the php to populate into, the code would execute from one to the next. I see why this is not correct, the code is running in both at the same time. I'm at a place where I'm considering have 2 buttons ("add one", "add another") but that seems redundant and not correct, especially considering I want a scale-able technique (the max may not always be 2.) I need help.
Your php request is fine.
I simply mean define a variable as your using javascript i.e.:
var sel = '<select name="genre_id[]" autocomplete="off" class="genre_output">' + response + "</select>';
and then each time you do a request it will include the response as the value of the element. This would allow you to append the parent div as many times as you want. Finally, use a simple if counter to decide whether to keep appending or not:
if ($(".genre_output").length <= 2){
$("PARENT_DIV_ID").append(sel);
};
Is this clearer? #kaari
Assuming you want to keep previous values in dropdown then you can try append() instead of html()
$('.genre_output').append(response.responseText);
Related
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 in a situation where I'm working with a vendor-provided system that has built in validation scripts that can't be modified.
One of the scripts on the page calls a validation method related to the number of characters in a textbox.
It passes the character count limit as a static number in the method call. The static number is from a configuration file, which I can change. The problem is that I need that number to change based on a value the user selects from a drop down.
What's happening is I have to append content in the textbox on form submit. The content I append includes a value from a drop down that has variable lengths.
The script I have running to append the content in the text box is working just fine. The problem I run into is the user enters the maximum amount of text they can (there is a character countdown) and when they hit submit, the system adds the content from the drop down but then truncates the end of the user's message because it is now longer than the accepted number.
Since this is a vendor / closed system, my options for adjusting existing on-page scripts, form elements, etc are extremely limited. I can add scripts (including jQuery scripts) to modify the DOM.
Any ideas on how to approach something like this would be really appreciated.
Thanks!
EDIT
This isn't a working example, but maybe illustrates what I'm trying to do:
<select name="selectedname" id="selectedname">
<option value="1">Value 1</option>
<option value="2">Value 2</option>
</select>
<textarea id="message"></textarea>
<span id="errormessage"><!-- this is where you would see the text counting down --></span>
<script>
vendor_script_that_counts_down_text_and_validates_length(arg1, arg2, 500)
</script>
<button id="send"></button>
My Script:
/* Attempt to add the name to the question*/
if (window.jQuery) {
//Adding this to prevent conflicts with existing javascript
jQuery.noConflict();
// Adding usual jQuery symbol to the local scope of this method
jQuery(document).ready(function($){
$("#send").on('click', function(e) {
var valueSelected = getName($); // this is a function that gets the value of the dropdown
var message = "This message is for " + valueSelected + ". The message begins here:\n\n";
$("#message").val(function(index, userMessage){
return message + userMessage;
})
});
});
}
In terms of how the scripts are currently working together, they aren't and I guess that's the crux of my question, can they work together? Is there a way I can modify my script to change the number used in the validation script call (500) based on the dropdown value selected with the constraints that I can't modify any html or on-page scripts other than the one I created?
From what you added, it seems that the vendor function is a global function. If that's the case, you could overwrite it with a new one, giving you the possibility to alter/manipulate the third parameter.
E.g.: (adding this after the vendor script is loaded, but before the function get's called):
vendor_script_that_counts_down_text_and_validates_length = function (orgFunc) {
// return a new function
return function (arg1, arg2, charCount) {
// add your code...
// call the original function
return orgFunc(arg1, arg2, charCount || 500);
};
}(vendor_script_that_counts_down_text_and_validates_length);
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');
});
On my aspx page I dynamically create html controls on client side using javascript. For example, after page load you can click button in a browser, by clicking button html input and select elements appear. You may click once again, and this elements (input and select) will added again. So, you can create so many inputs and selects as you want (all this using javascript, no postbacks)
After user created some inputs and selects and entered some information in it, he posted form. I want on server side to find all this dynamically added elements and perform some actions depends on values in this controls.
How can I find dynamically added elements, and what is the best and elegant way to achieve this?
Thanks in advance.
In the Javascript that creates the new elements, increment a counter each time an element is created. Add the value of the counter to the name of the input element so each element has a unique name.
Add the final value of the counter to a hidden form field when the form is posted.
In your server side code, create a loop that starts at zero and continues until you have reached the value of the counter. Within the loop, fetch the posted value of the corresponding form field.
When you add the elements, assign unique IDs to them, and then retrieve their values using Request.Form["UniqueIdHere"] (C#) or Request.Form("UniqueIdHere") (VB.NET).
Create a loop that loops through each input and select object, that grabs the name/id of the current object and its corresponding value. Then add those items to an array and once the loop is completed, pass those values to your aspx file.
You can view an example with this approach at: http://jsfiddle.net/euHeX/. It currently just alerts the values, but you could easily modify it to pass the values as a parameter via ajax to your handler aspx file. The code will add new inputs or select boxes based off of the input provided. This would of course be modified to reflect your current setup.
HTML:
<div id="dynamic"></div>
<input type="button" id="submit-form" value="Submit>>">
JavaScript (using jQuery):
function createInput(type){
for(var i=0; i<5; i++){
if(type==0){
var obj = '<input type="text" id="'+i+'" class="dynamicContent">';
}else if(type==1){
var obj = '<select id="'+i+'" class="dynamicContent"><option>--Select--</option></select>';
}
$("#dynamic").append(obj);
}
}
function getContent(){
var inputArray = [];
$(".dynamicContent").each(function(k,v){
var o = $(this);
var oType;
if(o.is("input")){ oType = "input"; }
if(o.is("select")){ oType = "select"; }
var oID = oType+o.attr("id");
var oValue = o.val();
inputArray.push(oID+'='+oValue);
});
alert(inputArray);
}
$("#submit-form").click(function(){
getContent();
});
// Set type to 0 for input or 1 for select
var type = '1';
createInput(type);
If you're using jQuery you can use .live() to achive this like a peace of cake!
http://api.jquery.com/live/
I don't know if your controls will survive the postback the way you're creating them, but a good technique for accessing dynamically generated controls (assuming that you've figured out how to persist them) is to do something like the following:
Add a panel to your page. Add your dynamically created controls to this panel.
In the OnClick event handler (or other method), do something like the following:
foreach (DropDownList ddl in Panel1.Controls.OfType<DropDownList>())
{
//put code here
}
foreach (TextBox txt in Panel1.Controls.OfType<TextBox>())
{
//put code here
}
I'm using JEditable and trying to populate a select based on a variable. I need a way to pass a variable from my page back through the JQuery to dynamically create the select.
JQuery:
$(".dblclick_district").editable('miscfreqs.php?mode=save_edit&module=miscfreqs&type=district',
{
type: 'select',
loadurl: 'tools.php?mode=get_districts_json',
submit: 'OK',
event: 'dblclick'
});
The HTML that I use is generated by PHP:
<div class="dblclick_province" id="freq_id">Province</div>
<div class="dblclick_district" id="freq_id">District</div>
I'd like to be able to somehow pass the value of province through the dblclick event of District, since the Districts available depend on which Province is selected.
First thing two elements on the same page cannot have same id.
In your case both div are having same id ie freq_id so it should be changed.
You can have html as below -
<div class="dblclick_province" id="province_id">Province</div>
<div class="dblclick_district" id="district_id">District</div>
Then write the below code in your js file.
It uses jquery's dbclick event.
$('document').ready(function(){
$('#district_id').dblclick(function() {
var province_value = $('#province_id').html();
// write you code here in which you want to process province value.
});
});