reactive js nested templates not handled - ractivejs

I am trying to use nested templates using reactivejs in this jsfiddle:
https://jsfiddle.net/2hLzhwyd/3/
<script id="templateMain" type="text/ractive">
<div>Inputs:</div>
<div>
{{#inputs:index}}
<div>
<div>Input Number {{index}}:</div>
<template-input input={{.}} />
</div>
{{/inputs}}
</div>
<div>Rows:</div>
<div>
{{#rows:index}}
<div>
<div>RowNumber {{index}}:</div>
<template-row row={{.}} >
</div>
{{/rows}}
</div>
</script>
But I can't make the nested template to work, only the first level template is handled.
In the jsfiddle We can see that if the "template-input" is at the first level so it is handled, and if it under another template ("template-row") it is not handled
I saw the same question here:
ractivejs component nesting
but I didn't succeed make the answer to work.
Can someone help me with this?
Thank you very much!
Gadi

Have you tried adding isolated:false to the component
Eg:
var templateInput = Ractive.extend({ isolated:false, template: '#templateInput' });
var templateRow = Ractive.extend({ isolated:false, template: '#templateRow' });
Herewith a Js fiddle

It's because the templateRow component does not know about the template-input component.
In order to do so, either define template-input globally:
Ractive.components['template-input'] = Ractive.extend(...)
https://jsfiddle.net/2hLzhwyd/15/
Or internally:
var templateRow = Ractive.extend({ template: '#templateRow',
components: {
'template-input': templateInput
}
})
https://jsfiddle.net/2hLzhwyd/13/
I strongly advise against using isolated:false if you are unsure what you are doing as it may lead to unwanted side effects.

Related

How to assign dynamic variables to CSS content in Vue.js?

Apologies if this shows how much of a novice I am, but I'd like to know more about dynamic variables and CSS in Vue. I'd like to create a system where each time a button is pressed, the letters of the button label become further apart.
Inside a component is it possible to use a counter script such as:
<script>
export default {
name: 'Counter',
data() {
return {
count: 3,
}
},
methods: {
intrement() {
this.count += 1;
}
}
}
</script>
And then use the count integer value to change CSS text spacing for example?
So that in the template, I could use:
<template>
<header>
<div>
<button class="header_button" style="letter-spacing: `v-bind(count) + ch`;">MYBUTTON</button>
</div>
</header>
</template>
I appreciate this is a strange and specific example, but if anyone could give me some feedback as to why this doesn't work, as well as suggestions on how I could achieve this I'd be super appreciative.
In that case, you can directly use the following
<button :style="`letter-spacing: ${count}ch;`">
Here is a playground.
PS: :style is a shorthand for v-bind:style as explained here.
v-bind for CSS (mixing script + style) is also a thing.
Here, you're only using script + template combo, so an interpolation is enough.

Vue JS CSS style binding

I am trying to bind CSS styling to vuejs tags. I dont seem to be able to get it working.
Below is the code which i am trying. Can anyone help me out with this? I am not able to get the Styling to work. I am trying this as well as binding based on conditional. Both doesnt seem to work. Can anyone help me with this? I have tried all the ways i could find on stackoverflow, none of them seem to work for me. Can any one help me if i am doing something wrong?
<b-table
class="PatientTable"
borderless
hover
v-on:row-clicked="redirectToPatientView"
:items="users"
:fields="fields"
:current-page="currentPage"
:per-page="perPage"
id="tableData"
>
<template v-for="key1 in fields" v-slot:[`cell(${key1})`]="{ value }" id="tableData" >
<b class="patientData" id="tableData" v-bind:key="key1" v-bind:style="'{font-size:200px;}'">{{ value }}</b>
</template>
When you bind a style, pass in an object instead of a string of an object.
<!-- Instead of: -->
<b :style="'{font-size:200px;}'">{{ value }}</b>
<!-- Do: -->
<b :style="{ 'font-size' : '200px' }">{{ value }}</b>
Notice that, in the second line, the object is placed directly into the double-quotes, without its own set of single-quotes. The contents of those double-quotes are straight up JavaScript, so you don't have to escape the object in them. What you're essentially trying to do is along these lines:
<b :style="styleBinding">{{ value }}</b>
<script>
export default {
data: function() {
return {
styleBinding: {
'font-size': '200px',
'margin-top': '5em',
'other-css-property': 'value'
}
}
}
}
</script>
It's just that, since you're only using a single property, it's a little cleaner to do in-line in the template.
use :class binding instead?
<component :class="{'your-classname' : condition}">
Since inline styling is not really advisable. https://v2.vuejs.org/v2/guide/class-and-style.html

Add className attribute to dangerouslySetInnerHTML contents

How to specify className attribute for div which contains 'hello world':
<div dangerouslySetInnerHTML={{__html: '<div>hello world</div>'}} />
One way is to set is to outer div like so:
<div dangerouslySetInnerHTML={{__html: '<div>hello world</div>'}} className='class-name'/>
and then in css style the child:
.class-name div {
(css stuff here)
}
But I want to set className directly to the div with 'hello world'
EDIT: Adding class name to injected html does not solve the problem, for example:
let content = '<div class="class-name">hello world</div>'
<div dangerouslySetInnerHTML={{__html: content}}
does not work, because in case same content is used many times then CSS collisions occur (I am using style-loader with CSS modules on)
I came across this question after 2 years and I wanted to achieve the exact same results. I didn't find any accurate answers here but I came up with a solution thanks to #jash8506 due to the brilliant answer to this question.
We have to utilize two react hooks
useRef
useLayoutEffect
According to the documentation basically, useRef can be used to access the DOM elements in React and useLayoutEffect can be used to read layout from the DOM and synchronously re-render.
We can access the firstChildElement in the container div and add classes to it's classList
Here is how the completed code looks like
const containerRef = useRef();
useLayoutEffect(()=>{
if (containerRef.current){
containerRef.current.firstElementChild.classList.add('class-name');
}
});
return (
<div ref={elRef} dangerouslySetInnerHTML={{__html: '<div>hello world</div>'}} />
)
<div className="post-excerpt" dangerouslySetInnerHTML={{ __html: post.excerpt}}/>

Bootstrap DatePicker style not working properly angularjs

Can someone help me look at this plunkr. The style seems not to be working.
<!DOCTYPE html>
<div ng-controller="testController">
<h1>Hello Plunker!</h1>
<input type="text" name="bDay" ng-model="mydate | date : 'dd-MM-yyyy'" id="" value="" ng-click="showDatePicker('bday')" />
<div date-picker="mydate" view="year" min-view="date" ng-class="{hidden: (picker !== 'bday')}" auto-close="true"></div>
{{mydate}}
</div>
<script>
var app = angular.module('sample', ['datePicker']);
app.controller('testController', ['$scope', function($scope){
$scope.picker = 'null';
$scope.showDatePicker = function(picker){
$scope.picker = 'null';
setTimeout(function(){
$scope.picker = picker;
$scope.$apply();
}, 100);
}
}]);
</script>
http://plnkr.co/edit/94TifOjXZjEAhA25Kl4A?p=preview
I assume you mean you want it to look like this datepicker. For the most part, it does look like the yearly datepicker from that page. Few differences:
The arrows need the "prev" and "next" classes for proper font sizing
The difference in color is the difference between the "active" and "now" classes being applied to that year box
Your datepicker isn't in a popup since the html is inserted inline, rather than as a grandchild of an element with body as its parent.
If you want any gray dates, you need to apply the "old" class.
Make sure your jquery versions are not clashing.i had the exact same issue and resolved it.You cant use jquery 1.10.4 and 1.1.34....etc...

Simplify a jQuery function for multiple elements

I'm working on my new portfolio and I have a list of projects which are using show and hide functions. In my case, I'wrote the code for each project, but is it very repetitive. So I would like to know if there's a technique to write the same function for each project.
Here is my jquery code:
$project1.hide();
$("a.show_hide_project1").show();
$('a.show_hide_project1').click(function() {
$project1.delay(100).slideToggle("slow");
$project2.hide(); $project3.hide(); $project4.hide(); $project5.hide();
$project6.hide(); $project7.hide(); $project8.hide(); $project9.hide();
$project10.hide();$project11.hide(); $project12.hide();
});
$('a.next1').click(function() {
$project2.fadeToggle("slow");
$project1.delay(600).hide();
});
$project2.hide();
$("a.show_hide_project2").show();
$('a.show_hide_project2').click(function() {
$project2.delay(100).slideFadeToggle("slow");
$project1.hide(); $project3.hide(); $project4.hide(); $project5.hide();
$project6.hide(); $project7.hide(); $project8.hide(); $project9.hide();
$project10.hide();$project11.hide(); $project12.hide();
});
$('a.next2').click(function() {
$project3.fadeToggle("slow");
$project2.hide();
});
$('a.previous2').click(function(){
$project1.fadeToggle();
$project2.hide();
});
$project3.hide();
$("a.show_hide_project3").show();
$('a.show_hide_project3').click(function() {
$project3.delay(100).slideFadeToggle("slow");
$project2.hide(); $project1.hide(); $project4.hide(); $project5.hide();
$project6.hide(); $project7.hide(); $project8.hide(); $project9.hide();
$project10.hide();$project11.hide(); $project12.hide();
});
$('a.next3').click(function(){
$project4.fadeToggle("slow");
$project3.hide();
});
$('a.previous3').click(function() {
$project2.fadeToggle();
$project3.hide();
});
Any help will be very appreciated.
Thanks in advance.
Here's a quick stab at it: http://jsfiddle.net/Jj2Q7/1/
The animations are not exactly as you have it, and I doubt if that's the most efficient way to do it, but hopefully it'll serve as a starting point.
Update
Here's another version which makes liberal use of data attributes: http://jsfiddle.net/Jj2Q7/3/
It should be faster than the previous, but relies on the HTML tags having the right attributes set.
First off, you should probably be leveraging a common css class to select all of them
$('.projectItem').click(function () {
$('.projectItem').hide(); //hide them all
$(this).delay(100).slideFadeToggle("slow"); //then show the one being clicked.
});
Where your Html would look more like this.
<div class="projectItem" id="project1"/>
<div class="projectItem" id="project2"/>
<div class="projectItem" id="project3"/>
<div class="projectItem" id="project4"/>
Just a really rough idea.
Basically you need to give your HTML a sort of class that makes it identifiable as a "project" , and add some rel or data attribute to the individual projects
Your code then translates to something like this: (depending on your HTML , may vary)
$(function(){
$(".project").hide();
$("a.show_hide_project").show();
$('a.show_hide_project').click(function(){
$(".project").hide();
$(".project[rel="+$(this).attr('rel')+"]").delay(100).slideFadeToggle("slow");
});
});

Resources