How to identify multiple forms in one template? - javascript

I'm trying to implement a follower/following system in Django. In the template, all follow requests have a user and they all have user id's that can be displayed. The template is a profile page that contains several follow requests made by other users. I have created a separate form for each accept/decline and I want to uniquely identify each form so that I can submit that one and remove it subsequently.
<div class="col s12 l6 trending-panel container">
<h4>
Requests
</h4>
<div class="divider"></div>
{% for bond_request in bond_requests %}
{% if bond_request.accepted == False %}
<div>
<div class="row bond-request-row" id="{{bond_request.by_user.id}}">
<div class="col s6">
<a href="{% url 'accounts:profile' bond_request.by_user.username %}">
<div class="col s8">
<img class="profile-image-request" src="https://m.media-amazon.com/images/M/MV5BNjUxNDcwMTg4Ml5BMl5BanBnXkFtZTcwMjU4NDYyOA##._V1_.jpg" alt="">
</div>
<div class="col s4">
<h6 id="follower-username">
#{{bond_request.by_user}}
</h6>
</div>
</a>
</div>
<div class=" col s12 center accept-decline-margin">
<div class="col s12 l6">
<form action="accounts:accept_bond_request" method="POST" id="bond-request-accept-form">
<!-- <a href="#" id="bond-request-accept" class="green-text white btn">
<div>
<ion-icon name="add"></ion-icon>
<span>Accept</span>
</div>
</a> -->
<button id="bond-request-accept" class="green-text white btn" type="submit">Accept</button>
</form>
</div>
<div class="col s12 l6">
<a href="" class="grey-text white btn">
<div class="">
<ion-icon name="remove"></ion-icon>
<span>Ignore</span>
</div>
</a>
</div>
</div>
</div>
<!-- HERE -->
</div>
{% else %}
{% endif %}
<div class="divider">
</div>
{% endfor %}
</div>
$("#bond-request-accept-form").on('submit',function(){
// Cleans the username
// var each_bond_request = $();
var raw_follower_username = $("#follower-username").text().trim();
var follower_username = raw_follower_username.replace("#","");
console.log("Follower username: ",follower_username);
$.ajax({
type: "POST",
url: "/accounts/user/" + follower_username + "/accept_request",
data:{
"follower_username" : follower_username,
},
success: function(data){
console.log(data);
M.toast({html: follower_username + ' started following you',classes: 'green'}, );
},
error: function(data){
console.log("All error data: ",data);
M.toast({html: 'Failure',classes: 'red'}, );
},
});
});

You should create a standalone function to handle submit. And reference this function in each form you created.
function SubmitHandler (e) {
// Cleans the username
// var each_bond_request = $();
var raw_follower_username = $(e).find("#follower-username").text().trim();
var follower_username = raw_follower_username.replace("#","");
console.log("Follower username: ",follower_username);
$.ajax({
type: "POST",
url: "/accounts/user/" + follower_username + "/accept_request",
data:{
"follower_username" : follower_username,
},
success: function(data){
console.log(data);
M.toast({html: follower_username + ' started following you',classes: 'green'}, );
},
error: function(data){
console.log("All error data: ",data);
M.toast({html: 'Failure',classes: 'red'}, );
},
});
return false;
}
Then in your template:
...
<form id="bond-request-accept-form" onsubmit="SubmitHandler(this)">
...
Note the #follower-username should be nested within the form tag for jQuery to find the correct one.

First, I just want to say that I may be understanding your question wrong. If so, feel free to correct me.
If I am understanding this right, you have multiple copies of essentially the same form with slight variations depending on the user that is sending the request. Since IDs are meant to be unique and can cause issues in JavaScript if there are more than one instance of them, I would change the bond-request-accept-form to a class rather than an ID, and do something like this in JQuery:
$(".bond-request-accept-form").toArray().forEach(function(elem){
$(elem).on('submit', function(){
// Logic to perform when the form is submitted
});
});

Put different URLs in the action for the two forms. Then you'll have two different view functions to deal with the two different forms.

