Using a date picker in Zeppelin jdbc interpreter - apache-zeppelin

I have a set of charts in my Zeppelin notebook which fetch data from a database for a certain period of time using a jdbc interperter. What I'd like to do is to be able to choose a period which would apply to all the charts.
I can see that one could create an input field using a Dynamic Form or even a date picker with Angular (which would be even better). Is it possible to somehow use the chosen period in a jdbc interperter?
In the example given in Apply Zeppelin Dynamic Forms I can see how this could be done in one chart, but this is not what I want: to be able to define one field that will affect all of the charts.

My solution (with angular intepreter):
first param (dependencies):
%angular
<script type="text/javascript" src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" />
second param (daterangepicker) - change param ID :
%angular
<span>Date range picker:</span>
<div id="reportrange" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc; width:250px;">
<i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
<span></span> <b class="caret"></b>
</div>
<p>
<p>
<input id="start" ng-model="start" style="visibility: hidden;"></input>
<input id="end" ng-model="end" style="visibility: hidden;"></input>
<button type="submit" class="btn btn-primary pull-right" ng-click="z.angularBind('start',start,'fixme to param ID');z.angularBind('end',end,'fixme to param ID');"> Apply</button>
<script type="text/javascript">
$(function() {
var start = moment().subtract(29, 'days');
var end = moment();
function cb(start, end) {
$('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY'));
$('#start').val(start.toISOString());
$('#start').trigger('input'); // Use for Chrome/Firefox/Edge
$('#start').trigger('change'); // Use for Chrome/Firefox/Edge + IE11
$('#end').val(end.toISOString());
$('#end').trigger('input'); // Use for Chrome/Firefox/Edge
$('#end').trigger('change'); // Use for Chrome/Firefox/Edge + IE11
}
$('#reportrange').daterangepicker({
startDate: start,
endDate: end,
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
}, cb);
cb(start, end);
});
</script>
third param:
%jdbc
SELECT *
FROM TABLE
WHERE DATE >= TO_TIMESTAMP('${start}') AND DATE <= TO_TIMESTAMP('${end}')

Related

Angularjs Bootstrap to Material

I am changing the UI code from bootstrap to material. I am using angularjs and material 1.1.20. I do not know angularjs but would like to learn. Please see the code I need to change to angularjs material below.
I know that md-select does not accept ng-options, but I do not have any idea how I can change it to work with md-select tag.
My background is designing HTML CSS but I want to learn more js and angular etc.
<div class="col-md-12 col-no-pad">
<div class="input-group">
<span class="input-group-addon" id="LANGUAGE">Language</span>
<select name="LANGUAGE" class="form-control" tabindex="8"
ng-init="LANGUAGE = null"
ng-model="LANGUAGE"
ng-options="language.KEYID as language.DESC for language in languages">
<option value="">-Select One-</option>
</select>
</div>
js:
dataService.getAll('language').then(function(data) {
$scope.languages = data.data;
});
I want it to work as an angularjs material dropdown.
You need to use ng-repeat on <md-option>. Check the snippet below.
angular.module('myApp', ['ngMaterial'])
.controller('AppCtrl', function($scope) {
$scope.languages = [{
desc: 'English',
keyid: 1,
position: 5
}, {
desc: 'Italian',
keyid: 2,
position: null
}, {
desc: 'Spanish',
keyid: 3,
position: 43
}, {
desc: 'Malayalam',
keyid: 4,
position: 8
}];
});
md-input-container {
min-width: 50%;
}
<link rel="stylesheet" href="https://rawgit.com/angular/bower-material/master/angular-material.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-animate.js"></script>
<script src="https://rawgit.com/angular/bower-material/master/angular-material.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-aria.js"></script>
<div ng-app="myApp" ng-cloak ng-controller="AppCtrl as ctrl">
<md-input-container>
<label>Languages</label>
<md-select ng-model="languageSelected">
<md-option ng-repeat="item in languages" ng-value="item.keyid">
{{ item.desc }}
</md-option>
</md-select>
</md-input-container>
<div>Your selection: {{ languageSelected || '--' }}</div>
<div ng-repeat="item in languages" ng-if="item.keyid == languageSelected">
<div>desc: {{ item.desc || '--' }}</div>
<div>position: {{ item.position || '--' }}</div>
<div>keyid: {{ item.keyid || '--' }}</div>
</div>
</div>

