I want to refactor the code to have less functions - javascript

How would I go about refactoring my code to be more concise:
const an1 = document.getElementById("an1");
const bt1 = document.getElementById("bt1");
bt1.addEventListener("click", () => {
if (an1.value.toLowerCase() === "test") {
document.getElementById("bt1").style.display = "none";
document.getElementById("an1").style.display = "none";
document.getElementById("wo1").style.display = "initial";
} else {
bt1.innerText = "Wrong!";
document.getElementById("bt1").style.background = "red";
}
});
const an2 = document.getElementById("an2");
const bt2 = document.getElementById("bt2");
bt2.addEventListener("click", () => {
if (an2.value.toLowerCase() === "test1") {
document.getElementById("bt2").style.display = "none";
document.getElementById("an2").style.display = "none";
document.getElementById("wo2").style.display = "initial";
} else {
bt2.innerText = "Wrong!";
document.getElementById("bt2").style.background = "red";
}
});
<tr>
<td class="c1"><input id="an1" placeholder="test" type="text" onblur="this.value=removeSpaces(this.value);" /><a id="wo1" style="display: none;">test</a><button id="bt1">Submit</button></td>
<td class="c1">test</td>
</tr>
<tr>
<td class="c2"><input id="an2" placeholder="test1" type="text" onblur="this.value=removeSpaces(this.value);" /><a id="wo2" style="display: none;">test1</a><button id="bt2">Submit</button></td>
<td class="c2">test1</td>
</tr>

Try below code, update the arrays if this fucntionality requires for others field too.
// change below arrays if you need this functionality for more fields
const expectedElementAnswer = [{ id: 'an1', expectAns: 'test' }, { id: 'an2', expectAns: 'test1' }];
const btnElementList = [
[{ id: 'bt1', displayValue: 'none' },{ id: 'an1', displayValue: 'none' }, { id: 'wo1', displayValue: 'initial' }],
[{ id: 'bt2', displayValue: 'none' }, { id: 'an2', displayValue: 'none' }, { id: 'wo2', displayValue: 'initial' }]
];
document.getElementById('myTable').addEventListener('click', (event) => {
const curElemetId = event.target.id;
const btnIndex = (curElemetId === 'bt1') ? 1 : (curElemetId === 'bt2') ? 2 : -1;
if ((btnIndex === 1) || (btnIndex === 2)) {
const idx = btnIndex - 1;
const { id, expectAns } = expectedElementAnswer[idx];
if (getElementValue(id).toLowerCase() === expectAns) {
changeDisplayStyles(idx);
} else {
setErrorWarning(curElemetId);
}
}
});
function changeDisplayStyles(idx) {
btnElementList[idx].forEach(({ id, displayValue }) => {
setDisplayStyle(id, displayValue)
});
}
function setDisplayStyle(displayId, value) {
document.getElementById(displayId).style.display = value;
}
function setErrorWarning(displayId, bgColor = 'red') {
const element = document.getElementById(displayId);
element.innerText = 'Wrong!';
element.style.background = bgColor;
}
function getElementValue(id) {
const value = document.getElementById(id)?.value || '';
return value;
}
<table id="myTable">
<tr>
<td class="c1">
<input id="an1" placeholder="test" type="text"/>
<a id="wo1" style="display: none;">test</a>
<button id="bt1">Submit</button>
</td>
<td class="c1">test</td>
</tr>
<tr>
<td class="c2">
<input id="an2" placeholder="test1" type="text"/>
<a id="wo2" style="display: none;">test1</a>
<button id="bt2">Submit</button>
</td>
<td class="c2">test1</td>
</tr>
</table>

Related

Reset the data on table using reset button

