I'm new to vue, but I'm learning how to use it without webpack.
I have the necessity to use some components nested inside a main component that will render the homepage of my wordpress custom theme. The components I want to nest need to pass a data attribute to an ajax call that will fetch the related data to display, I will set it manually for each instance of it I need to use. How I can do this?
This is the component code
Vue.component('theme-section',{
template: '#section-tpl',
data(){
return{
sectionData: []
}
},
mounted: function(){
this.getSection();
},
methods: {
getSection: function(){
axios.get(theme.base_url+'theme/v1/sections?slug='+ )
.then( (response) => {
console.log(response.data);
response.data.forEach( (item, i) => {
this.sectionData = [item];
});
});
}
}
});
This is the markup of the component. I'm loading it using get_template_part() function of wordpress in the footer of the theme where also all the other components markup is loaded.
I will call it inside the home component I have definde
<script type="text/x-template" id="section-tpl">
<div class="container-fluid p-0">
<div class="row m-0" v-for="section in sectionData" :data-section="" >
<div class="col-sm-12 col-md-12 col-lg-12 p-0">
<!-- <a class="h4 mt-5" href=""></a> -->
<div class="col-sm-12 col-md-6 col-lg-6 p-4">
<h1 class=" font-weight-bold mt-3 mb-3"></h1>
<h4 class="mt-3 mb-3"></h4>
</div>
</div>
</div>
</div>
</script>
// this is the home component markup where the other component will be reused
<script type="text/x-template" id="home-tpl">
<div class="container-fluid p-0">
<div class="row m-0" v-for="page in pageData">
<div class="col-sm-12 col-md-12 col-lg-12 p-0" v-if="page._embedded['wp:featuredmedia'][0].source_url">
<img class="img-fluid w-100" :src="page._embedded['wp:featuredmedia'][0].source_url">
</div>
<div class="col-sm-12 col-md-12 col-lg-12 p-5 mt-5">
<h1>{{ page.title.rendered }}</h1>
</div>
<div class="col-sm-12 col-md-12 col-lg-12 p-5 mt-5" v-html="page.content.rendered"></div>
</div>
<theme-section data-section="about"></theme-section>
</div> <!-- end container-fluid -->
</script>
Related
I did live search by using ajax and have other jquery customizations (Tilt.js etc..) for my card component.
I get search results successfully but it doesn't have whole js customizations .
Ajax
$(document).ready(function() {
$('#location , #sector').on('change',function(){
var location = $('#location').val();
var sector = $('#sector').val();
$.ajax({
url:'search',
type:'GET',
data:{
'location':location,
'sector':sector,
},
success:function(data){
$('#content').html(data);
}
})
}) });
Component that returns from Controller
$output ='';
foreach($data as $post){
$output .='
<div class="card mb-4" id="card" data-tilt data-tilt-max="5" data-tilt-glare data-tilt-max-glare="0.2">
<div class="card-body">
<div class="card my-2 rounded shadow item" role="button" id="'.$post->id.'" >
<div class="row no-gutters">
<div class="col-sm-2 pt-3 pl-2">
<img src="'.$post->image.'" class="img-fluid resim" alt="...">
</div>
<div class="col-sm-10">
<div class="card-body">
<h4 style="font-weight: bolder;">'. $post->company_name.'</h4>
<h5 class="card-title" style="font-weight: bold;">'. $post->job_title.'</h5>
<p class="card-text">'. $post->description.'.</p>
<div class="row">
<div class="col-sm"><div class="rounded-pill text-white text-center py-2 sector " style="background-color: #003777;"> '.$post->sector.'</div></div>
<div class="col-sm"><div class="rounded-pill text-white text-center py-2 location " style="background-color: #003777;"> '.$post->location.'</div></div>
<div class="col-sm"><div class="rounded-pill text-white text-center py-2 " style="background-color: #003777;"> Apply Now!</div></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
';
}
This is due to javascript only loads once the document has finished loading, It then scans all of your dom elements for the elements and adds the listeners, If you are loading dom elements in after this has happened they will not have the event listeners. To get around this there are a few ways but one of the easiest is
$(document).ready(function(){
$('body').on('click','.js-card',function(){
// This body click function will only trigger if the element has the class js-card.
});
});
Another way is to add the onclick to the elements you are loading in <button onClick="yourGlobalFunction">
I want to ask how I can append ajax data on the bootstrap carousel. 2 post-show on the bootstrap carousel when the page load for the first time then if someone clicks the next arrow bootstrap carousel slide and shows the next 2 posts I'm getting 2 posts per click with ajax now I want to append next 2 posts on the bootstrap carousel and so on like this
here's my blade code where I'm using foreach to show 2 posts when pages load for example I'm showing post 1 and 2 here
<div id="carousela" class="carousel slide" data-touch="false" data-interval="false">
<div class="carousel-inner">
#foreach($magazine->chunk(2) as $magazines)
<div class="carousel-item {{ $loop->first ? 'active' : '' }}">
#foreach($magazines as $row)
<div class="row no-gutters m-0 p-0">
<div class="col-md-2 col-sm-12">
<img src="{{(!empty($row->magazine_sys_file_name) ? asset('/uploads/'.$row->magazine_sys_file_name):'')}}" class="img-thumbnail border-0 p-0" alt="" srcset="">
</div>
<div class="col-md-10 col-sm-12 px-4 m-0 m-mb">
<h4 class="text-light m-0 p-0">{{$row->title}}</h4>
{{($row->magazine_des) ? $row->magazine_des: ''}}
<div>{{__('Read More')}}</div>
</div>
</div>
#endforeach
</div>
#endforeach
</div>
</div>
now I'm using onclick function to get the next 2 posts here's ajax code and with this code, i'm getting post 3 and 4 now I want to append these 2 posts on the bootstrap carousel
$('#nextclick').on('click',function(){
var val = $('#hidden').val();
var data = {val:val}
$.ajax({
url: "{{url('/user/nextmagazine')}}",
method: 'get',
data: data,
success: function(data){
$('#hidden').val(parseInt(val) + parseInt(2));
}
})
})
here's my result after onclick
if anyone can help me with how I can append this data in the ajax success function to show on the bootstrap carousel
Thank you
You can loop through your jsons return from backend and append that inside some variable using += .Finally , add generated html inside your carousel using $(html).insertAfter('#carousela .carousel-item:last') this will insert new slide after last slide .
Demo Code :
$(document).ready(function() {
$("#carousela").carousel();
//using `one` just for demo change it to `on`
$('#nextclick').one('click', function() {
/* var val = $('#hidden').val();
success: function(data){
//your other codes..
$('#hidden').val(parseInt(val) + parseInt(2));*/
//suppose data return look like this..
var data = [{
"id": 3,
"title": "Something3",
"magazine_sys_file_name": "somehting",
"link": null
}, {
"id": 4,
"title": "Something4",
"magazine_sys_file_name": "somehting",
"link": null
}]
if (data.length > 0) {
var html = ""
//loop
$(data).each(function(i, v) {
//generate htmls//
html += ` <div class="carousel-item">
<div class="row no-gutters m-0 p-0">
<div class="col-md-2 col-sm-12">
<img src="/uploads/${v.magazine_sys_file_name}" class="img-thumbnail border-0 p-0" alt="" srcset="">
</div>
<div class="col-md-10 col-sm-12 px-4 m-0 m-mb">
<h4 class="text-light m-0 p-0">${v.title}</h4>
<div>{{__('Read More')}}</div>
</div>
</div>
</div>`
})
//insert new html after last slide
$(html).insertAfter('#carousela .carousel-item:last')
}
/*}
})*/
})
});
#carousela{
background:black
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<div id="carousela" class="carousel slide" data-touch="false" data-interval="false">
<div class="carousel-inner">
<div class="carousel-item active">
<div class="row no-gutters m-0 p-0">
<div class="col-md-2 col-sm-12">
<img src="{{(!empty($row->magazine_sys_file_name) ? asset('/uploads/'.$row->magazine_sys_file_name):'')}}" class="img-thumbnail border-0 p-0" alt="" srcset="">
</div>
<div class="col-md-10 col-sm-12 px-4 m-0 m-mb">
<h4 class="text-light m-0 p-0">Something1</h4>
<div>{{__('Read More')}}</div>
</div>
</div>
</div>
<div class="carousel-item">
<div class="row no-gutters m-0 p-0">
<div class="col-md-2 col-sm-12">
<img src="{{(!empty($row->magazine_sys_file_name) ? asset('/uploads/'.$row->magazine_sys_file_name):'')}}" class="img-thumbnail border-0 p-0" alt="" srcset="">
</div>
<div class="col-md-10 col-sm-12 px-4 m-0 m-mb">
<h4 class="text-light m-0 p-0">Something2</h4>
<div>{{__('Read More')}}</div>
</div>
</div>
</div>
<a class="carousel-control-prev" href="#carousela" data-slide="prev">
<span class="carousel-control-prev-icon"></span>
</a>
<a class="carousel-control-next" href="#carousela" data-slide="next" id="nextclick">
<span class="carousel-control-next-icon"></span>
</a>
</div>
</div>
I'm working with Angular 9 with a Bootstrap 4 card applying NGFOR to paint as many elements as come from the database.
I have the following array with different styles for that card and I would like them to be applied to each one in a random way.
public color_border = ["border-left-warning", "border-left-info", "border-left-primary"]
The card code is as follows: the div card border-left-info has to be changed. I have tried a new NGFOR but it duplicates everything.
<!-- Pending Requests Card Example -->
<div class="col-xl-3 col-md-6 mb-4" *ngFor="let data of miDataInterior.DatagreenhouseRecuperado; let i = index">
<div class="card border-left-info shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">{{data.medidas[0].sensor_type[0].name_comun}}</div>
<font SIZE=3> {{data.medidas[0].marca}} </font>
<font SIZE=3>({{data.medidas[0].recvTime | date:'dd-MM-yy h:mm:ss a'}})</font>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{data.medidas[0].attrValue | number:'1.0-1'}} {{data.medidas[0].sensor_type[0].medida}}</div>
</div>
<div class="col-auto">
<i class="fas fa-chart-bar fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
How could I apply what is contained in the color_border variable in that div?
Error:
<!-- Pending Requests Card Example -->
<div class="col-xl-3 col-md-6 mb-4" *ngFor="let data of miDataInterior.DatagreenhouseRecuperado; let i = index">
<div *ngFor="let color_border of color_border" class="card {{color_border}} shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">{{data.medidas[0].sensor_type[0].name_comun}}</div>
<font SIZE=3> {{data.medidas[0].marca}} </font>
<font SIZE=3>({{data.medidas[0].recvTime | date:'dd-MM-yy h:mm:ss a'}})</font>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{data.medidas[0].attrValue | number:'1.0-1'}} {{data.medidas[0].sensor_type[0].medida}}</div>
</div>
<div class="col-auto">
<i class="fas fa-chart-bar fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
Thanks for your help.
EDIT
I am testing directly on NGCLASS, the problem is that it only shows the style of the last element in the array. How can I fix this?
<div class="card shadow h-100 py-2" [ngClass]="['border-left-primary', 'border-left-info', 'border-left-warning']">
Alternate border
[ngClass]="color_border[i%3]"
A random you need make a function (you can not use Math inside the .html)
[ngClass]="getRandomColor()"
getRandomColor()
{
return this.color_border[Math.floor(Math.random()*this.color_border.length]
}
If you miDataInterior.DatagreenhouseRecuperado has a property "color" from 0 to 2 you can use
[ngClass]="color_border[data.color]"
NOTE there're severals ways to use [ngClass], see the docs
Try this..
<div *ngFor="let color_border of color_border" class="card shadow h-100 py-2 " [ngClass]="{{color_border}}">
I've been working on this for a few hours and I can't seem to figure it out.
I am trying to get this function to remove the template when the button is clicked
here is the html of the template.
<script id="movieTemplate" type="text/template">
<div class="row my-3 t-3 card-movie ">
<div class="col-md-12 mb-4">
<div class="card border-0 shadow">
<img src="https://i.pravatar.cc/400?img=48" class="card-img-top" alt="...">
<div class="card-body text-center">
<h5 class="card-title mb-0">Title in Template</h5>
<div class="card-genre text-black-50">Genre in Template</div>
<div class="card-year text-black-50">Year in Template</div>
<button type="button" class="btn btn-danger deleteMovie mt-2">Delete</button>
</div>
</div>
</div>
</div>
and this is the function calling that button
function wireHandlers() {
$(".deleteMovie").on("click", onDeleteMovie);
};
and finally the function that should delete the template
function onDeleteMovie() {
$(".card-movie").remove();
};
I know there is probably a shorthand way to do this but I would really like to keep it as simple as possible. Any help is appriciated! :D
You could call click directly on the button:
$( ".deleteMovie" ).click(function() {
$(".card-movie").remove();
});
This method is a shortcut for .on( "click", handler )
Documentation for the same is here
You did not attached event because you not executed wireHandlers()
Your class selector was wrong .delete-movie
You have to attach event when document loads. More easy way to do is:
$(document).on("click",".deleteMovie", function(){
$(this).parent().parent().parent().parent().remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row my-3 t-3 card-movie ">
<div class="col-md-12 mb-4">
<div class="card border-0 shadow">
<img src="https://i.pravatar.cc/400?img=48" class="card-img-top" alt="...">
<div class="card-body text-center">
<h5 class="card-title mb-0">Title in Template</h5>
<div class="card-genre text-black-50">Genre in Template</div>
<div class="card-year text-black-50">Year in Template</div>
<button type="button" class="btn btn-danger deleteMovie mt-2">Delete</button>
</div>
</div>
</div>
</div>
This is best way when data is dynamically added:
$(this).parent().parent().parent().parent().remove();
I am using Bootstrap's grid to organize the layout of a webpage. Between lg and sm sizes, the webpage looks like this:
|col-1|col-2|
When the size of the window is in the xs range, the columns stack like this:
|col-1|
|col-2|
Instead, I want it to stack like this:
|col-2|
|col-1|
To do this, I created a function to switch the inner HTMLs of the div tags. It works some of the time, but occasionally col-1 is still above col-2.
function mobileHandler() {
var width=window.innerWidth;
if (width<768) {
var col1=document.getElementById('col1').innerHTML;
var col2=document.getElementById('col2').innerHTML;
document.getElementById('col1').innerHTML=col2;
document.getElementById('col2').innerHTML=col1;
}
}
window.onload=mobileHandler;
window.onresize=mobileHandler;
Is there a bug anyone can spot with my code? Or is there a better way to accomplish what I want?
Just use push and pull features of bootstrap.
See the snippet below.
.cols{
height:50px;
border:1px solid black;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-4 col-md-push-8 cols">
col-2
</div>
<div class="col-xs-12 col-sm-12 col-md-8 col-md-pull-4 cols">
col-1
</div>
</div>
</div>
Apply 'pull-right' to the col-1
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-4 cols pull-right">
col-md-4
</div>
<div class="col-xs-12 col-sm-12 col-md-8 cols">
col-md-8
</div>
</div>
</div>