Jquery Insert element in an other on event - javascript

First post here and quite new on javascript/jquery/webstuff but even after some research about the thing I'm trying to do, I didn't manage to find something that made this thing work.
So, here is the context :
I'm creating a schedule with HTML and Javascript/Jquery.
I want to be able to inject an automated generated <span> or something directly by clicking on the day (which is a <td>).
At first I used basic stuff like "getElementById()" but if I manage to do the thing with this, I'm going on a lot of repetitive code. And I'm quite sure I can avoid this.
So basically I wanted to do generic code and be able to get the which the user clicked.
Here is what I managed to do by now:
HTML part :
<table>
<tr>
<th class="day-name">Sun</th>
<th class="day-name">Mon</th>
<th class="day-name">Tue</th>
<th class="day-name">Wed</th>
<th class="day-name">Thu</th>
<th class="day-name">Fri</th>
<th class="day-name">Sat</th>
</tr>
{% set counter = namespace(a=0) %}
{% for x in range(0, 5) %}
<tr class="week">
{% for y in range(0, 7) %}
{% set counter.a = counter.a + 1 %}
<!-- <td id="2" class="day" onclick="addEvent()"><span class="number">{{ counter.a }}</span></td> -->
<td id="day_{{ counter.a }}" class="day"><span class="number">{{ counter.a }}</span></td>
{% endfor %}
{% endfor %}
</table>
Javascript Part :
function addEvent(){
var node = document.createElement("span");
node.setAttribute("class", "event");
document.getElementById("2").appendChild(node);
};
$(document).ready(function(){
$("td").click(function(){
alert("Ahahahah");
var node = document.createElement("span");
node.setAttribute("class", "event");
document.getElementById(this).appendChild(node);
});
});
The {% ... %} is from Flask/Jinja stuff, but I'm quite sure that's not the problem.
The script is in an other file, but the file is included. (Sure about it because the script "addEvent" works well).
So I tried many, many things, but still not working. The alert pop-up is not even showing up, so I can't try the script. I guess that the way to inject the new element is wrong, but I didn't saw anything with the way I was looking for.
So here it is, thanks in advance for those who take the time to help me on this