Related

Issue on getting id from Selected HTML elements from Ajax GET response with jQuery

I am using ajax to display product data and then delete on click a specific on using the product id but am not able to get the product id as it is showing undefine can you guys suggest something.
In this code first I am getting the product details for the cart dropdown menu and then displaying it in list format with delete button through the first ajax and then on clicking delete should delete the element in the second ajax using the elements product id which I have saved inside data-r but on console, it showing undefined can anyone tell me what is the issue. As I know that the elements are created dynamically but I am not getting a solution
function TopCartVal() {
// Used Route inside the ajax
var url = "{{ route('pdt.details', ':id') }}";
var yui = "{{ route('delete_fr.cart', ':id') }}";
// Ajax Structure
$.getJSON( "{{ route('my.cart','json') }}", function( data ) {
console.log(data);
var Cart = $('#cart_dp_sec_pdt_desc');
// Loop for data
$.each(data, function(key , value) {
console.log(value);
url = url.replace(':id', value.product_id);
yui = yui.replace(':id', value.product_id);
Cart.append(`
<div class="row">
<div class="col-xs-4">
<div class="image">
<a href="`+url+`">
<img src="{{ asset('')}}`+value.image+`" alt=""/>
</a>
</div>
</div>
<div class="col-xs-7">
<h3 class="name">
`+value.product_name+`
</h3>
<div class="price">`+value.currency+value.product_price+`</div>
</div>
<div class="col-xs-1 action">
<a href="#"
data-r"`+value.id+`"
class="cart_dp_btn_ctn_delete">
<i class="fa fa-trash"></i>
</a>
</div>
</div>
`);
});
});
}
// delete part
$(document).on('click', '.cart_dp_btn_ctn_delete', function(e){
e.preventDefault();
var id = $(this).attr('data-r'); // id of to be deleted element
var yui = "{{ route('delete_fr.cart', ':id') }}";
yui = yui.replace(':id', id);
console.log(yui);
console.log(id); // it is showing undefined`enter code here`
// $.getJSON( yui, function(data){
// TopCartVal();
// });
});
You are missing an = here:
data-r"`+value.product_id+`"
But using template literals correctly will make it easier to see
`<div class="row">
<div class="col-xs-4">
<div class="image">
<a href="${url">
<img src="{{ asset('')}}${value.image}" alt=""/>
</a>
</div>
</div>
<div class="col-xs-7">
<h3 class="name">
${value.product_name}
</h3>
<div class="price">${value.currency+value.product_price}</div>
</div>
<div class="col-xs-1 action">
<a href="#" data-r="${value.product_id}" class="cart_dp_btn_ctn_delete">
<i class="fa fa-trash"></i>
</a>
</div>
</div>`

can't refresh the data in a DIV python Django nor the page after a jquery

