Toggle visibility of checkboxes on and off using AlpineJS - alpine.js

I have a checkbox form on a profile page and based on whether they have ticked it I want it to toggle the visibility of further questions on and off.
I'm using something like this:
<div x-data="{ show: false }">
<input type = "checkbox" #click="show = !show" :aria-expanded="show ? 'true' : 'false'" :class="{ 'active': show }">
Tick this box
</input>
<div x-show="show">Checkboxes go here</div>
</div>
But this loads the visibility as automatically false when the page is loaded. How can I set the default visibility to be based on a variable (the Boolean behind "Tick this box", let's call it tick_box).
Thank you

Related

Livewire modal window with readonly inputs

I'm using Jetstream blade components in my project, including x-jet-dialog-modal and x-jet-input. The modal window is used to add or edit records and works fine. The inputs are bound to a model "person" using the "wire:" syntax, and everything goes as expected.
Now I want to use the same modal window to show the record fields in a read-only manner, when pressing a "view" button. My idea is to make the inputs read only and hide the "save" button dynamically, using a public property of the Livewire controller (component).
So, in Livewire component I have a default value:
public $disableEdition = false;
And in the blade file:
<div class="mt-2">
<x-jet-label for="name" value="{{ __('Name') }}" />
<x-jet-input id="name" type="text" class="form-control" wire:model.defer="person.name" {{ $this->disableEdition ? 'readonly' : '' }}/>
<x-jet-input-error for="person.name" class="mt-2" />
</div>
I expected the input field to appear with attribute "readonly" (and of course non-editable and formatted with corresponding Bootstrap styles), but the browser inspector reveals that no attribute was added to the input.
Maybe you can help me with a solution or even a better approach to accomplish my goal.
Best regards.

Alpine JS - Creating a menu with active states

I am trying to create a sidebar menu with Alpine JS
I am not even sure if this is possible to do with Alpine JS.
#foreach($kanbans as $kanban)
<div x-data="activeKanban : ????">
<div #click="activeKanban = {{$kanban->id}}">
<div x-show="activeKanban !== {{$kanban->id}}">
// Design for collapsed kanban
</div>
<div>
<div x-show="activeKanban === {{$kanban->id}}">
// Design for active kanban
</div>
</div>
#endforeach
As I switch trough the pages, the $kanban->id changes, and I was wondering instead of manually setting activeKanban : 1 is there a way to pass this information to AlpineJS?
So that by default if I load the other page, the default menu that would be open would be based on the ID instead of them all being collapsed or just 1 that is specified being open?
If you're aiming for an accordion menu of sorts here's how you might achieve it with AlpineJs based on the code you shared:
// Set x-data on a div outside the loop and add your active kanban as a property
<div x-data="{
activeKanban: {{ $activeKanbanId ?? null }}
}">
#foreach($kanbans as $kanban)
<div #click="activeKanban = {{ $kanban->id }}">
<div x-show="activeKanban !== {{ $kanban->id }}">
// Collapsed view
</div>
<div x-show="activeKanban === {{ $kanban->id }}">
// Expanded view
</div>
</div>
#endforeach
</div>
Here each kanban menu item will have access to the activeKanban property in AlpineJs component instance and can set it reactively.
i.e. if activeKanban is set to a new id the current open item will close and the new one will open
Adding flexibility
What if you want to open and close them all independently though? There's more than one way to achieve this but in this case we can modify the code above to allow for it:
// Here we add an array of openItems and two helper functions:
// isOpen() - to check if the id is either the activeKanban or in the openItems array
// toggle() - to add/remove the item from the openItems array
<div x-data="{
activeKanban: {{ $activeKanbanId ?? null }},
openItems: [],
isOpen(id){
return this.activeKanban == id || openItems.includes(id)
},
toggle(id){
if(this.openItems.includes(id)){
this.openItems = this.openItems.filter(item => {
return item !== id
});
}else{
this.openItems.push(id)
}
}
}">
#foreach($kanbans as $kanban)
<div #click="toggle({{ $kanban->id }})">
<div x-show="!isOpen({{$kanban->id}})">
// Collapsed view
</div>
<div x-show="isOpen({{$kanban->id}})">
// Expanded view
</div>
</div>
#endforeach
</div>
This allows us to set an active item and also optionally open/close other menu items.

