How to set two values to one html button - javascript

I'm working on a page where i'm rendering data from an api, where i make dynamic profile cards. And on clicking the button inside the card i'm calling an api through ajax. my problem is i need two values to pass to req.body to make the ajax success. I mananged the api call using one data using this code,
<div class="container" id="bb1">
<% locals.posts.rows.forEach(function (patient) { %>
<div class="patient-data">
<div >
<div style="padding-left: 100px"> <img src="<%= patient.dp %>" style="width: 45%;"> </div>
<br>
<div style="text-align: center;">
<h5> P.ID : <%= patient.p_id %></h5>
<p> Name : <%= patient.patient_name %></p>
</div>
<div style="padding-left: 110px;margin-bottom:20px ;">
<button type = "button" id="<%= patient.p_id %>" onclick="approve(this.id)" type="button" class="btn btn-info btn-sm" id="btn-success" style="background-color: #D1B147;"> View</button> </a></div>
</div>
</div>
<% }); %>
</div>
then inside my script;
<script type="text/javascript">
function approve(id) {
var p_id = id;
console.log(p_id);
var data = {};
data.p_id = p_id;
$.ajax({
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json',
url: "http://localhost:5000/mData",
success: function(data) {
console.log(data);
localStorage.setItem('myData', JSON.stringify(data));
window.location.href = 'mastersessionhistory';
},
error: function(){
alert("Error")
console.log('error occured')
}
})
}
</script>
using this i was able to hit api and return values. i needed only the p_id to hit api. But now i have new key m_id to so my req.body should be {p_id,m_id}. How to include m_id on that bitton click so that i can call the api.
can i use this
<button type = "button" id="<%= patient.p_id, patient.m_id%>" onclick="approve(this.id)" type="button" class="btn btn-info btn-sm" id="btn-success" style="background-color: #D1B147;"> View</button> </a></div>

Related

Why this alpine.js x-for looping 2 times

