Javascript working only after I open a modal - javascript

So I have a problem where my script for a filter/search list used to work, added a few lines of code to open a modal when a certain event occurs and now strangely when I go on my page, I can't use the search/filter list, but when I open the modal and close it, then I can use it..? It looks like it has to process the modal script first to be able to use the search/filter script.
I am working with Django and MySQL, here are the relevant lines of code:
.html ( first lines are about the search function, the second part is the modal and third block is the table used in the search/filter function and the conditions for opening the modal )
<div class="search-right">
<input type="text" id="mySearchInput" placeholder= " Search a stock.." title="Stock Search" style="float:left">
</div>
{% if warning %}
<div id="myModalAddaStock" class="modalAddaStock">
<div class="modal-content">
<span class="closeAddaStock">×</span>
<p>{{warning}} {% if stock_to_add %}{{stock_to_add}} {% endif %}{% if stock_to_replace %}{{stock_to_replace}} or {{flex}}{% endif %}</p>
</div>
</div>{% endif %}
<div class="grid-itam-2bottom">
<table id="myTable1" class="myTable"cellspacing="0" cellpadding="1" border="1" width="100%">
<tr class="stockheader">
<th width="8%" style="text-align:center;">Symbol</th>
<th width="35%"style="text-align:center">Company Name</th>
<th width="8%" style="text-align:center">Sector</th>
<th width="7%" style="text-align:center">Streak</th>
<th width="12%"style="text-align:center">Market Cap</th>
<th width="8%" style="text-align:center">Return</th>
<th width="6%" style="text-align:center">WL</th>
<th width="6%" style="text-align:center">Add</th>
</tr>
{% for stock in stock_list %}
<tbody id="searchAstock">
<tr>
<td id="searchsymmol" style="border-bottom:1px;padding-left: 5px;">{{stock.symbol}}</td>
<td style="border:0px;"class="Ellipsis Company">{{stock.company_name}}</td>
<td data-type="{{stock.sector}}">{{stock.sector}}</td>
<td>{{stock.streak}}</td>
<td>{{stock.market_cap_rounded}}</td>
<td>{% if 1w %}{{stock.five_day_avg}}{% elif 2w %}{{stock.ten_day_avg}}{% elif 3w %}{{stock.fifteen_day_avg}}{% else %}{{stock.change_percent}}{% endif %}</td>
<td style="text-align:center"><img onclick="myFunctionWL" id="WLtest"src="{% static "Myimages/images/flag.png" %}" alt="" title="Add to Watchlist" height=20 width=20 style="border-radius:50%;"></img></td>
<td style="text-align:center"><img src="{% static "Myimages/images/icon.png" %}" title="Add to my Team" height=20 width=20 style="border-radius:50%;"></img></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
And here are the scripts:
function myFunctionsearchbar() {
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById("mySearchInput");
filter = input.value.toUpperCase();
ul = document.getElementById("myTable1");
li = ul.getElementsByTagName("tr");
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
var modal = document.getElementById("myModalAddaStock");
var span = document.getElementsByClassName("closeAddaStock")[0];
span.onclick = function() {
modal.style.display = "none";
}
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
I feel like there is a core concept I have missed about Javascript? My script was working just fine before I implement the modal ( those loops at the beginning of the HTML files ) and now it only works AFTER those loops are done...

Related

Compare 2 columns data of a row and highlight one having same match using javascript

I have a query regarding javascript. I am working on a structure with nested tables and rows (tr) are in the loop and inside it (td) are also in the loop. I want to compare the data of 2 columns one outside the loop and one td inside the loop and in case of a match would like to highlight the td outside the loop. Here is a piece of code that I wrote but it is highlighting all the rows rather than only the corresponding one. Also, it's not running on all the td which are inside the for-loop.
function highlight_text(){
table = document.getElementById("table");
tr = table.getElementsByClassName("rows");
for (x = 0; x < tr.length; x++) {
td = tr[x].getElementsByTagName("td")[3];
txtValue = td.textContent || td.innerText;
txtValue = txtValue.trim()
search_text = tr[x].getElementsByTagName("td")[5];
search_value = search_text.textContent || search_text.innerText
search_value = search_value.trim()
if (txtValue.toUpperCase().indexOf(search_value.toUpperCase()) > -1) {
const regex = new RegExp(search_value,"gi");
let text = tr[x].getElementsByTagName("td")[3].innerHTML;
text = text.replace(/(<mark>|<\/mark>)/gim, '');
text = text.replace(regex, '<mark>$&</mark>')
td.innerHTML = text
}
}
}
<table id="table" style="border: none;">
{% for a in range(respondent_id|length) %}
<tr class="rows">
<td class="c1" colspan="2"><b>{{ Score[a] }}</b></td>
<td><span style="display:none;" id="id_resp">{{ respondent_id[a] }}</span></td>
<td>
<table width="980px;" style="border-color:white;">
<tr>
<td class="verb">{{ Verbatim_data[a] }}</td>
</tr>
</table>
<table>
<tr>
{% for w in range(Final_L1L2L3|length) %}
<td class="L3_comment" onclick="highlight_text()"><div>{{Final_L1L2L3[w] | safe}} </div></td>
<td style="display: none;" class="search">{{Final_verb[w] | safe}}</td>
{% endfor %}
</tr>
</table>
</td>
</tr>
{{endfor}}
</table>
enter image description here

IS there a way to access data-binding in span tag and store it in a variable in the script tag? knockoutjs

oi
<table class="table table-striped table-sm small" >
<thead class="bg-dark text-light">
<tr>
<th scope="col">Id</th>
<th scope="col">Name</th>
<th scope="col">Nationality</th>
<th scope="col" class="text-right"></th>
</tr>
</thead>
<tbody data-bind="foreach: records">
<tr>
<td class="align-middle" data-bind="text:DriverId"></td>
<td class="align-middle" data-bind="text:Name"></td>
<td class="align-middle">
<span id = "nation" data-bind="text:Nationality" class="float-left"> </span>
<img id="flagicon" src="" alt="" class="flag float-right float-center" />
<script>
var alpha_2_code = "pt";
/* for(let i=0; i < countrycodesobj.length ; i++){
if(countrycodes[i].Nationality === (data-bind = "text:Nationality"))
alpha_2_code = countrycodes[i].alpha_2_code;
}*/
var myPath = "https://countryflagsapi.com/png/" + alpha_2_code;
document.getElementById("flagicon").src= myPath;
</script>
</td>
</tr>
</tbody>
I want the information > data-bind="text:Nationality" < stored in a variable in script tag.
Im getting the information from an api and its being handled by knockoutjs. My knockoutjs knowledge is scarce and i dont know if i can access the information data-bind="text:Nationality" in the script tags. Any solution whether in jquery , knockouts or javascript would be perfect.
Thanks in advance.
you could make use of a simple function that you define before you applyBindings with knockout and after your countrycodesobj is defined, sth like:
function getFlagByNationality(n) {
var alpha_2_code = "pt";
for(let i=0; i < countrycodesobj.length ; i++){
if(countrycodes[i].Nationality == n ){
alpha_2_code = countrycodes[i].alpha_2_code;
}
}
return "https://countryflagsapi.com/png/"+alpha_2_code;
}
you can then use this in data-bind attribute:
<img src="" data-bind="attr:{src: getFlagByNationality(Nationality)}" />

Print table information after onclick event in Django

I want to print table row information in a Javascript function bind to the onclick event of a button.
view.py
def table(request):
test_list = TestInformation.objects.order_by()
context = { 'test_list' : test_list, }
return render(request, '/test.html', context)
test.html
<label ~~ id="btn_click" onclick="btn()">
<table class="table table-bordered" id="data_table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{% for li in test_list %}
<tr>
<td> {{ li.Id }} </td>
<td> {{ li.Name}} </td>
</tr>
{% endfor %}
</tbody>
</table>
<Script type="text/javascript">
function btn {
//I'd like to put above {for~~ endfor} source here!
}
</Script>
Currently Action
The table is displayed as soon as you load the html page.
Expected Action
Only visible when the table presses a button
How can I invoke Python objects in JavaScript functions for the actions I expect?

pagination for table rows with fixed tablehead

On my website I created a "dynamic" table. I want to include a pagination, to only show 10 rows at a time. The table head shall be displayed above the rows on every page.
But with my pagination function, all the content within is put under "Ref.". If I uncomment the commented part, the pagination does not work at all.
What needs to changed in my code to display the table correct on each page? (all ref{{i}} under "Ref." / "score{{i}} under "Score" /...)
Table:
{% if empty == False %}
<table style="float: left; width: 100%" class="table table-hover">
<thead id="header">
<tr >
<th>Ref.</th>
<th>Score</th>
<th>Title</th>
</tr>
</thead>
<tbody>
{% for i in range (0,numofresults) %}
<tr id="cardmb3n{{i}}">
<td id="ref{{i}}"> </td>
<td id="score{{i}}" "> </td>
<td>
<div>
<a id="header{{i}}" href=""></a><br>
<a id="hyperlink{{i}}" href="" ></a>
</div>
</td>
</tr>
</tbody>
{% endfor %}
</table>
Pagination:
{% if empty == False %}
function paginate(page){
var val = parseInt(document.getElementById("currentpage").innerHTML);
if(page=='Next'){
page = val + 1;
} else if(page=='Previous'){
page = val - 1;
} else{
page = parseInt(page);
}
if(val!=page){
for(var j = 0; j<ergebnisliste.length; j++){
if(j>=(page-1)*10 && j<10*page){
// document.geElementById("header").style = "display:table";
document.getElementById("cardmb3n" + j).style = "display:block";
}else{
// document.geElementById("header").style = "display:none";
document.getElementById("cardmb3n" + j).style = "display:none";
}
}
........some code.........
}
}
{% endif %}
found a solution: document.getElementById("cardmb3n" + j).style = "display:table-row";

Flask does not return db query when I use the JS hide/unhide. Works if I comment out JS

I am trying to retrieve data from the database based on a users search results. The results, in a table format, should only be shown after the user hits the search button.
Query executes fine when javascript is cancelled out and the table "list" display is changed to block. However, when I enable the javascript I get no results.
<div style="text-align: center;">
{% from "_formhelpers.html" import render_field %}
<form method=post action="/">
<dl style="display: inline-block; text:white;" >{{render_field(form.search)}} </dl>
<button id="searchbutton" type="submit" style="display: inline-block;" class="btn btn-outline-success my-2 my-sm-0" onclick="fetchlist(); return false;">Search</button>
<br>
{% if error %}
<p class = "error"><strong>Error:</strong>{{error}}</p>
{% endif %}
</form>
</div>
<div style="text-align:center;">
<table id="list" style="display:none;" class = "table table-hover" >
<thead>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Rating</th>
<th scope="col">Review</th>
</thead>
<tbody>
{% for row in data %}
<tr>
{% for d in row %}
<td>{{ d }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
<script>
function fetchlist() {
if (document.getElementById('searchbutton').onclick) {
document.getElementById('list').style.display = 'inline';
}
else document.getElementById('list').style.display = 'inline';
}
</script>
{% endblock %}
</html>
#app.route('/', methods=['GET', 'POST'])
def homepage():
try:
form=SearchForm(request.form)
global d1
d1 =""
if request.method == "POST" and form.validate():
search = form.search.data
a = search.split(" ",1)
firstname, lastname = (a[0], a[1])
c,conn = connection()
qry = "SELECT FirstName, LastName FROM posts WHERE FirstName LIKE (%s) AND LastName like (%s)"
c.execute(qry, ((thwart(firstname)), (thwart(lastname))))
d1 = c.fetchall()
c.close()
conn.close()
else: print('error')
return render_template("index.html", data=d1, form = form)
except Exception as e:
return(str(e))
As you already know the problem is caused by your JS. This is because the JS is waiting for the search button to be clicked before it changes the style of the list to inline.
This all seems fine, but the problem comes in the fact that the JS is executed when the button is clicked. But then the request is posted to the server and a new page is sent to the browser with the search results. However, this new page the search button has never been clicked.
You can fix writing the method to display the results into your template. For instance you could wrap the table in an if statement like this...
{% if data|length %}
<div style="text-align:center;">
<table id="list" style="display:none;" class = "table table-hover" >
<thead>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Rating</th>
<th scope="col">Review</th>
</thead>
<tbody>
{% for row in data %}
<tr>
{% for d in row %}
<td>{{ d }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table
</div>
{% endif %}
The |length filter makes sure data is not an empty string. Otherwise I believe it may always be true. You could try {% if data %} to double check. It may work.
There are a lot more options....
You could wrap you <script> in the if statement. You should modify it a little. So it does not wait of the search button to be clicked.
You could wrap the inline style in the if statement. Of course you could use CSS classes instead of inline styling. This would be cleaner.

Categories

Resources