v-if not working with conditional rendering on Dropdown value changes

I have implemented a Kendo DropDownlist as below:
<kendo-dropdownlist v-if="PaymentTypeList != null"
name='PayType'
class="form-control"
v-model="vModel.PayType"
:data-text-field="'Text'"
:data-value-field="'Id'"
:auto-bind="true"
:data-source="PaymentTypeList">
</kendo-dropdownlist>
I have to render only one div below according the value selected on the dropdown list.
<div v-if="vModel.PayType == PaymentTypes.Cash">
<div class="row">
<div class="col-sm-3">
<div class="form-group">
<label>Pay Code
<span class="text-red">*</span>
</label>
<input type="text" class="form-control" id="PayCode" name="PayCode" autocomplete="off" v-model="vModel.PayCode">
</div>
</div>
</div>
</div>
<div v-else>
<kendo-dropdownlist v-model="dropdownlistValue"
:data-source="dataSourceArray"
:data-text-field="'text'"
:data-value-field="'value'">
</kendo-dropdownlist>
</div>
But the first div is never shown whatever is the condition either false or true.
When i try with the v-show it works.
How should i make this code able to work on v-if.
The plunker implementation is here on the link
https://plnkr.co/edit/Xbhm67KjnpovOWNBy2O2?p=preview
Edited: According to vue js
v-if is also lazy: if the condition is false on initial render, it will not do anything - the conditional block won’t be rendered until the condition becomes true for the first time.
But in my case when the initial condition is true the first div is rendered, and after that the first division is never rendered whatever will be the condition either true or false.
I suggest you solve this issue by using v-show. v-if is "better" suited for (not) rendering the DOM at all opposed to v-show that is just manipulating display of DOM (hidden/shown).
Forked your Plunker to this one: https://plnkr.co/edit/PjOhBbuTO6czxvQQ10da?p=preview (had to introduce "empty" select value).
Hope it helps...

kendo listview with custom edit template - not able to change model values

I have a kendo listview with custom edit template,
And this is the list view Code
var warrantyContact_listview = $("#warrantyContact_listview").kendoListView({
autoBind: false,
dataSource: dataSource,
template: kendo.template($("#warrantyContact_listview_template").html()),
editTemplate: kendo.template($("#warrantyContact_editview_template").html())
}).data("kendoListView");
And here is the edit template Code
<script type="text/x-kendo-tmpl" id="warrantyContact_editview_template">
<div id="con_editview">
<dd>
<dt>Person</dt>
<input type="text"
data-role = "autocomplete"
data-source = "some_datasource"
data-text-field = "fname"
data-value-field = "bid"
class="k-textbox"
data-bind="value:some_value"
name="builder"
required = "required"
validationMessage = "required"
id="builder"/>
<span data-for="some_value" class="k-invalid-msg"></span>
</dd><br clear="all"/>
<dt>City</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:city" name="city" required = "required" validationMessage = "required" />
<span data-for="city" class="k-invalid-msg"></span>
</dd><br clear="all"/>
<dt>State</dt>
<dd>
<input type="text" name = "state" class="k-textbox" data-bind = "value:state" data-value-field="abbrev" data-text-field="abbrev" data-min-length="1" data-source="states_datasource" data-role="autocomplete" required = "required" validationMessage = "required" />
<span data-for="state" class="k-invalid-msg"></span>
</dd><br clear="all"/>
<dt>Zip</dt>
<dd>
<input type="text" class="k-textbox" data-bind="value:zip" name="zip" required = "required" validationMessage = "required" />
<span data-for="zip" class="k-invalid-msg"></span>
</dd><br clear="all"/>
</dl>
</div>
</script>
Here is the scenario
When the listview enters into the edit mode, I would fill in in the first field "Person" which is an auto complete.
Based on what value I select for the Autocomplete "Person", I would like to assign its corresponding values to the city, state and zip. I am able to assign the values successfully. ( which I do with jquery ajax in the select event of the Person Auto complete)
But, when I call the $("#warrantyContact_listview").data("kendoListView").save();
When I check the firebug console,
those changed values city, state and zip are not been passed to the server side.
What I am missing here?
Do I have to change the binding of values in the template here?
I tried to change the values in the parameter map function, but, it did not work.
Any help would be greatly appreciated!
My first guess is that when you change the values, you don't use the set() method of the ObservableObject in dataSource, so the kendo dataSource doesn't know that the fields of the observable are modified.
So on save() ( which calls sync() for the dataSource ) it doesn't see anything new, and it doesn't update anything.
Check manually your datasource, change something with set() and use save() to see if it's saved.

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?