Let me start by saying I have 2 variables in an HTML template(messages and users) and I have multiple buttons that when one of them is clicked it calls a jquery code that sends a post request to a Django server and it returns an update to a variable(messages)
however, it's not updating the loop, I also tried to return a new HTML page that contains the new variable updated but the jquery is not updating the whole page with the new HTML
if I can update the variable alone it would be better and if I can't do that how can I make jquery use the new HTML page
the python code i used to return the update to the varialbe messages:
if request.method == 'POST':
send=Message.objects.filter(from_id=request.POST.get('userId'),to_id=2)
rec=Message.objects.filter(from_id=2,to_id=request.POST.get('userId'))
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
print(messages)
return HttpResponse(list(messages))
and the code i used to return new HTML template:
m = Message.objects.filter(to_id=2).order_by('-id')
users = {}
for i in m:
if users.get(i.from_id.username) == None:
users[i.from_id.username] = User.objects.get(id=i.from_id.id)
users = list(users.values())
send=Message.objects.filter(from_id=users[0].id,to_id=2)
rec=Message.objects.filter(from_id=2,to_id=users[0].id)
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
if request.method == 'POST':
send=Message.objects.filter(from_id=request.POST.get('userId'),to_id=2)
rec=Message.objects.filter(from_id=2,to_id=request.POST.get('userId'))
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
print(messages)
return render(request,'psych.html',{"users":users, "messages":list(messages)})
return render(request,'psych.html',{"users":users, "messages":list(messages)})
the HTML code and jquery code that uses the variable and try to update it
function newUser(id){
$.ajax({
type: 'POST',
url:'/psych.html/',
data:{
userId:id,
},
success: function(data){
console.log(data);// the data returnd are correct and as needed
//but i cant make it update the messages
$('#messageDiv').load(document.URL + ' #messageDiv');
}
})
}
{% for i in users %}
<li class="">
<button type="button" class="btn" onClick="newUser({{i.id}})">
<div class="d-flex bd-highlight">
<div class="img_cont">
<!-- here was an image ----------------------------------------------->
</div>
<div class="user_info">
<span>{{i.id}}</span>
</div>
</div>
</button>
</li>
{% endfor %}
<!-- The varialbe that i'm trying to update is called messages bottom -->
{% for o in messages %}
{% if o.to_id.id != 2 %}
<div class="d-flex justify-content-start mb-4">
<div class="img_cont_msg">
<!-- here was an image-->
</div>
<div class="msg_cotainer">
{{o.message}}
<!-- <span class="msg_time">{{o.time}}</span> -->
</div>
</div>
{% else %}
<div class="d-flex justify-content-end mb-4">
<div class="msg_cotainer_send">
{{o.message}}
<!-- <span class="msg_time_send">{{o.time}}</span> -->
</div>
<div class="img_cont_msg">
<!-- here was an image-->
</div>
</div>
{% endif %}
{% endfor %}
if it helps i did it before and updated the messages from jquery but i used form and there was only 1 variable i will add the code to that too
$(document).on('submit','#submitMessage', function (e){
e.preventDefault();
$.ajax({
type: 'POST',
url:'/psych.html/',
data:{
message:$('#messageHolder').val(),
csrfmiddlewaretoken: $('input[message=csrfmiddlewaretoken]').val(),
},
success: function(data){
// it work like charm here
$('#messageDiv').load(document.URL + ' #messageDiv');
}
})
})
{% for o in messages %}
{% if o.to_id.id == 2 %}
<div class="d-flex justify-content-start mb-4">
<div class="img_cont_msg">
<!-- here was an image-->
</div>
<div class="msg_cotainer">
{{o.message}}
<!-- <span class="msg_time">{{o.time}}</span> -->
</div>
</div>
{% else %}
<div class="d-flex justify-content-end mb-4">
<div class="msg_cotainer_send">
{{o.message}}
<!-- <span class="msg_time_send">{{o.time}}</span> -->
</div>
<div class="img_cont_msg">
<!-- here was an image-->
</div>
</div>
{% endif %}
{% endfor %}
<form id="submitMessage" >
{% csrf_token %}
<div class="card-footer">
<div class="input-group">
<div class="input-group-append"></div>
<input name="message" class="form-control type_msg" placeholder="Type your message..." id="messageHolder">
<div class="input-group-append">
<button type="submit" class="btn">
<span class="input-group-text send_btn" ><i class="fas fa-location-arrow"></i></span>
</button>
</div>
</div>
</div>
</form>
Try this
$("#messageDiv").load(location.href+" #messageDiv>*");
i figured the problem and it was because i didn't know that
$("#messageDiv").load(location.href+" #messageDiv>*");
would make a GET request so all I did was adding the necessary data to the URL and then change the URL too(so if the client refreshed the page it would stay in the same spot) without refreshing the page and then do the command app there
if it could help anyone please look at the code below:
function newUser(id){
var url = document.URL;
url = url.split('/');
url[url.length-2] = id;
url = url.join('/');
window.history.pushState("object or string", "my website name", url);
$('#messageDiv').load(url + ' #messageDiv');
}
sadly i don't know how to do post requst then load the page please if you know comment down bellow so someone else might get help from it

How to add a hyperlink to the data in the created div using API