Add or Remove selected elements from multi select box using angular js

I want to display one dynamic table, But table columns I want to select at run time. For that purpose I have taken two multi select box, in first Multi select am loading all column names using Json.
Now my requirement is, I want add selected column names from first multi select box to second multi select box. And if required I also want to remove from second multi select box.
I have taken two buttons, one for adding and other for removing.
Can any one help me with this requirement. How can I do it using AngularJs?
please refer attached image to clear with my requirement.
Thank in advance..
angular.module('app', []).controller('MoveCtrl', function($scope) {
$scope.available = [];
$scope.selected = [];
$scope.moveItem = function(items, from, to) {
angular.forEach(items, function(item) {
var idx = from.indexOf(item);
from.splice(idx, 1);
to.push(item);
});
// clear selection
$scope.available = "";
$scope.selected = "";
};
$scope.moveAll = function(from, to) {
angular.forEach(from, function(item) {
to.push(item);
});
from.length = 0;
};
$scope.selectedclients = [];
$scope.availableclients = [{
id: 1,
name: 'Bob'
}, {
id: 2,
name: 'Sarah'
}, {
id: 3,
name: 'Wayne'
}, {
id: 4,
name: 'Pam'
}];
});
input {
display: block;
margin: 0 auto;
}
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.2.17" data-semver="1.2.17" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
<link href="style.css" rel="stylesheet" />
<script src="script.js"></script>
</head>
<body ng-controller="MoveCtrl">
<h1>Move items between Select boxes</h1>
<div style="float:left">
<div>Available Clients</div>
<div>
<select size="5" multiple ng-model="available" ng-options="client as client.name for client in availableclients" style="width: 100px;height:100px"></select>
</div>
</div>
<div style="float:left; width: 100px; text-align:center">
<div> </div>
<input id="moveright" type="button" value=">" ng-click="moveItem(available, availableclients,selectedclients)" />
<input id="moverightall" type="button" value=">>" ng-click="moveAll(availableclients,selectedclients)" />
<input id="move left" type="button" value="<" ng-click="moveItem(selected, selectedclients,availableclients)" />
<input id="moveleftall" type="button" value="<<" ng-click="moveAll(selectedclients,availableclients)" />
</div>
<div style="float:left">
<div>Selected Clients</div>
<div>
<select size="5" multiple ng-model="selected" ng-options="client as client.name for client in selectedclients" style="width: 100px;height:100px"></select>
</div>
</div>
<div style="clear:both">
<br/>
<div>Selected Clients: {{selectedclients}}</div>
<div>Available Clients: {{availableclients}}</div>
<div>Selected: {{selected}}</div>
<div>Available: {{available}}</div>
</div>
</body>
</html>
Credit goes to AngularJS moving items between two select list for the base. However, it would only move single items when multiple items are selected.

codeigniter multiple where clause is not working

