How to initialise components when using dynamic components - vue.js

I have this code:
<div id="blocks">
<component v-for="block in blockList"
:is="block.component"
:id="block.uniqueId"
:init-show-header="showHeaders"
v-model="block.model"
v-on:content-block-remove="removeBlock"
:key="block.uniqueId">
</component>
</div>
addBlock(name) {
let block = new Object()
block.model = new Object()
block.uniqueId = name + '-block-' + this.blockCount
block.component = name + '-block'
this.blockList.push(block)
this.blockCount = this.blockCount + 1
},
<div id="buttons">
<button v-on:click="addBlock('taxonomy')" type="button" name="button" class="btn btn-primary btn-sm">Add Taxonomy</button>
<button v-on:click="addBlock('text-input')" type="button" name="button" class="btn btn-primary btn-sm">Add Text Input</button>
<button v-on:click="addBlock('header')" type="button" name="button" class="btn btn-primary btn-sm">Add Header</button>
<!-- <button v-on:click="addBlock('text')" type="button" name="button" class="btn btn-primary btn-sm">Add Text</button> -->
I have different types of components that have different kind of options stored in data object. I plan to save these options to the database upon saving the page where they are added and their settings adjusted. Each component type, its order on the page and components options are going to be saved in the database.
My question is, how do I initialise this page again after refreshing it and getting all the components and their options from the database? How would I get the options to each component when adding them in a loop on a mount event of the parent component where I load all components saved in the database and want to render them with the correct options?
What are my options?

I suggest just use bare v-bind with an object of attributes for this.
Look: https://v2.vuejs.org/v2/api/#v-bind
Thats what I mean. Let's say you have this.someTestParams = {param1: 'test string', param2: true, param3: false} in your component.
So you just need to write: <my-child-component v-bind="someTestParams" />
Instead of: <my-child-component v-bind:param1="'test string'" v-bind:param2="true" v-bind:param3="false" />

Related

Vue's reactivity not triggered when using Bootstrap 5's alert div