learning javascript by doing (beginner), here i have a table where is 'animals' and 'persons' want to know is there a way to reset table data back to 'Animal' after selecting data from select box ? i thought by calling the whole thing again inside onclick would do the trick but...
my code :
function myFunction() {
paivitys()
}
function paivitys(data, arvvoja) {
console.log(data);
//----
if (data.hasOwnProperty("animal")) {
document.getElementById("1name").innerHTML = data.animal;
} else {
document.getElementById("1name").innerHTML = data.person;
document.getElementById("1name1").innerHTML = 'person';
}
//----
if (data.hasOwnProperty("animal2")) {
document.getElementById("2name").innerHTML = data.animal2;
} else {
document.getElementById("2name").innerHTML = data.person2;
document.getElementById("2name1").innerHTML = 'person';
}
//-----
document.getElementById("id").innerHTML = data.id;
}
function paivitaselekt(data, arvvoja) {
for (var i = 0; i < data.length; i++) {
var select = document.getElementById("Select");
var option = document.createElement("option");
arvvoja.forEach((value) => {
option.textContent += data[i][value] + " ";
});
select.appendChild(option);
}
}
data = {
"animal": "tiger",
"animal2": "lion",
"id": "54321",
"dole": {
"Key": "fhd699f"
}
}
paivitys(data);
let kokoarray;
data = [{
"person": "kaka",
"person2": "julle",
"id": "9874",
},
{
"person": "Ronaldo",
"person2": "jussi",
"id": "65555",
}
]
kokoarray = data;
paivitaselekt(data, ["person", "id"]);
document.getElementById("Select").addEventListener("change", function(event) {
const valittutunnsite = event.target.value.split(" ")[1];
const valittutieto = kokoarray.filter((data) => data.id === valittutunnsite)[0];
paivitys(valittutieto);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous" />
<div class="container">
<table class="table ">
<thead>
<tr>
<th style="width: 25%;" id="1name1" class="table-primary">Animal</th>
<th style="width: 25%;" id="2name1" class="table-primary">Animal</th>
<th style="width: 25%;" class="table-primary">id</th>
</tr>
</thead>
<tbody>
<th id="1name"></th>
<th id="2name"></th>
<th id="id"></th>
</tbody>
</table>
<select id="Select" name="name"></select>
<button onclick="myFunction()">Reset</button>
</div>
Works this.
let animals
let animalCols = ['Animal', 'Animal 2']
let peopleCols = ['Person', 'Person 2']
function myFunction() {
paivitys(animals, animalCols)
}
function paivitys(data, arvvoja) {
console.log(data);
//----
if (data.hasOwnProperty("animal")) {
document.getElementById("1name").innerHTML = data.animal;
} else {
document.getElementById("1name").innerHTML = data.person;
}
//----
if (data.hasOwnProperty("animal2")) {
document.getElementById("2name").innerHTML = data.animal2;
} else {
document.getElementById("2name").innerHTML = data.person2;
}
document.getElementById("1name1").innerHTML = arvvoja[0];
document.getElementById("2name1").innerHTML = arvvoja[1];
//-----
document.getElementById("id").innerHTML = data.id;
}
function paivitaselekt(data, arvvoja) {
for (var i = 0; i < data.length; i++) {
var select = document.getElementById("Select");
var option = document.createElement("option");
arvvoja.forEach((value) => {
option.textContent += data[i][value] + " ";
});
select.appendChild(option);
}
}
animals = {
"animal": "tiger",
"animal2": "lion",
"id": "54321",
"dole": {
"Key": "fhd699f"
}
}
paivitys(animals, animalCols);
let kokoarray;
people = [{
"person": "kaka",
"person2": "julle",
"id": "9874",
},
{
"person": "Ronaldo",
"person2": "jussi",
"id": "65555",
}
]
kokoarray = people;
paivitaselekt(kokoarray, ["person", "id"]);
document.getElementById("Select").addEventListener("change", function(event) {
const valittutunnsite = event.target.value.split(" ")[1];
const valittutieto = kokoarray.filter((data) => data.id === valittutunnsite)[0];
paivitys(valittutieto, peopleCols);
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous" />
<div class="container">
<table class="table ">
<thead>
<tr>
<th style="width: 25%;" id="1name1" class="table-primary">Animal</th>
<th style="width: 25%;" id="2name1" class="table-primary">Animal</th>
<th style="width: 25%;" class="table-primary">id</th>
</tr>
</thead>
<tbody>
<th id="1name"></th>
<th id="2name"></th>
<th id="id"></th>
</tbody>
</table>
<select id="Select" name="name"></select>
<button onclick="myFunction()">Reset</button>
</div>
I updated the code:
set columns
let animalCols = ['Animal', 'Animal 2']
let peopleCols = ['Person', 'Person 2']
udpate data
paivitys(animals, animalCols)
and
function paivitys(data, arvvoja) {
...
document.getElementById("1name1").innerHTML = arvvoja[0];
document.getElementById("2name1").innerHTML = arvvoja[1];
//...
}
Your reset button calls the function:
function myFunction() {
paivitys()
}
Which calls the paivitys function with no arguments.
function paivitys(data, arvvoja) {
The function takes data as its first argument, but you are not passing any variable to it.
This line is failing:
if (data.hasOwnProperty("animal")) {
Because data is undefined.
But as well as this, you are defining your data using animals, and then later changing the data to contain people. So the animals data is lost. You need to use a different variable to store people data.

Making load more function in Vue

Trying to make a load more button, when user click it add 10 more item into the page. But the button code is not running smoothly... I still see all items in the page, and also there is no error in the console too.. of course button is not working.
Additionally, trying to make it run with the filter function.. Thank you for any example, help.
data() {
return {
estates:[],
moreEstates: [],
moreEstFetched: false,
}
},
mounted() {
axios.get('/ajax').then((response) => {
this.estates = response.data
this.insertMarkers();
});
},
methods: {
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then((response) => {
this.moreEstates = response.data;
this.estates = this.moreEstates.splice(0, 10);
this.moreEstFetched = true;
});
}
var nextEsts = this.moreEstFetched.splice(0, 10);
this.estates.push(nextEsts);
},
},
computed: {
one: function () {
let filteredStates = this.estates.filter((estate) => {
return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
}
filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});
return filteredStates;
},
},
<table class="table table-hover">
<thead>
<tr style="background-color: #fff ">
<th scope="col">イメージ</th>
<th style="width:175px;"scope="col">物件名</th>
<th style="width:175px;"scope="col">住所</th>
<th scope="col">販売価格</th>
<th scope="col">間取り</th>
<th scope="col">専有面積</th>
<th scope="col">坪単価</th>
<th style="width:90px;" scope="col">物件詳細</th>
</tr>
</thead>
<tbody>
<tr  v-for="estate in one">
<td><img id="image" :src="estate.image" alt=""></td>
<td>{{estate.building_name}}</td>
<td>{{estate.address}}</td>
<td>{{priceSep(estate.price)}} 万円</td>
<td>{{estate.rooms}}</td>
<td>{{xtendSep(estate.extend)}} m²</td>
<td>{{estate.m2_price}}</td>
<td><a :href="/pages/+estate.id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-primary loadmorebutton" #click="handleButton">Load more</button>
As #pyriand3r pointed out that the axios request is async you can do something like this with async/await without modifiyng too much the code.
methods: {
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then(async (response) => {
this.moreEstates = await response.data;
this.estates = this.moreEstates.splice(0, 10);
this.moreEstFetched = true;
});
}
// Also you cant splice a boolean only arrays.
var nextEsts = this.moreEstFetched.splice(0, 10);
this.estates.push(nextEsts);
},
},
See: Async/await in JavaScript
Made some changes to your code, read the comment to understand.
But this is the same as the last post you added.
data() {
return {
visible:true ,
estates:[],
moreEstates: [],
moreEstFetched: false,
size: 10,
selectedPage:0,
init: false,
}
},
updated: function () { // when loaded, trigger only once
if (!this.init) {
this.handleButton();
this.init = true;
}
},
mounted() {
// why is this here, you should only have handleButton to load the data
// axios.get('/ajax').then((response) => {
// this.estates =this.filterData(response.data)
// this.insertMarkers();
// this.showMore();
// });
},
methods: {
filterData: function (data) {
let filteredStates = data.filter((estate) => {
return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
(this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
(this.regions.length === 0 || this.regions.includes(estate.region))});
if(this.sortType == 'price') {
filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
}
if(this.sortType == 'created_at') {
filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
}
filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});
return filteredStates;
},
showMore: function(){
if (Math.ceil( this.moreEstates.length / this.size) <= this.selectedPage +1 ){
this.selectedPage++;
// using slice is better where splice changes the orginal array
var nextEsts = this.moreEstFetched.slice((this.selectedPage * this.size), this.size);
this.estates.push(nextEsts);
}else this. visible= true; // hide show more
},
handleButton: function () {
if(!this.moreEstFetched){
axios.get('/ajax').then((response) => {
// filter the whole data at once
this.moreEstates = this.filterData(response.data);
this.moreEstFetched = true;
// not sure what this is, i moved it here
this.insertMarkers();
this.showMore();
});
}else this.showMore();
},
},
<table class="table table-hover">
<thead>
<tr style="background-color: #fff ">
<th scope="col">イメージ</th>
<th style="width:175px;"scope="col">物件名</th>
<th style="width:175px;"scope="col">住所</th>
<th scope="col">販売価格</th>
<th scope="col">間取り</th>
<th scope="col">専有面積</th>
<th scope="col">坪単価</th>
<th style="width:90px;" scope="col">物件詳細</th>
</tr>
</thead>
<tbody>
<tr v-for="estate in estates">
<td><img id="image" :src="estate.image" alt=""></td>
<td>{{estate.building_name}}</td>
<td>{{estate.address}}</td>
<td>{{priceSep(estate.price)}} 万円</td>
<td>{{estate.rooms}}</td>
<td>{{xtendSep(estate.extend)}} m²</td>
<td>{{estate.m2_price}}</td>
<td><a :href="/pages/+estate.id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button v-if="visible" class="btn btn-primary loadmorebutton" #click="handleButton">Load more</button>
actually, I am not sure it is the best way but, tried much more simplest way to achieve it...
data() {
return {
moreEstates: 10,
}
},
<table class="table table-hover">
<tbody>
<tr v-if="moreIndex < one.length"  v-for="moreIndex in moreEstates">
<td><img id="image" :src="one[moreIndex].image" alt=""></td>
<td>{{one[moreIndex].building_name}}</td>
<td>{{one[moreIndex].address}}</td>
<td>{{priceSep(one[moreIndex].price)}} 万円</td>
<td>{{one[moreIndex].rooms}}</td>
<td>{{xtendSep(one[moreIndex].extend)}} m²</td>
<td>{{one[moreIndex].m2_price}}</td>
<td><a :href="/pages/+one[moreIndex].id">物件詳細</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-primary loadmorebutton" #click="moreEstates += 10">次の10件を見る</button>

