I have an ASP.Net Core MVC web application and in my view I have a bootstrap carousel. I am trapping for the change event so I can get additional information of the image show. My problem is the image is not changing fast enough. When the change event fires and I get the unique image name it is still on the first image not the one being shown meaning the additional information I get is wrong.
Below is my bootstrap carousel: -
<div id="divCarousel" class="carousel slide" data-interval="false" data-ride="carousel">
<ul class="carousel-indicators">
#{
int Pos = 0;
}
#foreach (var photo in Model.PhotosList)
{
if (Pos == 0)
{
<li data-target="=#divCarousel" data-slide-to=#photo.Id class="active"></li>
}
else
{
<li data-target="=#divCarousel" data-slide-to=#photo.Id></li>
}
Pos++;
}
</ul>
<!-- The slideshow -->
<div class="carousel-inner">
#{
Int16 i = 0;
}
#foreach (var photo in Model.PhotosList)
{
var photoPath = "~/Photos/" + photo.PhotoPath;
if (i == 0)
{
<div class="carousel-item active">
<img class="photoSize" src="#photoPath" alt="No Photo" asp-append-version="true">
</div>
}
else
{
<div class="carousel-item">
<img class="photoSize" src="#photoPath" alt="No Photo" asp-append-version="true">
</div>
}
i++;
}
</div>
<!-- Left and right controls -->
<a class="carousel-control-prev" href="#divCarousel" data-slide="prev">
<span class="carousel-control-prev-icon"></span>
</a>
<a class="carousel-control-next" href="#divCarousel" data-slide="next">
<span class="carousel-control-next-icon"></span>
</a>
</div>
And here is my javascript to trap for the change event: -
#section Scripts {
<script>
function showPhotoDetails() {
var url = $('.carousel-item.active img').attr('src');
var photopath = url.split('?');
photopath[0] = photopath[0].substring(8, photopath[0].length);
$.ajax({
type: 'POST',
url: "/Photos/GetValue?path=" + photopath[0],
dataType: "json",
async: false,
success: function (data) {
$("input#txtCreatedBy").val(data.createdBy);
$("input#txtDateCreated").val(data.dateCreated);
$("textarea#txtNotes").val(data.notes);
}
});
}
$(document).ready(function () {
showPhotoDetails();
$('.custom-file-input').on("change", function () {
var fileLabel = $(this).next('.custom-file-label');
var files = $(this)[0].files;
if (files.length > 1) {
fileLabel.html(files.length + ' files selected.');
} else if (files.length == 1) {
fileLabel.html(files[0].name);
}
});
$('.carousel-control-previous').on("click", function () {
showPhotoDetails();
});
$('.carousel-control-next').on("click", function () {
showPhotoDetails();
});
});
</script>
}
I basically need to get the image name after the slide event. Any help much appreciated.
Thank you,
A managed to get this sorted. Basically rather than trapping for the click event of the previous and next I use the slid.bs.carousel class. All working fine now.
Related
I am using wizard in my page and server side validation using razor view.
output page
Index.cshtml
For validation in #step-3/#step-2 wizard i want my page goes to id->step-3 but it goes to #step-1 or at the start of wizard page
I have to return the id of html page in returning views of controller.controller.cshtml
You can try to use Tempdata and js,here is a demo:
action:
[HttpPost]
public IActionResult Index(Contact contData)
{
TempData["id"] = "step-3";
return View();
}
View:
<div class="tab-content">
<div id="step-1" class="tab-pane fade">
<h3>Step 1</h3>
<p>Some content in step 1.</p>
</div>
<div id="step-2" class="tab-pane fade">
<h3>Step 2</h3>
<p>Some content in step 2.</p>
</div>
<div id="step-3" class="tab-pane fade">
<h3>Step 3</h3>
<p>Some content in step 3.</p>
</div>
</div>
<form method="post">
<button>submit</button>
</form>
#section Scripts{
<script>
$(function () {
var s = "#TempData["id"]";
var indexValue=0;
$(".tab-pane").each(function (index) {
if ($(this).attr("id") == s) {
$(this).addClass("in active");
indexValue=index;
} else {
$(this).removeClass("in active");
}
})
$(".myClass").each(function (index) {
if (indexValue==index) {
$(this).addClass("active");
indexValue=index;
} else {
$(this).removeClass("active");
}
})
})
</script>
}
result:
I'm trying to mark a notification as read when a user clicks on it. Right now, when a user clicks on one of the notifications, it marks all of the user's notifications as read, instead of just the one.. I created a "click" function on the <a>.
AppHeader.vue:
<li class="dropdown-item preview-item dropdown-item-notifications" v-for="(unreadNotification, index) in unreadNotifications" :key="index">
<a class="dropdown-item" type="button" #click="markAsRead()">
<div class="preview-item-content flex-grow py-2">
<div v-if="unreadNotification ? unreadNotification.type === 'App\\Notifications\\InterviewRequestCandidateReply' : ''">
<p class="font-weight-light small-text"> <InterviewRequestCandidateReplyMessage /> </p>
</div>
<div v-else-if="unreadNotification ? unreadNotification.type === 'App\\Notifications\\InterviewRequestReplyConfirmed' : ''">
<p class="font-weight-light small-text"> <InterviewRequestReplyConfirmedMessage /> </p>
</div>
</div>
</a>
</li>
methods: {
markAsRead: async function() {
try {
const response = await employerService.markNotificationAsRead();
this.loadNotificationsData();
console.log(this.notifications);
} catch (error) {
this.$toast.error("Some error occurred, please refresh!");
}
},
},
employerService.js from code above:
export function markNotificationAsRead(id) {
return http().post(`employer/notifications/${id}`);
}
In my #click="markAsRead() function I think I need to get the id so maybe something like this #click="markAsRead(unreadNotification.id). Now the tricky part and where I'm stuck is, how can I pass this id into the markNotificationAsRead() function below?
const response = await employerService.markNotificationAsRead();
I'm not sure how to do this. I'm using Laravel for my backend.
--------------------- UPDATE: ---------------------
Something strange is happening. I know that the answers provided should work, but for some reason it's still marking all records as read.
EmployerNotificationsController.php:
public function markAsRead($id)
{
$notifications = Auth::user()->notifications->where('id', $id)->first()->markAsRead();
return response()->json($notifications, 200);
}
api.php:
Route::post('/employer/notifications/{id}', 'EmployerNotificationsController#markAsRead')
->name('employer.notifications.mark-as-read');
Any ideas why?
You're absolutely right about passing the ID to the click handler: #click="markAsRead(unreadNotification.id)
Your markAsRead method will receive the ID as an argument that you can then pass to your service method:
markAsRead: async function(id) {
try {
const response = await employerService.markNotificationAsRead(id);
//...
},
<li class="dropdown-item preview-item dropdown-item-notifications" v-for="(unreadNotification, index) in unreadNotifications" :key="index">
<a class="dropdown-item" type="button" #click="markAsRead(unreadNotification.id)">
<div class="preview-item-content flex-grow py-2">
<div v-if="unreadNotification ? unreadNotification.type === 'App\\Notifications\\InterviewRequestCandidateReply' : ''">
<p class="font-weight-light small-text"> <InterviewRequestCandidateReplyMessage /> </p>
</div>
<div v-else-if="unreadNotification ? unreadNotification.type === 'App\\Notifications\\InterviewRequestReplyConfirmed' : ''">
<p class="font-weight-light small-text"> <InterviewRequestReplyConfirmedMessage /> </p>
</div>
</div>
</a>
</li>
methods: {
markAsRead: async function(id) {
try {
const response = await employerService.markNotificationAsRead(id);
this.loadNotificationsData();
console.log(this.notifications);
} catch (error) {
this.$toast.error("Some error occurred, please refresh!");
}
},
},
just like this ...
I try to use my repository data to display in card view, then press button to see more information about the item, it does not work. #OnClick is only working for JSON data
#using Microsoft.AspNetCore.Components.Web - to access #onclick and more option
repoItem - my ItemRepository for get data from database
#OnClick="(e => SelectProduct(item.Id))" - when i click item card, its shoud get item id send to SelectProduct(item.Id) method.
but it work for following link. he works with JSON data but I need to work for model data.
https://github.com/dotnet-presentations/ContosoCrafts/blob/master/src/Components/ProductList.razor
<div class="card-columns">
#foreach (var item in repoItem.GetAll())
{
<div class="card">
<div class="card-header">
<h5 class="card-title">#item.Name</h5>
</div>
<div class="card-body">
<h5 class="card-title"> Total available items : #item.Quantity</h5>
<h5 class="card-title">Price : Rs. #item.Price.00</h5>
</div>
<div class="card-footer">
<small class="text-muted">
<button #onclick="(e => SelectProduct(item.Id))"
data-toggle="modal" data-target="#productModal" class="btn btn-primary">
More Info
</button>
</small>
</div>
</div>
}
</div>
#code {
Item selectedItem;
int selectedItemId;
void SelectProduct(int productId)
{
selectedItemId = productId;
selectedItem = _context.Items.Where(x => x.Id == selectedItemId).FirstOrDefault();
ContItem();
}
int itemcnt = 0;
string cuntLable;
void ContItem()
{
if (selectedItem.Quantity != null || selectedItem.Quantity != 0)
{
itemcnt = selectedItem.Quantity;
cuntLable = itemcnt.ToString();
}
else cuntLable = "Not available ..!";
}
}
problem: #onclick=".." is not hit my selectprodect method breakpoint when clicking the button.
Solution: the mistake is Statup.cs need to add services.AddServerSideBlazor() in ConfigureServices and then add in Configure part endpoints.MapBlazorHub()
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
endpoints.MapBlazorHub();
});
after 6 hours of hard work. #onclick is worked smoothly
Hy everyone,
sorry if my question is duplicate of some, but i didn't found solution for my problem.
However, i'm trying to implement custom like button for posts in my asp.net core mvc application and everything works fine, except when i click on like button, it changes color (like on facebook, blue color etc.) not just for current logged user, but for all logged users. But when other users refresh window, everything is back to normal...
What I want is, when I click on "like" button, to update "like counter" FOR EVERYONE and to change color JUST FOR ME (when I came back some other day, that I know that I liked that post.)
Does someone know how to acomplish this?
Here's my code
Index.cshtml
#using Fitness_Centar.Data
#using Fitness_Centar.Data.Models
#using Fitness_Centar.Web.Areas.ModulClan.ViewModels
#using Fitness_Centar.Web.Helper
#model List<TimelineVM>
#{
ViewData["Title"] = "Index";
MyContext _ctx = (MyContext)ViewData["_ctx"];
User u = Context.GetLoggedUser();
int userId = -1;
if (u.Coach != null)
{
userId = u.Coach.CoachId;
}
if (u.Employee != null)
{
userId = u.Employee.EmployeeId;
}
if (u.Member != null)
{
userId = u.Member.MemberId;
}
}
<div class="row">
<div class="col-sm-12 col-md-9 col-lg-9">
<div class="box box-info custom aktivnosti">
<div class="box-header with-border padding-l-25">
<h3 class="box-title">Activities</h3>
</div>
<div class="box-body">
#foreach (var p in Model)
{
<div id="#p.Post.PostClanovaId" class="post">
<div class="user-info">
<img class="img-circle img-bordered-sm" src="~/AdminLTE/dist/img/avatar5.png" />
<div class="desc">
<span class="username">#p.Post.User.Name #p.Post.User.LastName</span>
<span class="post-description">Published: #p.Post.PostDate</span>
</div>
</div>
<div class="post-content text-justify">
<p>#p.Post.Content</p>
</div>
<div class="post-footer">
#{int n = p.Post.PostId + 1594;}
#{
var c = _ctx.Likes.Where(x => x.UserId == userId && x.PostId == p.Post.PostId).FirstOrDefault();
if (c != null && c.UserId == userId)
{
<a href="" id="post-#n" class="likeButton link-black liked" data-postid="#p.Post.PostId" data-userid="#userId">
<i class="fa fa-thumbs-o-up margin-r-5"></i>
Like
</a>
}
else
{
<a href="" id="post-#n" class="likeButton link-black" data-postid="#p.Post.PostId" data-userid="#userId">
<i class="fa fa-thumbs-o-up margin-r-5"></i>
Like
</a>
}
}
<div class="num-of-likes" id="post-#n-numOfLikes">
#p.Likes.Count()
<span class="usersThatLiked">
#{
string g = "";
foreach (var l in p.Likes)
{
g += l.User.Ime + " " + l.Clan.Prezime;
}
#g;
}
</span>
</div>
<div class="comment pull-right">
<a href="#" class="link-black">
<i class="fa fa-comments-o margin-r-5"></i>
Comments
</a>
</div>
<div class="input-group">
<input type="text" class="form-control" placeholder="Komentiraj...">
<span class="input-group-btn">
<button type="button" class="btn btn-info btn-flat"><i class="fa fa-check"></i></button>
</span>
</div>
</div>
</div>
}
</div>
</div>
</div>
javascript.js
"use strict";
var $connection = new signalR.HubConnectionBuilder().withUrl("/ModulClan/Helper/LajkHub").build();
$(".likeButton").prop("disabled", true);
$connection.on("ReceiveMessage", function (numOfLikes, postId) {
var x = postId + 1594;
var s = "#post-" + x;
if ($(s).hasClass("liked")) {
$(s).removeClass("liked");
} else {
$(s).addClass("liked");
}
$(s + "-num-of-likes").text(numOfLikes);
});
$connection.start().then(function () {
$(".likeButton").prop("disabled", false);
}).catch(function (err) {
return console.error(err.toString());
});
$(".likeButton").bind("click", function (event) {
var userId = $(this).attr("data-userid");
var postId = $(this).attr("data-postid");
$connection.invoke("SetLike", userId, postId).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
LikeHub.cs
public class LikeHub : Hub
{
private readonly MyContext _ctx;
public LikeHub (MyContext context)
{
_ctx = context;
}
public async Task SetLike(int userId, int postId)
{
Likes l = new Likes();
Likes temp = _ctx.Likes.Where(x => x.PostId == postId && x.UserId == userId).FirstOrDefault();
if(temp != null)
{
_ctx.Likes.Remove(temp);
}
else
{
_ctx.Likes.Add(l);
l.UserId = userId;
l.PostId = postId;
}
_ctx.SaveChanges();
int numOfLikes= _ctx.Likes.Where(x => x.PostId == postId).Count();
await Clients.All.SendAsync("ReceiveMessage", numOfLikes, postId);
}
}
You can identify the current user (who clicked the like button) via
var userId = $(this).attr("data-userid"); (as you did when someone clicks the like button).
But the problem is this, you are not checking for the userId when the SetLike is succeeded (inside the on ReceiveMessage javascript function).
so to solve this you need to send the userId of the user who clicked the like button from the backend to the frontend (to the on("ReceiveMessage"..) function)
e.g.: await Clients.All.SendAsync("ReceiveMessage", numOfLikes, postId, userId);
and on the ReciveMessage check if the userId you got from the backend match the current user who's browsing by var currentUserId = $(this).attr("data-userid");
if they are equal then color the like button, otherwise just update the like counter.
this way would solve your issue.
Another solution would be to send 2 requests one is specific for the user who clicked the like button and the other is to everyone to update the like counter.
I'm using Vue.js v2 and I've defined a single-file component, RegionFacet.vue. It lists some regions that relate to polygons on a map (click a value, the corresponding polygon appears on the map).
Separately, I have a reset button. When that gets clicked, I call a method in RegionFacet to unselect any checkboxes displayed by RegionFacet. The model does get updated, however, the checkboxes remain checked. What am I missing?
<template>
<div class="facet">
<div class="">
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<a data-toggle="collapse"v-bind:href="'#facet-' + this.id"><h4 class="panel-title">Regions</h4></a>
</div>
<div v-bind:id="'facet-' + id" class="panel-collapse collapse in">
<ul class="list-group">
<li v-for="feature in content.features" class="list-group-item">
<label>
<input type="checkbox" class="rChecker"
v-on:click="selectRegion"
v-bind:value="feature.properties.name"
v-model="selected"
/>
<span>{{feature.properties.name}}</span>
</label>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['content'],
data: function() {
return {
id: -1,
selected: []
}
},
methods: {
selectRegion: function(event) {
console.log('click: ' + event.target.checked);
if (event.target.checked) {
this.selected.push(event.target.value);
} else {
var index = this.selected.indexOf(event.target.value);
this.selected.splice(index, 1);
}
this.$emit('selection', event.target.value, event.target.checked);
},
reset: function() {
this.selected.length = 0;
}
},
created: function() {
this.id = this._uid
}
}
</script>
<style>
</style>
You are directly setting the array length to be zero, which cannot be detected by Vue, as explained here: https://v2.vuejs.org/v2/guide/list.html#Caveats
Some more info: https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
To overcome this, you may instead set the value of this.selected as follows:
reset: function() {
this.selected = [];
}