I use the alpine.js to render a modal with a x-for loop who populate a select. Strange behavior, the x-for seems looping 2 times and I can't understand why:
the code:
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('load', () => ({
indicateurs: [],
indicateurDictionnaireForm: {},
typeIndicateurs: {},
detectedTypeIndicateur: '',
loadIndicateur() {
$('#overlay').fadeIn();
fetch('<%= request.getContextPath() %>/mesures.load.action')
.then(response => response.json())
.then(data => {
this.indicateurs = data;
$('#overlay').fadeOut();
})
.catch(error => {
});
},
deleteIndicateur(id) {
$.ajax({
type: "DELETE",
url: "<%= request.getContextPath() %>/mesures.delete.action?indicateurDictionnaireId=" + id,
}).then(() => this.loadIndicateur());
},
postForm() {
return {
submitData() {
$.ajax({
type: "POST",
url: "<%= request.getContextPath() %>/mesures.save.action",
data: JSON.stringify(this.indicateurDictionnaireForm),
dataType: "JSON",
contentType: "application/json; charset=utf-8",
}).then(() => {
this.loadIndicateur();
this.resetForm();
$('#modalIndicateur').modal('hide');
})
},
}
},
editIndicateur(id) {
$.ajax({
type: "GET",
url: "<%= request.getContextPath() %>/mesures.load.type-indicateur.action"
}).then(data => {
this.typeIndicateurs = data;
}).then(
$.ajax({
type: "GET",
url: "<%= request.getContextPath() %>/mesures.edit.action?indicateurDictionnaireId=" + id,
}).then(data => {
this.indicateurDictionnaireForm = data;
this.detectedTypeIndicateur = data.typeIndicateur.code;
this.loadIndicateur();
$('#modalIndicateur').modal('show');
})
);
},
resetForm() {
this.indicateurDictionnaireForm = {};
}
}))
})
</script>
the modal code:
<div class="modal" tabindex="-1" role="dialog" id="modalIndicateur">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><s:text name="indicateur.ce.add"/></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form action="<%= request.getContextPath() %>/save.action"
method="POST"
class="w-64 mx-auto" x-data="postForm()" #submit.prevent="submitData">
<div class="form-group" style="padding-left: 15px; padding-bottom: 5px">
<div class="row">
<label class="control-label col-md-2" style="text-align: left"
for="libelle_fr">
<s:text name="indicateur.ce.libelle_fr"/></label>
<div class="col-md-8">
<input id="libelle_fr" type="text"
name="indicateurDictionnaireForm.libelleFr"
class="form-control input-sm"
x-model="indicateurDictionnaireForm.libelleFr">
</div>
</div>
<div class="row">
<label class="control-label col-md-2" style="text-align: left"
for="libelle_nl">
<s:text
name="indicateur.ce.libelle_nl"/></label>
<div class="col-md-8">
<input id="libelle_nl" type="text"
name="indicateurDictionnaireForm.libelleNl"
class="form-control input-sm"
x-model="indicateurDictionnaireForm.libelleNl">
</div>
</div>
<div class="row">
<label class="control-label col-md-2" style="text-align: left"
for="code">
<s:text name="indicateur.ce.code"/></label>
<div class="col-md-8">
<input id="code" type="text"
name="indicateurDictionnaireForm.typeIndicateurCode"
class="form-control input-sm"
x-model="indicateurDictionnaireForm.code">
</div>
</div>
<div class="row">
<label class="control-label col-md-2" style="text-align: left"
for="code">
<s:text name="indicateur.ce.code"/></label>
<div class="col-md-4">
<div class="flex flex-col w-full md:w-2/3">
<select x-model="indicateurDictionnaireForm.typeIndicateurCode"
class="form-control input-sm">
<template x-for="option in typeIndicateurs" x-effect="console.log(detectedTypeIndicateur)">
<option :key="option.code"
:value="option.code"
selected="option.code === detectedTypeIndicateur"
x-effect="console.log('code:', option.code, ' type: ', detectedTypeIndicateur)"
x-text="option.libellefr"></option>
</template>
</select>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"
#click="resetForm()">
<s:text name="common.button.quitter"/>
</button>
<button type="submit" class="btn btn-primary">
<s:text name="common.button.save"/>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
With the x-effect tag, I tried to log the value of the the detected item to be selected in the select tag and the value itself.
this is the console output when the modal is open:
// first loop
<empty string>
code: RESULTAT type: <empty string>
code: INCIDENCE type: <empty string>
code: REALISATION type: <empty string>
// second loop
REALISATION
code: RESULTAT type: REALISATION
code: INCIDENCE type: REALISATION
code: REALISATION type: REALISATION
In the first loop I see the value from my function editIndicateur() is empty so I assume, alpine.s tries to render the modal before the call back and then do a second loop.
Have you an idea why the modal is populate before the value is return by the function and also why it loops a second time?
Thanks for your help
You bind the select element to the indicateurDictionnaireForm.typeIndicateurCode variable and its options to the typeIndicateurs variable (via loopig over it).
So when you call the editIndicateur method:
First you load only the select options via AJAX call and pass it to Alpine.js by this.typeIndicateurs = data.
Alpine detects that you changed typeIndicateurs and renders the template. This is the first loop. However neither indicateurDictionnaireForm or detectedTypeIndicateur have been set at this point, therefore these will be empty.
After that you make a new AJAX call, where you load additional form data and set indicateurDictionnaireForm and detectedTypeIndicateur variables.
Alpine.js detects that you changed two additional variables and renders the template again. This is the second loop.
This is normal behavior if you have two separate AJAX calls because the changes wont be in the same update queue. To fix this issue, you should create a local (non-reactive) variable inside editIndicateur function, then store the options's array in this variable at the first AJAX call. Then at the second AJAX call you set all 3 Alpine.js reactive variables together, therefore the changes will be in the same update queue, so Alpine.js renders the template only once.
editIndicateur(id) {
let indicators;
$.ajax({
type: "GET",
url: "<%= request.getContextPath() %>/mesures.load.type-indicateur.action"
}).then(data => {
indicators = data;
}).then(
$.ajax({
type: "GET",
url: "<%= request.getContextPath() %>/mesures.edit.action?indicateurDictionnaireId=" + id,
}).then(data => {
this.indicateurDictionnaireForm = data;
this.detectedTypeIndicateur = data.typeIndicateur.code;
this.typeIndicateurs = indicators;
this.loadIndicateur();
$('#modalIndicateur').modal('show');
})
);
},

