javascript and django - javascript

I am converting from PHP to Django and it's proving a real struggle. I want to do an inline edit (a breeze with PHP and Ajax) but I am really, really stuck. Sorry, in advance, for the large amount of code that follows.
I have rendered a 2 divs which contains a number of fields, all the same. One is displayed and the other hidden. When you click on the edit button the div to be updates is dispalyed and the data is in input boxes and a select dropdown so the user cna make changes. The HTML follows"
<div id="display1">
<span style="width:50px;">
<button class="edit" onclick="javascript:toggle('1')">EDIT</button>
</span>
<span>
Blair Leighton
</span>
<span>
Intertrust Private Partners
</span>
<span>
Japan
</span>
<span>
hands off
</span>
<span>
not connected
</span>
<span>
notes
</span>
</div>
<div class="noshow" id="edit1">
<span style="width:100px;"><button class="update" id="1">update</button></span>
<span>
Blair Leighton
</span>
<span style="width:220px;">
<input type="textfield" style="width:210px;" id="new_company" value="Intertrust Private Partners" />
</span>
<span>
<input type="text" id="new_country" value="Japan" />
</span>
<span>
<select id="new_status">
<option value="no contact">no contact</option>
<option value="no contact">hands off</option>
<option value="no contact">ongoing</option>
<option value="no contact">sent email</option>
<option value="no contact">waiting</option>
<option value="no contact">trash</option>
</select>
</span>
<span>
<input type="text" id="new_connection" value="not connected" />
</span>
<span style="width:220px;">
<input type="textfield" style="width:210px;" id="new_notes" value="notes" />
</span>
</div>
There are, in fact, many other divs which have a sequential id display2, edit2 and so on.
Once the edit div is displayed by clicking the toggle button I want to collect the data from each field (in a jquery array) and then pass it to a django view to update the database.
Then, remain on the same page which is refreshed to show the updated values.
How can I do this?
models.py is:
from django.db import models
class recruit(models.Model):
first_name = models.CharField(max_length=25)
last_name = models.CharField(max_length=35)
position = models.CharField(max_length=55)
company = models.CharField(max_length=55)
country = models.CharField(max_length=125)
connection = models.CharField(max_length=55)
status = models.CharField(max_length=55)
phone = models.CharField(max_length=55)
placed = models.CharField(max_length=55)
placed_with = models.CharField(max_length=55)
skype = models.CharField(max_length=55)
notes = models.TextField()
company_url = models.CharField(max_length=125)
All help very gratefully received. Thank you.
Richard

there are django apps which can do the job for you, although i never used them.
quick googling gave me this: http://pypi.python.org/pypi/django-inplaceedit, maybe there are more or even better solutions.
if you really want to code it all by yourselt i'd suggest using a django-ModelForm instead of putting all the fields together manually.
then you can just hook your form-submit with some javascript to make it being submitted with AJAX. i am using jQuery for tasks like this, but any other js library (prototype, dojo, mootools, ...) can do the job too.
in django just safe the data as descibed in the docs for ModelForm and pass it back rendered in the response. onSuccess of your AJAX call update the page with your response text and you are done.
for the views you can also use django's generic update views
you might also be interested in this: https://stackoverflow.com/questions/708801/whats-the-best-edit-in-place-plugin-for-jquery

I can't see how this is any different in Django from PHP. The principles are exactly the same: the JS collects up the data, POSTs it via Ajax, and updates the HTML with the response. The server-side code simply does the saving and returns the result for the Ajax: either as JSON, or as pre-rendered HTML fragments.

Related

Use Product Variants Select in Cart Prestashop

