I am new to Shiny.
When I run the following code I get the message "incorrect number of dimension".
I would like to place a checkboxgroupinput next to every rows of NameGen table, which is a result of a selectInput. Then, if one row is checked, this will go in a new table in the mainPanel.
ui.r
library(shiny)
fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("select","Type",c("C","R","V"),selected=NULL),
uiOutput("choose_row")
),
mainPanel(
tableOutput("result")
)
)
)
server.r
library(shiny)
function(input,output){
data1<-reactive({
setwd("/Users/me/Desktop/DirectoryAlR")
AlData<-read.delim2("AlR.csv",sep=";",stringsAsFactors = FALSE)
NameGen<-NULL
for(i in 1:nrow(AlData)){
if(AlData[i,7]==input$select){
NameGen[i]<-AlData[i,1]
}else{
NameGen[i]<-NA
}
}
NameGen<-NameGen[!is.na(NameGen)]
return(NameGen)
})
output$choose_row<-renderUI({
rn<-rownames(data1())
checkboxGroupInput("box","",rn,selected=NULL)
})
result<-reactive({
data2<-data1()
data2[input$box,,drop=FALSE]
})
output$result<-renderTable(result())
}
Try this .
data2[, input$box, drop = FALSE]
instead of
data2[input$box,,drop=FALSE]
I was dealing with a vector instead of a data frame, then i partially fixed in this way:
ui.r
library(shiny)
fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("select","Type",c("C","R","V"),selected=NULL),
uiOutput("choose_row")
),
mainPanel(
tableOutput("result")
)
)
)
server.r
library(shiny)
function(input,output){
data1<-reactive({
setwd("/Users/me/Desktop/DirectoryAlR")
AlData<-read.delim2("AlR.csv",sep=";",stringsAsFactors = FALSE)
NameGen<-NULL
for(i in 1:nrow(AlData)){
if(AlData[i,7]==input$select){
NameGen[i]<-AlData[i,1]
}else{
NameGen[i]<-NA
}
}
NameGen<-NameGen[!is.na(NameGen)]
return(NameGen)
})
output$choose_row<-renderUI({
checkboxGroupInput("box","",data1(),selected=NULL)
})
result<-reactive({
input$box
})
output$result<-renderTable(result())
}
Nevertheless, I still have a problem to collect checkboxgroupInput in the mainPanel because every time I change input$select it resets my data collected.
Related
I'm trying to export data in a LINQPad script and keep receiving Out of Memory exception. I feel like the script is doing all 'streamable' actions so not sure why I'm getting this.
The main loop of the code looks like the following. A few notes:
1) The first query returns around 60K rows profileDB.Profiles.Where(p => p.Group.gName == groupName).Select( d => d.pAuthID )
2) The second query for each pAuthID returns rows in a the database where one field is a Xml blob of data stored in a string field. It is not that big...< 500K for sure. Each pAuthID row could have as many as 50 rows of FolderItems. The query is profileDB.FolderItems.Where(f => f.Profile.pAuthID == p && ( folderTypes[0] == "*" || folderTypes.Contains(f.fiEntryType) ) ).OrderBy(f => f.fiEntryDate)
3) I only write a single line to the result pane when the processing starts.
4) The script runs for a long time, throwing exception when the output file is around 600-700MB. Huge I know, but it is a requirement that we dump out all the data into Xml.
5) The WriteFolderItems function/loop will be pasted below the main loop.
6) I call XmlWriter.Flush after each xDataDef element.
using (var xw = XmlWriter.Create(fileName, new XmlWriterSettings { Indent = false } ) )
{
xw.WriteStartElement( "xDataDefs" );
foreach( var p in profileDB.Profiles.Where(p => p.Group.gName == groupName).Select( d => d.pAuthID ) )
{
if ( totalRows == 0 ) // first one...
{
string.Format( "Writing results to {0}...", fileName ).Dump( "Progress" );
}
totalRows++;
var folderItems = profileDB.FolderItems.Where(f => f.Profile.pAuthID == p && ( folderTypes[0] == "*" || folderTypes.Contains(f.fiEntryType) ) ).OrderBy(f => f.fiEntryDate);
if ( folderItems.Any() )
{
xw.WriteStartElement("xDataDef");
xw.WriteAttributeString("id-auth", p);
xw.WriteStartElement("FolderItems");
WriteFolderItems(profileDB, datalockerConnectionString, xw, folderItems, documentsDirectory, calcDocumentFolder, exportFileData);
xw.WriteEndElement();
xw.WriteEndElement();
xw.Flush();
}
}
xw.WriteEndElement();
}
WriteFolderItems has looping code as well that looks like the following. A few notes:
1) I'd expect the foreach( var f in folderItems ) to be streaming
2) For some of the FolderItem rows that are Xml blobs of cached documents, I need to run ~ 1-5 queries against the database to get some additional information to stick into the Xml export: var docInfo = profileDB.Documents.Where( d => d.docfiKey == f.fiKey && d.docFilename == fileName ).FirstOrDefault();
3) I call XmlWriter.Flush after each FolderItem row.
public void WriteFolderItems( BTR.Evolution.Data.DataContexts.Legacy.xDS.DataContext profileDB, string datalockerConnectionString, XmlWriter xw, IEnumerable<BTR.Evolution.Data.DataContexts.Legacy.xDS.FolderItem> folderItems, string documentsOutputDirectory, string calcDocumentFolder, bool exportFileData )
{
foreach( var f in folderItems )
{
// The Xml blob string
var calculation = XElement.Parse( f.fiItem );
// If it contains 'cached-document' elements, need to download the actual document from DataLocker database
foreach( var document in calculation.Elements( "Data" ).Elements( "TabDef" ).Elements( "cache-documents" ).Elements( "cached-document" ) )
{
var fileName = (string)document.Attribute( "name" );
// Get author/token to be used during import
var docInfo = profileDB.Documents.Where( d => d.docfiKey == f.fiKey && d.docFilename == fileName ).FirstOrDefault();
if ( docInfo != null )
{
document.Add( new XElement( "author", docInfo.docUploadAuthID ) );
document.Add( new XElement( "token", docInfo.docDataLockerToken ) );
}
// Export associated document from DataLocker connection...XmlWriter is not affected, simply saves document to local hard drive
if ( exportFileData && DataLockerExtensions.ByConnection( datalockerConnectionString ).Exists( calcDocumentFolder, (string)document.Attribute( "name" ), null ) )
{
using ( var fs = new FileStream( Path.Combine( documentsOutputDirectory, fileName.Replace( "/", "__" ) ), FileMode.Create ) )
{
string contentType;
using ( var ds = DataLockerExtensions.ByConnection( datalockerConnectionString ).Get( calcDocumentFolder, (string)document.Attribute( "name" ), null, out contentType ) )
{
ds.CopyTo( fs );
}
}
}
}
// Write the calculation to the XwlWriter
xw.WriteStartElement( "FolderItem" );
xw.WriteElementString( "Key", f.fiKey.ToString() );
xw.WriteElementString( "EntryDate", XmlConvert.ToString( f.fiEntryDate.Value, XmlDateTimeSerializationMode.Local ) );
xw.WriteElementString( "ItemType", f.fiEntryType );
xw.WriteElementString( "Author", f.fiAuthor );
xw.WriteElementString( "Comment", f.fiComment );
xw.WriteStartElement( "Item" );
calculation.WriteTo( xw );
xw.WriteEndElement();
xw.WriteEndElement();
xw.Flush();
}
}
Make sure you disable Change Tracking, or the EF or L2S Change Tracker will retain references to each of the loaded entities.
My query as follows
$dueid = array('1','2');
for($n = 0; $n< count($post['percentage']); $n++) {
$due=invoiceduedates::whereIn('id',$dueid)
->update(array(
'percentage' => $post['percentage'][$n],
'amount'=>$post['pamount'][$n],
'date' => $post['date'][$n]
)
);
}
But in table,at 1st and 2nd ids the 2nd array data is getting updated.Please help me to sort it out.
I don't know what you what to get... but in this way it's normal that you get what you get. I can only sugest you to try like this:
$dueid = array('1','2');
$dues = invoiceduedates::whereIn('id',$dueid)->get();
for($n = 0; $n< count($post['percentage']); $n++) {
$due = $dues->find($dueid[$n+1]);
$due->update(array(
'percentage' => $post['percentage'][$n],
'amount'=>$post['pamount'][$n],
'date' => $post['date'][$n]
)
);
}
This function adds custom post 'event' data into a Salesforce db. I've tested the function outside of Wordpress and it works flawlessly. When I test it inside Wordpress by adding a new event, no error is generated and a the data is not inserted into the SF db. I've also tested this by printing out the $_POST and saw that the data is being collected. How can I get this display some errors so that I can trouble shoot this?
function add_campaign_to_SF( $post_id) {
global $SF_USERNAME;
global $SF_PASSWORD;
if ('event' == $_POST['post-type']) {
try {
$mySforceConnection = new SforceEnterpriseClient();
$mySoapClient = $mySforceConnection->createConnection(CD_PLUGIN_PATH . 'Toolkit/soapclient/enterprise.wsdl.xml');
$mySFlogin = $mySforceConnection->login($SF_USERNAME, $SF_PASSWORD);
$sObject = new stdclass();
$sObject->Name = get_the_title( $post_id );
$sObject->StartDate = date("Y-m-d", strtotime($_POST["events_startdate"]));
$sObject->EndDate = date("Y-m-d", strtotime($_POST["events_enddate"]));
$sObject->IsActive = '1';
$createResponse = $mySforceConnection->create(array($sObject), 'Campaign');
$ids = array();
foreach ($createResponse as $createResult) {
error_log($createResult);
array_push($ids, $createResult->id);
}
} catch (Exception $e) {
error_log($mySforceConnection->getLastRequest());
error_log($e->faultstring);
die;
}
}
}
add_action( 'save_post', 'add_campaign_to_SF');
I would use get_post_type() to check for "event" posts. Use error_log() to write to the PHP error log for additional debugging - check the status of your Salesforce login, etc.
Keep in mind that save_post will run every time a post is saved - created or updated - so you might want to do some additional checking (like setting a meta value) before creating a new Campaign in Salesforce, otherwise you will end up with duplicates.
function add_campaign_to_SF( $post_id ) {
$debug = true;
if ($debug) error_log("Running save_post function add_campaign_to_SF( $post_id )");
if ( 'event' == get_post_type( $post_id ) ){
if ($debug) error_log("The post type is 'event'");
if ( false === get_post_meta( $post_id, 'sfdc_id', true ) ){
if ($debug) error_log("There is no meta value for 'sfdc_id'");
// add to Salesforce, get back the ID of the new Campaign object
if ($debug) error_log("The new object ID is $sfdc_id");
update_post_meta( $post_id, 'sfdc_id', $sfdc_id );
}
}
}
add_action( 'save_post', 'add_campaign_to_SF' );
I'm having some issues trying to save an article that has 4 pictures. The thing is that i need to use the article id in order to name the pictures like article_id."-"$i
Since I have only 4 pictures per article this $i should be from 1 to 4 or from 0 to three.
Now the problem is that in order to achieve this i need to create and save Article model so i can have an id to use, but then after performing all the scripting to make the thumbs and form the names, when I go Article->saveAssociated() i have two times the article record created!! i tried to set the id to "-1" before saving but nothing...
Any suggestion will be very much appreciated !!!
Code:
public function add() {
if ($this->request->is ( 'ajax' )) {
$this->layout = 'ajax';
} else {
$this->layout = 'default';
}
if ($this->request->is ( 'post' )) {
$this->Article->create ();
$this->request->data ['Article'] ['time_stamp'] = date ( 'Y-m-d H:i:s', time () );
if ($this->Article->save($this->request->data) ) {
for ($i=0; $i<4; $i++){
$img_path = "./images/";
$extension[$i] = end(explode('.', $this->request->data['Image'][$i]['image']['name']));
$this->request->data['Image'][$i]['image'] = array('name'=>$this->Article->id."-".$i, 'tmp_name' => $this->request->data['Image'][$i]['image']['tmp_name']);
// $this->request->data['Image'][$i]['name'] = $this->Article->id."-".$i;
$this->request->data['Image'][$i]['ext']= $extension[$i];
$target_path[$i] = $img_path . basename($this->request->data['Image'][$i]['image']['name'].".".$extension[$i]);
if(!move_uploaded_file($this->request->data['Image'][$i]['image']['tmp_name'], $target_path[$i])) {
die(__ ( 'Fatal error, we are all going to die.' ));
}else{
$this->Resize->img($target_path[$i]);
$this->Resize->setNewImage($img_path.basename($this->request->data['Image'][$i]['image']['name']."t.".$extension[$i]));
$this->Resize->setProportionalFlag('H');
$this->Resize->setProportional(1);
$this->Resize->setNewSize(90, 90);
$this->Resize->make();
}
}
$this->Article->id;
pr($this->Article->id);
$this->Article->saveAssociated($this->request->data, array('deep' => true));
//$this->redirect ( array ('action' => 'view', $this->Article->id ) );
pr($this->Article->id);
exit;
$this->Session->setFlash ( __ ( 'Article "' . $this->request->data ["Article"] ["name"] . '" has been saved' ) );
} else {
$this->Session->setFlash ( __ ( 'The article could not be saved. Please, try again.' ) );
}
}
$items = $this->Article->Item->find ( 'list' );
$payments = $this->Article->Payment->find ( 'list' );
$shippings = $this->Article->Shipping->find ( 'list' );
$this->set ( compact ( 'items', 'payments', 'shippings' ) );
}
Instead of
$this->Article->saveAssociated();
which would save the Article AGAIN, just save the images separately using something like this:
foreach($this->request->data['Image'] as &$image) {
$image['name'] = 'whatever_you_want' . $this->Article->id;
$image['article_id'] = $this->Article->id;
}
$this->Article->Image->save($this->request->data['Image']);
Another option (not necessarily better - just another option) would just be to append the newly-created Article's id to the existing Article array, then saveAssociated(). If the Article has an id in it's data, it will update instead of create. I would suggest the first answer above, but - just brainstorming other options in case this helps for someone's scenario:
// 1) save the Article and get it's id
// 2) append the `id` into the Article array
// 3) do your image-name manipulation using the id
// 4) saveAssociated(), which updates the Article and creates the Images
I am trying to implement jqgrid v3.7 in my webapplication created using cakephp v1.3.
My controller code is as follows
function admin_index()
{
// get how many rows we want to have into the grid - rowNum parameter in the grid
$limit = $this->params['url']['rows'];
// get index row - i.e. user click to sort. At first time sortname parameter -
// after that the index from colModel
$sidx = $this->params['url']['sidx'];
// sorting order - at first time sortorder
$sord = $this->params['url']['sord'];
// if we not pass at first time index use the first column for the index or what you want
if( !$sidx ) $sidx = 1;
// calculate the number of rows for the query. We need this for paging the result
$row = $this->Constituency->find('count');
$count = $row;
// calculate the total pages for the query
if( $count > 0 )
{
$total_pages = ceil($count / $limit);
}
else
{
$total_pages = 0;
}
// if for some reasons the requested page is greater than the total
// set the requested page to total page
if( $page > $total_pages ) $page = $total_pages;
// calculate the starting position of the rows
$start = $limit * $page - $limit;
// if for some reasons start position is negative set it to 0
// typical case is that the user type 0 for the requested page
if( $start < 0 ) $start = 0;
// the actual query for the grid data
$limit_range = $start . "," . $limit;
$sort_range = $sidx . " " . $sord;
//$result = $this->Constituency->findAll(null, "id,name", $sort_range, $limit_range, 1, null);
$this->Constituency->recursive = -1;
$result = $this->Constituency->find('all', array(
'fields' => array('id', 'name'),
'order' => $sidx,
'limit' => $start .",". $limit_range
));
$i=0;
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
foreach($result as $result)
{
$response->rows[$i]['id'] = $result['Constituency']['id'];
$responce->rows[$i]['cell']=array($result['Constituency']['id'],$result['Constituency']['name']);
$i++;
}
echo json_encode($response);
}
the view file contains the following code
$this->Html->css('ui.jqgrid');
$this->Html->script('jquery.jqGrid.min');
<script type="text/javascript">
$(document).ready(function(){
$("#list").jqGrid(
{
url:'<?php echo $this->Html->url(array("controller" => "constituencies", "action" => "index")); ?>',
datatype: "json",
colNames:['Id','Name'],
colModel:[
{name:'id',index:'id', width:55},
{name:'name',index:'name', width:90},
],
rowNum:10,
rowList:[10,20,30],
pager: jQuery('#pager'),
sortname: 'id',
viewrecords: true,
sortorder: "desc",
caption:"Constituencies"
});
$("#list").navGrid("#pager",{edit:false,add:false,del:false});
})
</script>
<div class="constituencies index">
<h2><?php __('Constituencies'); ?></h2>
<table id="list" class="scroll"></table>
<div id="pager" class="scroll" ></div>
</div>
Now when I load the index action I get a lot of errors
Undefined index: rows
Undefined index: sidx
Undefined index: sord
etc. etc.
Has anybody included jqgrid in a cakephp based application ?
How do I include the jqgrid in my application ?
Please help me do this.
Thanks
I don't use cakephp myself, but probably two links
http://www.trirand.com/blog/?page_id=393/help/integration-of-cakephp-and-jqgrid-tutorial/
and
http://www.trirand.com/blog/?page_id=393/help/how-to-integrate-jqgrid-with-cakephp/
can be helpful for you.
The errors you're getting look like PHP errors. Try putting a debug($this->params); statement at the top of your view file to see what the controller is spitting out.
There was some incorrect values assigned in the find function for constituency model.
here is the correct complete working code:
THIS IS THE CONTROLLER CODE:
1.) Leave the function in which the grid is shown a blank like this
function index()
{
}
2.) Then create a new function for showing the grid with data like this :
function admin_showGrid()
{
$this->autoRender = false;
// get how many rows we want to have into the grid - rowNum parameter in the grid
$limit = $this->params['url']['rows'];
// get index row - i.e. user click to sort. At first time sortname parameter -
// after that the index from colModel
$sidx = $this->params['url']['sidx'];
// sorting order - at first time sortorder
$sord = $this->params['url']['sord'];
$page = $this->params['url']['page'];
// if we not pass at first time index use the first column for the index or what you want
if( !$sidx ) $sidx = 1;
// calculate the number of rows for the query. We need this for paging the result
$row = $this->{Model_Name}->find('count');
$count = $row;
// calculate the total pages for the query
if( $count > 0 )
{
$total_pages = ceil($count / $limit);
}
else
{
$total_pages = 0;
}
// if for some reasons the requested page is greater than the total
// set the requested page to total page
if( $page > $total_pages ) $page = $total_pages;
// calculate the starting position of the rows
$start = $limit * $page - $limit;
// if for some reasons start position is negative set it to 0
// typical case is that the user type 0 for the requested page
if( $start < 0 ) $start = 0;
// the actual query for the grid data
$limit_range = $start . "," . $limit;
$sort_range = $sidx . " " . $sord;
//$result = $this->{Model_Name}->findAll(null, "id,name", $sort_range, $limit_range, 1, null);
$this->{Model_Name}->recursive = -1;
$result = $this->{Model_Name}->find('all', array(
'fields' => array('id', 'name'),
'order' => $sort_range,
'limit' => $limit_range
));
$i = 0;
$response->page = $page;
$response->total = $total_pages;
$response->records = $count;
foreach($result as $result)
{
$response->rows[$i]['id'] = $result['{Model_Name}']['id'];
$response->rows[$i]['cell'] = array($result['{Model_Name}']['id'], $result['{Model_Name}']['name']);
$i++;
}
echo json_encode($response);
//writing exit() is necessary.
exit();
}
THIS IS THE VIEW CODE:
1.) include the necessary files
echo $this->Html->css('ui.jqgrid');
echo $this->Html->script('grid.locale-en');
echo $this->Html->script('jquery.jqGrid.min');
2.) add the following javascript code in your VIEW file
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#list").jqGrid(
/* '#list' is the ID of the table in which you want populated results */
{
url:'<?php echo $this->Html->url(array("controller" => "{Controller_Name}", "action" => "{Action_Name}")); ?>',
datatype: "json",
mtype: "GET",
colNames:['Id','Name'],
colModel:[
{name:'id',index:'id', width:55},
{name:'name',index:'name', width:90},
],
rowNum:10,
rowList:[10,20,30],
pager: jQuery('#pager'), /* id of the pagination element */
sortname: 'id',
viewrecords: true,
sortorder: "asc",
caption:"Enter table Heading or the name you want to show for the table",
height:"auto",
autowidth: true
});
jQuery("#list").navGrid("#pager",{edit:false,add:false,del:false});
})
</script>
3.) And finally the HTML in the same view file
<table id="list" style="height:auto;"></table>
<div id="pager"></div>
If you still face any problems with the code above let me know.