jQuery get clicked value in jinja2 loop - javascript

I have a small app with a flask backend and jinja2 templating.
In the html, I have a loop that organizes into batches creating 3 columns on the page:
{% for batch in df.iterrows() | batch(3) %}
<div class="row">
{% for row_id, row in batch %}
I have some jQuery to get the item that is clicked on in a cascading dropdown. A jinja2 loop is populating the dropdown by looping through a dataframe. The jQuery is getting the value from the html by ID (as the ul id):
<ul id="model1" class="list-group">
Ultimately I need three values, one for each batch. However, the code only returns the most recent item clicked on. The reason for that is I can't figure out how to get jQuery to get one item per batch -- or link to the batch somehow. Can I put the batch number in the ul id somehow?
$(document).ready(function(){
$('ul#menu li').hover(function(){
$(this).children('ul').delay(20).slideDown(200);
}, function(){
$(this).children('ul').delay(20).slideUp(200);
});
$('#model1 li').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('model1 ' + e.target.getAttribute('data-val'))
$("input[name=suggestion1]").val(e.target.getAttribute('data-val'));
});
//CODE is past here DOESN'T work but I left it in to give an idea
$('#model2 li').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('model2 ' + e.target.getAttribute('data-val'))
$("input[name=suggestion2]").val(e.target.getAttribute('data-val'));
});
$('#model3 li').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('model3 ' + e.target.getAttribute('data-val'))
$("input[name=suggestion3]").val(e.target.getAttribute('data-val'));
});
$("form").submit(function(){
var s1 = $("input[name=suggestion1]").val();
var s2 = $("input[name=suggestion2]").val();
var s3 = $("input[name=suggestion3]").val();
console.log(s1, s2, s3);
});
});

Posting this in case it helps someone else.
This excellent post explains how to use the loop variable in a flask template: count number of rows in flask templates
For my code, I made the div ID change based on the loop index.
{% for batch in recomm_df.iterrows() | batch(3) %}
<div class="row">
{% for row_id, row in batch %}
<div class="col-md-4" id="cat_{{loop.index}}">
Within that loop, I gave my unordered list an ID like :
<ul id="cat_sug" class="list-group">
Then you can grab those the data val that is clicked on in JQuery:
$('#cat_1 #cat_sug').on("click", function(e){
e.stopPropagation();
e.preventDefault();
console.log('cat_1 ' + e.target.getAttribute('data-val'))
// var s1 = e.target.getAttribute('data-val');
$("input[name=suggestion1]").val(e.target.getAttribute('data-val'));
});

Related

Jquery is sending multiple requests