I see
onclick="addingEvent()"
but
function addEvent(){
Mabay this is the problem?

You need to use the reference to this and using this can append with it.
$(document).ready(function(){
$("td").click(function(){
alert("Ahahahah");
var node = document.createElement("span");
node.setAttribute("class", "event");
this.appendChild(node);
});
});

Related

Jinja variable declared in javascript inside a for-loop

I coded a page using the Flask framework.
I intend to have each line of a table redirecting, on click, to another page.
For that, I used a js object and declared the page using Jinja.
Everything works, but I have an error in the IDE saying:
";" expected Javascript.
So the code is simplified as follows:
<tbody class="table-hover">
{% for x in top %}
<tr onclick="window.location='{{ url_for('example', parameter=x[0]) }}';">
<td class="text-left"> {{ x[1] }} </td>
</tr>
{% endfor %}
</tbody>
Declaring it before solves the syntax alert but doesn't work, as the variable can only have one value on the HTML page.
<tbody class="table-hover">
{% for x in top %}
<script>
let direction = "{{ url_for('example', parameter=x[0]) }}";
<tr onclick= "window.location= direction;">
<td class="text-left"> {{ x[1] }} </td>
</tr>
{% endfor %}
</tbody>
The above code would always redirect to the first x[0]. Should we declare direction with var, it would redirect to the last x[0] of the list.
I tried testing various quotation marks' orders. In the current solution, there is one quotation mark ' ' inside another ' ' which is usually bad. However, replacing the nested one with " " doesn't work. It would give an
Unterminated string literal.javascript
Once again, the first code does give the expected result (and the error doesn't prevent the pages from opening). But there is an error, and I would love to understand why / how to fix it.
Thank you for your help.

Link to content of last column of html table created from pandas dataframe

I am creating a dynamic html table, it is populated with data from a pandas dataframe in python. The last column contains a large block of text (article abstract) for each row, making the rows very large and the table hard to read/navigate. I am looking to hide the content of the last column behind a toggle button (either popover or link to a popup window would be fine). I'm using bootstrap css and javascript.
Is there a way to apply an if statement only to the last column/cell? How else can I achieve this?
Thank you very much in advance.
main.py looks like this:
from flask import Flask, render_template
from researchdashboard import combined_dictionaries
app = Flask(__name__)
headings = ("""list of headings""")
for x in combined_dictionaries:
data = combined_dictionaries.iloc
#app.route('/')
def index():
return render_template('index.html', headings=headings, data=data)
if name == "__main__"_
app.run(debug=True)
and the table section in the html looks like this:
<table class="""some specifics for the table design""">
<tr>
{% for header in headings %}
<th>{{ header }}</th>
{% endfor %}
</tr>
<tbody>
{% for row in data %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Edit: So I ended up using the following solution:
<tr>
{% for header in headings %}
<th>{{ header }}</th>
{% endfor %}
</tr>
{% for row in range(num_rows) %}
<tr>
{% for cell in data[row] %}
<td>{{ cell }}</td>
{% endfor %}
<td><button type="button" class="btn btn-secondary" data-container="body" data-toggle="popover" data-placement="left" data-content="{{ abstract_data[row] }}">Abstract</button></td>
</tr>
{% endfor %}
</table>
Where data contains the dataframe except for the column the contents of which I want to be hidden. abstract_data contains just said column and is thus called upon seperately. num_rows is generated from a len("""input measure that specifies the number of rows in the table""") function.
Thank you very much for any solutions that were suggested.
EDIT:
If you are fine just showing a popup window, you can check out the example I made in this fiddle
However, if you want to show a modal instead, please mind that there are many accessibility nuances that you'll have to face. It would probably be better to use a library to help with handling all those situations.
ORIGINAL:
in your situation I would use javascript to toggle a class on the table, and then hide the last column based on that class.
You can hide the last column of a row using css this way:
td:last-child {
display: none;
}
You can find a complete example of what I suggest in this fiddle

Display Product Variant Metafields

I need to display metafields based on the variants selected on the product page. I want them to change as the variants are clicked. I may need some jquery help but I am not that sure how to apply with liquid. Below is my code, any help is greatly appreciated!
{% for variant in product.variants %}
<div id="tab{{ forloop.index0 }}" class="zr-tabs-panel {% if forloop.first == true %}js-active{% endif %}">
<div class="table-responsive>">
<table class="table table-striped">
<tbody>
{% for field in current_variant.metafields.var_meta %}
<tr>
<td>{{ field | first }}</td>
<td>{{ field | last }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endfor %}
The short answer is that you will need to (a): Expose your meta fields to your site's javascript somehow, then (b): Update your variant-changing code to also update the section based on your meta fields.
In many themes, the variant-changing code is contained in a function named selectCallback (though this isn't the case in all themes - if you have trouble finding this code, you can try reaching out to your theme's developer for theme-specific advice).
Whenever you're using Liquid code to put values into Javascript code, I strongly recommend using the json filter - Liquid's magic filter that ensures your output will always be Javascript-legal. (Quotation marks and line breaks will be properly escaped, empty values will be printed as null, etc)

Combining ng repeat and django template language

I have a table that will have varying columns over time and I want my django view to support those changing columns. I also want to use ng-repeat to do some fancy stuff with it such as filtering and other things. However I am having trouble combining the two.
I am passing in the arbitrary col_names with django template language. packages is also sent in with the django template language and is essentially a json array where each row is a dict mapping col_name to some value. i.e.
$scope.packages = [{'col1': 'row1col1', 'col2': 'row2val2'}, {'col1': 'row2col1' ....
However when I go to put in the rows using packages I can't "nest" my templates. Is there a way to grab arbitrary values out of each row in `packages?
<input ng-model="search" placeholder="Search">
<table style="width:100%;">
<thead>
<tr>
<th>Permanent Column 1</th>
<th>Permanent Column 2</th>
{# changing columns #}
{% for col_name in col_names %}
<th>{{ col_name }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr ng-repeat="package in packages | filter:searchPackage">
{% for col_name in columns %}
<td>{{package.{{ col_name }}}}</td> DOESN'T WORK!
{% endfor %}
</tr>
</tbody>
</table>
In that problem line I essentially want to have {{package.ACTUAL_ARBITRARY_COL_NAME}} but I don't know how to do that programmatically
The problem
By default, Django and AngularJS use the same tokens {{ and }} for templating.
So this gets first processed by Django template
{% for col_name in columns %}
<td>{{package.{{ col_name }}}}</td> DOESN'T WORK!
^ ^
|________________________|
Django template will try to process this value
Because Django tries to expand what's inside the first {{...}}, you will not get what you want AngularJS to see.
If you want to continue down that road, I suggest you read some solutions to this problem here
Better solution
A better approach is to give AngularJS the items you want Django to loop for you.
$scope.columns = [...];
Then use AngularJS to do all the loops. Whichever way you do it, if you need it done in AngularJS, better do it all in AngularJS and not half-Django half-AngularJS.

Django / jQuery - Button to update a value on each row of a table

I am just learning Django, so I am making an app that can keep track of books with a Boolean for whether I have read them or not as a learning project. The model is relatively self explanatory books have title and id and a boolean completed "field". I want to have a page that lists the books and has a button next to each book that will change the read status to True and update immediately using AJAX/jQuery (and eventually a similar unread button for mistakes). I am having trouble getting the button to work. Specifically I think I need to somehow assign some sort of id to each row so that jQuery knows which item it is working with.
Apologies for any obvious errors. I am new to web programming and I regret having to ask you all for help, but I have been trying to work out a solution myself for a few days now.
Here is the django template snippet:
{% for book in lib_dict.books %}
<tr>
<td>{{ book.title }}</td>
<td>{{ book.date_due }}</td>
<td id="book_completed_{{ book.id }}">{{ book.completed }}</td>
<td>
<button id="{{ book.id }}" data-bookid="{{ book.id }}" class="btn-mini btn-primary c" type="button">Complete</button>
</td>
</tr>
{% endfor %}
views.py:
def complete_book(request):
context = RequestContext(request)
book_id = None
if request.method == 'GET':
book_id = request.GET['book_id']
if book_id:
book = Book.objects.get(id=int(book_id))
if book:
book.completed = True
book.save()
return HttpResponse(book.completed)
jQuery code - I would imagine the error(s) are here
$('.btn-mini btn-primary c').click(function(){
var bookid;
bookid = $(this).attr("data-bookid");
$.get('/libco/complete_book/', {book_id: bookid}, function(data){
var bookstring = '#book_completed_' + bookid;
$(bookstring).html(data); \\trying to update the completed table cell
$('#bookid').hide(); \\trying to hide the button
});
});
Please note, all of the connectivity works fine. If I just make this button for a single row with a dedicated id, and use the appropriate #-tag in the first line of the jQuery it works, but I am having trouble with the generalization. Maybe the "." thing isn't the way to get the class in the first line?
Also, I am very much trying to teach myself, so if there are any good resources for this kind of thing please let me know. I started working on the official jQuery tutorial, but I looked through it quickly and nothing seemed too related to this.
Thanks you all!
Change this:
$('.btn-mini btn-primary c')
to:
$('.btn-mini.btn-primary.c')

Categories