Vue filter array A by array B

I have a table with data from a rest API.
The table has objects with unique ids and I have a group filter with unique group ids.
The group id does not appear in the table, therefore I have to create an array which only contains the ids of the table objects.
Every time the group changes the array will be updated.
My goal is to show only the table objects which are in the array I have created before.
During research I found this interesting example, but I can't get it to work.
HTML:
<div class="row ">
<div class="col-12">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text" id="searchAddon"><i class="fa fa-search" aria-hidden="true"></i></div>
</div>
<input type="text" class="form-control form-control-sm" id="searchInput" placeholder="Fahrzeug suchen" autocomplete="off" title="Funknummer" v-model="vehicleSearch" v-bind:disabled="filterDisabled">
<div class="input-group-append">
<button class="btn btn-outline-secondary btn-sm" type="button" #click="vehicleSearch = ''" v-bind:disabled="filterDisabled"><i class="fa fa-times" aria-hidden="true"></i></button></span>
</div>
</div>
</div>
</div>
<div class="row mt-3" name="selectVehicleFilterGroup">
<div class="col-sm-12">
<select id="dropDownVehicleFilterGroupSidebar" class="custom-select custom-select-sm" v-model="vehicleGroup" #change="updateTomTomGroupSelect" v-bind:disabled="filterDisabled">
<option v-for="group in tomTomVehicleGroup" v-bind:value="group.objectgroupuid">{{ group.objectgroupname }} ({{ group.objectcount }})</option>
</select>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="CheckboxShowActiveVehicle" title="Aktive Fahrzeuge anzeigen" v-model="filterActiveVehicle" v-bind:disabled="filterDisabled">
<label class="custom-control-label" for="CheckboxShowActiveVehicle">Aktive Fahrzeuge  <span id="spanActiveVehicle" class="badge badge-secondary">{{ countActiveVehicle.length }}</span></label>
</div>
</div>
</div>
<table class="table table-hover table-sm" style="">
<thead>
</thead>
<tbody>
<tr v-for="vehicle in filteredTomTomVehicle" :key="vehicle.properties.objectuid" v-bind:id="vehicle.properties.objectno">
<td>{{ vehicle.properties }}</td>
</tr>
</tbody>
</table>
Vue:
var vehicleList = new Vue({
el: '#appTomTomVehicleList',
data: {
tomTomVhehicle: [], // Array A
tomTomVehicleGroup: [],
tomTomVehicleObjects: [], // Array with group id and object id
tomTomGroupSelect: [], // Filter Array B
vehicleSearch: undefined,
vehicleGroup: '1-44060-0414****',
filterActiveVehicle: false,
filterDisabled: true,
loading: true
},
methods: {
getTomTomVehicle: function() {
var self = this;
$.getJSON('http://127.0.0.1/app/index.php/api/1/vehicle/showAll?format=json', function(data) {
self.tomTomVhehicle = data;
})
.done(function() {
// console.log('TomTom vehicle loaded');
})
.fail(function(data) {
console.log('TomTom vehicle: '+data.statusText+' ('+data.status+')');
// console.log(data.responseText);
})
.always(function() {
// console.log('always');
self.filterDisabled = false;
self.loading = false;
});
},
getTomTomVehicleGroup: function() {
var self = this;
$.getJSON('http://127.0.0.1/app/index.php/api/1/vehicleGroup/showGroups?format=json', function(data) {
self.tomTomVehicleGroup = data;
})
.done(function(data) {
// console.log('TomTom vehicle group loaded');
})
.fail(function(data) {
console.log('TomTom vehicle group: '+data.statusText+' ('+data.status+')');
// console.log(data.responseText);
})
.always(function() {
// console.log('always');
});
},
getTomTomVehicleObjects: function() {
var self = this;
$.getJSON('http://127.0.0.1/app/index.php/api/1/vehicleGroup/showObjects?format=json', function(data) {
self.tomTomVehicleObjects = data;
})
.done(function(data) {
// console.log('TomTom vehicle objects loaded');
})
.fail(function(data) {
console.log('TomTom vehicle objects: '+data.statusText+' ('+data.status+')');
// console.log(data.responseText);
})
.always(function() {
// console.log('always');
});
},
updateTomTomGroupSelect() {
var self = this;
this.tomTomGroupSelect = [];
this.tomTomVehicleObjects.forEach(function(element) {
if (self.vehicleGroup === element.objectgroupuid) {
self.tomTomGroupSelect.push(element.objectno)
}
})
}
},
computed: {
filteredTomTomVehicle: function() {
let vehicles = this.tomTomVhehicle.features;
if (this.vehicleSearch) {
vehicles = vehicles.filter((v) => {
return v.properties.objectno.indexOf(this.vehicleSearch.trim()) !== -1
});
}
if (this.filterActiveVehicle) {
vehicles = vehicles.filter((v) => {
return v.properties.ignition === 1 && v.properties.standstill === 0;
});
}
if (this.vehicleGroup) {
/*
vehicles = vehicles.filter((v) => {
return v.properties.objectno.indexOf(this.tomTomGroupSelect);
});
*/
}
return vehicles;
},
countActiveVehicle: function() {
let vehicles = this.tomTomVhehicle.features;
if (vehicles != undefined) {
vehicles = vehicles.filter((v) => {
return v.properties.ignition === 1 && v.properties.standstill === 0;
});
this.count = vehicles.length
} else {
vehicles = 0;
}
return vehicles
}
},
mounted: function() {
var self = this;
this.getTomTomVehicle();
this.getTomTomVehicleObjects();
this.getTomTomVehicleGroup();
setInterval(function() {
self.getTomTomVehicle();
// this.getTomTomVehicle();
}, 60000)
}
});
I got the solution:
if (this.vehicleGroup && this.tomTomGroupSelect.length !== 0) {
vehicles = vehicles.filter((v) => {
return this.tomTomGroupSelect.includes(v.properties.objectno);
});
}

