Each block looping through array is not working in svelte - sveltekit

So i have been working on this svelte project which is a notes app. So my goal is that whenever i press the submit button the note gets added to a array and the array get printed out as a each block in svelte. However my array gets updated but not my UI. i have console logged the array every time i press the submit button. I have to added any components yet. You can have a look at my code:
let value = ""
let values = []
function logic(){
values.push(value)
}
</script>
<input type="text" bind:value={value}>
<br>
<button on:click={logic}>Submit</button>
<hr>
{#each values as name, index}
<li>{index} - {name}</li>
{/each}
<style>
input {
height:100px;
width: 200px;
margin-bottom: 1em;
}
button{
height: 50px;
width: 100px;
}
</style>
Hope you find the problem,
Thanks in advance

It looks like your problem is because pushing an item into an array does not trigger Svelte's reactivity. Since a value that is being stored into a variable from an array is just the memory location, Svelte does not detect any change in the variable, because it changes the value of the array not the variable.
The svelte devs recommended to try to reassign the value of an array such like:
<script>
let value = ""
let values = []
function logic(){
// As you can see here, I'm reassigning the array.
values = [...values, value]
}
</script>
<input type="text" bind:value={value}>
<br>
<button on:click={logic}>Submit</button>
<hr>
{#each values as name, index}
<li>{index} - {name}</li>
{/each}
<style>
input {
height:100px;
width: 200px;
margin-bottom: 1em;
}
button{
height: 50px;
width: 100px;
}
</style>
Here's the tutorial that the Svelte docs gave:
https://svelte.dev/tutorial/updating-arrays-and-objects

Related

Angular - Solution for complex router params with link href

I have a card that I want the user to be able to open in a new tab by using mouse middle button. So for this purpose I added a link <a> with an href that is being automatically generated for each card. The problem is that the route I'm trying to navigate to takes as parameters some complex structures that cannot be passed directly in the route link. Sometimes the user just clicks on the card and the browser takes the link instead of the js method that passes the parameters. As a result the new route is loaded like there where no parameters (this is the correct behavior if it were in a new tab).
const openDocument = function (){
console.log('open doc in the same tab using custom router params');
//params contains also a big array of numbers that cannot be passed in route
}
.container{
background-color: gray;
width:200px;
height: 200px;
padding: 30px;
}
.global-link{
position: absolute;
background-color:red;
min-width: 230px;
min-height: 230px;
margin-left: -15px;
margin-top: -15px;
}
.card-container{
background-color: green;
width: 100%;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div class="container">
<a class="global-link"></a>
<div class="card-container" ng-click="openDocument()">
</div>
<div>
I solved this issue by preventing the onclick event default behavior. And then executing openDocument() method.
<a class="global-link" href="document/id" ng-click="$event.preventDefault(); openDocument();"></a>
And it works really well because angular wont intercept the middle or right click, so you will be able to open in a new tab etc.

Dynamic close button on search bar using AngularJS

When I enter some value in search text box, the [X] close button dynamically appear in the left corner of the text box and I need to clear and search results when I click the [X] close button using AnglarJS.
Example - Exactly like in Microsoft Outlook email search.
In order to display the X, you'll need to use ng-show to only show it when there's content in the input and ng-click to bind the clear text logic, as such:
div {
width: 300px;
position: relative;
}
input {
width: 100%;
}
span {
position: absolute;
right: 2px;
top: 2px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="">
<input type="text" ng-model="text">
<span ng-show="text" ng-click="text='';">X</span>
</div>

ng-class and class css/style atrributes

I do not know when use one over the other and when I should use both at the same time for an html element (div, span, table, etc). Please advise. Mixing both of them may cause some issues, mayn't it?
Ngclass is used when you need the class to be conditional based on some logic
Such as ng-class="{'choose-this-class': ifThisAngularScopeIsTrue}"
Class is just a fixed class of css
The ng-class directive dynamically binds one or more CSS classes to an HTML element.
Eg: ng-class
You should use class and style attributes as you see fit to your desired designs. The ng-class directive is generally used when you want to change some html's class based on some variable or expression.
Here's a simple example
angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<style>
.blue {
height: 100px;
width: 100%;
background-color: blue;
display: block;
}
.red {
height: 100px;
width: 100%;
background-color: red;
display: block;
}
</style>
<div ng-app="app">
<div style="height: 100px; width 100%; background-color: red; display: block;" ng-class="{'red': red == true, 'blue': red == false}"></div>
<br />
<button ng-click="red = !red">Changing Red to Blue won't work because of the style attribute!</button>
<br />
<br />
<div class="blue" ng-class="{'blue': blue, 'red': !blue}"></div>
<br />
<button ng-click="blue = !blue">Toggle between Red & Blue</button>
</div>
Notice how inline style attribute overwrites the class ;)
Do read this for further insight.

How can I fade in and out the visibility of a DIV using ng-show with AngularJS 1.3 beta?

My code looks like this:
<div class="block-border"
data-ng-show="qty > 0">
xxx
</div>
I know there have been a lot of changes with Animation in AngularJS. Can someone tell me the easiest way for me to make it take 500ms to show and 50ms to hide the xxx when the value of qty changes. Note that I am using the very latest AngularJS.
Reference angular-animate.js
Add ngAnimate as a dependent module:
var app = angular.module('app', ['ngAnimate']);
Pick a name for your transition, for example 'fade', and then define the appropriate CSS classes based on the naming convention described in the documentation:
.fade.ng-hide {
opacity: 0;
}
.fade.ng-hide-remove,
.fade.ng-hide-add {
display: block !important; /* or inline-block, as appropriate */
}
.fade.ng-hide-remove {
transition: all linear 1000ms;
}
.fade.ng-hide-add {
transition: all linear 500ms;
}
Add the class to your element:
<div class="block-border fade" ng-show="qty > 0">
Demo: http://plnkr.co/edit/HWi0FfDOsHeSOkcrRtN2?p=preview
I couldn't get the accepted answer to work, but the following did work (taken largely from this ng-nuggets post):
.fade {
transition: all linear 500ms;
opacity: 1;
}
.fade.ng-hide {
opacity: 0;
}
and then my HTML element which I wanted to fade in and out looked something like this:
<span data-ng-show="copyLinkClicked" class="fade">some text here</span>
As #MichaelNguyen mentioned, Bootstrap does appear to have a style already called fade, and we are using Bootstrap in our application, yet the above styles worked nonetheless. If you already have a style named fade, then change the name to something unique before using the above code.
If you want to fade in using ng-if as a boolean angular has some nice documentation here https://docs.angularjs.org/api/ngAnimate . I used ng-if for my fading purposes here's an example below:
form.html
<form name="exampleForm" ng-submit="submit()">
<input type="email" placeholder="Email Address" ng-model="email" required>
<input type="text" placeholder="Name" ng-model="name" required>
<input class="invalid-btn" ng-if="exampleForm.$invalid" type="submit" value="Invalid" />
<input class="valid-btn" ng-if="exampleForm.$valid" type="submit" value="Valid">
</form>
form.css
/* css for button that will show when form is invalid */
.invalid-btn {
border: 1px solid #222;
width: 100px;
height: 50px;
color: #222;
background: #fff;
}
.invalid-btn.ng-enter {
opacity: 1;
}
/* The finishing CSS styles for the enter animation */
.invalid-btn.ng-enter.ng-enter-active {
opacity: 0;
}
.valid-btn {
width: 100px;
height: 50px;
background: #F26623;
color: #fff;
}
/* The starting CSS styles for the enter animation */
.valid-btn.ng-enter {
transition:0.5s linear all;
opacity: 0;
}
.valid-btn.ng-enter-stagger {
/* this will have a 100ms delay between each successive leave animation */
transition-delay: 0.3s;
/* As of 1.4.4, this must always be set: it signals ngAnimate
to not accidentally inherit a delay property from another CSS class */
transition-duration: 0s;
}
/* The finishing CSS styles for the enter animation */
.valid-btn.ng-enter.ng-enter-active {
width: 100px;
height: 50px;
background: #F26623;
color: #fff;
opacity:1;
}
The way this works is if you want to fade in a button with a different color or text and different text color you can fade in a button when the form is filled out and valid and the invalid button will fade out leaving only one button depending on the state of the form. Kind of a hack but it works and looks smooth. I had to set a delay using .ng-enter-stagger because loading the animations at the same time was causing the buttons to blink and jump and not animate smoothly. So in this case we let invalid button hide first then load valid button when form is valid and all input fields have been filled out correctly.

How to change the class on one div while hovering over another div with AngularJS?

I want to change the class of one div while hovering over another div using AngularJS directives. Here is what I have so far http://jsfiddle.net/E8nM5/38/
HMTL
<div ng-controller="Ctrl" ng-app>
<div ng-class="my-class">This div will change class when one hovers over bottom DIV </div>
<br/>
<div class="hover-div" ng-mouseenter="my-class = 'highlight'" ng-mouseleave="my-class = 'lowlight'">HOVER OVER ME TO CHANGE THE UPPER DIV's CLASS</div>
</div>
CSS
div.highlight {
padding: 10px;
background: red;
color: white;
}
div.lowlight {
padding: 10px;
background: blue;
color: white;
}
div.hover-div {
padding: 10px;
background: green;
color: white;
}
JS
function Ctrl($scope){
}
Any ideas?
Change my-class to myclass (i.e. the dash causes problem).
<div ng-controller="Ctrl" ng-app>
<div ng-class="myclass">This div will change class when one hovers over bottom DIV </div>
<br/>
<div class="hover-div" ng-mouseenter="myclass = 'highlight'" ng-mouseleave="myclass = 'lowlight'">HOVER OVER ME TO CHANGE THE UPPER DIV's CLASS</div>
</div>
Updated: the reason my-class isn't allowed in the expression is because AngularJS treats the dash as minus symbol and tries to parse it that way. Apparently, it can't parse the statement my - class = 'highlight'. Unfortunately, after reading AngularJS parser code, I can't find a way to "help" it distinguish between dash and minus.
You need to remove the hyphen from my-class so it will work properly in your Controller. Other than that it looks like you have it mostly done. Here's a little snippet - I also added it as text in the div so you can see it change
Your HTML File:
<div class="{{myClass}}"> {{myClass}} </div>
<div class="hover" style="height:50px; width:50px; border:1px solid black;" ng-mouseleave="myClass='test'" ng-mouseenter="myClass='hola'"> </div>
Controller
function Ctrl($scope){
$scope.myClass="test";
}

Resources