Vue.js - on click collapse the nearest div - javascript

Below are some snippets of my code. Basically I have a few sections in my code to show some data and all these sections are collapsible. First load all sections expanded. On click on the chevron arrow, div -'ibox-content' will be collapsed.
How do I target only the nearest ibox to collapse? At moment when one arrow is clicked all sections are collapsed.
var vue = new Vue({
el: '#vue-systemActivity',
data: {
loading: false,
collapsed: false,
dateStart: '',
dateEnd: '',
status: 'fail',
msg: '',
meta: '',
data: ''
},
created: function() {
this.fetchData();
},
ready: function() {
this.fetchData();
},
methods: {
fetchData: function() {
var self = this;
if (self.dateStart != '' && self.dateEnd != '') {
this.loading = true;
$.get(baseUrl + '/backend/getSystemActFeed?dateStart=' + self.dateStart + '&dateEnd=' + self.dateEnd, function(json) {
self.data = json.data;
self.status = json.status;
self.meta = json.meta;
self.msg = json.msg;
}).always(function() {
self.loading = false;
});
}
}
}
});
");
<div v-if="data.events">
<div class="ibox float-e-margins" :class="[collapsed ? 'border-bottom' : '']">
<div class="ibox-title">
<h5>Events</h5>
<div class="ibox-tools">
<a v-on:click=" collapsed = !collapsed" class="collapse-link">
<i :class="[collapsed ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>
</a>
</div>
</div>
<div v-for="event in data.events" class="ibox-content inspinia-timeline" v-bind:class="{'is-collapsed' : collapsed }">
<div class="timeline-item">
<div class="row">
<div class="col-xs-3 date">
<i class="fa fa-calendar"></i> {{event.fDateStarted}}
<br/>
</div>
<div class="col-xs-7 content no-top-border">
<!-- <p class="m-b-xs"><strong>Meeting</strong></p> -->
<b>{{event.title}}</b> started on {{event.fDateStarted}} at {{event.at}}
</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="data.mentorBookings">
<div class="ibox float-e-margins" :class="[collapsed ? 'border-bottom' : '']">
<div class="ibox-title">
<h5>Mentorship</h5>
<div class="ibox-tools">
<a v-on:click=" collapsed = !collapsed" class="collapse-link">
<i :class="[collapsed ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>
</a>
</div>
</div>
<div v-for="mentorProgram in data.mentorBookings" class="ibox-content inspinia-timeline">
<div class="timeline-item">
<p class="m-b-xs"><strong>{{mentorProgram.programName}}</strong></p>
<div v-for="upcomingBooking in mentorProgram.upcomingBookings">
<div class="row">
<div class="col-xs-3 date">
<i class="fa fa-users"></i> {{upcomingBooking.fBookingTime}}
<br/>
</div>
<div class="col-xs-7 content no-top-border">
#{{upcomingBooking.id}} {{upcomingBooking.mentor.firstname}} {{upcomingBooking.mentor.lastname}} ({{upcomingBooking.mentor.email}}) mentoring {{upcomingBooking.mentee.firstname}} {{upcomingBooking.mentee.lastname}} ({{upcomingBooking.mentee.email}}) on
{{upcomingBooking.fBookingTime}} thru {{upcomingBooking.sessionMethod}}
<!--
<p><span data-diameter="40" class="updating-chart">5,3,9,6,5,9,7,3,5,2,5,3,9,6,5,9,4,7,3,2,9,8,7,4,5,1,2,9,5,4,7,2,7,7,3,5,2</span></p> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Each div should have each own collapsed state for control. You can turn collapsed into an array/object to control them.
simple example: https://codepen.io/jacobgoh101/pen/QQYaZv?editors=1010
<div id="app">
<div v-for="(data,i) in dataArr">
{{data}}<button #click="toggleCollapsed(i)">toggle me</button>
<span v-if="collapsed[i]">this row is collapsed</span>
<br/>
<br/>
</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
dataArr: ["data0", "data1", "data2"],
collapsed: [false, false, false]
},
methods: {
toggleCollapsed: function(i) {
this.$set(this.collapsed, i, !this.collapsed[i]);
}
}
});
</script>