make row clickable after refresh in mvc

I want to make a row clickable after a refresh. I have this in the view:
#foreach (var item in Model) {
<tr class="#(item.Id == (int)(Session["Id"] ?? 0) ? ".tr.sfs-selected .table.sfs-selectable tbody .dataTable sfs-selected .dataTable sfs-selectable .table-responsive" : String.Empty)" onclick="'<tr>'" data-url="#Url.Action("Index", new RouteValueDictionary { { "id", item.Id } })">
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsEnabled)
</td>
<td>
</tr>
}
I have this jQuery:
$("table.sfs-selectable tbody").on("click", "tr", function (ev) {
var $row = $("tr.sfs-selected").each(function(){
selectRow($row, !$row.hasClass("sfs-selected"));
});
});
However the row is not clicked after refresh.
Thank you
the view:
<table class="table table-striped table-bordered table-hover dataTable sfs-selectable sfs-col1-right-aligned">
<thead>
<tr>
<th>
#Html.RouteLink(Html.DisplayNameFor(model => firstItem.Id).ToString(), "Sort-Product", new { sortColumn = "id", sortOrder = (ViewBag.sortColumn == "id" && ViewBag.sortOrder != "desc") ? "desc" : "", searchString = ViewBag.SearchString, filter = ViewBag.Filter })
#ViewHelper.GetSortIndicator("id", ViewBag.sortColumn, ViewBag.sortOrder)
</th>
<th>
#Html.RouteLink(Html.DisplayNameFor(model => firstItem.Name).ToString(), "Sort-Product", new { sortColumn = "name", sortOrder = (ViewBag.sortColumn == "name" && ViewBag.sortOrder != "desc") ? "desc" : "", searchString = ViewBag.SearchString, filter = ViewBag.Filter })
#ViewHelper.GetSortIndicator("name", ViewBag.sortColumn, ViewBag.sortOrder)
</th>
<th>
#Html.RouteLink(Html.DisplayNameFor(model => firstItem.IsEnabled).ToString(), "Sort-Product", new { sortColumn = "enabled", sortOrder = (ViewBag.sortColumn == "enabled" && ViewBag.sortOrder != "desc") ? "desc" : "", searchString = ViewBag.SearchString, filter = ViewBag.Filter })
#ViewHelper.GetSortIndicator("enabled", ViewBag.sortColumn, ViewBag.sortOrder)
</th>
<th>
#Html.RouteLink(Html.DisplayNameFor(model => firstItem.FormName).ToString(), "Sort-Product", new { sortColumn = "formname", sortOrder = (ViewBag.sortColumn == "formname" && ViewBag.sortOrder != "desc") ? "desc" : "", searchString = ViewBag.SearchString, filter = ViewBag.Filter })
#ViewHelper.GetSortIndicator("formname", ViewBag.sortColumn, ViewBag.sortOrder)
</th>
<th>
#Html.RouteLink(Html.DisplayNameFor(model => firstItem.TemplateName).ToString(), "Sort-Product", new { sortColumn = "design", sortOrder = (ViewBag.sortColumn == "design" && ViewBag.sortOrder != "desc") ? "desc" : "", searchString = ViewBag.SearchString, filter = ViewBag.Filter })
#ViewHelper.GetSortIndicator("design", ViewBag.sortColumn, ViewBag.sortOrder)
</th>
<th>
#Html.RouteLink(Resources.Entity.Product.PublicUrl, "Sort-Product", new { sortColumn = "urlname", sortOrder = (ViewBag.sortColumn == "urlname" && ViewBag.sortOrder != "desc") ? "desc" : "", searchString = ViewBag.SearchString, filter = ViewBag.Filter })
#ViewHelper.GetSortIndicator("urlname", ViewBag.sortColumn, ViewBag.sortOrder)
</th>
<th>
#Html.DisplayNameFor(model => firstItem.SubmittedForms)
</th>
<th>
#Html.RouteLink(Html.DisplayNameFor(model => firstItem.ModificationDate).ToString(), "Sort-Product", new { sortColumn = "modified", sortOrder = (ViewBag.sortColumn == "modified" && ViewBag.sortOrder != "desc") ? "desc" : "", searchString = ViewBag.SearchString })
#ViewHelper.GetSortIndicator("modified", ViewBag.sortColumn, ViewBag.sortOrder)
</th>
<th class="hidden"></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr class="#(item.Id == (int)(Session["Id"] ?? 0) ? ".tr.sfs-selected .table.sfs-selectable tbody .dataTable sfs-selected .dataTable sfs-selectable .table-responsive" : String.Empty)" data-url="#Url.Action("Index", new RouteValueDictionary { { "id", item.Id } })">
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsEnabled)
</td>
<td>
#{
bool viewLink = item.IsEnabled;
if (!String.IsNullOrEmpty(item.FormName)) {
var form = item.FormLibraryEntry;
if (form == null) {
viewLink = false;
#Html.DisplayFor(modelItem => item.FormName)
<em>(#Resources.Entity.Environment.Removed)</em>
}
else {
#Html.DisplayFor(modelItem => form.Name)
<i class="fa fa-fw fa-external-link-square text-info"></i>
}
}
}
</td>
<td>
#{
if (!String.IsNullOrEmpty(item.TemplateName)) {
var template = item.TemplateLibraryEntry;
if (template == null) {
viewLink = false;
#Html.DisplayFor(modelItem => item.TemplateName)
<em>(#Resources.Entity.Environment.Removed)</em>
}
else {
#Html.DisplayFor(modelItem => template.Name)
<i class="fa fa-fw fa-external-link-square text-info"></i>
}
}
}
</td>
<td>
#if (!String.IsNullOrEmpty(item.UrlName)) {
var defaultProductUri = CustomerConfig.ToHostUri(Request.Url.Scheme, defaultHostHeader, Request.Url.Port, (isProduction ? "" : "TEST/") + item.UrlName);
if (viewLink) {
#item.UrlName
<i class="fa fa-fw fa-external-link-square text-info"></i>
}
else {
#item.UrlName
}
}
</td>
<td>
#{
int cnt = item.SubmittedForms.Where(prod => prod.Order.IsProduction == isProduction).Count();
#(cnt.ToString() + " ")
if (cnt > 0) {
<a href="#Url.Action("Index", "SubmittedForms", new { filter = item.Id })">
<i class="fa fa-fw fa-external-link-square text-info"></i>
</a>
}
}
</td>
<td class="text-nowrap">
#item.ModificationDate.ToString("G")
</td>
<td class="hidden">
<span>
#if (!String.IsNullOrEmpty(item.UrlName) && !String.IsNullOrEmpty(item.FormName)) {
#Html.RouteLink(Resources.Action.Navigation.Preview, "ProductPreview", new { productUrl = item.UrlName, customerSchema = custSchema }, new { target = "_blank" })
}
else { #(Resources.Action.Navigation.Preview) }
| #Html.ActionLink(Resources.Action.Navigation.Details, "Details", new { id = item.Id })
| #Html.ActionLink(Resources.Action.Navigation.Edit, "Edit", new { id = item.Id })
</span>
</td>
</tr>
}
</tbody>
</table>
so I have tbody in it. but the problem is now that I have to double click on a row
this is the selectRow function:
function selectRow($row, doSel) {
var $section = $row.closest("section");
if (doSel) {
$section.find("tr.sfs-selected").removeClass("sfs-selected");
$row.addClass("sfs-selected");
$section.find(".sfs-actionbutton").each(function (index) {
var $btn = $(this);
$btn.addClass("disabled");
var href = $row.find("td:last a").filter(function () {
return $(this).text().trim() == $btn.text().trim();
}).attr("href");
if (href) {
$btn.attr("href", href).removeClass("disabled");
if ($btn.parent().is(".btn-group")) {
$btn.parent().children("a").removeClass("disabled");
$btn.attr("data-href", href + "/");
$btn.attr("href", href + "/" + $(".sfs-select-preview-template .active a").attr("href"));
}
}
});
}
else {
$row.removeClass("sfs-selected");
$section.find(".sfs-actionbutton").addClass("disabled");
}
}
You just have wrong selector, i gess it should be like this:
var $row = $("tr.sfs-selected").each(function(){
selectRow( $(this), $(this).hasClass("sfs-selected"));
});
The point is in each() method you can get one of collection element with this keyword.
You seem to be specifying class names by adding leading dots . to them, but I don't think you mean to have them like that (or the jQuery selectors won't work). Also the inline onclick is not in a working state, but your jQuery event should take care of that so that can be removed.
<tr class="#(item.Id == (int)(Session["Id"] ?? 0) ? "sfs-selected sfs-selectable" : String.Empty)" data-url="#Url.Action("Index", new RouteValueDictionary { { "id", item.Id } })">
Now, I am assuming you don't really want a classes named tbody dataTable table-responsive on each row either, so I removed them. They should probably be set on the <table> and/or <tbody> but if you need them back just re-add them.
For you jQuery:
The call to selectRow() seems a bit odd, since it will only iterate table rows with class sfs-selected, hence it will always call the function with selectRow($(element), false).
In other words: when you click a table row any row with class sfs-selected will have it's class removed and actionbutton will be disabled. Is this the desired behavior?