I'm trying to make a search bar which sends a request for proposals from the entered letter. jQuery is sending the same number of requests as the number of the entered letters.
If I write "sa" jQuery is sending 2 requests. If I write "Sa" jQuery is sending 3 Requests (the big letter is counted as 2 letters since I'm pressing shift".
The code should work like the following instructions: The user writes the name of what he wants to found and the code search in the database and shows all possible search words.
EDITS:
the script should send 2 Request: the first one to get all results which have "sa". after selecting a result. it should send only one request to the database to get the rest of the information. what my script is doing: he is sending the firs request as he should do. the second request is getting send as same time as the number of the letters. even when only one request is enough
here is also a link to a youtube video which I record to explain the problem
Here is my jQuery code:
$('.sucherInput').on('keyup', function () {
// ** .sucherInput is the class of the input field
var inputValue = $('.sucherInput').val();
var result = $(".sucherres");
var resultList = $(".sucherres ul");
if (inputValue.length) {
console.log(inputValue);
$.post("action/php/artikelSucher.php", {
name: inputValue
}).done(function(data){
// Display the returned data in browser
//console.log(data);
resultList.html(data);
result.show();
}); //.done
} else{
console.log("empty");
resultList.empty();
result.hide();
}
$(document).on("click", ".sucherres ul li p", function(){
//set the search bar value as same as the clicked <p> tag
$('.sucherInput').val($(this).text());
//clear the Proposals list
$(resultList).empty();
$(result).hide();
//renew the value of the search bar
//since im taking the value which have to be searched in the database from the searchbar
var sucherLastIndex = $('.sucherInput').val();
console.log("Getting data from database: " + sucherLastIndex);
//load the data into the HTML file
$("#updateDiv #info").load("action/php/index-preis-liste.php", {
name: sucherLastIndex
});
});
});
Here is the Html Code:
<div class="sucher">
<ul style="width: 100%; margin-bottom: 0;">
<li style="width: 33%;">
<input type="text" class="sucherInput" placeholder="Geben Sie einen Suchbegriff ein">
</li>
</ul>
<div class="sucherres">
<ul>
<!-- ## HERE COMES THE Proposals ## -->
</ul>
</div>
<div id="info">
</div>
I found the solution**
it's by changing
$(document).on("click", ".sucherres ul li p", function(){
to
$(document).off('click').on("click", ".sucherres ul li p", function(){
so simply by adding
.off('click')
**

Update dynamically generated list item (generated using PHP) after ajax call

The following HTML code is being echoed using a while loop in PHP which is adding a list item after fetching data from database.
PHP:
echo '
<li>
<div class="collapsible-header">
<div class = "left">
<div class = "issueStatusIcon" style = "background-color:'.$smallCircleColor.';">'.$smallMsg.'</div>
<span class = "issueTitle" style = "font-family: robotoBold">'.$issueTitle.'</span>
</div>
<div class = "issueButtonsGroup">
<form id = "archiveIssueForm'.$i.'" issue-name = "'.$issueTitle.'" action = "archiveIssue.php">
<input type = "hidden" value = "'.$issueID.'" name = "issueID"/>
</form>
<a class = "right archiveIconButton" onclick = "ajaxIssueArchive('.$i.')" href = "#">
<i class="material-icons black-text issueOptions archiveIcon">archive</i>
</a>
<a class = "right"><i class="material-icons black-text issueOptions">edit</i></a>
</div>
</div>
</li>
';
This is the preview image of the generated list:
Notice the cursor over the archive button which archives the list item. The class for that button is archiveIconButton (you can find it in the above code). When the button is clicked, archiveIssueForm is submitted via AJAX (each form has a unique identifier variable $i appended to its id).
Following is the JQuery AJAX code:
JQuery:
<script>
function ajaxIssueArchive($num){
$.ajax({
type: "post",
url: "archiveIssue.php",
data: $('#archiveIssueForm' + $num).serialize(),
success: function(data){
$fetchIssueName = $('#archiveIssueForm' + $num).attr("issue-name");
$toastText = $fetchIssueName + " has been archived";
Materialize.toast($toastText, 3000);
$('#archiveIssueForm' + $num).html(data);
}
});
}
</script>
After archiving any list item, it gets deleted from the database. I want to update the ul element which contains these list items so that the list item which gets deleted doesn't gets displayed after the AJAX form submission.
Assume the id of ul to be issueListUL.
What i'm currently getting is the whole code of the html page displayed in the li item. I am certainly doing something wrong, any help would be appreciated!
After archiving a list item:
I was able to solve this issue in the following way, The JQuery script in the question should be changed like this:
JQuery:
<script>
function ajaxIssueArchive($num){
$.ajax({
type: "post",
url: "archiveIssue.php",
data: $('#archiveIssueForm' + $num).serialize(),
success: function(data){
//assigning the updated ul's html to a variable
$afterIssueArchival = $(data).find("#issueListContainer").html();
//toast
$fetchIssueName = $('#archiveIssueForm' + $num).attr("issue-name");
$toastText = $fetchIssueName + " has been archived";
Materialize.toast($toastText, 3000);
//updation of ul's html, ID of the ul which contains all the list items is assumed to be 'listContainer'
$("#issueListContainer").html($afterIssueArchival);
}
});
}
</script>
When updating an element's html, just extract the element's updated html code from data attribute in the ajax code (as show in the above code) and update the existing element's html with it!
Hope this helps people with the same problem as mine! :D

Octobercms Component Twig

Can someone show me how to set unique Id for components?
I only know I have to put this code in my default.htm
{% set uid = '{{__SELF__.id}}' %}
how to use it in javascript?
and what is this for?
var avatar_{{uid}} = {{ avatar }};
for example this is my js
$(function(){
$("#tab-close").click(function() {
$("#tab").addClass("hidden");
});
});
How do I set a unique Id for it so that when I duplicate the component both can still work normally without errors?
It might be better to encapsulate your control with a single identifier, like this
<div id="mycontrol{{ __SELF__.id }}">
...
</div>
Then in JavaScript, you can target elements inside:
function initTabs(controlEl) {
var $control = $(controlEl)
$(".tab-close", $control).click(function() {
$(".tab", $control).addClass("hidden");
});
}
The code above targets the class names found only inside the $control container. You would call this function from the markup like so
<script>
$(function(){
initTabs('#mycontrol{{ __SELF__.id }}');
});
</script>

How to insert Bootstrap drop-down values in database

i am using bootstrap for making a user form.
Now i need to insert selected drop-down value in database.
But i am facing two problems.
1) When i select any item from drop-down, it jumps to top of my screen in url because of href="#". When i removed "#", it started the page refresh on selection item.
2) How i target my drop-down list to insert any selected value in database using php.
My code is
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">Select City
<span class="caret"></span></button>
<ul class="dropdown-menu">
<li>Lahore</li>
<li>Islamabad</li>
<li>karachi</li>
</ul>
</div>
javascript code
$(document).ready(function() {
$(".dropdown-menu li a").click(function(){
$(this).parents(".dropdown").find('.btn').html($(this).text() + ' <span class="caret"></span>');
$(this).parents(".dropdown").find('.btn').val($(this).data('value'));
});
For the point 1 :
Since you have the # in the href the page scrolls up (i.e. navigating to the link target). You can prevent this event by adding event.preventDefault() in your code.
For Point 2: Since you said if you are able to get the value to your server side php code then you can proceed further you can make use of AJAX Post method. The final code would be
$(document).ready(function() {
$(".dropdown-menu li a").click(function(e){
e.preventDefault(); //this is the line which prevents the event
$(this).parents(".dropdown").find('.btn').html($(this).text() + ' <span class="caret"></span>');
$(this).parents(".dropdown").find('.btn').val($(this).data('value'));
//this is the code to post the value to server
$.post("YourPHPMethod.php",{name: $(this).text()} ,function(response){
alert("Response from server: "+response);
});
});
You have to post it to a php. I do it with ajax like this.
Look: http://www.codesheet.org/codesheet/wOHDXFju
function postContent(cv) {
$("#myDiv").html('L O A D I N G ...').show();
var url = "/post.php";
$.post(url, {id: cv} ,function(data) { //contentVar is the variable in post.php
$("#myDiv").html(data).show();
});
}

A better way to pull an ID from a form submission Javascript/Django

Currently what I have coded up works, but it seems rather crude. Basically here's what I have (simplified):
JQuery ready:
<script type="text/javascript">
$(document).ready(function() {
$('div.partDelete').click(function() {
// TODO this seems like a dirty hack
var split = this.id.split('_');
if(split.length == 3) {
$('#part_id').val(split[0]);
alert($('#part_id').val());
$('#removePartForm').submit();
} else {
alert('There was a problem removing the selected part');
}
});
</script>
The form I am using:
<form id="removePartForm" action="{% url remove_part %}" method="post">
<input type="hidden" id="part_id" name="part_id" value="-1" />
{% for part in current_build.parts.all %}
<div id="{{ part.id }}_part_id" class="partDelete">remove</div>
{% endfor %}
</form>
All I'm trying to do is set the hidden input to take the part.id that has been selected by the user so that I can use it in my views.
For all I know this is the correct way to go about this, but I just have a feeling it isn't. I am new to Django & JQuery so there may be some built in functionality for this that I haven't found yet.
Thanks for any suggestions that you may have!
Solution (see mikaelb's answer below)
Javascript:
$('div.partDelete').click(function() {
var selected_id =$(this).data("id");
$('#part_id').val(selected_id);
$('#removePartForm').submit();
});
HTML changes:
<div class="partDelete" data-id="{{ part.id }}">remove</div>
First of all; IDs shouldn't start with a number (http://www.w3.org/TR/html4/types.html#type-name).
Aside from that, you'd typically use the data-* attribute for setting IDs to communicate with JS from server side. The data-* attribute can be anything you want. So data-foo="" is a valid attribute.
Example:
HTML:
<div class="item" data-id="{{ part.id }}">
<p>Foo</p>
</div>
Javascript:
$(function () { // same as document read
$(".button-class").on("click", function () {
// Here "this" will be the element
var id = $(this).data("id"); // same as getting attribute data-id
// Could also use $(this).attr("data-id")
});
});
Hope this helps.
Edit: Moved comment to make it more clear, changed the example to be more specific to OP's problem.

Categories