I am retrieving data based on users input (zipcode), using API. They get three types of information, name of the institution, address and webpage. I would like to add a hyperlink to the webpage line (<p>${data[i].website}</p>) but none of my ideas worked. Thank you, guys.
function ajaxCallNY(zipcode){
$.ajax({
url: "https://data.cityofnewyork.us/resource/72ss-25qh.json?zip_code=" + zipcode,
type: "GET",
data: {
"$limit" : 50,
"$$app_token" : app_token
}
}).done(function(data) {
console.log(data);
for (var i=0; i<data.length; i++){
var nyDiv = $(`<div class="col s12 m6">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class"card-title">${data[i].agency_id}</span>
<p>${data[i].address}</p>
<p>${data[i].website}</p>
</div>
</div>
</div>
`);
$("#zipcode").append(nyDiv);
}
});
}
Since you're using template literals already, you can do it like this:
`
<div class="col s12 m6">
<p>${data[i].address}</p>
<p>Link</p>
</div>
</div>
`

AJAX call botched by DOM Traversal

I am attempting to implement a Like / Dislike system with a counter. I am having problems with my AJAX call, more specifically when I am trying to change the HTML of selected elements in the view after passing values to the DB.
The element in question is .likeCount, a class with about a dozen or so siblings. If i simply use the selector $('.likeCount'), the AJAX call will actually successfully update the like count but it will do it for every instance of the class. If i attempt to use DOM traversal (.closest, this, .parent, etc) the like count does not update until I refresh the page.
the up and downvote carry a $('like') class.
$(document).ready(function()
{
$('.like').on('click', function(event)
{
postId = event.target.parentNode.parentNode.dataset['postid'];
var isLike = event.target.previousElementSibling == null;
$.ajax(
{
method: 'POST',
url: urlLike,
cache: false,
data: {isLike : isLike, postId : postId, _token : token},
success: function()
{
//first function working great
//(changes the like button to a disklike button and visa versa)
$.ajax(
{
method: 'POST',
url: urlCount,
cache: false,
data: {postId : postId, _token : token},
dataType: 'json',
async: true,
success: function(data)
{
var likeCount = event.target.parentNode.parentNode.childNodes[2].textContent;
$('likeCount').html(data["count"]);
console.log(data["count"]);
}
})
}
})
})
})
The console.log spits out the correct count every time.
How do I select the currently active likeCount without botching my AJAX call?
Here is the markup:
<div class="row posts">
<div class="col-md-6 col-md-offset-3">
<header><h3>Recent Posts:</h3></header>
#foreach($posts as $post)
#if (Storage::disk('local')->has($post->user->id . '.jpg'))
<div class="col-xs-2">
<img src="{{ route('account.image', ['filename' => $post->user->id . '.jpg']) }}" alt="" class="img-responsive">
</div>
#else
<div class="col-xs-2">
<img src="default.gif" alt="" class="img-responsive">
</div>
#endif
<article class="post col-xs-10" id="post" data-postid={{ $post->id }}>
<p class="post-body">{{ $post->body }}</p>
<div class="info">
Posted by {{ $post->user->name }} on {{ $post->created_at }}
</div>
<div class="likeCount">{{ $post->likes->where('like', '1')->count() }} other people liked this.</div>
<div class="interaction">
<a class="like btn upvote">{{ Auth::user()->likes()->where('post_id', $post->id)->first() ? Auth::user()->likes()->where('post_id', $post->id)->first()->like == 1 ? 'You like this' : 'Like' : 'Like'}}</a> |
<a class="like btn downvote">{{ Auth::user()->likes()->where('post_id', $post->id)->first() ? Auth::user()->likes()->where('post_id', $post->id)->first()->like == 0 ? 'You dislike this' : 'Dislike' : 'Dislike'}}</a>
#if(Auth::user() == $post->user)
|
Edit |
Delete
#endif
</div>
</article>
#endforeach
<?php echo $posts->links(); ?>
</div>
</div>
The issue here is incorrect DOM Traversal.
var likeCount should be:
$(event.currentTarget.parentNode.parentNode.childNodes[5]);
Using 'event' simplifies things when multiple elements share a class name.