My controller (I want to select records based on some conditions) :
public function promotion()
{
if(!$this->user_permission->check_permission())return;
$data['startDate'] = $this->input->post('input_date_from');
$data['endDate'] = $this->input->post('input_date_to');
$email = $this->input->post('email');
var_dump($email);
var_dump($data['startDate']);
var_dump($data['endDate']);
$this->db->select('a.booking_id as booking_id, a.from_email as from_email, a.booking_date as booking_date, a.status as status, b.vendor_airway_bill as awb, b.tariff as tariff');
$this->db->where('from_email', $email);
$this->db->where('booking_date >=', date('Y-m-d',strtotime($data['startDate'])));
$this->db->where('booking_date <=', date('Y-m-d',strtotime($data['endDate'])));
$this->db->where('status = 1');
$this->db->or_where('status = 2');
$this->db->from('booking as a');
$this->db->join('shipment as b','a.booking_id = b.booking_id','left');
$query = $this->db->get();
$data['result'] = $query->result_array();
$this->template->render('admin/promotion',$data,'admin');
}
My view (I want to show booking shipment based on from_email from the user input. I set the table to display:none, and when the user input something in from_email input then click view, it shows the datatable) :
<form action="" method="post" id="cashback">
User Email :
<input type="text" name="email" id="email">
Booking Date :
<div id="daterange" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc; display:inline">
<span></span> <b class="caret"></b>
</div>
<input type="hidden" name="input_date_from" id="input_date_from" value="">
<input type="hidden" name="input_date_to" id="input_date_to" value="">
<button type="button" class="btn btn-primary" onclick="promotion();">View
</button>
</form>
<table class="table table-bordered table-striped table-condensed" id="promotion" style="display:none">
<thead>
<tr>
<th>BookingDate</th>
<th>UserEmail</th>
<th>AirwayBill</th>
<th>Tariff</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($result as $r) : ?>
<tr>
<td>
<?php echo $r['booking_date'];?>
</td>
<td>
<?php echo $r['from_email'];?>
</td>
<td>
<?php echo $r['awb'];?>
</td>
<td>
<?php echo $r['tariff'];?>
</td>
<td>
<?php echo $r['status'];?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</template>
<template block="custom_js">
<script type="text/javascript" src="https://cdn.datatables.net/r/bs/dt-1.10.9/datatables.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/2.15.1/moment.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/bootstrap.daterangepicker/2.1.24/daterangepicker.js"></script>
<script src="<?php echo base_url('asset/js/typeahead.bundle.min.js') ?>"></script>
<script type="text/javascript">base_url='<?php echo base_url()?>'</script>
<script>
<?php if(isset($startDate) && isset($endDate)): ?>
var startDate = '<?php echo $startDate ?>';
var endDate = '<?php echo $endDate ?>';
<?php endif; ?>
$(function() {
$('#promotion').DataTable();
var start = typeof(startDate) === 'string' ? moment(startDate) : moment().startOf('month');
var end = typeof(endDate) === 'string' ? moment(endDate) : moment();
$('#input_date_from').val(start.format('YYYY-MM-DD'));
$('#input_date_to').val(end.format('YYYY-MM-DD'));
function cb(start, end) {
$('#daterange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY'));
}
$('#daterange').daterangepicker({
startDate: start,
endDate: end,
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
}, cb);
cb(start, end);
$('#daterange').on('apply.daterangepicker', function(ev, picker) {
$('#input_date_from').val(picker.startDate.format('YYYY-MM-DD'));
$('#input_date_to').val(picker.endDate.format('YYYY-MM-DD'));
});
});
function promotion() {
input_date_to = $('#input_date_to').val();
input_date_from = $('#input_date_from').val();
email = $('#email').val();
$.ajax
({
url: "<?php echo site_url('admin/promotion')?>",
type: "POST",
dataType: "text",
data: {email: email, input_date_from: input_date_from, input_date_to: input_date_to},
success: function(data)
{
$('#promotion').show();
console.log(email);
console.log(input_date_from);
console.log(input_date_to);
}
})
}
</script>
I try to filter data based on from_email, date_range_from and date_range_to. When I var_dump the input post, it showing the value as I expected, but it didn't run the this->db->where('from_email',$email), so I get all result..
Try to replace
$this->db->where('status = 1');
$this->db->or_where('status = 2');
into something like:
$this->db->where('(status = 1 OR status = 2)');
note parenthesis is important to make OR operator get higher presedence than AND operator. Also turn on your query log and check what actual SQL is sent to database server to better understand why.
[SOLVED]. Use where_in() instead of or_where

searchable drop down in AngularJs

