extjs 4 how to wrap children components of container in custom html? - model-view-controller

I need to create Twitter Bootstrap basic NavBar component in my ExtJS 4.2 application. All I want to make my component generate the following html:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<ul class="nav">
<li class="active"><i class="icon1"></i> Item #1</li>
<li><i class="icon2"></i> Item #3</li>
<li><i class="icon3"></i> Item #3</li>
</ul>
</div>
</div>
I've created two views (NavBar and NavBarItem correspondingly):
Ext.define('My.view.layout.Navbar', {
extend: 'Ext.container.Container',
xtype: 'navbar',
cls: 'navbar navbar-inverse navbar-fixed-top',
defaultType: 'navbaritem',
initComponent: function() {
Ext.apply(this, {
items: [
{
title: 'Item #1',
icon: 'icon1',
selected: true
},
{
title: 'Item #2',
icon: 'icon2'
},
{
title: 'Item #3',
icon: 'icon3'
}
]
});
this.callParent(arguments);
}
});
Ext.define('My.view.layout.NavbarItem', {
extend: 'Ext.Component',
xtype: 'navbaritem',
autoEl: { tag: 'li' },
config: {
title: '',
icon: null,
selected: false
},
renderTpl: '{icon}{title}',
initComponent: function() {
....
this.callParent(arguments);
}
});
I get something like this as an output:
<div class="navbar navbar-inverse navbar-fixed-top">
<li class="active"><i class="icon1"></i> Item #1</li>
<li><i class="icon2"></i> Item #3</li>
<li><i class="icon3"></i> Item #3</li>
</div>
How can I modify my NavBar view in order it could have a custom template and children components could be added to a particular element?

You're halfway there: your child items are rendering more or less properly, but the container will require a bit of work to avoid rendering extra elements. The catch here is that for a container, the rendering process is tightly intertwined with the layout and in fact containers render from within a layout. So you will need to fudge the auto layout a bit:
Ext.define('My.view.layout.NavBar', {
extend: 'Ext.container.Container',
alias: 'widget.navbar', // Not xtype here!
defaultType: 'navbaritem',
// Let's be declarative
items: [{
title: 'Item #1',
icon: 'icon1',
selected: true
}, {
title: 'Item #2',
icon: 'icon2'
}, {
title: 'Item #3',
icon: 'icon3'
}],
renderTpl: [
'<div class="navbar-inner">',
'<ul class="nav">',
'{%this.renderChildren(out,values)%}',
'</ul>',
'</div>',
{
renderChildren: function(out, renderData) {
// We have to be careful here, as `this`
// points to the renderTpl reference!
var me = renderData.$comp.layout,
tree = me.getRenderTree();
if (tree) {
Ext.DomHelper.generateMarkup(tree, out);
}
}
}
]
});
Instantiating this container will give you approximately this output:
<div ...>
<div class="navbar-inner">
<ul class="nav" ...>
<li ...>
...
</li>
<li ...>
...
</li>
<li ...>
...
</li>
</ul>
</div>
</div>
I'm simplifying here and the actual elements rendered to the DOM will get a lot of auto-generated classes, ids, and other attributes, so you will have to tweak your templates even more, but I hope you get the gist of it.

Related

RTL picker with dependent values