Related

In vue js with the help of loop i am showing all elements and i want to hide one element from that but all elements are getting hide

First Image without clicking on Edit
Second Image when i click on Edit
here when i click on which ever edit button all the task which is in loop plus it is in if part will be hidden and else part will be shown but i want to hide particular task when i click on edit button. can anyone help me with that?.
<script>
export default {
data(){
return{
newTaskTitle: "",
isEditing : false
}
},
props:{
Task:{
type:Array,
required: true
},
},
methods:{
removeTask: function(idx){
this.Index = idx;
this.$emit('remove',this.Index);
},
EditTaskI(tsk){
this.task = tsk;
console.log(this.task);
this.isEditing = this.isEditing == true ? false : true;
this.newTaskTitle = this.task;
},
TaskUpdated(indx){
this.Index = indx
this.$emit('update',this.Index,this.newTaskTitle);
this.isEditing = this.isEditing == true ? false : true;
},
taskContentChange(e){
this.newTaskTitle = e.target.value;
}
}
}
</script>
<template>
<section v-if="Task.length > 0" class="taskMainSection">
<section v-for="(tasks,index) in Task" :key="index" class="sectionTask" >
<section class="TaskBox" v-if="!isEditing">
<div class="TaskTitleList" >
<div class="TaskSection">
<p class="listTask">{{ tasks.Task }}</p>
</div>
</div>
<div class="OptionSectionMain">
<div class="OptionSection">
<p class="removeTask fa fa-close" #click="removeTask(index)"></p>
<p class="editTask fa fa-edit" #click="EditTaskI(tasks.Task,index)"></p>
</div>
</div>
</section>
<section class="TaskBoxEdit" v-else>
<div class="TaskTitleList" >
<div class="TaskSection">
<input type="text" class="form-control" :value="newTaskTitle" #change="taskContentChange">
</div>
</div>
<div class="OptionSectionMain">
<div class="OptionSection">
<p class="removeTask fa fa-check" #click="TaskUpdated(index)"></p>
</div>
</div>
</section>
</section>
</section>
</template>
Instead of boolean use index for isEditing:
Vue.component('child', {
template: `
<section v-if="Task.length > 0" class="taskMainSection">
<section v-for="(tasks,index) in Task" :key="index" class="sectionTask" >
<section class="TaskBox" >
<div class="TaskTitleList" >
<div class="TaskSection">
<p class="listTask">{{ tasks.Task }}</p>
</div>
</div>
<div class="OptionSectionMain">
<div class="OptionSection">
<p class="removeTask fa fa-close" #click="removeTask(index)"></p>
<p class="editTask fa fa-edit" #click="EditTaskI(tasks.Task,index)"></p>
</div>
</div>
</section>
<section class="TaskBoxEdit" v-if="isEditing === index">
<div class="TaskTitleList" >
<div class="TaskSection">
<input type="text" class="form-control" :value="newTaskTitle" #change="taskContentChange">
</div>
</div>
<div class="OptionSectionMain">
<div class="OptionSection">
<p class="removeTask fa fa-check" #click="TaskUpdated(index)"></p>
</div>
</div>
</section>
</section>
</section>
`,
data(){
return{
newTaskTitle: "",
isEditing : null
}
},
props:{
Task:{
type:Array,
required: true
},
},
methods:{
removeTask(idx){
console.log(idx)
this.$emit('remove', idx);
},
EditTaskI(tsk, i){
this.task = tsk;
this.isEditing = i;
this.newTaskTitle = this.task;
},
TaskUpdated(indx){
this.Index = indx
this.$emit('update',this.Index,this.newTaskTitle);
this.isEditing = null;
},
taskContentChange(e){
this.newTaskTitle = e.target.value;
}
}
})
new Vue({
el: "#demo",
data(){
return{
tasks: [{Task: 'aaa'}, {Task: 'bbb'}, {Task: 'ccc'}],
}
},
methods: {
updateTasks(i, name) {
this.tasks[i].Task = name
},
removeTask(i) {
this.tasks.splice(i, 1)
}
}
})
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<child :task="tasks" #update="updateTasks" #remove="removeTask"></child>
</div>
Observation : isEditing is a culprit in your code. As isEditing is a global variable containing boolean value. Hence, On edit you are updating the value of isEditing which impact for all the tasks.
Solution : Instead of defining isEditing globally, You can add isEditing in each object of Task array. So that you can just update the value of clicked task not for every task.
Your template code will be :
<section class="TaskBox" v-if="!tasks.isEditing">
instead of
<section class="TaskBox" v-if="!isEditing">