I am fetching data from API and I need a searchable dropdown so that when I start typing it shows me the data coming from the API. Currently I have this piece of code.
<select class="formControl" name="repeatSelect" id="repeatSelect" ng-model="facilitiesData.business_id">
<option ng-repeat="option in businesses" value="{{option.id}}">{{option.business_name}}</option>
</select>
Thanks.
Probably you are looking for this. This could be one of the solution.
This has different type of typeaheads. You can pick one as per your needs.
<input type="text" ng-model="customPopupSelected" placeholder="Custom popup template" uib-typeahead="state as state.name for state in statesWithFlags | filter:{name:$viewValue}" typeahead-popup-template-url="customPopupTemplate.html" class="form-control">
Note - You will require a library ui-bootstrap-tpls which is officially created by AngularJS team.
Try this. you cannot directly put textbox inside option and filter select based on it. but this is one way that you can don so. another way is to use plugin or angular material design.
// Angular
var myApp = angular.module('app', []);
myApp.controller('ListCtrl', function($scope) {
$scope.items = [{
'name': 'Item 1'
}, {
'name': 'Item 2'
}, {
'name': 'Account 3'
}, {
'name': 'Account 4'
}, {
'name': 'Item 5'
}, {
'name': 'Item 6'
}, {
'name': 'User 7'
}, {
'name': 'User 8'
}];
});
// jQuery
$('.dropdown-menu').find('.dontClose').click(function(e) {
e.stopPropagation();
});
.dropdown.dropdown-scroll .dropdown-menu {
max-height: 200px;
width: 60px;
overflow: auto;
}
.search-control {
padding: 5px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<div class="dropdown dropdown-scroll" ng-app="app">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">Select <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1" ng-controller="ListCtrl">
<li role="presentation" class="dontClose">
<div class="input-group input-group-sm search-control">
<span class="input-group-addon">
<span class="glyphicon glyphicon-search"></span>
</span>
<input type="text" class="form-control" placeholder="Query" ng-model="query"></input>
</div>
</li>
<li role="presentation" ng-repeat='item in items | filter:query'> {{item.name}}
</li>
</ul>
</div>
you can use datalist tag also If you want to build your own searchable dropdown ..Here is the working code:
HTML Part:
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<form ng-submit="click(search);">
<label class="child-label" for="existing-phases">Existing: </label>
<input type="text" ng-model="search" list="names">
<datalist id="names" class="form-control" ng-model="name">
<option value=''>-- select an option --</option>
<option ng-repeat="option in contacts | filter:search | limitTo:3" value="{{option.name}}"></option>
</datalist>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
JS Part:
var app = angular.module('app', []);
app.controller('myCtrl', function($scope) {
$scope.showContacts = function() {
$scope.contacts = [{
id: 1,
name: "Ben",
age: 28
}, {
id: 2,
name: "Sally",
age: 24
}, {
id: 3,
name: "John",
age: 32
}, {
id: 4,
name: "Jane",
age: 40
}];
};
$scope.showContacts();
$scope.click = function(MyData) {
alert(JSON.stringify(MyData));
};
});
Working Demo is available here..https://plnkr.co/edit/hamW3F05YUPrWwS3RmmG?p=preview
You're in the right path. All you need to do now is create an http service or factory that triggers an API call every keypress, and the result of which populates your $scope.businesses array.
If you want to build searchable drop-down on your own then you can make use of filters.searchable drop-down with filters using textbox
If you want to go for a plugin check angular multi select
I've recenlty used in one of my projects. It is a flexible plugin and it allows multi-select also.
You can use dropdown select plugin
JS
const app = angular.module('DropdownSelectApp', ['DropDownSelect']);
HTML
<dropdown-select dd-model="exampleModel" dd-data="exampleItemList" dd-label="labelName" >
See this like for demo: https://saravanajd.github.io/Angularjs-Dropdown-Search/

Highchart.js and AngularJS after navigation some chart does not load

I am currently facing a problem. I have a HTML page which contains multiple div to load highcharts. Same page have all the jquery script.
I am using angularJS to route the page. Index page, Chart1Page and Chart2Page. When i am loading chart1page 1st time all charts load but if i come back from chart2page to chart1page some charts does not load. Below code is one of the chart which not load. If i replace with some other chart like pie the result is same. Do i need to check the sequence?
<script>
function freecapacity() {
$(function () {
// Set up the chart
var chart = new Highcharts.Chart({
chart: {
renderTo: 'freecapacity',
type: 'column',
margin: 75
},
title: {
text: 'Free Capacity'
},
subtitle: {
text: ''
},
plotOptions: {
column: {
depth: 25
}
},
xAxis: {
categories: ['A', 'B', 'C', 'S', 'D', 'DD', 'PD']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6]
}]
});
});
}
freecapacity();
</script>
<html>
<div class="row">
<h5 class="form-control" style="background-color:#D2D7D3"><label>Hub and GSA Information</label></h5>
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-6 small">
<div class="form-control" style="height: 350px;" id="freecapacity"></div>
</div>
<div class="col-xs-12 col-sm-8 col-md-6 col-lg-6 small">
<div class="form-control" style="height: 350px;" id="gsanomination"></div>
</div>
</div>
</html
I recommend you use the Angularjs directive for Highcharts: https://github.com/pablojim/highcharts-ng
Than set up the Highchart object in the view controller instead of using script tags in the html file.

Resources