Vue's reactivity not triggered when using Bootstrap 5's alert div.
See my code:
<template>
<div>
<div
v-if="alertICDMsg!==''"
id="alertICDCode"
class="alert alert-info alert-dismissible fade show"
role="alert"
>
<i class="fa-solid fa-lightbulb" />
<strong> Note!</strong> <span v-html="alertICDMsg" />
<button
type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="Close"
/>
</div>
<div class="input-group mb-3">
<div class="col-xs-1">
<input
id="ICDCode"
v-model="editing_icdCode"
class="form-control"
placeholder="ICD Code"
aria-label="ICD Code"
#input="ICDCodeSearchRequested"
>
</div>
<input
id="Diagnosis"
v-model="editing_diagnosis"
type="text"
class="form-control"
placeholder="Diagnosis"
aria-label="Diagnosis"
aria-describedby="basic-addon1"
list="icdsearchlist"
#change="SelectedDiagnosisTextOption"
#input="ICDTextSearchRequested"
>
<datalist id="icdsearchlist">
<option
v-for="(disease_option, index) in icd_diagnosis_options"
:key="index"
>
{{ disease_option }}
</option>
</datalist>
<button
id="btnAddDiagnoses"
href="#"
class="btn btn-primary mx-1"
#click="AddDiagnosis"
>
<i class="fal fa-plus-circle" />
</button>
<button
id="btnCopyPreviousDiagnoses"
href="#"
class="btn btn-primary BtnSaveGroup mx-1"
>
<i class="far fa-history" />
</button>
<button
id="quickbill"
class="btn btn-primary mx-1"
>
<i class="fas fa-search-plus" />
</button>
<button
id="clearICD"
class="btn btn-danger mx-1"
#click="ClearICDFields"
>
<i class="fad fa-times-circle" />
</button>
</div>
</div>
<template>
<script>
export default {
data() {
return {
alertICDMsg:"",
};
},
watch: {
alertICDMsg: {
handler(val) {
console.log(`Val for alertICDMsg changed to :${val}`);
},
immediate: true,
deep: true,
},
},
methods: {
ICDCodeSearchRequested() {
console.log(`Search by ICD code`);
this.alertICDMsg="Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box."
console.log(`alertICDMsg is ${this.alertICDMsg}`);
setTimeout(function() {
console.log(`Dismissing alert`);
this.alertICDMsg='';
console.log(`alertICDMsg is ${this.alertICDMsg}`);
}, 5000);
},
},
}
</script>
Console log:
Search by ICD code
SubClinicalBlock.vue?d801:291 alertICDMsg is Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box.
SubClinicalBlock.vue?d801:220 Val for alertICDMsg changed to :Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box.
SubClinicalBlock.vue?d801:293 Dismissing alert
SubClinicalBlock.vue?d801:298 alertICDMsg is
The problem is that after 5 seconds, though the value of the variable changes, the alert is still visible.
I checked some similiar questions, and have seen this happening when bootstrap's javascript wasnt loaded. But for me, Bootstrap v5.0.1 JS is being loaded from the CDN and appears in the sources tab in Chrome.
Try to change the function inside of setTimeout to arrow function like this
setTimeout(() => { // code here })
The this inside of setTimeout(function () => {}) reference to the wrong context (the function itself) instead of the Vue component.
The arrow function doesn't have the this binding so when you use the arrow function the this keyword will reference the Vue component and change the state.
More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

how can i pass a value to inArray helper in handelbar template from object

i am using InArray helper to check weather a value is present in array or not and render the block according to result.
if i hardcode the value then its working fine like show below.
{{#inArray this.likes "5e20c3d45df5dc29e4a403c3"}}
<button class="btn btn-primary likebtn" value="{{this._id}}">unLike</button>
{{else}}
<button class="btn btn-primary likebtn" value="{{this._id}}">like</button>
{{/inArray}}
but i want the value from an object pass while rendering the template. my value is in user_data.user_id.
i tried the below code but its not working .
{{#inArray this.likes "{{user_data.user_id}}"}}
<button class="btn btn-primary likebtn" value="{{this._id}}">unLike</button>
{{else}}
<button class="btn btn-primary likebtn" value="{{this._id}}">like</button>
{{/inArray}}
Create custom hbs helpers.
hbs.registerHelper("in_array", function(key, arr, options) {
if (arr.includes(key)) return options.fn(this);
else return options.inverse(this);
});
And use it in your hbs file like this.
{{#in_array key arr}}
<h1>{{key}} is present</h1>
{{else}}
<h1>{{key}} is not present</h1>
{{/in_array}}

closing dropdown after click in clarity

I am able to select the dropdown and fetch data,but later dropdown is not closing.
Below is my html code for the same:
<clr-dropdown [clrCloseMenuOnItemClick]="true" >
<button type="button" clrDropdownTrigger>
<clr-icon shape="error" class="is-error" size="24"></clr-icon>
<clr-icon shape="caret down"></clr-icon>
</button>
<clr-dropdown-menu *clrIfOpen> <label
class="dropdown-header">Dropdown header</label>
<button type="button" class="dropdown-item "
*ngFor="let module of moduleVal" (click)="selectModuleHandler($event)"
value={{module}}>{{module}}</button>
</clr-dropdown-menu> </clr-dropdown>
I need to close dropdown once work is over,please help me on this.
You should use the Angular component for the dropdown, and then any link you want to autoclose on click you apply the clrDropdownItem directive to the menu items.
https://vmware.github.io/clarity/documentation/v0.11/dropdowns#example
A simple example of About menu on the header:
<div class="header-actions">
<clr-dropdown>
<button class="btn" clrDropdownTrigger>
{{loggedOnUsername}}
<clr-icon shape="caret down"></clr-icon>
</button>
<clr-dropdown-menu clrPosition="bottom-right" *clrIfOpen>
<button type="button" (click)="openUserDialog = true" clrDropdownItem>Manage Users</button>
<button type="button" (click)="openAboutDialog = true" clrDropdownItem>About</button>
<button type="button" (click)="onLogout($event)" clrDropdownItem>Logout</button>
</clr-dropdown-menu>
</clr-dropdown>
</div>

Selenium webElement property change

I am automating an application with selenium.There are no normal labels like id,tag by which I will be able to find an element. So I was using the xpath[driver.findElement(By.xpath())]. But now i find that some of the xpaths of the WebElement changing dynamically while runtime and so my test cases are failing.Even the relative xpath option is not available for the HTML.I am pasting a part of the html of the AUT. Please let me know how to handle this scenario .
<div>
<button class="btn btn-primary ng-hide" ng-click="unlockOrder('/content/boss/en/dashboard');" ng-show="enableUnlockButton" type="button">Unlock Order</button>
<button class="btn btn-primary" ng-click="discardOrder('/content/boss/en/create-order/pre-order-options');" type="button">Discard Order</button>
<button class="btn btn-primary" ng-click="saveOrder(showSaveButton && ban_search.$valid);" ng-disabled="showSaveButton==false || ban_search.$invalid" type="button" disabled="disabled">Save Order</button>
</div>
I would rely on the button text:
driver.findElement(By.xpath('//button[. = "Unlock Order"]'))
where . refers to button's text.

Twitter bootstrap : collapsible element in collapsible element

Disclaimers first :
1) First question ever, I hope I'm doing this right, apologies if it's not the case.
2) English is not my native language, so sorry for any mistakes.
3) Made a search and couldn't find an answer.
Trying to explain in words will mean many words while a bootply can say it all :
http://www.bootply.com/EBIMFQ5jEC
Basically, what I want is almost working except for this : I would like that clicking on "title 3" for instance (after you've clicked on "title 1" or "title 2") hides the "first/second column(s)" so that the "third column" is the only one shown (and vice-versa of course). I hope this is clear.
I tried a few things with data-parent (such as this: http://www.bootply.com/pgoT2IPG8D which has data-parent="#collapse1" added for the first three buttons) but couldn't achieve anything...
Thanks in advance for any help !
To get what you want you will indeed have to set the `data-parent', but also notice that this also require a '.panel' class. From the docs:
If a selector is provided, then all collapsible elements under the
specified parent will be closed when this collapsible item is shown.
(similar to traditional accordion behavior - this is dependent on the
panel class)
demo: http://www.bootply.com/qhs4dQbFZK
So you should wrap you collapsible item in a .panel class (or change the plugin). See also: https://github.com/twbs/bootstrap/issues/15341
Then a collapsible item will look that shown below:
<div class="panel">
<div class="col-md-2 collapse" id="collapse1">
<div class="btn-group-vertical btn-block" data-toggle="buttons">
<button class="btn btn-default btn-lg" href="">First subtitle column</button>
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" href="#collapse1-1"><input type="radio" name="subtitle" id="st11">Subtitle 1-1</button>
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" href="#collapse1-2"><input type="radio" name="subtitle" id="st12">Subtitle 1-2</button>
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" href="#collapse1-3"><input type="radio" name="subtitle" id="st13">Subtitle 1-3</button>
</div>
</div>
</div>
Your button should get a data-parent attribute:
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" data-parent="#menurow" href="#collapse1"><input type="radio" name="title" id="title1">Title 1</button>
And your items should be wrapped inside the id set before (#menurow):
<div class="row" id="menurow"></div>
Notice that the .panel class also set some style rules, which should be overrules (undo) for your situation, for instance: .panel {margin-bottom: 0;}