JavaScript ajax didn't working.Where am I going wrong?

<div class="media-bottom">
#Html.TextAreaFor(model => model.Message, new { #class = "ui form", #rows = "5", #maxlenght = "300", #placeholder = "Paylaşmak istedikleriniz" })
</div>
<br />
<div class="footer-logo">
<button class=" mini ui right labeled right floated icon button" id="Button_Click" onclick="javascript: Button_Click();">
<i class="right arrow icon"></i>
Paylas
</button>
<div class="container bootstrap snippets bootdey downlines">
<div class="row">
<div class="col-md-6 col-xs-12">
<section class="widget">
<div class="widget-body">
<div class="widget-top-overflow windget-padding-md clearfix bg-info text-white">
</div>
<div class="post-user mt-n-lg">
<span class="thumb-lg pull-left mr media-object">
<img class=" img-circle" src="https://bootdey.com/img/Content/user_3.jpg" alt="...">
</span>
<span class="thumb-lg pull-right mr star">
<img src="~/Content/img/star.png" />
</span>
<div class="Thanksicon">
</div>
<div class="namespace">
<h5 class="mt-sm fw-normal text-black txt post">
#Html.DisplayFor(model => model.FullName)
<br />
<small class="text-black text-light departmen post">#Html.DisplayFor(model => model.Departmen)</small>
</h5>
</div>
</div>
<br />
<br />
<div class="text-light fs-mini m" id="Label1">
<div id="label1">
<p class="article">
#Html.DisplayTextFor(model=>model.Message)
</p>
</div>
<div class="thanksnames">
<span class="thumb-xs avatar mr-sm">
<img class="img-circle thank" src="https://bootdey.com/img/Content/user_2.jpg" alt="...">
</span>
<div class="mt-sm fw-normal text-black " id="person"> <small class="text-black text-light">Rose Tyler</small></div>
</div>
<br />
<div class="img"></div>
<div class="fs-mini text-muted text-right"><time class="time-table-top"></time></div>
</div>
</div>
</section>
</div>
</div>
</div>
This is my javascript
$(function () {
$('#Button_Click').on('click', function () {
$.ajax({
type: "POST",
url: '#Url.Action("Share")',
data: {
fullname: $("#username").val(),
departmen: $("#departmen").val(),
textarea: $(".ui.form").val()
},
datatype: "json",
success: function (data) {
$('.downlines').html(result);
}, error: function (data) {
}
});
});
});
This is my controller httppost
[HttpPost]
private JsonResult Share(SocialMedia data,string id)
{
var employee = _employeeRepository.GetById(id);
ViewBag.IsOwner = id == Session.GetEmployeeNo();
if (Session["MediaList"] == null)
{
Session["MediaList"] = new List<SocialMedia>();
}
var fullname = data.FullName;
var departmen = data.Departmen;
var textarea = data.Message;
foreach (MediaList list in data.MediaLists)
{
list.FullName = fullname;
list.Departmen = departmen;
list.Message = textarea;
list.Date = DateTime.Now.ToLocalTime();
if(data.Photo!=null)
{
list.Photo = data.Photo;
string fileName = Path.GetFileNameWithoutExtension(list.Photo);
list.Photo = "~/Image/" + fileName;
string _path = Path.Combine(Server.MapPath("~/Image/"),fileName);
}
}
return Json(new { data = PartialView("~/Views/SocialMedia/DisplayTemplates/MediaList.cshtml") });
// return PartialView("~/Views/SocialMedia/DisplayTemplates/MediaList.cshtml",
//return Json(new { success = true, message = GlobalViewRes.CreatedSuccessfully }, JsonRequestBehavior.AllowGet);
}
When I write an article and press the button, I want the page to appear below without refreshing and I want it to be repeated. It should be with the whole design. But when I press the button, I made ajax, but my ajax does not work, where am I going wrong?
Sorry for my English:)
success: function (data) {
$('.downlines').html(result);
}, error: function (data) {
}
You handle the data named 'data'. Then you are trying use it like 'result'. What is result, where is it came from? Whatever, try this
$('.downlines').html(data)

