Fetch works by categoryId - javascript

Hello i am learning JS actually i try to fetch some data from an API, i have fetch all the work from api/works and display them in a div but now i need to create 3 button who represent the 3 category who regroup all works, i created dynamically the buttons but now i need to put a function on these button to display the api/works from the category id give (example button 1 represent category id 1 and when i click, all api/works from category id 1 are displayed, same for 2nd et 3rd button) there is the json format for data
[
{
"id": 1,
"title": "Abajour Tahina",
"imageUrl": "http://localhost:5678/images/abajour-tahina1651286843956.png",
"categoryId": 1,
"userId": 1,
"category": {
"id": 1,
"name": "Objets"
}
}
i don't know how said fetch all works but with categoryId 1, hide all and display these categoryId of works
if someone know how to do this or documentation to doing this
document.getElementById("button").addEventListener("click", function(){
// Clear the container element
document.getElementById("works").innerHTML = "";
// Make GET request to API endpoint for all works with categoryId 1
fetch("http://localhost:5678/api/works?categoryId=1")
.then(response => response.json())
.then(data => {
// Loop through the list of works
data.forEach(function(work) {
// Create a new HTML element for each work
var workElement = document.createElement("div");
workElement.innerHTML = "Work ID: " + work.id + "<br>" + "Title: " + work.title + "<br>" + "Content: " + work.content;
// Append the new HTML element to the page
document.getElementById("works").appendChild(workElement);
});
})
.catch(error => console.log(error));
i tried this but he give me all /works the url http://localhost:5678/api/works?categoryId=1 not working for me i think

put console.log on the function that handle the click on button to see if the function is actualy triggerd.
i think because your buttons are dynamically added javascript can't recognize them.

Related

JSON select data at specific ID

In PHP, I've created a function to create a JSON file:
function writeJSONData(PDO $conn): void
{
$contentJSON = "SELECT * FROM tb_content";
$contentResultsJSON = $conn->query($contentJSON);
$contentJSONExt = array();
while ($JSON = $contentResultsJSON->fetchAll(PDO::FETCH_ASSOC)) {
$contentJSONExt = $JSON;
}
$infoJSON[] = json_encode(array('movies' => $contentJSONExt));
$target_dir = $_SERVER['DOCUMENT_ROOT'] . "/CineFlex/private/api/api.json";
file_put_contents($target_dir, $infoJSON);
}
In my HTML file I've created a button which sends the ID of the selected movie:
<!-- Edit Button -->
<button onclick="toggleDialog(editMovie, this.id)" id="<?php echo($info['content_id']) ?>Edit Movie</button>
My JavaScript file contains the function:
// Toggle Dialog
function toggleDialog(dialogName, dialogID) {
// Toggle Dialog Visibility
$(dialogName).fadeToggle(200);
$.getJSON("./private/api/api.json", function (data) {
console.log(data)
})
}
When I click on the edit button, it prints the entire JSON file in the console. Which is understandable.
Current output:
{
"movies": [
{
"content_id": 15,
"title": "Scream (2022)",
"description": "25 years after a streak of brutal murders shocked the quiet town of Woodsboro, Calif., a new killer dons the Ghostface mask and begins targeting a group of teenagers to resurrect secrets from the town's deadly past."
},
{
"content_id": 16,
"title": "Fear Street: Part Two - 1978",
"description": "Shadyside, 1978. School's out for summer and the activities at Camp Nightwing are about to begin. But when another Shadysider is possessed with the urge to kill, the fun in the sun becomes a gruesome fight for survival."
},
{
"content_id": 17,
"title": "Archive 81",
"description": "An archivist hired to restore a collection of tapes finds himself reconstructing the work of a filmmaker and her investigation into a dangerous cult."
}
]
}
Now my issue is, I want the "dialogID" to be selected from the JSON file where it matches with "content_id". For example: When I click on a movie with 16 as "dialogID", I want the console to just print everything from that array.
Expected output:
{
"movies": [
{
"content_id": 16,
"title": "Fear Street: Part Two - 1978",
"description": "Shadyside, 1978. School's out for summer and the activities at Camp Nightwing are about to begin. But when another Shadysider is possessed with the urge to kill, the fun in the sun becomes a gruesome fight for survival."
}
]
}
To get it, you need to create dynamic API instead of static file content. In alternative case, you can get it only from JS loop (check all and check suitable ID). If you want to do it with API, you must change html and php script like this:
function getDataById(PDO $conn):string
{
$id = (int) $_GET['id'];
$contentJSON = "SELECT * FROM tb_content where id = :id";
$contentResultsJSON = $conn->prepare($contentJSON);
$contentResultsJSON->execute([':name' => 'David', ':id' => $_SESSION['id']]);
$rows = $contentResultsJSON->fetchAll(PDO::FETCH_ASSOC);
$contentJSONExt = array();
while ($JSON =$rows) {
$contentJSONExt = $JSON;
}
return json_encode(array('movies' => $contentJSONExt));
}
And, JS codes to change like this:
// Toggle Dialog
function toggleDialog(dialogName, dialogID) {
// Toggle Dialog Visibility
$(dialogName).fadeToggle(200);
$.getJSON("https://my-site.com/getDataById/?id="+dialogID, function (data) {
console.log(data)
})
}
I don't know if you want to select in your php the right ID, and send back only the right one or if you want the whole json back and select in javascript.
First answer here gives the answer to dynamic php: only the right ID back from server.
I will try to answer the second possibility: all json movies back, selection in javascript.
html (3 buttons for example):
<button onclick="toggleDialog(this.id)" id="15">Edit Movie 15</button>
<button onclick="toggleDialog(this.id)" id="16">Edit Movie 16</button>
<button onclick="toggleDialog(this.id)" id="17">Edit Movie 17</button>
javascript, let say we have back the whole json movies, I put a variable here (it's supposed to be the whole json back from php):
let json = {
"movies": [
{
"content_id": 15,
"title": "Scream (2022)",
"description": "25 years after a streak of brutal murders shocked the quiet town of Woodsboro, Calif., a new killer dons the Ghostface mask and begins targeting a group of teenagers to resurrect secrets from the town's deadly past."
},
{
"content_id": 16,
"title": "Fear Street: Part Two - 1978",
"description": "Shadyside, 1978. School's out for summer and the activities at Camp Nightwing are about to begin. But when another Shadysider is possessed with the urge to kill, the fun in the sun becomes a gruesome fight for survival."
},
{
"content_id": 17,
"title": "Archive 81",
"description": "An archivist hired to restore a collection of tapes finds himself reconstructing the work of a filmmaker and her investigation into a dangerous cult."
}
]
}
javascript function:
function toggleDialog(dialogID) {
dialogID = parseInt(dialogID);
json.movies.every(e => {
if (e.content_id === parseInt(dialogID)) {
console.log(e.content_id);
console.log(e.title);
console.log(e.description);
return false;
}
return true;
})
}
You iterate through the json.movies (it's an object) with "every" instead of forEach. With every, you can break the loop when condition is met dialogID === content_id with return false. You have to put return true at the end of the loop otherwise it breaks immediately.
Your content_id are numbers, so parseInt on the dialogID. If coming from php json, it'll normally be string so no need for that.
A friend of mine helped me out:
// Toggle Dialog
function toggleDialog(dialogName, dialogID) {
// Toggle Dialog Visibility
$(dialogName).fadeToggle(200);
$.getJSON("./private/api/api.json", function (data) {
for (let i = 0; i < data['movies'].length; i++) {
if (data['movies'][i]['content_id'] == dialogID) {
$('#editMovieTitle').val(data['movies'][i]['title'])
}
}
})
}

Adding json object via .data() to dynamically added td via jquery

I am using HTML, CSS and JQuery/JavaScript to create a table which its td is populated during runtime. Depending on the data returned via Ajax, only some tds are populated. I have added click and doubleclick event to the populated tds. For doubleclick event, I need to call a function and pass JSON object to it. The JSON data are something like below or here
{
"is_active": true,
"timeslots": [
{
"department": "department01",
"end_time": "13:00:00",
"id": 3,
"start_time": "09:00:00",
"number": 1
}
//... and other timeslots
}
Below are the code snippets:
HTML:
...
<tr id="department_row">
<td class="first-column">Department</td>
<!-- TODO: To add cells via JQuery/JavaScript-->
</tr>
JavaScript/JQuery:
$.getJSON(
"http://url_for_the_data"
).done(function(data) {
let allDepartmentData = data['timeslots']
let scheduleRow: string
for (let singleData of allDepartmentData) {
scheduleRow += '<td id="td_schedule_'+ singleData.id +'>'+ singleData.trolleys +'</td>'
// The part I want to add the data to the td
$('#td_schedule_' + singleData.id).data('slot', singleData);
}
$('#department_row').append(scheduleRow)
})
Then, after the page is loaded, in Chrome DevTool, I accessed via its console $('#td_schedule_3').data('slot') but it gave me undefined. As written in my first paragraph, the purpose is when the td with the data is double clicked, the JSON object (i.e. department, end_time, id, start_time and number) will be passed to a function which will call up an Edit Modal with the data from JSON object. For simplicity, I do not put in the codes related to the double click event and edit modal.
Can anyone help with this? Thanks.

How to store data from api call with vanilla javascript to firestore database?

I am bringing in data from an api call and outputting the data to html inside a template string using variables from the main.js file. All of that works fine. The problem that has me blocked is I want to have an add to favorites button that a user can click and add the title to a favorites list. When I add the button inside the template literal the addEvenListener I have for the button is null and if I add the button to the index.html I cannot access the data from the api. I am trying to store the data first into firestore database after the user clicks the button. Then output the data into a dropdown list.
I've added a collection to the firestore database and can display the data from the backend to the favorites list but I need to grab the data from the front end, store it on the back end, and display it in the favorites list.
function getMovie(){
let movieId = sessionStorage.getItem('movieId');
// Make a request for a user with a given ID
axios.get("https://api.themoviedb.org/3/movie/" + movieId + "?
api_key=redacted")
.then(function (response) {
console.log(response)
let movie = response.data;
//console.log(movie);
let output = `
<div class="dropdown">
<button class="dropbtn" id="dropbtn">Favorites</button>
<div id="myDropDown" class="dropdown-content"></div>
</div>
`;
$('#movie').html(output);
})
.catch(function (error) {
console.log(error);
});
}
addFavorite.addEventListener('submit', (e) => {
e.preventDefault();
firebase.firestore().collection('favorites').add({
Title: addFavorite['movieid'].value
}).then(() => {
//close
console.log(addFavorite)
})
})
Not sure if I need to do another api call for this functionality or not. I did one api call to get a list of movies then another to get one movie. When the user goes to the one movie that is where I want the add favorite button. I hope someone knows how to lead me in the right direction. First time asking on Stackoverflow don't hurt me lol
i am taking simple ul list as example
<ul id="movie">
</ul>
<script>
// DUMMY records
const apiCallDataExample = [
{
id: 1,
name: "A"
},
{
id: 2,
name: "B"
},
{
id: 3,
name: "C"
}
];
let movies = [];
getMovie();
function getMovie() {
movies = apiCallDataExample; // You will call your API to get the data, and store it in upper scope 'movies' variable.
let htmlContent = ''; // prepare your html content -> in your case it is droup down i guess.
for (let movie of movies) {
htmlContent += `
<li>
<span> ${movie.name} </span>
<button onclick="addToFavourite(${movie.id})"> click me </button>
</li>
`
// Attach click event or any listener to get selected movie id or any identifier
}
let elem = document.getElementById("movie").innerHTML = htmlContent;
}
/**
* click event will trigger and we can fetch selected movie by given identifier, in my case it is `id `field.
*/
function addToFavourite(id) {
let selected_movie = movies.find(movie => movie.id === id); // find your movie by id.
console.log("selected movie is", selected_movie)
// add your data into collection as per your defined property , my case { id, name}.
/*
// Your fire base function
firebase.firestore().collection('favorites').add({
id: selected_movie.id,
name: selected_movie.name
}).then(() => { })
*/
}
</script>

jQuery 'change' doesn't show most up-to-date data

I have a jQuery change function that populates a dropdown list of Titles from the user selection of a Site dropdown list
$("#SiteID").on("change", function() {
var titleUrl = '#Url.Content("~/")' + "Form/GetTitles";
var ddlsource = "#SiteID";
$.getJSON(titleUrl, { SiteID: $(ddlsource).val() }, function(data) {
var items = "";
$("#TitleID").empty();
$.each(data, function(i, title) {
items +=
"<option value='" + title.value + "'>" + title.text + "</option>";
});
$("#TitleID").html(items);
});
});
The controller returns JSON object that populates another dropdown list.
public JsonResult GetTitles(int siteId)
{
IEnumerable<Title> titleList;
titleList = repository.Titles
.Where(o => o.SiteID == siteId)
.OrderBy(o => o.Name);
return Json(new SelectList(titleList, "TitleID", "Name"));
}
The markup is:
<select id="SiteID" asp-for="SiteID" asp-items="#Model.SiteList" value="#Model.Site.SiteID" class="form-control"></select>
<select id="TitleID"></select>
The problem is that the controller method is only touched on the FIRST time a selection is made. For example,
The first time SITE 1 is selected, the controller method will return the updated list of Titles corresponding to SITE 1
If SITE 2 is selected from the dropdown, the controller will return the updated list of Titles corresponding to SITE 2
The user adds/deletes Titles in the database corresponding to SITE 1
User returns to the form and selects SITE 1 from the dropdown. The list still shows the results from step 1 above, not the updates from step 3
If I stop debugging and restart, the selection will now show the updates from step 3.
Similar behavior described in jQuery .change() only fires on the first change but I'm hoping for a better solution than to stop using jQuery id's
The JSON response is:
[{"disabled":false,"group":null,"selected":false,"text":"Title2","value":"2"},{"disabled":false,"group":null,"selected":false,"text":"Title3","value":"1002"},{"disabled":false,"group":null,"selected":false,"text":"Title4","value":"2004"},{"disabled":false,"group":null,"selected":false,"text":"Title5","value":"3"},{"disabled":false,"group":null,"selected":false,"text":"Title6","value":"9004"}]
The issue was that the JSON result was being read from cache as #KevinB pointed out. This was fixed by adding the following line within the change function
$.ajaxSetup({ cache: false });

Modifying Replicated EditorTemplates with Javascript

I have an Editor Template which contains a table row with (among other stuff) a dropdown/combobox to select a currency. This edit template is shown many times on the same View and it's possible for a user to add these rows as many times as he wants.
I want changes on a row's dropdown to reflect in an EditorFor (the currency's rate) on the same row, so I've added a onchange html parameter:
<td>
#*#Html.LabelFor(model => model.Currency)*#
#Html.DropDownListFor(model => model.Currency, new SelectList(Model.CurrencyList, "Code", "Code"), new { onchange = "updateCurrency(this)" })
#Html.ValidationMessageFor(model => model.Currency)
</td>
My javascript function makes an ajax call to retrieve the rate for the selected currency:
function updateCurrency(elem) {
alert("Currency changed!")
$.ajax({
type: "GET",
url: "Currency?code=" + elem.value,
success: function (msg) {
// The Rate field's Id:
var RateId = "#Html.ClientIdFor(model=>model.Rate)" // // Halp, problem is here!
document.getElementById(RateId).value = msg;
}
});
}
My problem is that
var RateId = "#Html.ClientIdFor(model=>model.Rate)"
has that Html helper which is server-side code. So when i view the page's source code, the javascript code is replicated (once for each row) and all the var RateId = "#Html.ClientIdFor(model=>model.Rate)" are pointing to the most recently added column's EditorFor.
Probably my way of attempting to solve the problem is wrong, but how can I get my javascript code to update the desired field (i.e. the field in the same row as the changed dropdown list).
I believe that one of the problems is that I have the javasript on the Editor Template, but how could I access stuff like document.getElementById(RateId).value = msg; if I did it like that?
Thanks in advance :)
Figured it out. Hoping it helps somebody:
In my view:
#Html.DropDownListFor(model => model.Currency, new SelectList(Model.CurrencyList, "Code", "Code"), new { #onchange = "updateCurrency(this, " + #Html.IdFor(m => m.Rate) + ", " + #Html.IdFor(m => m.Amount) + ", " + #Html.IdFor(m => m.Total) + ")" })
In a separate JavaScript file:
function updateCurrency(elem, RateId, AmountId, TotalId) {
var cell = elem.parentNode // to get the <td> where the dropdown was
var index = rowindex(cell) // get the row number
// Request the currency's rate:
$.ajax({
blah blah blah .........
(RateId[index - 1]).value = 'retreived value'; // Set the rate field value.
});
}
Seems to be working so far.

Categories