The reequirement is to make an RTL picker with multiple levels.
I copied the example from the documentation into a page equiped with the official frameworks' CSS for RTL users.
I have modified "textAlign" properties of each column as well.
For some reason the picker isn't acting as expected. open the snippet in full page mode.
var app = new Framework7({
root: '#app',
rtl: true,
theme: 'md'
});
app.views.create('#mainView', {
});
var carVendors = {
Japanese: ['Honda', 'Lexus', 'Mazda', 'Nissan', 'Toyota'],
German: ['Audi', 'BMW', 'Mercedes', 'Volkswagen', 'Volvo'],
American: ['Cadillac', 'Chrysler', 'Dodge', 'Ford']
};
var pickerDependent = app.picker.create({
inputEl: '#demo-picker-dependent',
rotateEffect: true,
formatValue: function(values) {
return values[1];
},
cols: [{
textAlign: 'right',
values: ['Japanese', 'German', 'American'],
onChange: function(picker, country) {
if (picker.cols[1].replaceValues) {
picker.cols[1].replaceValues(carVendors[country]);
}
}
},
{
textAlign: 'right',
values: carVendors.Japanese,
width: 160,
},
],
routableModals:false
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/css/framework7.rtl.md.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/js/framework7.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block-title">
Dependent values</div>
<div id="app">
<div id="mainView">
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" placeholder="Your car" readonly="readonly" id="demo-picker-dependent" />
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
That seems like a bug in Framework7.
CSS 'right' and 'left' properties for first and last '.picker-column' don't fit RTL layout (flipped). The attached repair solved it.
var app = new Framework7({
root: '#app',
rtl: true,
theme: 'md'
});
app.views.create('#mainView', {
});
var carVendors = {
Japanese: ['Honda', 'Lexus', 'Mazda', 'Nissan', 'Toyota'],
German: ['Audi', 'BMW', 'Mercedes', 'Volkswagen', 'Volvo'],
American: ['Cadillac', 'Chrysler', 'Dodge', 'Ford']
};
var pickerDependent = app.picker.create({
inputEl: '#demo-picker-dependent',
rotateEffect: true,
formatValue: function(values) {
return values[1];
},
cols: [{
textAlign: 'right',
values: ['Japanese', 'German', 'American'],
onChange: function(picker, country) {
if (picker.cols[1].replaceValues) {
picker.cols[1].replaceValues(carVendors[country]);
}
}
},
{
textAlign: 'right',
values: carVendors.Japanese,
width: 160,
},
],
routableModals:false
});
.picker-column.picker-column-first:after{
left:100% !important;
right:0 !important;
}
.picker-column.picker-column-last:after{
left:0 !important;
right:100% !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/css/framework7.rtl.md.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/js/framework7.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block-title">
Dependent values</div>
<div id="app">
<div id="mainView">
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" placeholder="Your car" readonly="readonly" id="demo-picker-dependent" />
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
EDIT:
github issue

Passing data between 2 MVC widgets

I've got created a widget(combobox) with data from an external server.
I just want the value that I select from that combobox see into the label from another widget.
Source of the widget from the combobox:
<div id="exampleCombo">
<div class="demo-section k-content">
<h4>Facility</h4>
<input id="fac" style="width: 30%;" />
</div>
<script>
$(document).ready(function (user) {
$("#fac").kendoComboBox({
dataTextField: "client",
dataValueField: "client",
order: "ascending",
height: 400,
dataSource: {
// type: "odata",
type: "json",
transport: {
read: "/mvc/controllers/UserfacilitiesCombo/get/" + user
},
group: { field: "facility" }
},
});
});
Source of the widget with the label on it:
<div id="exampleLabel">
<div class="demo-section k-content">
<ul class="forms">
<li>
<label>FacilityName</label>
<input id="FacPass" name="FacPass" value="Test" class="k-textbox" style="width: 100%;" />
</li>
</ul>
</div>
Can anybody help me on this?
You can use the change event. Put this after your dataSource and add a class name to your target label
change: function(e) {
var value = this.value();
$('.yourLabelClass').html(value);
}
Here is some more info about the available events
https://docs.telerik.com/kendo-ui/api/javascript/ui/combobox/events/change

How can I prevent Vue template from reloading when loading a Laravel view

I am quite new to Laravel and Vue and I'm currently building an app and trying to incorporate Vue to handle my sidebar navigation items.
Currently my sidebar is populating as expected from my view template. Everything is working great and when I first launch my app, navigation item 0 is selected and highlighted. However, when I click on any other navigation item, I can see the active class being added briefly to that item, but then the new Url loads and my vue template is getting reloaded making navigation item 0 once again active.
I would have thought that only my #yeild( 'content' ) should be reloading and anything sitting in my main blade template should remain unchanged.
Which makes me think I have overlooked something somewhere or have something wrong.
Main blade template:
<body>
<div class="main-wrapper">
<!-- Header -->
#include( 'layouts.header' )
<!-- Sidebar -->
#include( 'layouts.sidebar' )
<!-- Content Wrapper. Contains page content -->
<div #auth class="content-wrapper" #else class="content-wrapper-no_sidebar" #endauth>
<div class="container-fluid">
<!-- Main content -->
<section class="content">
#yield('content')
</section><!-- /.content -->
</div>
</div><!-- /.content-wrapper -->
</div>
...
</body>
layouts.sidebar:
<div id="side_bar">
#auth
<aside class="left-sidebar">
<nav>
<side-bar></side-bar>
</nav>
</aside>
#endauth
</div>
SideMenu.vue (side-bar template file):
<template>
<div class="sidebar-menu">
<a v-for="( item, index ) in items" class="side-nav-item" :class="{ active: item.active }" :href="item.Url" #click="toggleItem( index )">
<i :class="item.Icon"></i><br>
{{ item.Description }}
</a>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{
active: false,
Description: 'Dashboard',
Icon: 'fas fa-tachometer-alt',
Url: '/home'
},
{
active: false,
Description: 'Test Cases',
Icon: 'fas fa-calendar-check',
Url: '/testcases'
},
{
active: false,
Description: 'Applications',
Icon: 'fab fa-windows',
Url: '/applications'
},
{
active: false,
Description: 'Testers',
Icon: 'fas fa-users',
Url: '/testers'
},
{
active: false,
Description: 'Modules',
Icon: 'fas fa-sitemap',
Url: '/categories'
}
],
currentActiveIndex: 0,
}
},
methods: {
toggleItem( index ) {
this.items[this.currentActiveIndex].active = false;
this.items[index].active = true;
this.currentActiveIndex = index;
}
},
mounted() {
this.items[this.currentActiveIndex].active = true;
console.log( 'Sidebar Loaded' );
}
}
</script>
app.js:
Vue.component( 'side-bar', require( './components/SideMenu.vue' ) );
// Define new vue instances
const side_bar = new Vue({
el: '#side_bar'
});

