[Django][Admin] change_form auto populated fields with javascript - javascript

I'm a little lost and don't know how to continue, after a lot of search I think that I'm not doing correctly it.
My problem is that I've got a offer class model like this one:
class Offer(models.Model):
design_hours = models.IntegerField()
design_price = models.DecimalField(max_digits=10, decimal_places=2)
devel_hours = models.IntegerField()
devel_price = models.DecimalField(max_digits=10, decimal_places=2)
offer_price = models.DecimalField(max_digits=10, decimal_places=2)
Where offer_price is a calculated field (desig_hours * design_price + devel_hours * devel_price), I don't have problems overriding the save method.
class OfferAdmin(VersionAdmin):
list_display = (
'design_hours',
'design_price',
'devel_hours',
'devel_price',
'offer_price')
What I'd like to do is in the add/change form show a not editable field wich auto calculate when changing the design_hours or the design_prices form fields.
I supose that I have to override the change_form.html template but from here I don't know what to do :(
Thanks,

Do you really need to save the offer_price in your database? It could always be recalculated from any model object, since all the required fields are there, and could be saved as a method for your object class.
If you decide that you do need to save this field in your database, then you'll need to add some sort of event logic in javascript to update the calculated value whenever your other inputs change.
You'll need to override your template as you thought. First, print everything out normally and then you can add a disabled tag to the offer_price input field (or better yet, create a new item that's not an input, such as a text field), then at the bottom add this script (assuming jQuery is imported in your template):
// load jQuery
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
// when any input in this form changes, call recalculate price
$('#form_name input').on('change', reclaculate_price);
var reclaculate_price = function(){
// whatever your logic is for calculating the offer price
var value = $('#design_hours').val() * $('#design_price').val();
// Add some error checking here to ensure the price is valid
// Set the value to you field
$('#offer_price').val(value);
}
</script>
You'll need to change the id field names to whatever the appropriate fields are in your template.
Make sure the offer price saved in your database is calculated on the server-side because a malicious user could put whatever they wanted in the offer price field by flipping the disabled switch to enabled (see this post) It'd be best to override the ModelForm and exclude the offer_price field. Though hopefully you can trust the users in your admin, so this may not be required.

Related

How can I write the code to append all of the items(XPages)?

I have many documents in Notes, all of the documents have a different form, like this picture :
(possibly like pic 1, pic 2, or pic 3)
How can I write the code in Xpages?
use the "computed field"? Or use the "input text"?
I used the "input text".But only for one item, not for all.
var doc = purchase.getDocument();
var A0 = doc.getItemValueString("DAY_A0");
if(A0 != 0){
return "Division processing";
}
If the form not only has one item, like the pics. How can I write the code to append all of the items?
I'm making the following assumptions here:
You have 10 fields in the document with numbers that might or might not be > 0
The 11th value (Total) shall be computed
You want to show one document at a time, not a list
You know how to add a data source to a page
Version 1:
Create a regular XPages form, use the wizard when adding the document data source. It now would show also the field with 0 values
Click on each ROW and change visibility property to computed (make sure you hit the row, not the cell or field) and add a visibility formula based on the field oof that row. Something like doc.DAY_A0 > 0
Add a computed field where you add the values of all 11 fields
done
Version 2:
in the page open event, get a handle on the document and compute a scoped variable that only contains the values you are interested in. Could be messy since you need a label (that is not your field name) and a value
Use a repeat control to render the values
Hope that helps

AngularJS: Limit selections from dropdown list (using angularMultipleSelect)

I'm stuck on this issue: I'm trying to limit the number of selections a user can make from an available dropdown selection list. The list is drawn from a database, so its not a hard-coded option list. I'm currently using angularMultipleSelect, its works fine expect for this requirement.
If the user exceeds the maximum selections, I want to set the field to invalid, so that the user cannot save the form. The user should then remove one or more of the selections, until the valid selections are made, then the field should reset to valid. I've tried using:
after-select-item (a directive available with angularMultipleSelect)
ng-change
custom validation directive
None of these work. I can get ng-change & custom validation directive to work on other input fields in the same form, but not on the 'multiple-autocomplete' tag. Nothing is triggered when the user makes selections from the dropdown list.
Here is a simple sample of the code used with after-select-item method. I'm trying to limit the user to 3 or less selections from the available options in the 'cats' array.
HTML:
<multiple-autocomplete
ng-model="selectedCats"
name="selectedCats"
object-property="name"
after-select-item="afterSelectItem"
required
suggestions-arr="cats">
</multiple-autocomplete>
Controller.js:
$scope.afterSelectItem = function(selectedCats) {
var catLength = $scope.selectedCats.length;
var valid = (catLength <= 3);
$scope.myStoryForm.selectedCats.$setValidity("maxLength", valid);
};
Again, nothing gets triggered in this controller when selections are been made (checked at console).
Is there something I'm not doing right, or is there another approach I could use to meet this requirement?
Thanks.
You could try using $watch to watch for changes in your model.
E.g.
$scope.$watch("selectedCats", function (newValue, oldValue) {
var catLength = newValue.length;
var valid = (catLength <= 3);
$scope.myStoryForm.selectedCats.$setValidity("maxLength", valid);
});
This gets triggered every time that your "selectedCats" value changes as well as the first time that you initialise the value.