show records on same details page by clicking next button in asp.net mvc getting error

I want to display the records on details page when user click on next button then he should be able to display the next record of table. Suppose user select the details of a particular record id 1 he get the details of that id 1 at the same time on the same page by clicking the next button user should be able to get the record of id 2 and vice versa. I have done it but getting some error when table has no such id named id 3 after id 1 and id 2 its showing me the error. Please help me to find out where i am wrong.
View
#model WebApp.ViewModels.ViewTeamList
<script type="text/javascript">
var dataid = '#Html.Raw(Json.Encode(Model.TeamDetails.TeamId))';
for( var item in dataid)
console.log(dataid[item]);}();
</script>
<script type="text/javascript">
$("#btnNext").click(function () {
var $buttonClicked = $(this);
var nid = $buttonClicked.attr('data-id');
console.log(nid);
$.ajax({
url: 'Team/Next',
data: { dataid: nid },
//data: JSON.stringify(data.TeamId),
success: function (response) {
divDetail.html(data);
}
});
});
</script>
<div class="row">
<div class="col-md-11 col-sm-11 pull-left" style=" font-size:large; font-weight:600">
#Model.TeamDetails.TeamName
</div>
#* <div class="col-md-1 col-sm-1 pull-right">*#
<div class="navi-but">
<a href="#" id="btnPrevious" data-id="#Model.TeamDetails.TeamId" class="details">
<span class="previous">Previous</span>
</a>
<a href="#" class="details" data-id="#Model.TeamDetails.TeamId" id="btnNext">
<span style="padding-right:7px">Next</span><span class="next"></span>
</a>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="~/Images/settings.png" />
</a>
<ul class="dropdown-menu" role="menu">
<li>Edit</li>
</ul>
</li>
</div>
#* </div>*#
</div>
<div class="row">
<div class="col-md-4 col-sm-4">
#Html.CustomLabel("lblTeam","CT Team Name:")
</div>
<div class="col-md-8 col-sm-8">
#Model.TeamDetails.TeamName
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4">
#Html.CustomLabel("lblDescription","Description:")
</div>
<div class="col-md-8 col-sm-8">
#Model.TeamDetails.Description
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4">
#Html.CustomLabel("lblCTUserCount","User Count")
</div>
<div class="col-md-8 col-sm-8 pull-left">
#Model.TeamDetails.UserCount
</div>
</div>
Controller
public ActionResult Next(int dataid)
{
dataid++;
ViewTeamList viewTeamList = new ViewTeamList();
viewTeamList.ViewTeamDetails(dataid);
return PartialView("_ViewTeamDetails", viewTeamList);
}
View model
public class ViewTeamList
{
public TeamDetails TeamDetails;
private ITeamService teamService;
public ViewTeamList()
{
}
public void ViewTeamDetails(int Id)
{
teamService = new TeamService(pDbContext);
TeamDetails = teamService.GetTeamDetails(Id);
//return (TeamDetails.First());
}
}
Please help where i am doing wrong.
I didn't look your code in detail but it seems to me that you have a logical problem. Since you are always incrementing id by one ( dataid++; ) that won't work if some record is deleted in the meantime. For example let's say that you have Record1 with id 1, Record2 with id 2 and Record 3 with id 3 and you delete Record2. Now when you are trying to get next record after Record1 you are incrementing id by 1 so you have 2 and there is no record with id 2 in the db anymore.
Instead of dataid++; you should find next id that really exists in db. As I said I didn't read code in detail so there may be more possible problems.
To Display from WebMethod You Should follow these steps:
create
[webmethod]
to retrieve all the data
List items then make a javascript method in client side use:
ajax({ type:'post', url:'exaple.aspx/showMethod', data:{}, datatype:'json', contentType:'application/json; charset=utf-8',
scuccess:function(data) --display from here in table or any other
data ), error:function(){ alert('Error'); } })

Categories

Resources