How to call api path in thymeleaf to reload table data in javascript function

I need click the submit button to reload table data,
But in javascript function , I don't known how to call the url pass parameters in thymeleaf.
I call this web page is below:
.....[menu partial code]....
<a class="dropdown-item" th:href="#{/registeredUserList(type=0,userId=id0001,page=0,size=10)}">user list</a>
.....
the query and content Page:
<form >
<div class="col-sm-3 my-1">
<label class="sr-only" for="inlineFormInputName">Name</label> <input
type="text" class="form-control" id="inlineFormInputName"
placeholder="user name">
</div>
<div class="col-auto my-1">
<button type="submit" class="btn btn-primary query-submit"
id="querySubmit">Submit</button>
</div>
</div>
</form>
.....
<div class="row mt-5" th:fragment="table_content">
<div class="col">
...
<table class="table table-responsive table-hover">
<tbody>
<tr th:each="users,iter : ${response.content}">
<th scope="row" th:text="${iter.index+1}"></th>
<td class="text-info text-center"
th:text="${users.name}"></td>
</tr>
</tbody>
</table>
</div>
</div>
.....
I don't know the syntax in thymeleaf , if I need pass the params and call api in the js function. If the url will write #{/registeredUserList(type=0,userId=id0001,page=0,size=10)} like menu path, how can I write the syntax in the js function at url.
thank you~
$(function() {
$('#querySubmit').click(querySubmitClickAction);
querySubmit.addEventListener('click', querySubmitClickAction);
function querySubmitClickAction(e) {
$.ajax({
url: url, // here , I don't know syntax, I can't use [#{/registeredUserList(type=0,userId=id0001,page=0,size=10)}] the path in here . how can I write the syntax.
type: 'POST',
success: function (data) {
$(".table_content").html(data);
}
})
}
});
</script>
Use th:inline="javascript" and the /*[[#{/url/}]]*/ syntax:
<script th:inline="javascript">
$(function() {
$('#querySubmit').click(querySubmitClickAction);
querySubmit.addEventListener('click', querySubmitClickAction);
function querySubmitClickAction(e) {
$.ajax({
url: /*[[#{/registeredUserList(type=0,userId=id0001,page=0,size=10)}]]*/ 'dummy',
type: 'POST',
success: function (data) {
$(".table_content").html(data);
}
})
}
});
</script>

Calling JQuery Ajax Functions in Foreach loop - Need assitance