MeteorJS the good way to build & access my documents

I'm trying to build an MeteorJS App. This is a kind of playlist manager.
It looks like spotify, There is 3 colums so I made 3 templates,
from left to right :
- The playlists list
- The medias of the selected playlist
- The selected media's details
so here's my code :
server.js
Playlists = new Meteor.Collection("playlists");
if (Meteor.isServer) {
Meteor.startup(function() {
if (Playlists.find().count() === 0) {
var names = ["test1",
"222",
"test3",
"444",
"test5",
"666"];
for (var i = 0; i < names.length; i++)
Playlists.insert({'name': names[i]});
}
return (
Meteor.methods({
addPlaylist: function(playlistName) {
Playlists.insert({'name': playlistName, 'medias': []});
},
delPlaylist: function(playlistId) {
Playlists.remove({'_id': playlistId});
},
renPlaylist: function(playlistId, newName) {
Playlists.update({'_id': playlistId}, {'$set': {'name': newName}});
},
addMedia: function(playlistId, newMedia) {
var current_playlist = Playlists.findOne({'_id': playlistId});
Playlists.update(current_playlist, {$push: {'medias': newMedia}});
}
})
);
});
Playlists.allow({
insert: function(userId, doc) {
return (false);
},
update: function(userId, doc, fields, modifier) {
return (false);
},
remove: function(userId, doc) {
return (false);
}
});
}
my templates :
<template name="t_playlistsCol">
<button id="newPlaylist" class="btn btn-primary" type="button">
New Playlist
</button>
<div id="listPlaylist">
{{#each playlists}}
<button class="playlist {{Pselected}} btn btn-default" type="button">
{{name}}
</button>
{{/each}}
</div>
</template>
<template name="t_mediasCol">
{{#if current_playlist}}
<div class="menuPlaylist">
<img id="playPlaylist" class="btn" src="icon_play1.png">
<h4>{{current_playlist}}</h4>
<div id="optionsPlaylist">
<button id="insertMedia" class="btn btn-primary">Insert</button>
<button id="renamePlaylist" class="btn btn-info">Rename</button>
<button id="deletePlaylist" class="btn btn-danger">Delete</button>
</div>
</div>
<table id="listMedias">
<thead>
<tr>
<th class="mediaName">Titre</th>
<th class="mediaType">Type</th>
<th class="mediaTime">Durée</th>
</tr>
</thead>
<tbody>
{{#each medias}}
<tr class="media {{Mselected}}">
<td class="mediaName">{{name}}</td>
<td class="mediaType">{{type}}</td>
<td class="mediaTime">{{time}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{else}}
<div class="menuPlaylist">
<h3 id="noPlaylist">Select a playlist</h3>
</div>
{{/if}}
</template>
<template name="t_previewCol">
{{#if current_media}}
<div class="menuPreview">
<p>{{current_media}}</p>
</div>
{{else}}
<div class="menuPreview">
<h3 id="noPreview">Select a media</h3>
</div>
{{/if}}
</template>
client.js :
(
Playlists = new Meteor.Collection("playlists");
if (Meteor.isClient) {
Template.t_playlistsCol.playlists = function() {
return (Playlists.find({}, {sort: {"name": 1}}));
};
Template.t_playlistsCol.events = {
'click #newPlaylist': function() {
var playlistName = prompt("Nom de la playlist : ");
if (playlistName) {
Meteor.call('addPlaylist', playlistName);
}
},
'click .playlist': function() {
Session.set("selected_playlist", this._id);
}
};
Template.t_playlistsCol.Pselected = function() {
return ( Session.equals("selected_playlist", this._id) ? "Pselected" : '' );
};
Template.t_mediasCol.current_playlist = function() {
var playlist = Playlists.findOne(Session.get("selected_playlist"));
return (playlist && playlist.name);
};
Template.t_mediasCol.medias = function() {
var current_playlist = Playlists.findOne(Session.get("selected_playlist"));
return ( current_playlist.medias );
};
Template.t_mediasCol.events = {
'click #insertMedia': function() {
var playlistId = Session.get("selected_playlist");
var newMedia = {
name: "mediaTest",
type: "img",
time: "00:15"
};
newMedia._id = new Meteor.Collection.ObjectID();
Meteor.call('addMedia', playlistId, newMedia);
},
'click #deletePlaylist': function() {
var playlistId = Session.get("selected_playlist");
Meteor.call('delPlaylist', playlistId);
},
'click #renamePlaylist': function() {
var playlist = Playlists.findOne(Session.get("selected_playlist"));
var newName = prompt("Renommer " + playlist.name + " en :");
if (newName) {
Meteor.call('renPlaylist', playlist._id, newName);
}
},
'click .media': function() {
Session.set("selected_media", this._id);
}
};
Template.t_mediasCol.Mselected = function() {
return ( Session.equals("selected_media", this._id) ? "Mselected" : "" );
};
Template.t_previewCol.current_media = function() {
var playlistId = Session.get("selected_playlist");
var mediaId = Session.get("selected_media");
var playlist = Playlists.find({'_id': playlistId});
return(playlist.medias[0] && playlist.medias[0].name);
};
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY'
});
}
I'm a newbie, I'm learning Meteor for 3 weeks.
SO, MY PROBLEM is that, I want the user to be able to select a media and see its details with the template "t_previewCol" .
It works for the playlists, but I don't have what I want with the helper "Template.t_previewCol.current_media", it prints this error when I do a console.log to debug :
Exception in template helper:
Template.t_previewCol.current_media#http://localhost:3000/client
/client.js?7212665c7dc29cf721272fa4cabeb499f2e18bf5:69:5
bindToCurrentDataIfIsFunction/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2448:7
Blaze.wrapCatchingExceptions/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1552:7
Spacebars.call#http://localhost:3000/packages
/spacebars.js?8717c3bee1160f47e7a46ea4e1bd0796f944cad8:169:5
#http://localhost:3000/client
/template.client.js?d2b9a924f64621cd0bcfc1292538f5b63523959a:117:5
Blaze.If/</<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2275:11
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.If/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2277:1
fireCallbacks#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1818:9
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze._fireCallbacks/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1815:5
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
Blaze._fireCallbacks#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1814:3
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1830:3
.visitObject#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
doMaterialize#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
.visitObject#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
.visitTag#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1441:9
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:101:11
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
.visitTag#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1441:9
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:101:11
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
doMaterialize#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
.visitObject#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
doMaterialize#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
Blaze.render#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2068:3
instantiateBody#http://localhost:3000/packages
/templating.js?e2c0d3bbe4292a0b20c3083eaf4fcd0f5f91bb52:245:7
ready#http://localhost:3000/packages
/meteor.js?7a66be7a03504cd2c18dd47b699e6233b60675ed:641:6
Perhaps its because of way I built my documents, they look like that :
{
_id: "idP",
name: "nameP",
medias: [
{
_id: "idM1",
name: "nameM1"
},
{
_id: "idM2",
name: "nameM2"
},
...
]
}
I tried to give you a maximum of details about my problem, I hope someone could help me.
thanks.
EDIT :
I have fixed the behavior of my "preview column" when the user click on a media
Template.t_previewCol.current_media = function() {
var playlistId = Session.get("selected_playlist");
var mediaId = Session.get("selected_media");
var playlist = Playlists.findOne({'_id': playlistId});
for (var i = 0 ; i < playlist.medias.length ; ++i)
if (playlist.medias[i]._id._str === mediaId._str)
return(playlist.medias[i] && playlist.medias[i].name);
return (null);
};
I was trying to do
if (playlist.medias[i]._id === mediaId)
but since I've assigned the medias._id using Meteor.Collection.ObjectId() it was not working.
Now I just want to understand what is the error I pasted above.
Playlists.find returns a cursor. I think that you want Playlists.findOne.
Template.t_previewCol.current_media = function() {
var playlistId = Session.get("selected_playlist");
var mediaId = Session.get("selected_media");
var playlist = Playlists.findOne({'_id': playlistId});
return(playlist.medias[0] && playlist.medias[0].name);
};

Categories

Resources