I have list of product , If I click on one product it needs to be added in database and again if I click on same product it should be removed from database, I am toggling wishlistFlag on ng-click. It should be fine on one div element, for second div element it is working reverse of first div element, I mean in case first product is added then if I click second product it has to be added but it is removing first product.
<div class="hmpal-prprt-post-wdgt hmpal-prprt-wishlist">
<a href="">
<span class="prprt-icon"><i class="fa fa-heart" aria-hidden="true"
ng-click="WishlistAdd($index,project.propertyId)"></i></span>
<span>Wishlist</span>
</a>
</div>
And inside Controller code is here,
a.WishlistAdd = function (index,propertyId) {
a.wishlistFlag = !a.wishlistFlag;
var data = {
wishlistFlag:a.wishlistFlag,
propertyId:propertyId
};
e.createWishLists(data).then(function (result) {
alert("sucesss");
alert(JSON.stringify(result));
}, function (error) {
alert("error");
alert(JSON.stringify(error));
});
}
How I can implement toggle wishlistFlag for different product .
Since you want at most one product selected in your wish list, instead of having a boolean flag, you can use the selected product id (called propertyId in your code if I'm right). The selectedProductId variable, defined in the controller, is either null if there is no product selected, or the product id if there is one.
The toggling is done by checking if the current selected id is equal to the clicked one.
I assume that
when wishListFlag === true in the sent data, you want to add the
product identified by propertyId, and otherwise, remove the
product from the database.
when you add a product, the server side
actually replace the selected product if there is an existing one.
// Is there a selected product ?
var selectedProductId = null;
a.WishlistAdd = function (index, propertyId) {
selectedProductId = (selectedProductId === propertyId ? null : propertyId);
var data = {
wishlistFlag: (selectedProductId !== null),
propertyId: propertyId
};
e.createWishLists(data).then(function (result) {
alert("sucesss");
alert(JSON.stringify(result));
}, function (error) {
alert("error");
alert(JSON.stringify(error));
});
}
You can make use of $index to have seperate flag to each of the wishList. Here, you can write your code as..
a.wishListFlag[index]
maintain a array of added propertyIds before save to the database check that id is in array if so remove from database and array else remove from database and array.
var wishList = [];
a.WishlistAdd = function (index,propertyId) {
var data = {
wishlistFlag: wishList.indexOf(propertyId) === -1,
propertyId:propertyId
};
e.createWishLists(data).then(function (result) {
//add or remove propertyid from whishList
if(data.wishlistFlag)
wishList.push(propertyId);
else
wishList.splice(wishList.indexOf(propertyId), 1);
alert("sucesss");
alert(JSON.stringify(result));
}, function (error) {
alert("error");
alert(JSON.stringify(error));
});
}
Related
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>
I have a Dictionary of names/numbers that are passed through to my View from my Controller. This becomes:
Model.arrayPositions[x]
These are then added to a select list:
<form>
<div class="col-xs-12">
<select id="ListIn" class="select-width" name="SelectionIn" multiple="multiple" size="#Model.arrayPositions.Count">
#foreach (var item in Model.arrayPositions)
{
if (item.Value != null)
{
<option class="active" value="#item.Value">#Html.DisplayFor(modelItem => #item.Key)</option>
}
}
</select>
</div>
</form>
Array items with no value are ignored, the rest is added to the list.
Items can then be added/removed or moved up/down the list using JavaScript:
function AddSelected() {
$('#ListOut option:selected').each(function (i, selected) {
$('#ListIn').append('<option class="active" value="1">' + selected.innerText + '</option>');
selected.remove();
});
}
function RemoveSelected() {
$('#ListIn option:selected').each(function (i, selected) {
$('#ListOut').append('<option class="inactive" value="-1">' + selected.innerText + '</option>');
selected.remove();
});
function MoveUp() {
var select1 = document.getElementById("ListIn");
for (var i = 0; i < select1.length; i++) {
if (select1.options[i].selected && i > 0 && !select1.options[i - 1].selected)
{
var text = select1.options[i].innerText;
select1.options[i].innerText = select1.options[i - 1].innerText;
select1.options[i - 1].innerText = text;
select1.options[i - 1].selected = true;
select1.options[i].selected = false;
}
}
}
(Moving down is pretty much just the opposite of Moving up)
(#ListOut is simply a second list that has the array items with a value of null added to it)
(The final value is not too important right now, so I'm not specifically retaining it. The order of the list is more important)
I'm changing the order using Javascript to avoid having the page refresh constantly for such a simple action.
However, once I press an update button I'll have a call to my Controller (ASP.NET Core in C#). What I am wondering is how I could retrieve the final values of the list in the new order.
i.e.
If Model.arrayPositions = {a=1,b=2,c=null,d=3}, it would add them to the list as: [a,b,d]
I then use javascript to remove 'a' and move 'd' up, resulting in [d,b]
When I press the update button I would like the retrieve the current list of [d,b] from the View.
What would be the best way to achieve this? Or, alternatively, what other methods might be used to achieve the same goal (note that I wouldn't want page refreshes or partial refreshes if possible).
You can use ajax method to hit your controller on the click of your update button
syntax of jquery ajax is:-
<script>
$.ajax({
type:'POST',
url : 'controllerNAME/ActionNAME',
datatype: 'json',
data : {'parameterOne': parameterone, 'parameterTwo' : parametertwo,...},
success : function(response)
{
alert(response.d)
//put your logic here for further advancements
}
});
</script>
In my template I have this code:
<li class="row timeline-item" data-ng-repeat="item in data | filter:workoutFilter" data-ng-include="getTemplateUrl(item)"></li>
And in my controller I have:
$scope.workoutFilter = null;
$rootScope.$on('workout', function(e, data) {
$scope.workoutFilter = "{Type: 'workout'}";
});
When I click button workouts, everything just disappears as if there are no items that match this filter, but that isn't the case (and I know this for a fact because getTemplateUrl detects type workout and returns right template)
Why is this happening ? Is there any other way I can filter items which have property Type "workout" ?
EDIT
Here is what happens when I click button:
In my other controller :
$scope.onWorkoutsClick = function () {
feedService.setWorkoutFilter();
};
In service:
setWorkoutFilter : function() {
$rootScope.$broadcast('workout');
}
And in my main controller:
$rootScope.$on('workout', function(e, data) {
$scope.workoutFilter = "{Type: 'workout'}";
});
I assume you're trying to filter based on item.Type == 'workout'?
You need to set your filter to an object rather than a string:
$scope.workoutFilter = {Type: 'workout'};
I'm a little stuck here. I have a page that displays three different views by loading with jQuery: a view of all categories associated with the user, the image and name of all the items within the category that is selected and a full detail view of all the properties of the item selected. HOw to get the id of the category selected than display the items and same with the item to display the full details. Ajax isn't the problem, so I think.
When the user clicks on an <li> within the test <div> this fires to retrieve items for that category
$(document).ready(function() {
$('#test li').click(function() {
//get id of cat selected
$.ajax({
url: "",
type: "POST",
data: {//return all the item info},
success: function(data) {
//when returns display updated results
}
});
});
I figure it would be the same as when you click an item. But how to write the query for the controller. Right now I'm just displaying all:
//Item Controller
//two queries; one for displaying items when certain cat is selected and
// another to display full details when an item is selected
public ActionResult Partial(Item item)
{
//var query = from i in db.Items
// orderby i.dateAdded
// where i.user_id==4
// select i;
//var results = query;
var model = db.Items;
return PartialView("_Partial1", model);
}
public ActionResult PartialTwo() //pass in the catId??
{
var query = from d in db.Items
// how to get catID which is in the item table?
select d;
var results = query;
return PartialView("_FullInfoPartial", results);
}
//Category controller
//get the categories from
public ActionResult GetCats( Category cat)
{
var query = from c in db.Cats where c.user_id == 4 orderby c.catId select c;
var results = query;
return PartialView("_PartialGetCats", results);
}
Am I on the right track?
A trick can be that for each <li> element, create a <input type="hidden" value="catID" ...> element for holding ids of categories.
So, as you render the category names in your view, add another line to create a hidden field for storing that category id like the following:
<li id="liCat1">
</li>
<input type="hidden" name="liCat1" value="catID1" />
Note that I set the name of the hidden field asa same as the id of the related li element.
Then, change your jquery like the following:
$(document).ready(function() {
$('#test li').click(function() {
var selector = "input[name='" + $(this).id + "value']";
var catID = $(selector).val();
// Now, you have the categoryID in the catID variable. Enjoy using it...!
$.ajax({
url: "...",
type: "POST",
data: {//return all the item info},
success: function(data) {
//when returns display updated results
}
});
});
});
I'm trying to update a select box based on another..
In my active admin resource, I did the following just for some test data:
controller do
def getcols
list = new Hash
list = {"OPTION1" => "OPTION1", "OPTION2" => "OPTION2"}
list.to_json
end
end
In active_admin.js I have the following
$('#worksheet_type').change(function() {
$.post("/admin/getmanifestcols/", { ws_type: $(this).val() }, function(data) {
populateDropdown($("#column_0"), data);
});
});
function populateDropdown(select, data) {
select.html('');
alert('hi');
$.each(data, function(id, option) {
select.append($('<option></option>').val(option.value).html(option.name));
});
}
The above is working in the sense that when my primary select box is changed, the jquery is called and I even get the alert box of 'hi' to be called. However, it's not replacing the contents of the select box with my test OPTION1 and OPTION2 data.
I think I'm passing in the JSON wrong or something, or it's not being read.
What am i missing?
It looks to me as if you're not properly iterating over the map.
What about:
$.each(data, function(value, name) {
select.append($('<option></option>').val(value).html(name));
});
?