I am trying to create a dashboard in Google script HTML web app, the data consist, assigned project and total time spent on project by user
I have used some HTML code however it got jumbled, sharing the google sheet which consists data I want to replicate this data in the web app.Functions I am looking here is "Date Picker" "User name / Project name" are the search parameters
The dashboard should reflect according to the search parameters and data should consist Total worked users by the user or total hours or users spent on the project.
I know it's bit complex, if your refer my sheet you will get some idea what I am looking to publish in web app
Sheet
function doGet() {
return HtmlService
.createTemplateFromFile('index')
.evaluate();
}
function getData() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet4')
.getDataRange()
.getValues();
}
function getData1() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet5')
.getDataRange()
.getValues();
}
function getData2() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet6')
.getDataRange()
.getValues();
}
function getData3() {
return SpreadsheetApp
.openById('1Xr_zcL0hnfmKoECytosdgv2kffdalCdfe0ildF-_Re4')
.getSheetByName('Sheet7')
.getDataRange()
.getValues();
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
/* Add a gray background color and some padding to the footer */
footer {
background-color: #f2f2f2;
padding: 25px;
}
.carousel-inner img {
width: 100%; /* Set width to 100% */
min-height: 200px;
}
}
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Logo</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
<li>Projects</li>
<li>Contact</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><span class="glyphicon glyphicon-log-in"></span> Login</li>
</ul>
</div>
</div>
</nav>
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
<div class="row">
<div class="col-xs-3"><label for="usr"><p class="text-primary">User Name</label><input type="text" class="form-control" id="#"></div>
<div class="col-xs-3"><label for="usr"><p class="text-primary">Date Range Picker</label><input type="text" class="form-control" id="#"></div>
</div>
<hr style="height:2px;border-width:0;color:gray;background-color:gray">
<div class="col-sm-6">
<div class="well">
<p><html>
<? var data = getData(); ?>
<table class="table table-striped table-bordered table-hover table-condensed">
<tr>
<p>Today Report</p>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</html></p>
</div>
<div class="well">
<table class="table table-bordered">
<thead>
<tr>
<td class="bg-primary"style="background-color:#4885ed"><b>Project Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
</thead>
<tbody>
<tr>
<td>Test1</td>
<td>A</td>
<td>12:00:00</td>
</tr>
<tr>
<td>Test2</td>
<td>B</td>
<td>11:00:00</td>
</tr>
<tr>
<td>Test3</td>
<td>C</td>
<td>10:00:00</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-sm-6">
<div class="well">
<p><html>
<? var data = getData1(); ?>
<table class="table table-striped table-bordered table-hover table-condensed">
<tr>
<p>Monthly Report</p>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
<? for (var i = 0; i < data.length; i++) { ?>
<tr>
<? for (var j = 0; j < data[i].length; j++) { ?>
<td><?= data[i][j] ?></td>
<? } ?>
</tr>
<? } ?>
</table>
</html></p>
</div>
<div class="well">
<table class="table table-bordered">
<thead>
<tr>
<td class="bg-primary"style="background-color:#4885ed"><b>Project Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>User Name</b></td>
<td class="bg-primary"style="background-color:#4885ed"><b>Total Worked Hours</b></td>
</tr>
</thead>
<tbody>
<tr>
<td>Test1</td>
<td>A</td>
<td>122:00:00</td>
</tr>
<tr>
<td>Test2</td>
<td>B</td>
<td>211:00:00</td>
</tr>
<tr>
<td>Test3</td>
<td>C</td>
<td>190:00:00</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr>
This is a simple html file communicating with Google Apps Script contained in a Spreadsheet. I test it a lot as a dialog and I also run it as a web app. The html file and the Google Apps Script communicate with each other and I pass one array from the html file to the Google Script. Hope this helps.
The Code.gs file:
function doGet()
{
var html = HtmlService.createHtmlOutputFromFile('index');
return html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}
function getData(a)
{
var ts = Utilities.formatDate(new Date(), "GMT-6", "M/d/yyyy' 'HH:mm:ss");
a.splice(0,0,ts);
var ss=SpreadsheetApp.openById('SPREADSHEETID')
ss.getSheetByName('Form Responses 1').appendRow(a);
return true;
}
function getURL()
{
var ss=SpreadsheetApp.openById('SPREADSHEETID');
var sht=ss.getSheetByName('imgURLs');
var rng=sht.getDataRange();
var rngA=rng.getValues();
var urlA=[];
for(var i=1;i<rngA.length;i++)
{
urlA.push(rngA[i][0]);
}
return urlA;
}
The index.html file:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id="data">
<br />Text 1<input name="t1" type="text" size="15" id="txt1" placeholder="Text 1" />
<br />Text 2<input name="t2" type="text" size="15" id="txt2" placeholder="Text 2" />
<br />Text 3<input name="t3" type="text" size="15" id="txt3" placeholder="Text 3" />
<br />Text 4<input name="t4" type="text" size="15" id="txt4" placeholder="Text 4" />
<br /><input type="radio" name="Type" value="Member" checked />Member
<br /><input type="radio" name="Type" value="Guest" />Guest
<br /><input type="radio" name="Type" value="Intruder" />Intruder
<br /><input type="button" value="submit" id="btn1" />
<br /><img id="img1" src="" alt="img1" width="300" />
</div>
<div id="resp" style="display:none;">
<h1>Response</h1>
<p>Your data has been received.</p>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
$('#btn1').click(validate);
$('#txt4').val('');
$('#txt3').val('');
$('#txt2').val('');
$('#txt1').val('')
google.script.run
.withSuccessHandler(setURL)
.getURL();
});
function setURL(url)
{
$('#img1').attr('src',url[0]);
}
function setResponse(a)
{
if(a)
{
$('#data').css('display','none');
$('#resp').css('display','block');
}
}
function validate()
{
var txt1 = document.getElementById('txt1').value || '';
var txt2 = document.getElementById('txt2').value || '';
var txt3 = document.getElementById('txt3').value || '';
var txt4 = document.getElementById('txt4').value || '';
var type = $('input[name="Type"]:checked').val();
var a = [txt1,txt2,txt3,txt4,type];
if(txt1 && txt2 && txt3 && txt4)
{
google.script.run
.withSuccessHandler(setResponse)
.getData(a);
return true;
}
else
{
alert('All fields must be completed.');
}
}
function loadTxt(from,to)
{
document.getElementById(to).value = document.getElementById(from).value;
}
function radioValue()
{
var radios = document.getElementsByName('genderS');
for (var i = 0, length = radios.length; i < length; i++)
{
if(radios[i].checked)
{
return radios[i].value;
}
}
}
console.log('My Code');
</script>
</body>
</html>
Related
I want to get the output as single row like group name and visible or not. but in my scenario i am getting different output .
enter image description here
Here is my html code.
#model List<F3CentricMVCApp.Areas.KnowledgeBox.Models.GroupResponse>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<div class="col-12">
<table id="tblSectionGroups" class="table responsive table-striped" bPaginate="true">
<thead>
<tr>
<th width="95%">Groups</th>
<th width="5%" class="no-sort"></th>
</tr>
</thead>
<tbody>
#if (#ViewBag.UnAssidnedGroups is not null)
{
#foreach (var item in Model)
{
<tr>
<td>#item.Name</td>
#foreach (var unassinedGroup in ViewBag.UnAssidnedGroups)
{
#if (#unassinedGroup.GroupId == #item.Id)
{
<td>
<input type="checkbox" class="chkSectionVisibility" />
</td>
}
else
{
<td>
<input type="checkbox" class="chkSectionVisibility" checked="checked" />
</td>
}
}
</tr>
}
}
</tbody>
</table>
</div>
<script>
$('#tblSectionGroups').DataTable({
"bLengthChange": false,
"pageLength": 5,
"bPaginate": true,
"stripeClasses": [],
"info": false,
language: {
searchPlaceholder: "Type to filter list",
search: ""
},
"order": [],
"columnDefs": [{
"targets": 'no-sort',
"orderable": false,
}]
});
</script>
<div class="col-md-12 text-right">
<button type="button" class="btn btn-custom" tabindex="3" id="btnSave">Save</button>
</div>
Single checkbox for each group in a row is my requirement. any body can guide me how to deal with two collections in a code which is going through 2 foreach statements. but the logic should not be disturbed after all.
Update your foreach code as below i.e.
#if (#ViewBag.UnAssidnedGroups is not null)
{
#foreach (var item in Model)
{
int isUnassigned = 0;
<tr>
<td>#item.Name</td>
#foreach (var unassinedGroup in ViewBag.UnAssidnedGroups)
{
#if (#unassinedGroup.GroupId == #item.Id)
{
<td>
<input type="checkbox" class="chkSectionVisibility" />
</td>
// Setting.
isUnassigned++;
}
}
if (isUnassigned <= 0)
{
<td>
<input type="checkbox" class="chkSectionVisibility" checked="checked" />
</td>
}
</tr>
}
}
Hopefully this will solve your issue.
I am trying to add a search function for every table in my page using jquery and ejs format. It is working when I use 2 same function with different ID. But it seems pointless and waste of time if I repeat the whole function for every table in the page. What do I need to do for this?
This is the code for search function.
$(document).ready(function(){
$('#search').keyup(function(){
search_table($(this).val());
});
function search_table(value){
$('#table_body tr').each(function(){
var found = 'false';
$(this).each(function(){
if($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0)
{
found = 'true';
}
});
if(found == 'true')
{
$(this).show();
}
else
{
$(this).hide();
}
});
}
});
And this is the ejs code
<div class="dropdown">
<button class="button button1">Add</button>
<button class="button button2">Edit</button>
<form action="" class="search-form">
<input type="search" id="search" name="search" class="search-input" />
<i class="fa fa-search"></i>
</form>
</div>
<br />
<table class="table table-sortable" id="pagination">
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Description</th>
<th>Date</th>
</tr>
</thead>
<tbody id="table_body">
<% for(var i=0; i < data.employeeProfile.length; i++) { %>
<tr>
<td>
<%= data.employeeProfile[i].name %>
</td>
<td>
<%= data.employeeProfile[i].category %>
</td>
<td>
<%= data.employeeProfile[i].description %>
</td>
<td>
<%= data.employeeProfile[i].date %>
</td>
</tr>
<% } %>
</tbody>
</table>
Yes, you're right, it should be a reusable code. It's known as DRY ( Do not Repeat Yourself )
So one way of doing this is to create a function which handles the search functionality
Example :
function setSearch(inputEle, rowEle){
$(inputEle).keyup(function(){
search_table(rowEle, $(this).val());
});
}
function search_table(rowEle, value){
$(rowEle).each(function(){
var found = 'false';
$(this).each(function(){
if($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0)
{
found = 'true';
}
});
if(found == 'true')
{
$(this).show();
}
else
{
$(this).hide();
}
});
}
Now you can set search functionality by calling setSearch for all the tables like :
setSearch('#search', '#table_body tr');
So this is the EJS code
<div class="topnav">
<img class="logo-img" src="img/cyberview.png" alt="AVATAR" />
Home
<a class="active" href="http://localhost:3000/employee">Employee</a>
Attendance
Benefit
Calendar
Medical Portal
Contracts
Feedback
Rewards
Log Out
</div>
<div class="grid-container">
<div>
<h1>Performance</h1>
<div class="dropdown">
<button class="button button1">Add</button>
<button class="button button2">Edit</button>
<form action="" class="search-form">
<input type="search" id="search" class="search-input" />
<i class="fa fa-search"></i>
</form>
</div>
<br />
<table class="table table-sortable" id="pagination">
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Description</th>
<th>Date</th>
</tr>
</thead>
<tbody id="table_body">
<% for(var i=0; i < data.employeeProfile.length; i++) { %>
<tr>
<td>
<%= data.employeeProfile[i].name %>
</td>
<td>
<%= data.employeeProfile[i].category %>
</td>
<td>
<%= data.employeeProfile[i].description %>
</td>
<td>
<%= data.employeeProfile[i].date %>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
<div class="grid-container">
<div>
<h1>Personal Information</h1>
<div class="dropdown">
<button class="button button1">Add</button>
<button class="button button2">Edit</button>
<form action="" class="search-form">
<input type="search" id="search" class="search-input" />
<i class="fa fa-search"></i>
</form>
</div>
<br />
<table class="table table-sortable" id="pagination2">
<thead>
<tr>
<th>Name</th>
<th>Phone</th>
<th>Email</th>
<th>Emergency Contact</th>
<th>Joined Date</th>
</tr>
</thead>
<tbody id="table_body">
<% for(var i=0; i < data.employeeResponse.length; i++) { %>
<tr>
<td>
<%= data.employeeResponse[i].name %>
</td>
<td>
<%= data.employeeResponse[i].contact %>
</td>
<td>
<%= data.employeeResponse[i].email %>
</td>
<td>
<%= data.employeeResponse[i].emergencyContact %>
</td>
<td>
<%= data.employeeResponse[i].joinedDate %>
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
And this is the code you have provided
function setSearch(inputEle, rowEle){
$(inputEle).keyup(function(){
search_table(rowEle, $(this).val());
});
}
function search_table(rowEle, value){
$(rowEle).each(function(){
var found = 'false';
$(this).each(function(){
if($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0)
{
found = 'true';
}
});
if(found == 'true')
{
$(this).show();
}
else
{
$(this).hide();
}
});
}
setSearch('#search', '#table_body tr');
I did this in the past year and it works just fine. Until recently I encounter this problem which I don't know what caused it.
Here I'm trying to pass supplierID from a (1)form through (2)ajax javascript and return the (3)data from AdminController to a (4)div in the same view
(1)form:-
<?php $form = ActiveForm::begin([
'id'=>'chatform'
]);?>
<div class="box-body">
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>No</th>
<th>Supplier</th>
<th>Option(s)</th>
</tr>
</thead>
<tbody>
<?php
for($x = 0; $x < count($supplierChatInfoListTable); $x++){ ?>
<tr>
<td>
<?=$x+1?>
<div class="form-group">
<input type="hidden" name="supplierID" id="supplierID" class="form-control"
value="<?=$supplierChatInfoListTable[$x]['supplierID']?>" style="width: 50px">
</div>
</td>
<td >
<h4><?=$supplierChatInfoListTable[$x]['supplierFirstname']?></h4>
</td>
<td>
<button type="button" class="btn btn-primary btnchat"><i class="fa fa-edit"></i></button>
</td>
</tr>
<?php } ?>
</tbody>
<tfoot>
<tr>
<th>No</th>
<th>Supplier</th>
<th>Option(s)</th>
</tr>
</tfoot>
</table>
</div>
<?php ActiveForm::end();?>
and here is my (2)javascript running in the same view:-
<?php
$urproudcode= Url::to(['admin/chatinfo2pass']);
$this->registerJs("
$(function(){
$('.btnchat').click(function(){
var supplierID = $('#supplierID').val();
$.ajax({
'url':'".$urproudcode."',
'data':{supplierID:supplierID},
'method':'POST',
beforeSend: function (xhr) {
$.blockUI({
message: 'Processing...',
css: {
border: 'none',
padding: '15px',
backgroundColor: '#000',
'-webkit-border-radius': '10px',
'-moz-border-radius': '10px',
opacity: .5,
color: '#fff'
}
});
},
'success':function(data){
$('.chatmessages').html('Success');
if(data == 'false'){
$.unblockUI();
$('.chatmessages').html('Data False');
}else{
$.unblockUI();
$('.chatmessages').html(data);
}
},
error: function (xhr, ajaxOptions, thrownError) {
$.unblockUI();
$('.chatmessages').html('Failed');
console.log(data);
}
});
});
});
");
?>
(3)div with class=chatmessages in the same view
<div class="col-md-8 chatmessages">
</div>
(4)actionChatinfo2pass in AdminController
public function actionChatinfo2pass()
{
$postData = \Yii::$app->request->post('supplierID');
$supplierID = intval($postData);
// fetch all supplier for chat
$supplierChatInfoListTable = SupplierProfile::find()
->select(['supplier_profileID AS supplierID','supplier_profile.first_name AS supplierFirstname',
'supplier_profile.middle_name AS supplierMiddlename', 'supplier_profile.last_name AS
supplierLastname', 'login_profile.login_profileID AS loginID', 'status_login.status_loginID AS
statusLoginID', 'status_login.description AS statusLogindesc'])
->leftJoin('login_profile', 'login_profile.login_profileID = supplier_profile.login_profile_ID')
->leftJoin('status_login', 'status_login.status_loginID = login_profile.status_login_ID')
//->where(['=', 'status_login.description', $activeSupplier])
->orderBy(['supplier_profile.supplier_profileID' => SORT_ASC])
->asArray()
->all();
$dataSend['supplierChatInfoListTable'] = $supplierChatInfoListTable;
$this->layout = 'admin/main';
$html= $this->renderAjax('#app/views/admin/displaychatmessage.php',$dataSend);
echo $html;
}
But it return the 'same' supplierID for both supplier as show below:
and browser console give me this error?(updated):-
btw, this is the content of displaychatmessage.php (I just try to display supllierID and their name)
<!-- DIRECT CHAT WARNING -->
<div class="box box-warning direct-chat direct-chat-warning">
<div class="box-header with-border">
<h3 class="box-title">Direct Chat</h3>
<div class="box-tools pull-right">
<span data-toggle="tooltip" title="3 New Messages" class="badge bg-yellow">3</span>
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
<button type="button" class="btn btn-box-tool" data-toggle="tooltip" title="Contacts" data-widget="chat-pane-toggle">
<i class="fa fa-comments"></i></button>
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
</div>
</div>
<!-- /.box-header -->
<div class="box-body">
<!-- Conversations are loaded here -->
<div class="direct-chat-messages">
<!-- Message. Default to the left -->
<div class="direct-chat-msg">
<div class="direct-chat-info clearfix">
<?php for($z = 0; $z < count($supplierChatInfoListTable); $z++){?>
<span class="direct-chat-name pull-left">Supplier ID: <?=$supplierChatInfoListTable[$z]['supplierID']?>, <?=$supplierChatInfoListTable[$z]['supplierFirstname']?> <?=$supplierChatInfoListTable[$z]['supplierMiddlename']?> <?=$supplierChatInfoListTable[$z]['supplierLastname']?></span>
<?php }?>
<span class="direct-chat-timestamp pull-right">23 Jan 2:00 pm</span>
</div>
<!-- /.direct-chat-info -->
<img class="direct-chat-img" src="dist/img/user1-128x128.jpg" alt="Message User Image"><!-- /.direct-chat-img -->
<div class="direct-chat-text">
Is this template really for free? That's unbelievable!
</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
<!-- Message to the right -->
<div class="direct-chat-msg right">
<div class="direct-chat-info clearfix">
<span class="direct-chat-name pull-right">Sarah Bullock</span>
<span class="direct-chat-timestamp pull-left">23 Jan 2:05 pm</span>
</div>
<!-- /.direct-chat-info -->
<img class="direct-chat-img" src="dist/img/user3-128x128.jpg" alt="Message User Image"><!-- /.direct-chat-img -->
<div class="direct-chat-text">
You better believe it!
</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
</div>
<!--/.direct-chat-messages-->
<!-- Contacts are loaded here -->
<div class="direct-chat-contacts">
<ul class="contacts-list">
<li>
<a href="#">
<img class="contacts-list-img" src="dist/img/user1-128x128.jpg" alt="User Image">
<div class="contacts-list-info">
<span class="contacts-list-name">
Count Dracula
<small class="contacts-list-date pull-right">2/28/2015</small>
</span>
<span class="contacts-list-msg">How have you been? I was...</span>
</div>
<!-- /.contacts-list-info -->
</a>
</li>
<!-- End Contact Item -->
</ul>
<!-- /.contatcts-list -->
</div>
<!-- /.direct-chat-pane -->
</div>
<!-- /.box-body -->
<div class="box-footer">
<form action="#" method="post">
<div class="input-group">
<input type="text" name="message" placeholder="Type Message ..." class="form-control">
<span class="input-group-btn">
<button type="submit" class="btn btn-warning btn-flat">Send</button>
</span>
</div>
</form>
</div>
<!-- /.box-footer-->
</div>
<!--/.direct-chat -->
Can you help me with this? I don't know where it went wrong.
As you have mentioned you are getting same supplierID on clicking both supplier. This problem is caused because in your js code you are getting supplierID by id of the input i.e '#supplierID', and according to your html code the input elements of both of the suppliers have same value in their id attribute i.e 'supplierID', because of that every time js will get value from first input element with id attribute value 'supplierID'. So you need to make some changes in your html and js code. As there is separate edit button for each supplier so instead of using input to store supplierID value you can store it in a data attribute in the edit button. So your updated html code would become
<?php $form = ActiveForm::begin([
'id'=>'chatform'
]);?>
<div class="box-body">
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>No</th>
<th>Supplier</th>
<th>Option(s)</th>
</tr>
</thead>
<tbody>
<?php
for($x = 0; $x < count($supplierChatInfoListTable); $x++){
$supID = $supplierChatInfoListTable[$x]['supplierID']; ?>
<tr>
<td>
<?=$x+1?>
<div class="form-group">
<input type="hidden" name="<?='supplierID'.$supID?>" id="<?='supplierID'.$supID?>" class="form-control"
value="<?=$supID?>" style="width: 50px">
</div>
</td>
<td >
<h4><?=$supplierChatInfoListTable[$x]['supplierFirstname']?></h4>
</td>
<td>
<button type="button" class="btn btn-primary btnchat" data-supplierID="<?=$supID?>"><i class="fa fa-edit"></i></button>
</td>
</tr>
<?php } ?>
</tbody>
<tfoot>
<tr>
<th>No</th>
<th>Supplier</th>
<th>Option(s)</th>
</tr>
</tfoot>
</table>
</div>
<?php ActiveForm::end();?>
And then get the supplierID of clicked supplier from data attribute of button in js. So your js code would become
<?php
$urproudcode= Url::to(['admin/chatinfo2pass']);
$this->registerJs("
$(function(){
$('.btnchat').click(function(){
var supplierID = $(this).attr('data-supplierID');
$.ajax({
'url':'".$urproudcode."',
'data':{supplierID:supplierID},
'method':'POST',
beforeSend: function (xhr) {
$.blockUI({
message: 'Processing...',
css: {
border: 'none',
padding: '15px',
backgroundColor: '#000',
'-webkit-border-radius': '10px',
'-moz-border-radius': '10px',
opacity: .5,
color: '#fff'
}
});
},
'success':function(data){
$('.chatmessages').html('Success');
if(data == 'false'){
$.unblockUI();
$('.chatmessages').html('Data False');
}else{
$.unblockUI();
$('.chatmessages').html(data);
}
},
error: function (xhr, ajaxOptions, thrownError) {
$.unblockUI();
$('.chatmessages').html('Failed');
console.log(data);
}
});
});
});
");
?>
I hope your problem will be solved.
I have such a simplified markup which appends and fills in every next row by surname and name; also by clicking the "List" button I need to fill in additional data about this person in a new popup div and save all information into LocalStorage.
The problem is when I click on different "List" buttons appears and hides the same div but the task is:
by clicking on different "List" buttons appear and hide different divs(clones).
Your support highly appreciated.
var app = angular.module("myApp",['listOfBooks']);
app.controller("myCtrl", function($scope){
$scope.authors = [];
$scope.addAuthor = function(){
var author = {};
author.surname = "";
author.name = "";
$scope.authors.push(author);
};
});
var app = angular.module("listOfBooks",[]);
app.controller("booksCtrl", function($scope){
$scope.showBooks = false;
$scope.showBookList = function(){
$scope.showBooks = !$scope.showBooks;
}
$scope.books = [];
$scope.addBook = function(){
var book = {};
book.title = "";
$scope.books.push(book);
};
});
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div class="container">
<h3>AUTHORS' LIST</h3>
<div class="btn-group">
<button ng-click ="addAuthor()" type="button" class="btn btn-default">Add</button>
</div>
<form ng-controller="booksCtrl" name ="myForm">
<table class="table table-bordered">
<tr>
<th>Surname</th>
<th>Name</th>
<th>Books</th>
</tr>
<tr ng-repeat="author in authors">
<td><input ng-model="author.surname" type="text" class="form-control"></td>
<td><input ng-model="author.name" type="text" class="form-control"></td>
<td>
<button ng-click="showBookList()" type="button" class="btn btn-default">List</button>
</td>
</tr>
</table>
<div ng-show="showBooks" class="col-sm-8" style="background-color:lightblue; position: absolute; left:5px; top:5px;z-index:2;">
<div class="btn-group">
<button ng-click ="addBook()" type="button" class="btn btn-default">Add</button>
</div>
<table class="table table-bordered">
<tr>
<th>Title</th>
</tr>
<tr ng-repeat="book in books">
<td><input ng-model="book.title" type="text" class="form-control"></td>
</tr>
</table>
</div>
</form>
</div>
</body>
</html>
I understand the question to be around how should you add a list of books with respect to the author. The current code creates a list of books, but does not allow the books to associate to a given author. I've done this with minimal changes, aside from adding a section to display the contents of the author array. I also added a simple close button within the list div for easier use.
This example takes advantage of the existing authors array that you have, and adds a child array under the books property. When you add an author, and then add a book, the property will be created if it does not already exist.
var app = angular.module("myApp", ['listOfBooks']);
app.controller("myCtrl", function($scope) {
$scope.authors = [];
$scope.addAuthor = function() {
var author = {};
author.surname = "";
author.name = "";
$scope.authors.push(author);
};
});
var app = angular.module("listOfBooks", []);
app.controller("booksCtrl", function($scope) {
$scope.showBooks = false;
$scope.currentAuthor = {};
$scope.showBookList = function(author) {
$scope.showBooks = !$scope.showBooks;
$scope.currentAuthor = author;
}
$scope.addBook = function() {
// If the current author doesn't have a books array yet, create an empty one.
$scope.currentAuthor.books = $scope.currentAuthor.books || [];
var book = {};
book.title = "";
$scope.currentAuthor.books.push(book);
};
});
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div class="container">
<h3>AUTHORS' LIST</h3>
<div class="btn-group">
<button ng-click="addAuthor()" type="button" class="btn btn-default">Add</button>
</div>
<form ng-controller="booksCtrl" name="myForm">
<table class="table table-bordered">
<tr>
<th>Surname</th>
<th>Name</th>
<th>Books</th>
</tr>
<tr ng-repeat="author in authors">
<td><input ng-model="author.surname" type="text" class="form-control"></td>
<td><input ng-model="author.name" type="text" class="form-control"></td>
<td>
<button ng-click="showBookList(author)" type="button" class="btn btn-default">List</button>
</td>
</tr>
</table>
<div ng-show="showBooks" class="col-sm-8" style="background-color:lightblue; position: absolute; left:5px; top:5px;z-index:2;">
<div class="btn-group">
<button ng-click="addBook()" type="button" class="btn btn-default">Add</button>
</div>
<table class="table table-bordered">
<tr>
<th>Title</th>
</tr>
<tr ng-repeat="book in currentAuthor.books">
<td><input ng-model="book.title" type="text" class="form-control"></td>
</tr>
</table>
<button class="btn btn-sm btn-warning" ng-click="showBooks = false">Close</button>
</div>
</form>
</div>
<hr />
<h2>authors data</h2>
<ul>
<li ng-repeat="a in authors">
Surname: {{ a.surname }}, Name: {{ a.name }}
<ul>
<li ng-repeat="b in a.books">Book: {{ b.title }}</li>
</ul>
</li>
</ul>
</body>
</html>
I am using onaftersave() function to save the table data. In dir-paginate i am using ng-repeat to read the table row values. I kept itemsperpage is 5. obviously 6th row will be display in second Page. When I try to edit the second page row values it is not updating the second page rows. How to resolve it?
<form editable-form name="tableform1" oncancel="cancel()" onaftersave="saveTable(Manage_Role.Description)">
<div class="row">
<div class="col-xs-12">
<div class="panel panel-default panel-table">
<div class="panel-heading">
<div class="row">
<div class="col col-xs-6">
</div>
<div class="col col-xs-6 text-right">
<button type="button" data-toggle="modal" data-target="#myModal" class="btn btn-sm btn-primary btn-create" title="Add New Role">Add New Role</button>
</div>
</div>
</div>
<div class="panel-body scrollbar">
<table class="table table-striped table-bordered table-list">
<thead>
<tr>
<th style="width: 25%" align="center">
Name
</th>
<th style="width: 35%">
Description
</th>
<th style="width: 30% " align="center">
IsActive?
</th>
<th style="width: 10% " align="center"><a href="" ng-click="orderByField='IsActive';
reverseSort = !reverseSort" title="Assign">Assign</a></th>
<th style="width: 1%" align="center" ng-show="false">DirtyFlag</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="text" id="RoleNameID" ng-model="Manage_Role1.RoleName" placeholder="search" class="searchbox" onkeydown="return (event.keyCode!=13);"
/>
</td>
<td>
<input type="text" id="DescriptionID" ng-model="Manage_Role1.Description" placeholder="search" class="searchbox" onkeydown="return (event.keyCode!=13);"
/>
</td>
<td>
<select name="DropFilter" ng-model="Manage_Role1.IsActive" class="searchbox">
<option value="">All</option>
<option value=false>False</option>
<option value=true>True</option>
</select>
</td>
<!--<td></td>-->
</tr>
<tr dir-paginate="Manage_Role in Manage_Roleser | itemsPerPage:5 | filter:DropFilter | filter:Manage_Role1 | orderBy:orderByField:reverseSort "
ng-class-odd="'odd'">
<td ng-click="tableform1.$show()">
<span e-ng-change="applyHighlight($data,$index)" editable-text="Manage_Role.RoleName" ng-attr-title="{{Manage_Role.RoleName}}"
e-form="rowform" ng-click="rowform.$show()">
{{ Manage_Role.RoleName | uppercase }}
</span>
</td>
<td ng-click="tableform1.$show()">
<div>
<span e-ng-change="applyHighlight($data,$index)" editable-text="Manage_Role.Description" e-form="rowform" ng-attr-title="{{Manage_Role.Description}}"
ng-click="rowform.$show()">
{{ Manage_Role.Description || 'empty' }}
</span>
</div>
</td>
<td ng-click="tableform1.$show()" align="center">
<span e-ng-change="applyHighlight($data,$index)" ng-checked="Manage_Role.IsActive" editable-checkbox="Manage_Role.IsActive"
e-form="rowform" ng-click="applyHighlight($data,$index);tableform.$show()">
<input type="checkbox" ng-model="Manage_Role.IsActive" width="20" ng-attr-title="{{Manage_Role.IsActive}}" />
</span>
</td>
<td align="center">
<input type="image" data-toggle="modal" ng-click="Rolepopupclick(Manage_Role._id,Manage_Role.RoleName)" title="Assign UI"
data-target="#Div1" src="App_Themes/Images/AssignUser.png"
alt="Submit" width="28" height="28" />
</td>
<td ng-show="false">
<input type="text" ng-model="Manage_Role.DirtyFlag" ng-show="false" />
</td>
</tr>
</tbody>
</div>
</table>
</div>
<div class="panel-footer">
<div class="row">
<div class="col col-xs-8">
<dir-pagination-controls max-size="5" direction-links="true" boundary-links="true">
</dir-pagination-controls>
</div>
<div class="col col-xs-4">
<div class="btn-form" ng-show="tableform1.$visible" style="float:right">
<button type="submit" ng-disabled="tableform1.$waiting" title=" Save Changes" class="btn btn-primary fa fa-save" ng-click="NotifyClick()"> Save</button>
<input type="button" ng-disabled="tableform1.$waiting" title=" Close Edit Form Without Saving Changes" ng-click="refreshUI();tableform1.$cancel()"
class="btn btn-danger fa fa-close" value="X Cancel" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
controller code:
$scope.saveTable = function ()
{
debugger;
if(NotifyCount!=1){
var RoleNamechk = '';
for (var i = 0; i < $scope.Manage_Roleser.length; i++) {
RoleNamechk = $scope.Manage_Roleser[i].RoleName;
for (var j = 0; j < $scope.Manage_Roleser.length; j++) {
var RoleName = $scope.Manage_Roleser[j].RoleName;
if (RoleNamechk == RoleName) {
count++;
}
}
}
if (count == $scope.Manage_Roleser.length)
{
for (var i = 0; i < $scope.Manage_Roleser.length; i++) {
var id = $scope.Manage_Roleser[i]._id;
var rolename = $scope.Manage_Roleser[i].RoleName;
var isactive = $scope.Manage_Roleser[i].IsActive;
var description = $scope.Manage_Roleser[i].Description;
if (description == "")
{
description = 'empty';
}
if ($scope.Manage_Roleser[i].DirtyFlag == "True")
{
$scope.LoggedinUsers = $cookieStore.get('LoggedinUser');
var updatedBy= $scope.LoggedinUsers;
$http.put('/Roleupdate/' + id + '/' + rolename + '/' + isactive + '/' + description + '/' + updatedBy).then(function (response) {
refresh();
});
}
count=0;
}
$notify.success('Success', 'Role is Updated Successfully');
}
else {
$notify.warning('Warning', 'Role Name is Already Exists');
count = 0;
return '';
}
}
};
in ng-change I am checking dirty flag of selected index because it is updating all the row values. for that I am updating only selected($dirty) row alone. In second page it is not taking table index correctly. If I select 2nd page 3 row it will assume or taking index of the particular page. It should take index of selected row from the over all table row
$scope.applyHighlight = function ($data,index) {
$scope.Manage_Roleser[index].DirtyFlag = "True";
var dataSpan = $(event.currentTarget).closest('td');
if (!dataSpan.hasClass("highlighted")) {
$(dataSpan).addClass("highlighted");
}
}