I'm working on a handlebar's page that show some books. Books can be filtered by title or by author or by city/library.
The page is rendered well the first time, but if I use filters and recall the handler with new parameters, the query is executed well (I can see new books' list) but handlebar doesn't update the page with new data
here is a part of my code:
#Get()
#Render("ciclo/index")
async getCicloBooks(
#Query("ciclo") ciclo,
#Query("codProv") codProvincia,
#Query("comune") idComune,
#Query("title") title,
#Query("author") author
) {
let books = undefined;
let comuni = undefined;
let librariesId = [];
const libraries = [];
let data = {};
this.logger.debug("[getCicloBooks] ciclo: " + ciclo);
const province = await this.cicloService.getProvince();
// Titolo
if (title != undefined) {
this.logger.log(`[getCicloBooks] per ciclo: ${ciclo} e titolo ${title}`);
const query = { ciclo: ciclo, title: title };
books = await this.bookService.getBooksByAdvancedQuery(query);
// TODO considerare che lo stesso libro può essere in più librerie
data = {
pageTitle: `Trovate n librerie che hanno in catalogo ${title}`,
ciclo: `${ciclo}`,
books: books,
libraries: null,
provincie: province,
comuni: comuni,
comune: null,
author: `${author}`,
title: `${title}`,
};
} // Autore
else if (author != undefined) {
this.logger.log(`[getCicloBooks] per ciclo: ${ciclo} e autore ${author}`);
const query = { ciclo: ciclo, author: author };
books = await this.bookService.getBooksByCicloAndAuthor(query);
// TODO considerare che lo stesso libro può essere in più librerie
data = {
pageTitle: `Trovate n librerie con libri di ${author}`,
ciclo: `${ciclo}`,
books: books,
libraries: null,
provincie: province,
comuni: comuni,
comune: null,
author: `${author}`,
title: `${title}`,
};
} // Provincia e comune
else if (idComune != undefined) {
this.logger.log(`[getCicloBooks] ciclo: ${ciclo} id comune ${idComune}`);
const comune = await this.cicloService.getComune(idComune);
const allLibraries = await this.cicloService.getAllLibrariesInCities();
this.logger.log("[getCicloBooks] comune " + JSON.stringify(comune));
librariesId = [];
allLibraries.forEach((library) => {
if (library.comune.id == idComune) {
libraries.push(library);
librariesId.push(library.id);
}
});
this.logger.log("[getCicloBooks] ids " + JSON.stringify(librariesId));
const query = { ciclo: ciclo, id: In(librariesId) };
// join book e libreria oppure find in table book_library_libreria where libreriaID in [libreriaId])
books = await this.bookService.getBooksByAdvancedQuery(query);
// this.logger.log("[getCicloBooks] books " + JSON.stringify(books));
books.forEach((book) => {
const libs = [];
book.library.forEach((l) => {
librariesId.forEach((id) => {
if (l.id == id) {
libs.push(l);
}
});
});
book.library = libs;
});
// this.logger.log("[getCicloBooks] books " + JSON.stringify(books));
data = {
pageTitle: `Tutti i libri disponibili per il ciclo: ${ciclo}`,
ciclo: `${ciclo}`,
books: books,
libraries: allLibraries,
provincie: province,
comuni: comuni,
comune: comune,
author: `${author}`,
title: `${title}`,
};
} else {
books = await this.bookService.getBooksByCiclo(ciclo);
data = {
pageTitle: `Tutti i libri disponibili per il ciclo: ${ciclo}`,
ciclo: `${ciclo}`,
books: books,
libraries: null,
provincie: province,
comuni: comuni,
comune: null,
author: `${author}`,
title: `${title}`,
};
}
this.logger.debug("[getCicloBooks] books: " + JSON.stringify(books));
if (books === undefined) {
data = {
title: "Book Store",
subtitle: `Attualmente non abbiamo nessun libro in catalogo per il ciclo ${ciclo}`,
books: null,
province: province,
comuni: comuni,
};
}
// this.logger.log(books);
return { viewData: data };
}
while this is the template code that doesn't update when new data are given
{{#> app}}
{{#*inline "content"}}
<div class="container">
<div class="row" style="margin-top: 25px;">
<div class="col">
<input id="ciclo" name="ciclo" value="{{viewData.ciclo}}" type="hidden">
<h3 class="fw-bold mt-5 text-center">{{ viewData.pageTitle }}</h3>
<h4 class="fw-bold text-center">Raffina la tua ricerca:</h4>
</div>
</div>
<div class="row mt-auto">
<!-- Navigatore delle Tabs -->
<ul class="nav nav-tabs mb-3" id="ex1" role="tablist">
<li class="nav-item" role="presentation">
<a id="tab1" href="#tabPlace" class="nav-link active" data-mdb-toggle="tab" role="tab" aria-controls="tabPlace"
aria-selected="true">Cerca per provincia e comune</a>
</li>
<li class="nav-item" role="presentation">
<a id="tab2" href="#tabAuthor" class="nav-link" data-mdb-toggle="tab" role="tab" aria-controls="tabAuthor"
aria-selected="false">Cerca per autore</a>
</li>
<li class="nav-item" role="presentation">
<a id="tab3" href="#tabTitle" class="nav-link" data-mdb-toggle="tab" role="tab" aria-controls="tabTitle"
aria-selected="false">Cerca per titolo</a>
</li>
</ul>
<!-- Tabs navs -->
</div>
<!-- Tabs content -->
<div id="search-content-tabs" class="tab-content">
<!-- Cerca per comune -->
<div id="tabPlace" class="tab-pane fade show active" role="tabpanel" aria-labelledby="tab-1">
<div class="container">
<div class="row mt-2" style="border: 1px;">
{{!-- blocco provincia --}}
<div class="col-lg-1 col-xs-1" style="margin-top: 8px;"> Provincia:</div>
{{#with viewData}}
<div class="col-lg-3 col-xs-3">
<select name="provincia" id="provinciaDropdown" class="form-select" aria-label="example">
<option value="">Seleziona la Provincia</option>
{{#each provincie}}
<option value="{{codice}}">{{provincia}}</option>
{{/each}}
</select>
</div>
{{/with}}
{{!-- blocco comune --}}
<div class="col-lg-1" style="margin-top: 8px;"> Comune:</div>
<div class="col-lg-3">
<select id="comuneDropdown" name="comune" class="form-select" aria-label="example">
<option value="">Seleziona il Comune</option>
</select>
</div>
</div> <!-- riga dei select provincia e comune -->
<div class="row mt-4"> <!-- riga bottone cerca -->
<div class="col-2">
**<button id="cityBtn" type="submit" class="btn btn-primary" onclick="onCityClicked(event)">Cerca</button>**
</div>
</div>
</div>
</div>
<!-- Cerca per comune -->
<!-- Cerca per autore -->
<div id="tabAuthor" class="tab-pane fade" role="tabpanel" aria-labelledby="tab-2">
<div class="container">
<div class="row mt-2" style="border: 1px;">
{{!-- blocco autore --}}
{{!-- <div class="col-lg-1" style="margin-top: 8px;"> Autore:</div> --}}
<div class="col-lg-3 form-outline">
<input id="formAuthor" type="text" class="form-control form-control-lg" />
<label class="form-label" for="formAuthor">Cerca per autore del libro</label>
</div>
</div>
<div class="row mt-4"> <!-- riga bottone cerca -->
<div class="col-2">
<button id="authorBtn" type="submit" class="btn btn-primary" onclick="onAuthorClicked(event)">Cerca</button>
</div>
</div>
</div>
</div>
<!-- Cerca per autore -->
<!-- Cerca per Titolo -->
<div id="tabTitle" class="tab-pane fade" role="tabpanel" aria-labelledby="tab-3">
<div class="container">
<div class="row mt-2" style="border: 1px;">
<div class="col-lg-1 form-outline">
<input id="formTitle" type="text" class="form-control form-control-lg" />
<label class="form-label" for="formTitle">Cerca per titolo del libro</label>
</div>
</div>
<div class="row mt-4"> <!-- riga bottone cerca -->
<div class="col-2">
<button id="titleBtn" type="submit" class="btn btn-primary" onclick="onTitleClicked(event)">Cerca</button>
</div>
</div>
</div>
</div>
<!-- Cerca per Titolo -->
</div>
<!-- Tabs content -->
</div>
<!-- Blocco Risultato ricerca -->
{{ log viewData}}
<ul id="booksPreview">
{{#each viewData.books}}
<li style="list-style-type: none">
<div class="container mt-5">
<div class="row bt-2" style="margin-top: 20px;">
<div class="col-lg-3 col-md-2 col-lg-2 mb-2">
<img src="/covers/{{getCoverImage}}" style="height: 320px; width: 230px;">
</div>
<div class="col-lg-7 col-md-8 col-lg-6 mb-2">
<div class="text-md-start text-black text-capitalize fa-2x">{{title}}</div>
<div class="text-md-start">Autore {{getAuthor}}</div>
<div class="text-md-start">Prezzo {{getPrice}} €</div>
<div class="text-md-start">Abstract {{getDescription}}</div>
</div>
<div class="col-lg-2 col-md-2 mb-2">
<div class="bi-text-left ">
Aggiungi al carrello
</div>
</div>
</div>
</div>
</li>
{{/each}}
</ul>
<!-- Blocco Risultato ricerca -->
{{/inline}}
{{/app}}
And this is part of scripts's functions called on serch button click
$(document).ready(function () {
$("#provinciaDropdown").on("change", function () {
console.log(`Selected provincia: ${this.value}`);
var country_id = this.value;
$("#comuneDropdown").html("");
uri = `http://${host}:${port}/admin/getComuni?prov=${country_id}`;
$.ajax({
url: uri,
type: "GET",
success: function (result) {
/* console.log(' Result listaComuni ' + result.viewData.comuni); */
if ($.isArray(result.viewData.comuni)) {
$("#comuneDropdown").html(
'<option value="">Seleziona il Comune</option>'
);
comuni = result.viewData.comuni;
for (i = 0; i < comuni.length; i++) {
str = `<option value="${comuni[i].id}"> ${comuni[i].comune} </option>`;
// console.log(str);
$("#comuneDropdown").append(str);
}
} // isArray
}, // success
});
}); // onChange
$("#comuneDropdown").on("change", function () {
var idComune = this.value;
console.log(`Selected comune with id ${this.value}`);
}); // onChange comuneDropdown
});
function onCityClicked(event) {
event.preventDefault();
var city = document.getElementById("comuneDropdown").value;
var ciclo = document.getElementById("ciclo").value;
console.log(`[onCityClicked] ciclo: ${ciclo} city: ${city} `);
var uri = `http://${host}:${port}/ciclo?ciclo=${ciclo}&comune=${city}`;
console.log(`[onCityClicked] uri: ${uri} `);
$.ajax({
url: uri,
type: "GET",
success: function (result) {
data = result.viewData;
console.log("----- SUCCESS -----");
}, // success
}); // ajax
}
So, from main page I show the book's page (default query is executed and template page is rendered successfully), then when I try to change filters, the book's page is called with choosen filters, the query is excuted well (I check logs) but the template doesn't update. I got the previous page
I added to original code the <ul id=".."> <li></li> </ul> tags, trying to intercept at runtime some action on id and clean the book's list before the new render, but I wasn't able to do
Can someone help me?
Thanks
Related
I'm having issue on getting the data from JSON to display it on a html element.
I try many ways but none is working
This is my code:
MYAPP.JS
$(document).ready(function() {
$(function() {
switch (menu) {
case 'sign in':
$('#signin').addClass('active');
break;
case 'vendors':
$('#vendors').addClass('active');
break;
case 'view passports':
$('#listpassports').addClass('active');
break;
case 'contact':
$('#contact').addClass('active');
break;
case 'home':
$('#home').addClass('active');
break;
}
});
AOS.init({
'duration': 1250
}
);
var jsonUrl = '';
if (window.categoryID == '') {
jsonUrl = window.contextRoot + '/json/data/all/passbeers';
}
else {
jsonUrl = window.contextRoot + '/json/data/category/' + window.categoryID + '/passbeers';
}
});
JSONCONTROLLER
package com.itconnect.lisboabeerpassport.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.itconnect.lisboabeerpassportbackend.dao.PassbeerDAO;
import com.itconnect.lisboabeerpassportbackend.dto.Passbeer;
#Controller
#RequestMapping("json/data")
public class JsonDataController
{
#Autowired
private PassbeerDAO passbeerDAO;
#RequestMapping("/all/passbeers")
#ResponseBody
public List < Passbeer > getAllPassbeer() {
return passbeerDAO.listActivePassbeer();
}
#RequestMapping("/category/{id}/passbeers")
#ResponseBody
public List < Passbeer > getPassbeerByCategory(#PathVariable int id) {
return passbeerDAO.listActivePassbeersByCategory(id);
}
}
HTML PAGE TO DISPLAY THE JSON DATA
<div class="container">
<%#include file="./shared/navbar.jsp"%>
<c:if test="${userclickAllpassbeers == true}">
<script>
window.categoryID = '';
</script>
</c:if>
<c:if test="${userclickSingleCategoryPassbeer == true}">
<script>
window.categoryID = '${category.id}';
</script>
</c:if>
<div class="row">
<div class="col-sm-12 text-center font-weight-normal">
<h2 class="cat_">CATEGORIES</h2>
</div>
</div>
<div class="row">
<c:forEach items="${categories}" var="category">
<div class="col-lg-2 col-sm-4 mb-4 mx-auto">
<!-- Portfolio item 2-->
<div class="portfolio-item">
<img class="img-fluid" src="${contextRoot}/resources/img/${category.imageURL}" "
alt="... " />
</a>
<div class="portfolio-caption ">
<div class="portfolio-caption-heading ">
<h5 class="card-title text-center ">
${category.name} PASS
</h5>
</div>
</div>
</div>
</div>
</c:forEach>
</div>
<div class="row ">
<div class="product-box col-md-4 ">
<div class="product-inner-box position-relative ">
<div class="icons position-absolute top-0 start-0 ">
<i class="fa-solid fa-eye "></i>
</div>
<!-- end /icons -->
<!-- end /icons -->
<img src="${contextRoot}/resources/img/portugal-passport.png "/>
<div class="cart-btn ">
<button class="btn btn-success shadow-sm "><i class="fa-solid fa-cart-shopping "></i>Add to cart</button>
</div>
<!-- end /cart-btn -->
</div>
<!-- end /product-inner-box -->
<div class="product-info ">
<div class="product-name ">
<spam>Premium Passport</spam>
</div>
<!-- end product name -->
<div class="product-price ">
$<spam>13</spam>
</div>
<!-- end product price -->
</div>
<!-- end product-info -->
</div>
<!-- end product-box -->
</div>
<!-- end div show passports -->
<div class="row ">
<div class="col-lg-12 ">
<div id="passbeerimage "></div>
</div>
</div>
</div>
I need help for this can't find a way to do it.
I try to use
$.ajax({ dataType: "json", url: url, data: data, success: success});
but I want the working way of getting JSON data AND display it on html tag
I have a solution that how to get JSON data then update to the HTML elements by using a Vanilla JS then I made my own examples as your reference follow these steps below
1. Create a HTML file named index.html
<!DOCTYPE html>
<html>
<body>
<div id="root">
<p id="name">
Name: {name}
</p>
<p id="birthdate">
Birthdate: {birthdate}
</p>
<p id="age">
Age: {age}
</p>
<p id="address">
Location: {location}
</p>
</div>
<script src="parser.js" type="text/javascript"></script>
</body>
</html>
2. Second create a JavaScript file named parser.js
// Initialize the headers
let init = {
method: "GET",
headers: {
"Content-Type": "application/json"
},
mode: "cors",
cache: "default"
};
let parseJSON = new Request("data.json", init);
// Use Fetch() API to get JSON data and update to the HTML element.
fetch(parseJSON).then((response) => {
return response.json();
}).then((data) => {
let name = document.querySelector("#name");
let birthdate = document.querySelector("#birthdate");
let age = document.querySelector("#age");
let adddress = document.querySelector("#location");
name.textContent = `Name: ${data.name}`;
birthdate.textContent = `Birthdate: ${data.birthdate}`;
age.textContent = `Age: ${data.age}`;
address.textContent = `Location: ${data.address}`;
});
3. Finally create JSON file named data.json
{
"name": "Yer",
"birthdate": "January 1, 2003",
"age": "19",
"address": "Philippines"
}
<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)
I'm using Axios to fetch data from a server, I'm trying to do a PUT request and I need to get data info from 3 tables in order to fill the form, when I do the PUT it sometimes works and sometimes doesn't, but when I open the browser terminal to debug the problem, the PUT request always works, also I notice that another component without nested GET requests always works fine, but I can't fetch the data from the server if those GET requests aren't nested.
Here is my script code, I don't know what I'm doing wrong with this.
<template>
<div class="container-fluid">
<div style="margin:40px;background-color:rgba(255, 255, 255, 0.7);">
<div class="row">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">Home</li>
<li class="breadcrumb-item">Usuarios</li>
<li class="breadcrumb-item">Roles</li>
<li class="breadcrumb-item"><a v-bind:href="rol_url">{{rol_name}}</a></li>
<li class="breadcrumb-item active" aria-current="page">Editar Rol</li>
</ol>
</nav>
</div>
<div class="row">
<div class="col-md-8 offset-md-2" style="margin-bottom:80px;">
<div class="row">
<div class="col">
<button onclick="window.history.back();" class="btn btn-primary" style="background:#003e1e;border-color:#003e1e;">
<font-awesome-icon icon="arrow-left" size="lg"></font-awesome-icon>
</button>
</div>
</div>
<div> </div>
<div class="row justify-content-center">
<div class="col-5 align-self-center">
<form>
<div class="form-group">
<label for="rolName">Nombre del rol:</label>
<input v-model="rol_name" type="text" class="form-control" id="rolName" aria-describedby="rolName" placeholder="Nombre">
</div>
<div class="form-group">
<label for="rolModules">Modulos del rol:</label>
<multiselect v-model="rol_mod" :options="modules" :multiple="true" :close-on-select="true" :clear-on-select="false" :hide-selected="true" :preserve-search="true" placeholder="Seleccione los modulos" label="name" track-by="modulo" :preselect-first="false">
</multiselect>
</div>
<div v-for='(module, index) in rol_mod' :key='index' class="form-group">
<label for="rolModules">Permisos de {{module.name}}</label>
<multiselect v-model="module.permisos" :options="permits" :multiple="true" :close-on-select="true" :clear-on-select="false" :hide-selected="true" :preserve-search="true" placeholder="Seleccione los permisos del modulo" label="name" track-by="_id" :preselect-first="false">
</multiselect>
</div>
<div class="form-group">
<label for="rolStates">Estado del rol:</label>
<multiselect v-model="rol_state" :options="states" track-by="name" label="name" :searchable="false" :close-on-select="true" :show-labels="true" :placeholder="rol_state_get">
</multiselect>
</div>
<div class="form-group">
<label for="permitDescription">Descripción:</label>
<textarea v-model="rol_description" class="form-control" aria-label="permitDescription"
placeholder="Descripción" :rows="6" :max-rows="10"></textarea>
</div>
<div> </div>
<div class="row justify-content-center">
<div class="col-4 text-center">
<button class="btn btn-primary" v-on:click="submit()" style="background:#003e1e;border-color:#003e1e;">
<font-awesome-icon icon="save" size="lg"></font-awesome-icon>
Guardar
</button>
</div>
<div class="col-4 text-center">
<a class="btn btn-primary" style="background:#003e1e;border-color:#003e1e;" v-bind:href="rol_url">
<font-awesome-icon icon="times-circle" size="lg"></font-awesome-icon>
Cancelar
</a>
</div>
</div>
<div> </div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
const axios = require('axios');
var API_IP = process.env.VUE_APP_API_IP
export default {
components: {
Multiselect
},
data () {
return {
rol_auditoria: {},
modules: [],
permits: [],
rol_name: "",
rol_state: "",
rol_state_get: "",
rol_description: '',
states: [
{ name: "Activo", activo: "true" },
{ name: "Inactivo", activo: "false" }
],
rol_mod: [],
rol_url: ""
}
},
mounted () {
axios
.get(API_IP+'/rol/'+this.$route.params.id)
.then(response => {
this.rol_auditoria = response.data.data.auditoria;
this.rol_name = response.data.data.nombre;
this.rol_state = response.data.data.activo;
response.data.data.activo? this.rol_state_get="Activo" : this.rol_state_get="Inactivo";
this.rol_description = response.data.data.descripcion
this.rol_id = response.data.data._id
this.rol_url = "/roles/"+response.data.data._id
for (var k in response.data.data.modulos){
var mod_info = {}
console.log(response.data.data.modulos[k].modulo.nombre);
mod_info["_id"] = response.data.data.modulos[k]._id
mod_info["modulo"] = { "_id" : response.data.data.modulos[k].modulo._id }
mod_info["name"] = response.data.data.modulos[k].modulo.nombre
var mod_per = []
for (var j in response.data.data.modulos[k].permisos){
var perms = {}
perms["_id"] = response.data.data.modulos[k].permisos[j]._id
perms["name"] = response.data.data.modulos[k].permisos[j].nombre
mod_per.push(perms)
}
mod_info["permisos"] = mod_per
this.rol_mod.push(mod_info)
}
axios
.get(API_IP+"/module/")
.then(response => {
for(var k in response.data.data){
var mod = {}
mod["modulo"] = { "_id" : response.data.data[k]._id }
mod["name"] = response.data.data[k].nombre;
this.modules.push(mod);
}
axios
.get(API_IP+"/permit/")
.then(response => {
for(var k in response.data.data){
var per = {}
per["name"] = response.data.data[k].nombre;
per["_id"] = response.data.data[k]._id;
this.permits.push(per);
}
});
});
})
},
methods: {
submit: function() {
axios
.put(API_IP+"/rol/"+this.$route.params.id, {
auditoria: this.rol_auditoria,
activo: this.rol_state.activo,
_id: this.rol_id,
nombre: this.rol_name,
descripcion: this.rol_description,
modulos: this.rol_mod
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
this.$router.push({ name: 'showrol', params: { id: this.rol_id} });
}
}
}
</script>
This may be a long shot without having information from the console output and the actual info or errors being returned from the GET requests, but I noticed a lot of "this" use on your code.
You are double nesting axios calls, which are async. "this" tends to be hard to debug in javascript, even if youre using arrow functions which should be relatively safe.
Please try to add:
let self = this;
Before you start your GET requests, and use "self" instead of "this" inside your promises.
This may be obvious, but I dont see you calling this.submit() anywhere in your code. Where inside the GET callbacks are you calling SUBMIT for the PUT request?
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>
I am currently using the list.js plugin along with it's filter extension to produce a search results page that allows the user to filter down the end results to make it easier for them to find exactly what they are looking for.
I have been using their API to try and come up with a solution but in all honesty it is a little dated and not sure when it was last updated.
http://www.listjs.com/docs/list-api
My code is as follows:
HTML
<div id="search-results">
<div class="col-md-3">
<div class="panel panel-warning">
<div class="panel-heading">Filters</div>
<div class="panel-body">
<div class="search-filter">
<ul class="list-group">
<li class="list-group-item">
<div class="list-group-item-heading">
<h4>Filter Options</h4>
</div>
</li>
<li class="list-group-item">
<div class="nameContainer">
<h5 class="list-group-item-heading">Name</h5>
</div>
</li>
<li class="list-group-item">
<div class="typeContainer">
<h5 class="list-group-item-heading">Type</h5>
</div>
</li>
<li class="list-group-item">
<div class="difficultyContainer">
<h5 class="list-group-item-heading">Difficulty</h5>
</div>
</li>
<li class="list-group-item">
<label>Tour contains</label>
<input class="search form-control" placeholder="Search" />
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-9">
<div class="panel panel-primary">
<div class="panel-heading">Results</div>
<div class="list panel-body">
<div class="package well">
<div class="name">Niagra Falls</div>
<div class="type hidden">Boat Trip</div>
<div class="difficulty">Relaxed</div>
</div>
<div class="package well">
<div class="name">Pyramids</div>
<div class="type hidden">History Holiday</div>
<div class="difficulty">Relaxed</div>
</div>
<div class="package well">
<div class="name">Great Barrier Reef</div>
<div class="type hidden">Snorkling Holiday</div>
<div class="difficulty">Dangerous</div>
</div>
<div class="package well">
<div class="name">Boar Hunting</div>
<div class="type hidden">Hunting Trip</div>
<div class="difficulty">Active</div>
</div>
<div class="package well">
<div class="name">Thames Cruise</div>
<div class="type hidden">Cruise</div>
<div class="difficulty">Easy</div>
</div>
</div>
<ul class="pagination"></ul>
</div>
</div>
</div>
Javascript
var options = {
valueNames: ['name', 'type', 'difficulty'],
page: 3,
plugins: [
ListPagination({})
]
};
var userList = new List('search-results', options);
var updateList = function () {
var name = new Array();
var type = new Array();
var difficulty = new Array();
$("input:checkbox[name=name]:checked").each(function () {
name.push($(this).val());
});
$("input:checkbox[name=type]:checked").each(function () {
type.push($(this).val());
});
$("input:checkbox[name=difficulty]:checked").each(function () {
difficulty.push($(this).val());
});
var values_type = type.length > 0 ? type : null;
var values_name = name.length > 0 ? name : null;
var values_difficulty = difficulty.length > 0 ? difficulty : null;
userList.filter(function (item) {
return (_(values_type).contains(item.values().type) || !values_type)
&& (_(values_name).contains(item.values().name) || !values_name)
&& (_(values_difficulty).contains(item.values().difficulty) || !values_difficulty)
});
}
userList.on("updated", function () {
$('.sort').each(function () {
if ($(this).hasClass("asc")) {
$(this).find(".fa").addClass("fa-sort-alpha-asc").removeClass("fa-sort-alpha-desc").show();
} else if ($(this).hasClass("desc")) {
$(this).find(".fa").addClass("fa-sort-alpha-desc").removeClass("fa-sort-alpha-asc").show();
} else {
$(this).find(".fa").hide();
}
});
});
var all_type = [];
var all_name = [];
var all_difficulty = [];
updateList();
_(userList.items).each(function (item) {
all_type.push(item.values().type)
all_name.push(item.values().name)
all_difficulty.push(item.values().difficulty)
});
_(all_type).uniq().each(function (item) {
$(".typeContainer").append('<label><input type="checkbox" name="type" value="' + item + '">' + item + '</label>')
});
_(all_name).uniq().each(function (item) {
$(".nameContainer").append('<label><input type="checkbox" name="name" value="' + item + '">' + item + '</label>')
});
_(all_difficulty).uniq().each(function (item) {
$(".difficultyContainer").append('<label><input type="checkbox" name="difficulty" value="' + item + '">' + item + '</label>')
});
$(document).off("change", "input:checkbox[name=type]");
$(document).on("change", "input:checkbox[name=type]", updateList);
$(document).off("change", "input:checkbox[name=name]");
$(document).on("change", "input:checkbox[name=name]", updateList);
$(document).off("change", "input:checkbox[name=difficulty]");
$(document).on("change", "input:checkbox[name=difficulty]", updateList);
I've also created a working example on Codepen.
http://codepen.io/JasonEspin/pen/bdajKo
What I wish to achieve is for some packages, they may have multiple type values such as:
<div class="package well">
<div class="name">Niagra Falls</div>
<div class="type hidden">Boat Trip</div>
<div class="type hidden">Other trip type</div>
<div class="difficulty">Relaxed</div>
</div>
So in this situation, I would expect my filter to detect that there is a type of Boat Trip and Other trip type and display these options as a filter option. If either is selected, this package is then returned. However, it seems to ignore the second type.
I have even tried it like this as I expected it to act like an array but this was not the case. It just mashed the two items together to create a random option.
<div class="package well">
<div class="name">Niagra Falls</div>
<div class="type hidden"><div>Boat Trip</div><div>Other Trip Type</div> </div>
<div class="difficulty">Relaxed</div>
</div>
So, does anyone have any ideas how I can adapt my code to accept multiple options? My ideal scenario would be for me to attach a number of departure dates to each package and enable the user to filter by these departure dates.
Any help would be greatly appreciated as I believe the issue may be with my Lodash code but as it is my first time using Lodash i'm a little bit unsure of what it is actually doing due to its unusual syntax.
This was actually fairly straightforward to implement using a combination of string.split() definitions and array concatenations.
HTML
<div id="search-results">
<div class="col-md-3">
<div class="panel panel-warning">
<div class="panel-heading">Filters</div>
<div class="panel-body">
<div class="search-filter">
<ul class="list-group">
<li class="list-group-item">
<div class="list-group-item-heading">
<h4>Filter Options</h4>
</div>
</li>
<li class="list-group-item">
<div class="nameContainer">
<h5 class="list-group-item-heading">Name</h5>
</div>
</li>
<li class="list-group-item">
<div class="typeContainer">
<h5 class="list-group-item-heading">Type</h5>
</div>
</li>
<li class="list-group-item">
<div class="difficultyContainer">
<h5 class="list-group-item-heading">Difficulty</h5>
</div>
</li>
<li class="list-group-item">
<label>Tour contains</label>
<input class="search form-control" placeholder="Search" />
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-9">
<div class="panel panel-primary">
<div class="panel-heading">Results</div>
<div class="list panel-body">
<div class="package well">
<div class="name">Niagra Falls</div>
<div class="type hidden">Boat Trip|Other Trip|My Trip</div>
<div class="difficulty">Relaxed</div>
</div>
<div class="package well">
<div class="name">Pyramids</div>
<div class="type hidden">History Holiday</div>
<div class="difficulty">Relaxed</div>
</div>
<div class="package well">
<div class="name">Great Barrier Reef</div>
<div class="type hidden">Snorkling Holiday</div>
<div class="difficulty">Dangerous</div>
</div>
<div class="package well">
<div class="name">Boar Hunting</div>
<div class="type hidden">Hunting Trip</div>
<div class="difficulty">Active</div>
</div>
<div class="package well">
<div class="name">Thames Cruise</div>
<div class="type hidden">Cruise</div>
<div class="difficulty">Easy</div>
</div>
</div>
<ul class="pagination"></ul>
</div>
</div>
</div>
JAVASCRIPT
var options = {
valueNames: ['name', 'type', 'difficulty'],
page: 3,
plugins: [
ListPagination({})
]
};
var userList = new List('search-results', options);
var updateList = function () {
var name = new Array();
var type = new Array();
var difficulty = new Array();
$("input:checkbox[name=name]:checked").each(function () {
name.push($(this).val());
});
$("input:checkbox[name=type]:checked").each(function () {
if($(this).val().indexOf('|') > 0){
var arr = $(this).val().split('|');
var arrayLength = arr.length;
type = type.concat(arr);
console.log('Multiple values:' + arr);
}else{
type.push($(this).val());
console.log('Single values:' + arr);
}
});
$("input:checkbox[name=difficulty]:checked").each(function () {
difficulty.push($(this).val());
});
var values_type = type.length > 0 ? type : null;
var values_name = name.length > 0 ? name : null;
var values_difficulty = difficulty.length > 0 ? difficulty : null;
userList.filter(function (item) {
var typeTest;
var nameTest;
var difficultyTest;
if(item.values().type.indexOf('|') > 0){
var typeArr = item.values().type.split('|');
for(var i = 0; i < typeArr.length; i++){
if(_(values_type).contains(typeArr[i])){
typeTest = true;
}
}
}
return (_(values_type).contains(item.values().type) || !values_type || typeTest)
&& (_(values_name).contains(item.values().name) || !values_name)
&& (_(values_difficulty).contains(item.values().difficulty) || !values_difficulty)
});
}
userList.on("updated", function () {
$('.sort').each(function () {
if ($(this).hasClass("asc")) {
$(this).find(".fa").addClass("fa-sort-alpha-asc").removeClass("fa-sort-alpha-desc").show();
} else if ($(this).hasClass("desc")) {
$(this).find(".fa").addClass("fa-sort-alpha-desc").removeClass("fa-sort-alpha-asc").show();
} else {
$(this).find(".fa").hide();
}
});
});
var all_type = [];
var all_name = [];
var all_difficulty = [];
updateList();
_(userList.items).each(function (item) {
if(item.values().type.indexOf('|') > 0){
var arr = item.values().type.split('|');
all_type = all_type.concat(arr);
}else{
all_type.push(item.values().type)
}
all_name.push(item.values().name)
all_difficulty.push(item.values().difficulty)
});
_(all_type).uniq().each(function (item) {
$(".typeContainer").append('<label><input type="checkbox" name="type" value="' + item + '">' + item + '</label>')
});
_(all_name).uniq().each(function (item) {
$(".nameContainer").append('<label><input type="checkbox" name="name" value="' + item + '">' + item + '</label>')
});
_(all_difficulty).uniq().each(function (item) {
$(".difficultyContainer").append('<label><input type="checkbox" name="difficulty" value="' + item + '">' + item + '</label>')
});
$(document).off("change", "input:checkbox[name=type]");
$(document).on("change", "input:checkbox[name=type]", updateList);
$(document).off("change", "input:checkbox[name=name]");
$(document).on("change", "input:checkbox[name=name]", updateList);
$(document).off("change", "input:checkbox[name=difficulty]");
$(document).on("change", "input:checkbox[name=difficulty]", updateList);
Codepen
http://codepen.io/JasonEspin/pen/bdajKo