What is the proper way to edit items in a listview when using Kendo UI Mobile & MVVM?
I don't get the expected results when using the following:
HTML
<div id="itemsView"
data-role="view"
data-model="vm">
<ul data-role="listview" data-bind="source: items"
data-template="itemsTemplate">
</ul>
<script id="itemsTemplate" type="text/x-kendo-template">
<li>
#=Name#
</li>
</script>
<input type="text" data-bind="value: newValue" />
<button data-role="button" data-bind="click: update">update</button>
</div>​
JavaScript
var vm = kendo.observable({
items: [{
Name: "Item1"}],
newValue: '',
update: function(e) {
var item = this.get("items")[0];
item.set("Name", this.get("newValue"));
//adding the follwoing line makes it work as expected
kendo.bind($('#itemsView'), vm);
}
});
kendoApp = new kendo.mobile.Application(document.body, {
transition: "slide"});​
I expect the listview to reflect the change to the Name property of that item. Instead, a new item is added to the listview. Examining the array reveals that there is no additional item, and that the change was made. (re)Binding the view to the view-model updates the list to reflect the change. Re-Binding after a change like this doesn't seem to make any sense.
Here is the jsfiddle:
http://jsfiddle.net/5aCYp/2/
Not sure if I understand your question properly: but this is how I did something similar with Kendo Web UI, I expect mobile is not so different from Web UI from API perspective.
$element.kendoListView({
dataSource: list,
template: idt,
editTemplate: iet,
autoBind: true
});
The way I bind the listview is different, but I guess you can get similar results with your method as well.
I pass two templates to the list view, one for displaying and one for editing.
Display template contains a button (or any element) with css class k-edit to which kendo will automatically bind the listview edit action.
display template:
<div class="item">
# if (city) { #
#: city #<br />
# } #
# if (postCode) { #
#: postCode #<br />
# } #
<div class="btn">
<span class="k-icon k-edit"></span>Edit
<span class="k-icon k-delete"></span>Delete
</div>
</div>
Edit template
<div class="item editable">
<div>City</div>
<div>
<input type="text" data-bind="value: city" name="city" required="required" validationmessage="*" />
<span data-for="city" class="k-invalid-msg"></span>
</div>
<div>Post Code</div>
<div>
<input type="text" data-bind="value: postCode" name="postCode" required="required" validationmessage="*" />
<span data-for="postCode" class="k-invalid-msg"></span>
</div>
<div class="btn">
<span class="k-icon k-update"></span>Save
<span class="k-icon k-cancel"></span>Cancel
</div>
</div>
Clicking that element will put the current element on edit mode using the editTemplate.
Then on the editTemplate there is another button with k-update class, again to which kendo will automatically bind and call the save method on the data source.
Hopefully this will give you more ideas on how to solve your issue.
The problem was caused by the <li> in the template. The widget already supplies the <li> so the additional <li> messes up the rendering. This question was answered by Petyo in the kendo ui forums

Resources