Vue function fires multiple time

I'm using vue cli and I have function that updates text #click but it keeps running multiple times:
User.vue
<div #click="newText('Volume')">
<Chart :text=text ></Chart>
volume
</div>
<div #click="newText('Temperature')">
<Chart :text=text ></Chart>
temp
</div>
<div #click="newText('Weight')">
<Chart :text=text ></Chart>
weight
</div>
<script>
newText: function(argT) {
const text = argT;
this.text = text;
console.log('text', this.text);
</script>
},
In Chart component when I console.log it ran 9 times!
props: ['text'],
text1(){
console.log('text', this.text)
},
It seems that since my User component is displayed 3 times(intentionally due to an array of 3 users I have) and there is a box for each measurement(temp, vol and weight), that's why it's 9 times. But I'm not sure why it runs each time.
I would like it to run only once for the box I clicked.
Any help would be great, thanks!
Update (additional code)
User.vue
<template >
<div class="user">
<div v-for="(item, index) in users" :key="item.id">
<div>
<div #click.stop="myFunction(index); newData(index, item.Vol); newText('Volume')">
<v-touch v-on:doubletap="isOpen = !isOpen;" >
<transition name="modal">
<div v-if="isOpen">
<div class="overlay" #click.self="isOpen = false;">
<div class="modal">
<Chart :text=text :dat=dat ></Chart>
</div>
</div>
</div>
</v-touch>
volume </div>
<div #click.stop="myFunction(index);newData(index, item.Temp); newText('Temperature')">
<v-touch v-on:doubletap="isOpen = !isOpen;" >
<transition name="modal">
<div v-if="isOpen">
<div class="overlay" #click.self="isOpen = false;">
<div class="modal">
<Chart :text=text :dat=dat ></Chart>
</div>
</div>
</div>
</v-touch>
temp </div>
<div #click.stop="myFunction(index); newData(index, item.Weight); newText('Weight')">
<v-touch v-on:doubletap="isOpen = !isOpen;" >
<transition name="modal">
<div v-if="isOpen">
<div class="overlay" #click.self="isOpen = false;">
<div class="modal">
<Chart :text=text :dat=dat ></Chart>
</div>
</div>
</div>
</v-touch>
weight</div>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
import Charts from './Charts'
export default {
name: 'User',
components: {
Charts,
},
methods:{
newData: function(arrIndex, event) {
const dat = event;
this.dat = dat;
},
newText: function(argT) {
const text = argT;
this.text = text;
console.log('text', this.text);
},
myFunction: function (arrIndex) {
const name = this.users[arrIndex].name;
this.name = name;
},
},
}
</script>
Charts.vue
<div class="tabs">
<a v-on:click="activetab=1" v-bind:class="[ activetab === 1 ? 'active' : '' ]">Settings</a>
<a v-on:click="activetab=2" v-bind:class="[ activetab === 2 ? 'active' : '' ]">Chart</a>
</div>
<div class="content">
<div v-if="activetab === 1" class="tabcontent">
<Settings></Settings>
</div>
<div v-if="activetab === 2" class="tabcontent">
<Chart :dat=dat :text=text ></Chart >
</div>
</template>
<script>
import Chart from './Chart'
import Settings from './Settings'
/* eslint-disable */
export default {
name: 'Charts',
props: ['activetab', 'dat','text' ],
components: {
Settings,
Chart,
},
methods: {
text1(){
console.log('text', this.text)
},
</script>
and finally I pass text to a chart:
<template>
<div id="container" ref="chart"></div>
</template>
<script>
title: {
text: this.text,
}
series: [ {
name: this.text,
data: this.dat,
}],
In my case browser-sync was the problem.

switching between v-if and v-else with a button

am having problem switching from the first section(v-if) to the second second(v-else) section using v-if. as default now section(v-if) is displaying and i created a button(startGame) to change to the second section(v-else) when clicked but i find it not easy to do please help me out
<section class="row controls" v-if="!gameIsrunning">
<div class="small-12 columns">
<button id="start-game" #click="startGame">START NEW GAME</button>
</div>
</section>
<section class="row controls" v-else>
<div class="small-12 columns">
<button id="attack">ATTACK</button>
<button id="special-attack">SPECIAL ATTACK</button>
<button id="heal">HEAL</button>
<button id="give-up">GIVE UP</button>
</div>
</section>
<script>
let app = new Vue({
el: "#app",
data: {
playerHealth: 100,
monsterHealth: 100,
gameIsRunning: false
},
methods: {
startGame: function() {
this.gameIsRunning = true;
}
}
});
</script>

AngularJS - passing a value to a function for the second time returns undefined

I'm new to Angular and on my way to learn while bulding a website I've stopped with a really stupid moment.
I have a function inside a controller that is supposed to be called on ng-click event, I'm passing an 'id' value to it and using that 'id' it's supposed to search an array of presenters(objects) returning and assigning to $scope.presenter the one that I'm looking for. The thing is that the functions works ok for the the first time, but when I'm trying to call it again using a next/previous button the console log returns that the 'id' is undefined. Here is the controller code:
angular.module('fpl15App').controller('PresentersCtrl', function ($scope, $filter) {
$('body').css({'overflow':'hidden'});
$scope.showDetails = false;
$scope.currentPresenter = {};
$scope.getPresenterDetails = function( presenterId ) {
var id = presenterId - 1;
console.log(id);
$scope.showDetails = true;
var i=0, len=$scope.presenters.length;
for (; i<len; i++) {
if (+$scope.presenters[i].id === +id) {
return $scope.currentPresenter = $scope.presenters[i];
}
}
return null;
};
$scope.hideOverlay = function(){
$scope.showDetails = false;
};
$scope.presenters = [
{
id: 1,
name: 'adam_wolf',
thumb: 'images/presenters/adam_wolf.jpg',
bio: 'lorem ipsum'
}.
...
{
id: 15,
name: 'aimee_nicotera',
thumb: 'images/presenters/aimee_nicotera.jpg',
bio: 'lorem ipsum'
}
];
});
end here is the view code:
<div class="row" id="presenters">
<div class="col-md-12 above-element" id="presenter-overlay" ng-show="showDetails">
<div class="col-md-12 col-md-offset-6 motion-container animated" ng-class="{fadeInRight : showDetails}">
<div class="col-md-12 skew-container bg-yellow no-pad">
<div class="skew-content col-md-6 no-pad">
<div class="row presenter-image-container">
<div class="col-md-6 flex-container name-holder">
<h2>{{currentPresenter.name}}</h2>
</div>
<div class="col-md-6 no-pad image-holder">
<figure><img src="{{currentPresenter.image}}" alt=""></figure>
</div>
</div>
<div class="row bg-white presenter-bio-container">
<div class="col-md-6 col-md-offset-6">
<p>{{currentPresenter.bio}}</p>
</div>
</div>
<div class="row bg-white presenter-navigation">
<div class="col-md-10 col-md-offset-2">
<div class="row">
<div class="col-md-6 no-pad"> <span class="presenter-nav" ng-click="getPresenterDetails({{currentPresenter.id - 1}})"> <i class="glyphicon glyphicon-menu-left"></i> Prev </span> </div>
<div class="col-md-6 no-pad"> <span class="presenter-nav" ng-click="getPresenterDetails({{currentPresenter.id + 1}})"> Next <i class="glyphicon glyphicon-menu-right"></i> </span> </div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12 under-element">
<ul id="presenters-list">
<li class="presenter animation" ng-repeat="presenter in presenters"> <a ng-href="" ng-click="getPresenterDetails({{presenter.id}})"><img ng-src="{{presenter.thumb}}" alt="{{presenter.name}}"></a> </li>
</ul>
</div>
</div>

Categories