I have a popup. It has three text input fields. All of them have some values that have been set up via another form. The second and third fields have the correct value when I focus on them.
On focusing on the first field, I don't get the content as expected. I have used html() function of jquery to display the content in these text input fields.
A screenshot is here:
A snippet of my ready function is here:
$(document).ready(function(){
$( "body" ).delegate( ".editDiv", "click", function() {
changed_id = this.id
var copyData = $("#" + changed_id).html();
var changed_class = "edit";
var new_input = "<input id=" + changed_id + " " + "class=" + changed_class + ">";
var editableText = $(new_input);
editableText.val(copyData);
$(this).replaceWith(editableText);
editableText.focus(function() { $(this).select(); });
});
The same code returns correct values for 2nd and 3rd fields. But it is not so for the first field. What could be the possible reason?
Edit
The HTML code for the popup is:
<div id="dialog-form" title="Add advance">
<h4>
<b>
{{ full_name }}
</b>
<span>
<small>
{{ month_name }} {{ year }}
</small>
</span>
</h4>
<table id="special" class="table" style="width: 70%; margin: auto;">
<tbody>
{% for a in old_advances %}
<tr>
<td class="text-right popup">
<span style="float:left;"> {{ a.advance_date }} </span>
<div class="editDiv" id="{{a.id}}">{{ a.advance_amount|floatformat:2 }}
</td>
</tr>
{% empty %}
<p> No advance given this month.</p>
{% endfor %}
</tbody>
</table>
</div>
</div>
You should use the val to get the value of input(textbox, checkbox, etc.).
var copyData = $.trim($("#" + changed_id).val());
To get the value of select dropdown:
var copyData = $.trim($("#" + changed_id +" option:selected").val());
OR
If you want to get the inner text(div, span, etc.) use text:
var copyData = $.trim($("#" + changed_id).text());
You might also want to trim it to remove extra spaces at the beginning and end of the string.
Related
I want to populate a select field with onclick but i don't know how to filter the array to only the value of the clicked button. With my code all the array objects populate the input and I want only the value of the clicked button to populate the input. Any hints?
<input type="hidden" id="id_user" value="{{user.id}}">
<select id="id_entities" class="js-example-programmatic" style="width:100%" multiple="multiple">
{% for teu in tagEntityUsers %}
<option value="{{teu.entity_id}}" class="js-programmatic-set-val">{{teu.entity}}</option>
{% endfor %}
</select>
{% for teu in tagEntityUsers %}
<tr>
<td>{{teu.entity}}</td>
<td>{{teu.user}}</td>
<td><button id ="{{teu.entity_id}}" class="js-programmatic-set-val" value="{{teu.entity_id}}" onclick="populate_box(this.id)">add entity</button></td>
</tr>
{% endfor %}
<script>
var $example = $(".js-example-programmatic");
var arr = $.map($('.js-programmatic-set-val'), function (el) { return el.value; });
function populate_box() {
$example.val(this.arr).trigger("change"); }
</script>
I'll add a prefix to button id and set jQuery listener to it:
$("button[id^='prefix_']").click(function(){
value = $(this).attr('data-value');
$('#id_entities option[value="' + value + '"]').prop("selected", true).change();
});
So, the button will be:
<button id="prefix_{{teu.entity_id}}" class="js-programmatic-set-val" data-value="{{teu.entity_id}}">add entity</button>
UPD: Code above is fixed, see it in action. And I highly recommend to change value attribute on button to data-value, read more about data-* attributes
Here I found the following helpful javascript to dynamically add a form to my python/django template. Here is the code:
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function addForm(btn, prefix) {
// Make a variable and assign to it a string convertd to an integer. The string is the variable
// with the the #id assigned to it. The value of this attribute is saved. The value will equal
// the current number of forms
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
// Find the element with the given class, and clone it after loading the 0 index get request.
// Var row is now a cloned row.
var row = $('.dynamic-form:first').clone(true).get(0);
$(row).removeAttr('id').insertAfter($('.dynamic-form:last')).children('.hidden').removeClass('hidden');
$(row).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, formCount);
$(this).val('');
});
$(row).find('.delete-row').click(function() {
deleteForm(this, prefix);
});
$('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1);
return false;
}
function deleteForm(btn, prefix) {
$(btn).parents('.dynamic-form').remove();
var forms = $('.dynamic-form');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, i);
});
}
return false;
}
Then I have my following template.
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% crispy form form.helper %}
{% load staticfiles %}
{% block extrahead %}
{% endblock %}
{% block blurb %}
<h1>Upload Samples</h1>
<p>Upload A Single Sample, Or A Batch Of Samples</p>
{% endblock %}
{% block form %}
<style>
tr th {text-align:center;}
</style>
<!-- Display formset -->
<form id="myForm" method="post" action="">
{{ formset.management_form }}
<div class='table'>
<table class='no_error' id='id_forms_table' border="2px" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr id="{{ form.prefix }}-row" class="dynamic-form">
<td></td>
<
<td {% if forloop.first %} class="hidden"{% endif %}>
<a id="remove-{{ form.prefix }}-row" href="javascript:void(0)" class="delete-row"><input type='button' value='Remove Row' class='delete-row'></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</form>
<!-- Dynamic Formset javascript -->
<script type="text/javascript">
$(function () {
$('.add-row').click(function() {
return addForm(this, 'form');
});
$('.delete-row').click(function() {
return deleteForm(this, 'form');
})
$('.add-10-rows').click(function() {
return addForm(this, 'form');
})
})
</script>
<input type='button' value='Add Row' class='add-row'>
<input type='button' value='Add 10 Rows' class='add-10-rows'>
<div style='padding-top:20px'>
<input class='btn btn-primary' type='submit' value='Upload' />
</div>
{% endblock %}
This works great, but now I would like to adjust this to allow for the addition of n rows. I will make a form that takes in an interger, then when a button is pressed, I would like to add that number of forms instead of one at a time. I am quite new to javascript/jquery, but I figured the psudo code would look something like this:
function addNForms(btn, prefix, n){
for(var i = 0; i < n; i++){
// Perform the same logic as addForm.
}
}
Unfortunately I have not been able to figure it out. I have performed the function logic n times in a for loop, but the result was that only one form at a time was being made. Which part of the addForm function can I put in a for loop to achive this goal?
In my given example, i have two text boxes. when value in first text box changed i want to find the immediate next text box (note : without id) and change its value.
The example given contains only single text box group. actually it can be more than one text boxes. (group of from & to text boxes of Financial Data)
so, when value in from text box (txtFinancialYearFrom) changed, i want to find the to text box (txtFinancialYearTo) and change its value as well.
JsFiddle Link - Example
Thanks in advance for the help!!
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Data :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>
Using the given information, since you are going to have more blocks (that should be rows on your table), this solution should work:
var rows = $('.fotm-table tr');
$(rows).each(function(){
$('input:first', $(this)).on('change', function(){
var fromValue = $(this).val();
var row = $(this).closest('tr');
$('td:last input', row).val(parseInt(fromValue) + 1);
});
});
The code gets all the rows from your table and for each one of them, it will add a listener that when you change the first textbox (input), it will change the value of the next textbox (here it's adding 1 to it).
If I've understood correctly, you need something like this:
/* Loop through all table rows */
$('tr','table.fotm-table').each(function() {
var tr = this;
/* Cache all inputs a jquery object - you may want to specify which type of input you are targeting i.e. $('input[type="text"]') */
var inputs = $('input',tr);
/* Cache the slave (second in the example) input in a jquery object - you can do the same for multiple inputs, simply by modifying the eq() index parameter
*/
var slaveInput = inputs.eq(1);
/* Listen for changes on the master input */
var masterInput = inputs.eq(0).on('change',function() {
/* Do smt on the slave input - fill it with the next year in the example */
var year = $(this).val();
var followingYear = parseInt(year,10)+1
slaveInput.val(followingYear);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Year :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>
Here's an updated fork of the jsFiddle you provided:
https://jsfiddle.net/jkdaza/thonfzwu/5/
You can use this tricky solution from link:
$('#txtFinancialYearFrom').change(function(el) {
$(':input:eq(' + ($(':input').index(this) + 1) + ')').val('test');
});
https://jsfiddle.net/g34yqL0u/2/
Let me first explain why I need to do this so that it makes sense. On the page there are various labels/titles for sections. Users might want to name these titles something else or use a different language. Instead of "Color" maybe "Hue". There is a table holding the information for the label and the section information. So, "color" and "red", and so on.
What I need is when the user changes a label input field in the table and clicks save - for the corresponding label(s) on the page to change. Within the table, the first column is the id of the matching label and also the class of the corresponding input. http://jsfiddle.net/NNpCB/4/
jQuery
// dynamically give table text inputs, with correct label classes
var valueCol = $("table#ruleTable tr td:nth-child(2)");
valueCol.html(function(){
return '<input value="' + $(this).text() + '" class="' + $(this).prev().text() + '" />';
});
// save new label text
$('.saveLbl').click(function () {
// for each input that was changed, find the corresponding label(s) and change the label text
// the input .class matches the label #id
});
HTML
<label id="lblcolor">Colors</label>
<ul>
<li>Red</li>
<li>Blue</li>
<li>Yellow</li>
</ul>
<label id="lblshape">Shapes</label>
<ul>
<li>Square</li>
<li>Circle</li>
<li>Rectangle</li>
</ul>
<br /><br />
<table id="ruleTable" border='1' cellpadding='15'>
<thead>
<tr>
<th>Label</th>
<th>Display Value</th>
<th>Language</th>
</tr>
</thead>
<tbody>
<tr>
<td>lblcolor</td>
<td>Colors</td>
<td>ENG</td>
</tr>
<tr>
<td>lblshape</td>
<td>Shapes</td>
<td>ENG</td>
</tr>
</tbody>
</table>
<br /><br />
<button class='saveLbl'>Save</button>
Try the following code : ( http://jsfiddle.net/W4k7W/ )
$('.saveLbl').click(function () {
// for each input that was changed, find the corresponding label and change the label text
// the input .class matches the label #id
var rows=$("#ruleTable tbody").children();
for(var i=0;i<rows.length;i++){
var rowKids = $(rows[i]).children();
var labelClass=$(rowKids[0]).text();
var value=$($(rowKids[1]).children()[0]).val(); // <--- rowKids[1] is the td , its first child is the input row
$("#"+labelClass).text(value);
}
});
I am working on a new system and am stuck at a point with jquery + ajax and getting it work work correctly with the other things happening on the page.
Basically the page is to submit a quote and on the page you can add as many quote items as you want. When someone clicks on new item it runs the below code wich gets the value of a hidden element and uses it in all of the new elements Ids in order to keep them all unique.
New Product code:
function addFormField() {
var id = document.getElementById("field_id").value;
$("#products").append("
<table width='600' cellpadding='5' cellspacing='0' class='Add_Products' id='row" + id + "'>
<td width='250' class='left'>
<label>Select Product Category</label>
</td>
<td class='right' >
<label><select name='ProductCategory' id='ProductCategory'>
<?php foreach($categories as $key=>$category){
echo "<option value=".$key.">".$category."</option>";
}
?>
</select>
</label>
</td>
</tr>
<tr>
<td width='250' class='left'>
<label>Select Product Template</label>
</td>
<td class='right' >
<label>
<select name='data[QuoteItem][" + id + "][product_id]' id='QuoteItem" + id + "product_id'></select>
</label>
</td>
</tr>
<tr >
<td class='left'>Name</td>
<td class='right'>
<label>
<input name='data[QuoteItem][" + id + "][name]' type='text' id='QuoteItem" + id + "name' size='50' />
</label>
</td>
</tr>
<tr >
<td class='left'>
Price (ex GST)
</td>
<td class='right'>
<input type='text' name='data[QuoteItem][" + id + "][price]' id='QuoteItem" + id + "price' onchange='totalProductPrice();' class='quote-item-price' />
</td>
</tr>
<tr>
<td class='left'>
Description
</td>
<td class='right'>
<label>
<textarea name='data[QuoteItem][" + id + "][description]' cols='38' rows='5' id='QuoteItem" + id + "description'>
</textarea>
</label>
</td>
</tr>
<tr>
<td>
<a href='#' onClick='removeFormField(\"#row" + id + "\"); return false;'>Remove</a>
</td>
</tr>
</table>
");
$('#row' + id).highlightFade({
speed:1000
});
id = (id - 1) + 2;
document.getElementById("field_id").value = id;
}
The next thing i want to do is setup an AJAX query using jQuery that when selected will request the appropriate data and populate the products box but i cannot figure out how to get the ID of that set of elements to ensure that the correct dropdown box is populated and also to make sure that the onchange is detected for the correct box.
Ive tried methods like adding the ID to the id of the dropdown box but then the onchagne doesnt work.
My jquery ajax code is below that retreives the list of products
$(function(){
$("select#ProductCategory").change(function(){
var url = "productList/" + $(this).val() + "";
var id = $("select#ProductCategory").attr('name');
$.getJSON(url,{id: $(this).val(), ajax: 'true'}, function(j){
var options = '';
options += '<option value="0">None</option>';
$.each(j, function(key, value){
options += '<option value="' + key + '">' + value + '</option>';
})
$("select#QuoteItem" + id + "product_id").html(options);
})
})
})
For the life on my cannot figure this out so if anyone could shed some light on the best way to do it that would be great.
ALso if i need to clarify further let me know because im strugling to explain it.
Thanks in advance
I have similar functionality in my project. Here how I do it:
I have a global variable that start with 0, and increased every time new field added:
var num = 0;
jQuery(function($){
$("#add_field").click(function(){
num++;
//here add new field, with id contains 'num'
});
});
to make it easier to debug, you should start with a simple element, test it so it's bug free, and add more field to it.
To submit form via AJAX, use jQuery form plugins, so you don't need to add all fields manually in ajax code that submit the form.