BootstrapV4 - Can't push a span to the right - twitter-bootstrap-4

In the following code (react isn't important here), I'm using the bootstrapV4 class "text-sm-right". It works perfectly for my <button>, but it doesn't for my post.categories <span> which remain on the left. I can't make it work and I don't explain it. Is someone having an explanation ?
renderPosts() {
return this.props.posts.map((post) => {
return (
<li className="list-group-item" key={post.id}>
<span className="text-sm-right">{post.categories}</span>
<strong>{post.title}</strong>
</li>
);
});
}
render() {
return (
<div>
<div className="text-sm-right post-new-button">
<Link to="/posts/new" className="btn btn-primary">Add post</Link>
</div>
<h3>Posts</h3>
<ul className="list-group">
{this.renderPosts()}
</ul>
</div>
);
}
Here is a screenshot of the rendered site, button positioned as wanted but categories remaining on the left...

.list-group-item has display: flex by default. This means that all you have to do is to add justify-content-between class to your <li> and move your declaration one line bottom.
Your renderPosts method should look as follow:
renderPosts() {
return this.props.posts.map((post) => {
return (
<li className="list-group-item justify-content-between" key={post.id}>
<strong>{post.title}</strong>
<span>{post.categories}</span>
</li>
);
});
}
You can find an example of this approach on bootstrap documentation

Related

Can't display datetime from v-for

I'm trying to show the datatime in a v-for, but it just keeps showing the same time over and over.
Is there a way to do this?
v-for -
<div class="location-box-container">
<ul class="location-box-list">
<ol v-for="(location, index) in lineStringData" :key="lineStringData.id">
<p class="locations">{{ location_time }} New Location</p>
</ol>
</ul>
</div>
JS -
data() {
return {
location_time: new Date().toLocaleTimeString(),
}
},
Use a method to lookup time. Not sure where you are storing the time, but you can look up timezone from coords if needed.
<div class="location-box-container">
<ul class="location-box-list">
<ol v-for="(location, index) in lineStringData" :key="lineStringData.id">
<p class="locations">{{ getTime(location) }} New Location</p>
</ol>
</ul>
</div>
methods: {
getTime(location) {
// lookup your timezone, etc here.
return new Date(location.theTime).toLocaleTimeString()
}
}

How to unshift to append under spicific div in Vue

I have comments and this comment containe likes, My propblem is when I try to push replay to the comment it is append to the wrong comment, So I used this.$el; to get the target comment bu the propblem is unshift/push just use with list and it shows error push is not a function
My qustion is how I can use unshift/push to append under spicific div not list
async addReplay(comment, e){
const element = this.$el; //this to get the target div
}
here the post replay function
async getaddReplay(id, setReplayPlace){
await axios.get('/account/api/auth/user/')
.then(response => {
this.currentUserImage = response.data.profile_image
})
const replayData = {
content: this.commentReplayContent,
video: this.$route.params.video_id,
parent: id
}
await axios.post(`/video/api/video/comment/${id}/replay/create/`, replayData)
.then(response => {
console.log(this.setReplayPlace)
// here I want append the item to spicific div
this.setReplayPlace.unshift({ content: this.commentReplayContent, author: this.$store.state.user.username, id:response.data.id, author_image:this.currentUserImage, video:this.$route.params.video_id ,likes:0, total_parents:0, check_like: false, publish:'now'})
this.commentReplayContent = ''
})
.catch(error => {
console.log(error)
})
}
Edit
Here there are comments with replies component and I pass the data to repliy component using props
<ul v-for="(comment, index) in comments" :key="index">
<li class="comment-object">
<div class="image-container">
<img class="profile-pic" :src="comment.author_image" v-on:change="currentUserImage" alt="profile picture" id="user_video_comment_profile_image" refs="user_video_comment_profile_image" />
</div>
<div class="comment-text">
<h2 class="username" style="color: #C2C3C4">{{comment.author}} <span class="muted">· {{comment.publish}}</span>
<DeleteComment :comment="comment" v-if="comments || index" :comments="comments" :index="index" />
</h2>
<p class="comment">{{comment.content}} </p>
<RepliesJustAdded #justAddedReplies="addRepliesToParent" :replaiesJustAdded="replaiesJustAdded" :setReplayPlace="setReplayPlace" :allReplies="allReplies" :replaiesData="replaiesData" v-if="replaiesJustAdded || setReplayPlace || allReplies || replaiesData" />
</div>
</li>
</ul>
The Replay component
<ul v-for="replay in replies" :key="replay.id" id="video_comments_replies" >
<li class="comment-object">
<div class="image-container">
<img class="profile-pic" :src="replay.author_image" alt="profile picture" id="user_video_comment_profile_image" refs="user_video_comment_profile_image" />
</div>
<div class="comment-text">
<h2 class="username" style="color: #C2C3C4">{{replay.author}} <span class="muted">· {{replay.publish}}</span></h2>
<p class="comment">{{replay.content}} </p>
<RepliesActionButtons :replay="replay" />
</div>
</li>
</ul>
I didn't find the line where you are trying to call push but I thing I know what's wrong: your are trying to call push but array-like collections don't have such method. You should convert your collection to array before calling push. Try something like that:
// create a `NodeList` object
const divs = document.querySelectorAll('div');
// convert `NodeList` to an array
const divsArr = Array.from(divs);
After that all methods of Array.prototype will be available.

vue.js basic function not working as wanted

I have create a set of pairs of divs, that use the v-for method to get data from a set of dummy objects in an array. The goal is for each pair of divs when I click on the visible div it opens the corresponding relevant div. At the moment my function which I have attached as a property of a method object only opens the invisible div of the first pair of divs even if I click on the 3rd visible div it still displays the invisible div. i am using the vue framework.
I have attached pictures of my code then the actual code.
[The div I am trying to open is session-on-click details atm it is opening only that for the first index][1]
<div class = "rowuserlog" id="log-container" v-for="session in sessions" :key="session.id"
>
<div id="log-container-user-row-1">
<div id="profile-log-title" #click="logToggler()"> {{session.name}} </div>
<div id="profile-log-date"> {{session.date}}</div>
<div id="user-log-metric-container">
<div id ="user-log-hr" class="log-metric">{{session.hr}}</div>
<div id ="user-log-time" class="log-metric"> {{session.time}}</div>
<div id ="user-log-meters" class="log-metric"> {{session.distance}} </div>
<div id="session-onclick-details">
<div id="log-comments">
{{session.comments}}
</div>
<div id="log-edit-buttons">
<button id="log-save" class="log-edit-button"> Save </button>
<button id="log-delete" class="log-edit-button"> Delete </button>
<button id="log-cancel" class="log-edit-button"> Cancel </button>
<button id="log-edit" class="log-edit-button"> Edit </button>
</div>
</div>
```
My method
The toggler is the method I want:Here is the code
methods:{
logToggler () {
const extraInfoLog = document.getElementById("session-onclick-details");
return extraInfoLog.style.display="block";
}
]
[2]
[1]: https://i.stack.imgur.com/ddrYo.png
[2]: https://i.stack.imgur.com/evriF.png
data() {
return {
sessions:[
{ name:'test',
value:false,
id:1
},
{ name:'test1',
value:false,
id:2
},
{ name:'test2',
value:false,
id:3
}
]
}
}
methods:{
logToggler(_index) {
for(let index=0;index<sessions.length;index++) {
if(index == _index)
sessions[index].value = true
else
sessions[index].value = false
}
}
}
Template
<div class = "rowuserlog" id="log-container" v-for="(session,index) in sessions" :key="session.id"
>
<div id="profile-log-title" #click="logToggler(index)" v-if="session.value"> {{session.name}} </div>

How to mark notification as Read using Vue js?

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 ...

How to fix my price to show on "Pris:" in java in vue?

<script>
// # is an alias to /src
export default {
name: 'home',
data() {
return {
inc: 0,
inc2: 0,
inc3: 0,
}
},
methods: {
toInc() {
this.inc++
},
toDec() {
this.inc--
},
toInc2() {
this.inc2++
},
toDec2() {
this.inc2--
},
toInc3() {
this.inc3++
},
toDec3() {
this.inc3--
}
}
computed:{ //here i get this error with ";"
total(){
return this.inc+this.inc2+this.inc3;
}
}
}
</script>
<div class="plane">
<div class="columns">
<ul class="price">
<div class="prisinfo">
<p class="item">Ordinarie (<span class="cost">85kr</span>/st)</p> //those prices i need to get when im pressing on +
<div class="priser">
<li class="pris1">-</li>
<p>{{inc}}</p>
<li class="pris1">+</li>
</div>
</div>
<div class="prisinfo">
<p class="item">Barn (<span class="cost">65kr</span>/st)</p> //those prices i need to get when im pressing on +
<div class="priser">
<li class="pris2">-</li>
<p>{{inc2}}</p>
<li class="pris2">+</li>
</div>
</div>
<div class="prisinfo">
<p class="item">Pensionär (<span class="cost">75kr</span>/st) </p> //those prices i need to get when im pressing on +
<div class="priser">
<li class="pris3">-</li>
<p>{{inc3}}</p>
<li class="pris3">+</li>
</div>
</div>
</ul>
</div>
<section id="totalprice">
<p>Pris:<span class="total_price">{{total}}</span></p> // and here my total price after getting all the prices togheter after choosing how many tickets you need.
</section>
I got error in console with "unexpected ;" and my dosnt work anymore after i did those changes. I need also to get the price to add when i press + and substact when i press -, i have the price in html.
You got my coments in the code if you need them.
Im so bad at vue right now, and java is my weak side too.
to show the total price, you may find computed property very useful:
after your data property, add :
computed:{
total(){
return this.inc+this.inc2+this.inc3;
}
},
and you HTML line would be:
<p>Pris:<span class="total_price">{{total}}</span></p>
now, about the + and - buttons:
they look good, i think its just a tiny mistake on the HTML side: you should call the function toInc with ().
like this:
<li class="pris3">+</li>
(#click is like v-on:click https://v2.vuejs.org/v2/guide/syntax.html#v-on-Shorthand)