I'm developing a cross sell module that will display products in cart that you can add to cart by clicking the button add to cart.
I need to take consideration of product variants (attributes).
I've already find out how to add the add to cart button to the cart page thanks to this code :
<form action="{$urls.pages.cart}" method="post" id="add-to-cart-or-refresh">
<input type="hidden" name="token" value="{$static_token}">
<input type="hidden" name="id_product" value="{$product->id}" id="product_page_product_id">
<span class="remove-from-cart">
<button class="btn btn-primary add-to-cart" data-button-action="add-to-cart" type="submit"
{if (!$product->checkQty(1))} disabled {/if}>
<i class="material-icons float-xs-left">shopping_cart</i>
{l s="Add to cart" d='Shop.Theme.Actions'}
</button>
</span>
</form>
But what I need now is to update the display price depending about the value chosen with the select option value dropdown set as on my product page and use the attribute id selected in order than when the user click on the add to cart button, it add to cart the product with the good attribute and not the default one
I'm sure that is from js script that the price is updated but I don't really find out which function is in charge of this
This is the select option as asked
<div class="clearfix product-variants-item">
<span class="control-label">ATTRIBUTE_GROUP_NAME</span>
<select class="form-control form-control-select" id="group_ATTRIBUTE_GROUP_ID" data-product-attribute="ATTRIBUTE_GROUP_ID" name="group[ATTRIBUTE_GROUP_ID]">
<option value="ATTRIBUTE_ID" title="ATTRIBUTE_NAME" selected="selected">ATTRIBUTE_NAME</option>
</select>
</div>
the solution is not very simple but is achievable, the same way as prestashop works on product page, you have to ajax refresh your content on the attribute change. We developed a complex upselling module on checkout using the same method and it works good.
The logical steps are:
-> Select value is changed
-> submit the data via ajax
-> get the fresh and updated data, best choice for me is to render your module view again and get an html as response
-> replace your content with the new html
Another way, not tested because little bit more complex in my opinion, could be to store in javascript all the data about all the variations/combinations and handle the logic there to get the price data you need on every change. A problem with this solution is that the data could be not always updated because stored locally.
I hope my hint helps, I wanted to comment but my ranking is still too low and I have to reply instead.
Simone

Send combination of two input values with htmx

I'm writing a simple website with Django and I decided to try htmx library in client side to load html fragments. Now I want to sort lists by different fields, ascending and descending. I have something like this:
<div class="col-auto">
<div class="input-group input-group-sm">
<select id="np-sort-key" name="key" class="form-select">
<option value="publish_date" selected>Publish date</option>
<option value="title">Title</option>
</select>
<button class="btn btn-outline-dark" type="button">
<span class="bi bi-sort-down"></span> <!-- bi-sort-up for Asc icon -->
</button>
</div>
</div>
I want to add/replace the order_by=<order><key> query parameter to/in the current url (For example /articles?page=2&order_by=-publish_date.) and send it back to Django view both on "select" change and "button" click. The endpoint returns a Html I want to swap it with another Html node with Htmx. (Note that span class should be changed on button click to show sorting is Asc or Dsc)
Is it possible using htmx? If not, simple Javascript solutions are welcome.
You could solve it like this:
You use
<form hx-get="...">
...
<input type="hidden" name="order_by">
</form>
Then you can display the user a nice icon for sorting. If the user clicks on the icon, you update the hidden input via JS.
The easiest approach would be to construct the URL server side based on the input values and then push it using the HX-Push response header:
https://htmx.org/reference/#response_headers
From what I understood of htmx documentations, htmx provides us two tools to send custom values:
hx-vals that lets you add custom parameters to the ongoing request. These parameters are in the form of a Json object and their values could be either static or dynamic (returned from a JS function). For example:
<div hx-get="/list" hx-vals='js:{"order_by": concatSortOrderAndKey()}'>
hx-include that adds values of the elements specified by a query selector to the ongoing request.
In case of my problem, in addition to #guettli answer, I could set htmx parameters on "select" and "button" tag and use hx-vals to calculate new order_by value. (also by using hx-boost, hx-* stuff could be set only on outer enclosing elements). But overall, I think the hidden input was a better solution.

Changing the value of a hidden field to the value of a checkbox on submit with javascript inside Contact Form 7 Wordpress plugin