How to attach onClick events to preview image in vue-dropzone-component

I have components dropzone on vue. Im install my template in settings.
Then i want to set v-on:click(method) to preview image in dropzone, but event don`t works. How to set correctly click to element?
<template>
<vue-dropzone :options="dropzoneOptions" ref="myVueDropzone" id="customdropzone"
:preview-template="template">
</vue-dropzone>
</template>
methods: {
template () {
return `<div class="dz-preview dz-file-preview" v-on:click.native="alert(1)">
<div class="dz-image" v-on:click="alert(1)">
<img data-dz-thumbnail>
</div>
<div class="dz-details" v-on:click="alert(1)">
<div class="dz-size"><span data-dz-size></span></div>
<div class="dz-filename"><span data-dz-name></span></div>
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<div class="dz-success-mark"><i class="fa fa-check"></i></div>
<div class="dz-error-mark"><i class="fa fa-close"></i></div>
</div>`
;
},
}
data: function () {
return {
dropzoneOptions: {
url: 'https://httpbin.org/post',
thumbnailWidth: 200,
maxFilesize: 0.5,
addRemoveLinks: true,
previewTemplate: this.template(),
headers: {"My-Awesome-Header": "header value"},
},
salonID: 0,
photos: [],
}
},

go to a laravel controller using vue js's data

This is my vue
new Vue({
el: '#notificationMenu',
data: {
showModal: false,
patients: [],
duepatients: []
},
created: function(){
this.getPatients();
this.addUsers();
},
methods: {
getPatients: function(){
$.getJSON("{{route('api_patients')}}", function(patients){
this.patients = patients;
}.bind(this));
setTimeout(this.getPatients, 1000);
},
addUsers: function(){
this.$http.get('/govaccine/addUsers', '').then((response) => {
}, (response) => {
this.formErrors = response.data;
});
setTimeout(this.addUsers, 10000);
},sendSMS: function(val){
$.getJSON('sendsms/' + val,function(duepatient){
this.duepatients = duepatient;
}.bind(this));
}
}
});
and this is my html
<ul class="notifications-list" v-for="patient in patients">
<li class="item no-data">You don't have notifications</li>
<!-- use the modal component, pass in the prop -->
<modal v-if="showModal" #close="showModal = false">
<!--
you can use custom content here to overwrite
default content
-->
<h3 slot="header">custom header</h3>
</modal>
<a v-on:click="sendSMS(patient.due_date)">
<li class="item js-item " data-id="5" >
<div class="details">
<strong>#{{ patient.total}} patients</strong> are due for immunization on #{{patient.due_date}}
<span class="date">{{-- #{{patient.created_at}} --}}</span>
</div>
<button type="button" class="button-default button-dismiss js-dismiss">×</button>
</li>
</a>
</ul>
If I loop through vue js data using v-for how do i pass the data each loop in {{route('patient.show', parameter)}} so i can put a parameter on it.
or is there anyway to go to the controller and go to the other page?
yes you should use router-link. complete example here.
if I got you question wrong just tell me.

Resources