How to deal with dynamic properties in Backbone and sync to database

I have been struggling with Backbone the last few days in trying how to best approach dealing with some dynamic elements added by a user and sync those successfully with the database. I have one model and one view.
The model created is fairly straightforward, it represents a product(t-shirt) in a database and has the attributes: id, price, size, brand, colors.
The problem I am faced with is the colors attribute. The colors cannot be pre-populated by design (unfortunate as it may be) to allow for the user to enter any custom color and name it as freely as they want. In addition to the name, the user has to specify if the color is available. Clicking the Add Text button/link will have an input field and dropdown appended to the div below.
My question: What is the best way to add these multiple color properties as ONE attribute of the model?
I need to have all the colors/availability values as one property when it attempts to insert or update itself with the API as the colors property and goes into one row in the db (mysql). I believe the backend programmer has this row configured as a type of TEXT.
e.g.
{"colors": [{"blue":true},{"orange":false},{"white":false}]}
My thinking is that I need to obviously have some sort of nested JSON within the model but I can't figure out how to write this properly. Any help or something to point me in the right direction would be much appreciated.
Ok, this solution involves jQuery maybe a bit too much, but should work fine. Basically, listen to both changes of your color textboxes and select:
events: {
'change .colorText': 'setColor',
'change .colorSelect': 'setColor'
},
setColor: function() {
// here make your `color` attribute's array
var colors = [];
this.$('.colorText').each(function() {
var val, color;
// adapt the next to navigate to the corresponding select...
(val = $(this).val()) && (((color = {})[val] = $(this).next().val()) || 1) && colors.push(color);
});
this.model.set('colors', colors);
}

Click function in Django form

I have no idea how can I solve my problem. I have Django template with two models. I put these models in inlineformset_factory.
Example
DhcpConfigFormSet = inlineformset_factory(Dhcp, IPRange, extra=1)
and I displayed this form in template like this pictures
form http://sphotos-h.ak.fbcdn.net/hphotos-ak-prn1/601592_10151469446139596_1335258068_n.jpg
I want implement event, when I click on plus stick (marked field on pictures), show one more row (ip initial field, ip final field and delete check box).
I tried to do it on this way :
$(document).ready(function() {
$(".plusthick-left").click( function() {
var tr= $(".sort-table").find("tbody tr:last").length;
$(".sort-table").find("tbody tr:last").after($(".sort- table").find("tbody tr:last").clone())
});
but I have problem, because I just made copy of last row and took same attributes values?
My question is : How can I make new row, and set all attributes with values of last row increased by one.
For example:
<input type="text" id="id_ip_initial_0_ip_range">
This is field that generated form in template, and I want make field with id value like this:
<input type="text" id="id_ip_initial_1_ip_range">
How can I do it? :)

cakephp - Javascript

We are working on an application using the CakePHP framework
Basically, its a questionnaire application and it has a few dependant questions, i.e. based on a response to a specific question, it needs to show or hide the next one
For e.g.
Question: Are you married? Yes/No
If the user selects Yes, then using javascript the next question gets displayed for user input
Question: Spouse's name
Saving this information is fine, but when editing, when populating the form, we would want to be able to display the fields for which user has inputted data - in this case, it needs to show the field that has the spouse's name
Since by default we are hiding the spouse name field, when editing, it doesn’t display the field, even though there is a value to it
Is there some way that CakePHP can handle this or does it require us to write some javascript to take care of this?
Thanks in advance.
CakePHP does not manage this for you. While CakePHP is very powerful and a great framework, it will not write this kind of logic for you. You must write it.
I would suggest making the EDIT screen different from the ADD screen. Build the list of values from the database and display the fields that have values (and include any empty fields that should require values).
Keep in mind reusable does not necessarily mean that all CRUD actions fit into the same view.
Like others I advise you use differents EDIT and ADD screens.
But you can try make it with Javascript like this:
<script>
function enableDisableField(targetFieldId){
var targetField = document.getElementById(targetFieldId);
var checkbox = event.target;
console.log(checkbox.checked);
if (checkbox.checked){
targetField.disabled = false;
targetField.value = "empyt";
}else{
targetField.disabled = true;
targetField.value = "empyt";
}
}
</script>
<label><input type="checkbox" onchange="enableDisableField('married')"/> Merried</label>
<?= $this->Form->input('married',['label' => false, 'disabled']); ?>
It works well for ADD, but if you and EDIT you have to change de disable value according a field value:
<label><input type="checkbox" onchange="enableDisableField('married')"/> Merried</label>
<?= $this->Form->input('married',['label' => false, !isset($user->married) ? 'disabled' : '' ]); ?>

Categories

Resources