I have been trying to get this working for more than a week now, searching endlessly for the solution and I can't figure out what I'm doing wrong. I am not a coder, just trying to duct tape some functions together to get this working... Please help!
I have the following checkbox inputs on my Contact Form 7 form inside a Wordpress page. I have Mailchimp for Wordpress updating a group which reflects the visitors interests. I'm trying to get the value of the group assigned to a hidden input field so that the built in mail feature and other Zapier integrations can use the interest values. Most of these apps seem to lack support for the groups functionality inside Mailchimp.
The form html is as follows:
<p>
<label>Which Are You Most Interested In?</label></br>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="ac2ed8233d"
required=""><span>Interest 1</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="s3g2c99k0x"
required=""> <span>Interest 2</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="k9n6xp3s26"
required=""> <span>Interest 3</span>
</label>
</p>
<input type="hidden" id="int-in" name="int-in"</input>
--
I've tried several variations of this including some inline stuff, putting the code in the top or bottom of the page, putting it into the Additional section of Contact Form 7, putting it into a scripts plugin inside wordpress, trying to see if it's an array thing and trying code for pushing from array (more over my head) and so many others. Here is what I'm basically trying to do, albeit wrongly via this code because obviously it is not working...
JS:
$('form').submit(function() {
$('input[name="#mc4wp-INTERESTS[gs8o25e9bc] .
[]"]').change(function(){
$('#int-in').val($('input[name="#mc4wp-INTERESTS[gs8o25e9bc] .
[]"]').val());
});
--
Online there is not much support for Mailchimp groups, and I suspect groups functions of most contact apps, not even with paid plugin feature. Mailchimp for Wordpress has the most support I could find and you still have to do some tinkering to get it working. I'm soooo ready to know what the heck works instead of all the stuff I've been trying! Thank you in advance. I really appreciate it!
Wordpress disables the $ shortcut, so you need to either replace $ with jQuery or wrap your code:
(function($){
// your code here
})(jQuery);
Plus, the name of those checkboxes doesn't contain a hashtag. I also have no idea what you're doing with those dots and linebreaks there.
In addition, you're assigning a onchange handler only when the form is submitted, but you'll want that to work from the start instead.
Here's a solution that sets the onchange handler to grab the value from all checked checkboxes and puts it into the hidden input.
var selector = 'form input[name="mc4wp-INTERESTS[gs8o25e9bc][]"]';
(function($) {
$(selector).change(function() {
var interests = Array.from(document.querySelectorAll(selector))
.filter(e => e.checked).map(e => e.value).join(",");
$('#int-in').val(interests);
console.log("set to", interests);
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<p>
<label>Which Are You Most Interested In?</label><br/>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="ac2ed8233d"><span>Interest 1</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="s3g2c99k0x"> <span>Interest 2</span>
</label>
<label>
<input name="mc4wp-INTERESTS[gs8o25e9bc][]" type="checkbox"
value="k9n6xp3s26"> <span>Interest 3</span>
</label>
</p>
<input type="hidden" id="int-in" name="int-in">
<input type="submit">
</form>

Several radio button groups in nested ng-repeat, but only last group shows the value

I have a page where I want to update a form with several radio buttons. I query an api, and use the returned array of objects to populate the current values for the radio buttons. The problem that I have is that only the last set of radio buttons actually shows the value. This is the code that I have (I am using [[ and ]] for the start and end symbols for angular):
<fieldset data-ng-repeat="s in sections">
<div class="form-group">
<div class="col-md-12">
<h2>[[ s.section.name ]]</h2>
</div>
</div>
<!-- Field Item -->
<div class="form-group m-b-20 bg-light" data-ng-repeat="f in s.fields">
<div class="col-md-12 m-b-30">
<h4>[[ f.field.name ]]</h2>
<input type="text" data-ng-model="f.comments" class="form-control input-md underline" placeholder="Comments">
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="pass" class="form-control" data-ng-model="f.field_condition">
<label class="eval-pass"><i class="fa fa-check-circle green"></i> Pass</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="fail" class="form-control" data-ng-model="f.field_condition">
<label class="eval-fail"> <i class="fa fa-exclamation-circle red"></i> Fail</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="n/a" class="form-control" data-ng-model="f.field_condition">
<label class="eval-na"> <i class="fa fa-circle blue"></i> N/A</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="caution" class="form-control" data-ng-model="f.field_condition">
<label class="eval-caution"><i class="fa fa-exclamation-triangle yellow"></i> Caution</label>
</div>
</div>
[[ f.field_condition ]]
<hr>
</fieldset>
So basically, I have several sections, and each section has several fields. Each field has it's own radio button group (I am using the section and field ids to name the radio group). What I currently see is only the last field in each section actually shows the selected radio button. The other fields don't have any selection, even though the value for ng-model definitely does (I am showing the value of f.field_condition just to make sure there is a value).
For each field, I can see that the model is set. And if I select a value manually, I can see that the model changes, so it seems to me that the model is setup correctly. I just don't know why it won't initially show as selected for all rows but the last one.
I should also mention that if I save the form even with the missing radio button selections, the database is updated properly (it doesn't set the values to null, and if I manually change the selected value, it is updated in the db as well).
Does anyone have any ideas? Thanks!
EDIT
Here is a fiddle for this, although, it is working as expected in the fiddle. http://jsfiddle.net/dq8r196v/367/
I tried using the static data that I used in the fiddle, but I am still having the same problem. Does anyone know if this could be a CSS problem? The radio buttons are styled, and I didn't write the HTML or CSS.
UPDATE
I am still having this issue, so I built a new angular app and only used the code that is included in the fiddle that I have created. I am having the same problem with this new app, even though the same code works in the fiddle. I really don't understand what's happening here, but if anyone could shed some light, I would really appreciate it.
I have literally copied and pasted the code from my fiddle into a new angular app, and only the last group of radio buttons in each section is showing the value in the app.
Here is my complete code for the new angular app if someone else wants to try it out and see exactly what is happening: https://pastebin.com/qSR33yfM
I created the app on a single page for simplicity.
Here is the link to a pastebin with the exact json that I am using in my app: https://pastebin.com/utfVVQfT
I fixed the problem you're having by simply adding an array of objects ($scope.values) representing the different radio button options, and using an ng-repeat to create your radio buttons. See the following for the updated code: https://pastebin.com/s3hNzaXX
I know there are semantics around ng-repeat creating new $scopes, and imagine there is a conflict in scopes with your nested ng-repeats where it's binding to the radio buttons incorrectly and at a scope different than you want (the section level ng-repeat).
To confirm this suspicion, you could convert all of your interpolations in the code to use functions and console.log s and f at different points and confirm that field_condition is being set at a level you didn't intend.
Either way, it' best practice to create your radio buttons through data (and using ng-repeat), as is done with the $scope.values array, and a good side effect to doing this is not only can you update the different value options using data through AJAX or however you would like, but you won't have weird angular scoping issues as you're experiencing in your current code above.

How to change input using a value from iterator (JavaScript and Struts2)

we have an bonus exercise in our JavaScript class which I can't solve. I have a problem regarding how to change what is written in the two <input> tags depending on which applicant I've chosen. I am retrieving from a database for the <div> and <input> tags using JavaScript (which is used to connect the front end and back end, I guess) and Struts2.
For example I select "examinee1", the first input should display the name of his/her father while the second input will provide the name of his/her mother. If "examinee2" was chosen, same thing applies.
Here's what I've already started.
<div>
Applicant:
<select id="examineeList">
<s:iterator value="examineeList" var="examinee">
<option value="${examinee.name}" id="${examinee.id}">${examinee.name}</option>
</s:iterator>
</select>
</div>
<div class="form-group col-lg-3">
<label for="examineeFather">Father:</label>
<input type="text" class="form-control" id="examineeFather"
name="examinee.father" placeholder="-----" maxlength="50" required />
</div>
<div class="form-group col-lg-3">
<label for="examineeMother">Mother:</label>
<input type="text" class="form-control" id="examineeMother"
name="examinee.mother" placeholder="-----" maxlength="50" required />
</div>
Moreover, if I have not choose any examinee, the input tags should have no value and after selecting the examinee, I can still change the value of 2 input tags whenever I want to (my instructor said that just in case i want to rename my father and mother, lol). Also, If I have selected an examinee, I can save directly with the default value of father and mother retrieved from the database. After all, saving the entry to the database follows.
Can anybody help me with the JavaScript code? I'm still learning it and only familiar with its basic/usual functions. Any hints and suggestions would be really much appreciated.
Thank you in advance!

Categories