I am currently studying programming and trying to build a website with .Net Core.
I have the following issue. I am not familiar with JavaScript that much and I have two JQuery/AJAX functions on my Index page. One of the function is for the posts likes/dislikes and the other for posts comments.
My ViewModel contains a collection of Posts:
public IEnumerable<IndexPostViewModel> Posts { get; set; }
public int PagesCount { get; set; }
public int CurrentPage { get; set; }
Into my view I am looping through each Post and in it, through each Comment.
#foreach (var post in Model.Posts)
{
<div class="post-content">
<img src=#post.ImageUrl width="500" height="500" alt="post-image" class="img-responsive post-image" />
<div class="post-container">
<img src="http://placehold.it/300x300" alt="user" class="profile-photo-md pull-left" />
<div class="post-detail">
<div class="user-info">
<h5>#post.User.UserName <span class="following">following</span></h5>
<p class="text-muted">Post published at: #post.CreatedOn</p>
</div>
<div class="reaction">
<a class="btn text-green" href="#" method="post" onclick="sendVote(#post.Id, true)"><div class="icon ion-thumbsup" id="upVotes">#post.UpVotes</div></a>
<a class="btn text-red" href="#" method="post" onclick="sendVote(#post.Id, false)"><div class="fa fa-thumbs-down" id="downVotes">#post.DownVotes</div></a>
</div>
<div class="line-divider"></div>
<div class="post-text">
<p>#post.Text</p>
</div>
<div class="line-divider"></div>
#foreach (var comment in post.Comments)
{
<div class="post-comment">
<img src="http://placehold.it/300x300" alt="" class="profile-photo-sm" />
<p>#post.User.Email<i></i> #comment.Text</p>
</div>
}
<form id="myForm" asp-controller="Comment" asp-action="Create" method="post">
<input type="hidden" name="PostId" id="postId" value="#post.Id" />
<textarea name="text"></textarea>
<input type="submit" value="Submit Comment" />
</form>
</div>
</div>
</div>
And these are the functions in the Scripts section:
#section Scripts {
function sendVote(postId, isUpVote) {
var json = { postId: postId, isUpVote: isUpVote };
$.ajax({
url: "/api/votes",
type: "POST",
data: JSON.stringify(json),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#upVotes").html(data.upVotes);
$("#downVotes").html(data.downVotes);
}
});
}
// wait for the DOM to be loaded
$(document).ready(function () {
// bind 'myForm' and provide a simple callback function
$('#myForm').each.ajaxForm(function () {
alert("You have just posted a comment");
document.location.reload(true);
});
});
</script>
}
My issue is that both functions are working correctly only for the first post. Can you please assist on how to modify the functions to be applied for each element in the loop?
Thanks in advance.
the problem is simple.
your selector and ids are not unique
id can only be defined for one element, same id on multiple/same elements will cause this issue.
the link tag has a common id for all records, it needs to be unique.
make the ids unique , i added #post.Id with ids, this will make each unique
<div class="reaction">
<a class="btn text-green" href="#" method="post" onclick="sendVote(#post.Id, true)"><div class="icon ion-thumbsup" id="upVotes_#post.Id">#post.UpVotes</div></a>
<a class="btn text-red" href="#" method="post" onclick="sendVote(#post.Id, false)"><div class="fa fa-thumbs-down" id="downVotes_#post.Id">#post.DownVotes</div></a>
</div>
and in you js change the selector by adding id
function sendVote(postId, isUpVote) {
var json = { postId: postId, isUpVote: isUpVote };
$.ajax({
url: "/api/votes",
type: "POST",
data: JSON.stringify(json),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#upVotes_"+postId).html(data.upVotes); // change here
$("#downVotes_"+postId).html(data.downVotes);
}
});
}
and also for myform do the same, you dont need id for form, but if you want just add the #post.Id to id,
<form id="myForm" class="myform" asp-controller="Comment" asp-action="Create" method="post">
<input type="hidden" name="PostId" id="postId" value="#post.Id" />
<textarea name="text"></textarea>
<input type="submit" value="Submit Comment" />
</form>
and in event change id to class to make it dynamic,
$('.myForm').each.ajaxForm(function () {
// $(this) will give you access to the specific form only
alert("You have just posted a comment");
document.location.reload(true);
});

Intermittent 405 Status response from ajax delete request

So I've got these cards, a user can click the delete button to remove a card. The card has an ID which deletes the card ID or community_id and user_id from the table. When the clicks the delete button, it sends an ajax delete request to the resource controller (delete method) which does delete the row from the database... sometimes.
It's very strange, sometimes it works, other times it returns a 405 (Method Not Allowed Exception).
Here's the code:
View:
#foreach($communities as $community)
<div class="col-md-3">
<div class="card communityCard">
<div class="loadingCard" loading>
<i class="loadingSpinner fas fa-circle-notch fa-spin"></i>
</div>
<div class="commandPanel">
<div class="commandPanelInterior">
#if($community->banned == 1)
#php($community->description = "This community has been removed for violating our terms of service.")
#else
<form class="form" action="/cad" method="GET">
#csrf
<input name="community_id" type="hidden" value="{{$community->id}}">
<button type="submit" class="sideMenuButton hvr-grow btn-primary"><i class="fas fa-door-open"></i></button>
</form>
#endif
#if($community->owner_id != Auth::user()->id)
<button id="deleteCommunity{{$community->id}}" value="{{$community->id}}" type="submit" class="deleteCommunityButton sideMenuButton hvr-grow btn-danger"><i class="fas fa-trash"></i></button>
#endif
</div>
</div>
<div class="card-header">
<img class="communityIcon" src="/images/communityIcons/{{$community->icon_path}}">
<span class="communityName">{{$community->name}}</span>
</div>
<div class="card-body">
<span class="communityDescription">{{$community->description}}</span>
</div>
#if($community->banned == 0)
<div class="card-footer">
<span class="badge badge-light"><i class="fas fa-users"></i> {{$community->user_count}}</span>
#php($communityBadges = $community->badge_types)
#foreach($communityBadges as $badgeType)
<span class="badge badge-primary" title="{{$badgeType->name}}">{!!$badgeType->badge_icon!!}</span>
#endforeach
</div>
#endif
</div>
</div>
#endforeach
Javascript:
// Remove User From Community Ajax
$('.deleteCommunityButton').click(function(event){
var clickedBtn = "#" + (event.target.id);
var community_id = $(event.target).val();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: "POST",
cache: false,
url: '/communitymembers/'+community_id,
data: {
"id": community_id,
"_method": 'DELETE'
},
success: function(response) {
$(clickedBtn).parent().parent().parent().parent().remove();
}
});
});
Controller:
public function destroy($id)
{
$memberList = CommunityMemberList::where('user_id', Auth::user()->id)->where('community_id', $id)->first();
$memberList->delete();
return redirect('/home')->with('message', 'The community has been successfully removed from your account');;
}
Web.php File:
Route::get('/home', 'HomeController#index')->name('home');
Error (From Console):
"message": "The DELETE method is not supported for this route. Supported methods: GET, HEAD, POST.",
Thanks :)

Safari again?? Form submits bypassing AJAX

My brain is exploding - can't figure out what the issue is with Safari. All browsers work just fine, but Safari simply doesn't read my JavaScript. Not even a simple ol' 'alert()'. Any clues?
============HTML===============
</div>
<div class="container top">
<h1 class="text">Weather Dashboard</h1>
<h3 class="text">Enter the city to get a 3-day forecast</h3>
<form id="cityForm" class="form-group">
<div class="container-fixed">
<div class="form-horizontal">
<div class="input-group inpWid">
<div class="input-group-addon">
<span class="glyphicon glyphicon-home"></span>
</div>
<input type="text" class="form-control" id="city"
name="city" placeholder="Enter the City">
</div>
<button type="submit" class="btn btn-primary btn-success">Weather Me!</button>
</div>
</div>
</form>
<div class="container-fixed" id="weatherBox">
</div>
</div>
============JQuery/JavaScript===============
$("#cityForm").submit(function(e) {
e.preventDefault();
alert("safari");
var url = "scraper.php"; // the script where you handle the form input.
var city1 = $("#city").val();
var city = city1.replace(/\s+/g, '');
$.ajax({
type: "POST",
url: url,
cache:false,
data: {city, city1},
success: function(data){
$("#weatherBox").html(data); // show response from the php script.
}
});
return false; // avoid to execute the actual submit of the form.
});
============PHP===============
$city = $_POST["city"];
$city1 = $_POST["city1"];
$url="http://www.weather-forecast.com/locations/$city/forecasts/latest";
$content = file_get_contents($url);
preg_match('/3 Day Weather Forecast Summary:<\/b>(.*?).<\/span>/s', $content, $day1);
preg_match('/7 Day Weather Forecast Summary:<\/b>(.*?).<\/span>/s', $content, $day2);
preg_match('/10 Day Weather Forecast Summary:<\/b>(.*?).<\/span>/s', $content, $day3);
for ($i=1; $i<=3; $i++) {
${d.$i} = '<img src="sun.gif" alt="sun" height="42" width="42">';
$wCon = ${day.$i}[1];
preg_match("/dry/i", $wCon, ${weather.$i});
if (${weather.$i}[0]!="dry"){
${d.$i} = '<img src="rain.png" alt="rain" height="42" width="42">';
};
unset(${weather.$i}[0]);
};
============Website===============
http://alexanderii.net/cover/
you have syntax error:-
change data: {city, city1}, to data:{'city':city,'city1':city1}
try this code:-
$.ajax({
type: "POST",
url: url,
cache:false,
data:{'city':city,'city1':city1},
success: function(data){
$("#weatherBox").html(data); // show response from the php script.
}
});

Categories