问:
c# 7 tuples not working (roslyn compiler exception)
For some time we're using some of the new c# 7.0 features in our razor files. We've integrated the Roslyn compiler into our web projects, which are currently targetting .NET Framework 4.6.2.

Today I wanted to try out the tuples in a razor file, like so:

```<code>@functions
{
    public (string labelName, string sfName) GetNames(PurchaseType purchaseType)
    {
        switch (purchaseType)
        {
            case PurchaseType.New:
                return (labelName: Booklist.New, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxNew);
            case PurchaseType.Rental:
                return (labelName: Booklist.Rent, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxRental);
            case PurchaseType.SecondHand:
                return (labelName: Booklist.Secondhand, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxSecondHand);
            default:
                throw new ArgumentOutOfRangeException(nameof(purchaseType), @"should not get here");
        }
    }
}

@helper RenderCheckbox(PurchaseType purchaseType, int index, decimal priceTo)
{
    var names = GetNames(purchaseType);
    var x = name.labelName;
    // render something
}
</code>```

This produces the following runtime exception:

CS8137: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?

CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported

This led me to https://stackoverflow.com/a/40826779/2772845 which mentions that I should add the System.ValueTuple package to the project. But I've already got that added.

These are the packages used in the config:

```<code><package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.8" targetFramework="net462" />
<package id="Microsoft.Net.Compilers" version="2.4.0" targetFramework="net462" developmentDependency="true" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="net462" />
</code>```

So, I'm back to using the old Tuple<> right now.
I'd like to know if anyone knows what I'm overlooking.

Edit 11/16/2017:

So I've altered the public (string labelName, string sfName) GetNames(PurchaseType purchaseType) into public ValueTuple<string, string> GetNames(PurchaseType purchaseType) and that gives me the following exception:

CS0433: The type 'ValueTuple' exists in both 'System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

And that led me to 'ValueTuple<T1, T2>' exists in both 'System.ValueTuple ...' and 'mscorlib ...' giving the actual answer. I've got .NET Framework 4.7 installed, and since razor is compiled at runtime it just uses that version.

Kind regards,
Rick

答:
Razor views are compiled at runtime by ASP.Net, and don't automatically inherit references or other settings from your project.

You need to add System.ValueTuple to the ASP.Net runtime compilation in Web.config:

```<code><system.web>
    <compilation>
      <assemblies>
        <add assembly="System.ValueTuple" />
</code>```

Body:
For some time we're using some of the new c# 7.0 features in our razor files. We've integrated the Roslyn compiler into our web projects, which are currently targetting .NET Framework 4.6.2.

Today I wanted to try out the tuples in a razor file, like so:

@functions
{
    public (string labelName, string sfName) GetNames(PurchaseType purchaseType)
    {
        switch (purchaseType)
        {
            case PurchaseType.New:
                return (labelName: Booklist.New, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxNew);
            case PurchaseType.Rental:
                return (labelName: Booklist.Rent, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxRental);
            case PurchaseType.SecondHand:
                return (labelName: Booklist.Secondhand, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxSecondHand);
            default:
                throw new ArgumentOutOfRangeException(nameof(purchaseType), @"should not get here");
        }
    }
}

@helper RenderCheckbox(PurchaseType purchaseType, int index, decimal priceTo)
{
    var names = GetNames(purchaseType);
    var x = name.labelName;
    // render something
}

This produces the following runtime exception:

CS8137: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?

CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported

This led me to https://stackoverflow.com/a/40826779/2772845 which mentions that I should add the System.ValueTuple package to the project. But I've already got that added.

These are the packages used in the config:

<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.8" targetFramework="net462" />
<package id="Microsoft.Net.Compilers" version="2.4.0" targetFramework="net462" developmentDependency="true" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="net462" />

So, I'm back to using the old Tuple<> right now.
I'd like to know if anyone knows what I'm overlooking.

Edit 11/16/2017:

So I've altered the public (string labelName, string sfName) GetNames(PurchaseType purchaseType) into public ValueTuple<string, string> GetNames(PurchaseType purchaseType) and that gives me the following exception:

CS0433: The type 'ValueTuple' exists in both 'System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' and 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

And that led me to 'ValueTuple<T1, T2>' exists in both 'System.ValueTuple ...' and 'mscorlib ...' giving the actual answer. I've got .NET Framework 4.7 installed, and since razor is compiled at runtime it just uses that version.

Kind regards,
Rick

Body:
Razor views are compiled at runtime by ASP.Net, and don't automatically inherit references or other settings from your project.

You need to add System.ValueTuple to the ASP.Net runtime compilation in Web.config:

<system.web>
    <compilation>
      <assemblies>
        <add assembly="System.ValueTuple" />


来源: stackexchange

问:
Can I use BeginInvoke with a MulticastDelegate?
I want to raise a series of events from my library class, but I'm worried that some event subscribers will be rude and take a long time to process some events, thus blocking the thread that is raising the events. I thought I could protect the raising thread by using a thread pool thread to raise each event:

```<code>if (packet != null && DataPacketReceived != null)
{
    var args = new DataPacketEventArgs(packet);
    DataPacketReceived.BeginInvoke(this, args, null, null);
}
</code>```

That works fine when there's only one subscriber to the event, but as soon as a second subscriber arrives, DataPacketReceived becomes a multicast delegate, and I get an argument exception with the error message, "The delegate must have only one target." Is there an easy way to raise the event on a separate thread, or do I have to start a thread and then raise the event from there?

答:
I found a similar question on another site, and of course Jon Skeet had answered it. For my scenario, I chose to raise the event for each subscriber on a separate thread:</p>

```<code>if (packet != null && DataPacketReceived != null)
{
    var args = new DataPacketEventArgs(packet);
    var receivers = DataPacketReceived.GetInvocationList();
    foreach (EventHandler<DataPacketEventArgs> receiver in receivers)
    {
        receiver.BeginInvoke(this, args, null, null);
    }
}
</code>```

ContentLicense: CC BY-SA 2.5

Body:
I want to raise a series of events from my library class, but I'm worried that some event subscribers will be rude and take a long time to process some events, thus blocking the thread that is raising the events. I thought I could protect the raising thread by using a thread pool thread to raise each event:

if (packet != null && DataPacketReceived != null)
{
    var args = new DataPacketEventArgs(packet);
    DataPacketReceived.BeginInvoke(this, args, null, null);
}

That works fine when there's only one subscriber to the event, but as soon as a second subscriber arrives, DataPacketReceived becomes a multicast delegate, and I get an argument exception with the error message, "The delegate must have only one target." Is there an easy way to raise the event on a separate thread, or do I have to start a thread and then raise the event from there?

Body:
I found a similar question on another site, and of course Jon Skeet had answered it. For my scenario, I chose to raise the event for each subscriber on a separate thread:

if (packet != null && DataPacketReceived != null)
{
    var args = new DataPacketEventArgs(packet);
    var receivers = DataPacketReceived.GetInvocationList();
    foreach (EventHandler<DataPacketEventArgs> receiver in receivers)
    {
        receiver.BeginInvoke(this, args, null, null);
    }
}


问:
Time Date Objects JavaScript getUTCMilliseconds
From the Chrome console:

```<code>Me:    var dateObj = new Date("2013-04-14 11:48");
undefined
Me:    dateObj
Sun Apr 14 2013 11:48:00 GMT+0200 (Central Europe Daylight Time)
Me:    dateObj.getUTCMilliseconds();
0
</code>```

Can anyone tell me why these Date functions aren't working? I want to take a date string and turn it into UTC milliseconds. As you can see I passed the string to the Date constructor, then applied the function getUTCMilliseconds() to the returned date object. Why is it returning zero??

答:
The result is correct - the understanding of the function name is wrong (as was mine).

Date.getUTCMilliseconds() is defined to return the millisecond part of the date in the same way that getMinutes() returns the minutes stored in the object (in your example, that would return 48 minutes).

To clarify, with respect to your date [2013-04-14 11:48] the various parts are:

getFullYear() === 2013

getDate() === 14

getSeconds() === 0 (because your date string defines a whole number of minutes)

getMilliseconds() === 0 (for the same reason)

A counter-example may be [2017-11-15 16:53:10.78]:

getSeconds() === 10

getMilliseconds() === 78

The functions on Date are laid out nicely on the W3Schools page here.

I looks like you were after the Unix timestamp value (which is what I wanted when Google brought me here).

Date.getTime() will return the number of milliseconds since 1970/01/01

Luckily this is the underlying value in the current implementations, which is why the other answer works so nicely.

ContentLicense: CC BY-SA 3.0

Body:
From the Chrome console:

Me:    var dateObj = new Date("2013-04-14 11:48");
undefined
Me:    dateObj
Sun Apr 14 2013 11:48:00 GMT+0200 (Central Europe Daylight Time)
Me:    dateObj.getUTCMilliseconds();
0

Can anyone tell me why these Date functions aren't working? I want to take a date string and turn it into UTC milliseconds. As you can see I passed the string to the Date constructor, then applied the function getUTCMilliseconds() to the returned date object. Why is it returning zero??


问:
How to distribute horizontally a bubble chart in d3js v4
I am creating a bubble chart using d3js v4. I have a 1000px width and 500px height svg and I want the bubbles to be distributed horizontally while grouped by category. To keep them grouped, I am using stratify. When I use pack layout, it makes the circles spread around in a circle pattern, so it gets limited by the height.

How can I distribute the bubbles more horizontally?

This is my code:

```<code>        let svg = d3.select('svg#circle'),
            width = 1000,
            height = +svg.attr('height');
        svg.attr('width', width);

        let stratify = d3.stratify()
            .id((d: any) => d.name)
            .parentId(function(d: any) { return d.categoryId; });

        let pack = d3.pack()
            .size([width, height])
            .padding(20);

        let root = stratify(this.subcategoryData)
            .sum(function(d: any) { return d.total; })
            .sort(function(a: any, b: any) { return b.total - a.total; });

        let node = svg.selectAll('.node')
                .data(pack(root).leaves())
                .enter().append('g')
                .attr('class', 'node')
                .style('text-anchor', 'middle')
                .attr('transform', function(d: any) { return 'translate(' + d.x + ',' + d.y + ')'; });

            let div = d3.select('body').append('div')
                .attr('class', 'tooltip')
                .style('opacity', 0);

            node.append('circle')
                .attr('id', function(d: any) { return d.id; })
                .attr('r', function(d: any) { return d.r; })
                .attr('class', (d: any) => `circle-${d.data.categoryId}`);
</code>```

答:
Did you try to increase the X translation like so :

```<code>.attr('transform', function(d: any) { return 'translate(' + d.x * 1.5 + ',' + d.y + ')'; });
</code>```

multiplying that d.x should spread the circles. Maybe if it doesn't work with 1.5 try something more.

Hope I helped.

Body:
I am creating a bubble chart using d3js v4. I have a 1000px width and 500px height svg and I want the bubbles to be distributed horizontally while grouped by category. To keep them grouped, I am using stratify. When I use pack layout, it makes the circles spread around in a circle pattern, so it gets limited by the height.

How can I distribute the bubbles more horizontally?

This is my code:

        let svg = d3.select('svg#circle'),
            width = 1000,
            height = +svg.attr('height');
        svg.attr('width', width);

        let stratify = d3.stratify()
            .id((d: any) => d.name)
            .parentId(function(d: any) { return d.categoryId; });

        let pack = d3.pack()
            .size([width, height])
            .padding(20);

        let root = stratify(this.subcategoryData)
            .sum(function(d: any) { return d.total; })
            .sort(function(a: any, b: any) { return b.total - a.total; });

        let node = svg.selectAll('.node')
                .data(pack(root).leaves())
                .enter().append('g')
                .attr('class', 'node')
                .style('text-anchor', 'middle')
                .attr('transform', function(d: any) { return 'translate(' + d.x + ',' + d.y + ')'; });

            let div = d3.select('body').append('div')
                .attr('class', 'tooltip')
                .style('opacity', 0);

            node.append('circle')
                .attr('id', function(d: any) { return d.id; })
                .attr('r', function(d: any) { return d.r; })
                .attr('class', (d: any) => `circle-${d.data.categoryId}`);

Body:
Did you try to increase the X translation like so :

.attr('transform', function(d: any) { return 'translate(' + d.x * 1.5 + ',' + d.y + ')'; });

multiplying that d.x should spread the circles. Maybe if it doesn't work with 1.5 try something more.

Hope I helped.


问:
Use variable value from .gs file in custom HTML sidebar
I have a google sheet where I have scripted a custom sidebar.

Within the sidebar, I want to display the value of column I within the active row.

I've managed to work out the script to store the variable 'I' when the sidebar is opened:

```<code>var hotelName = ""

function openSidebar() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi().showSidebar(html);
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getSheetByName("Contract Registry Document");
var row=s.getActiveCell().getRow();
var column=9;
hotelName = s.getRange(row, column).getValue();
Logger.log(hotelName);
}
</code>```

However I now need this to appear in an empty DIV element in my sidebar. How do I export this variable?

UPDATE:

That works great. I've now added as well a button to the sidebar to refresh and what I want that to do is to update the script so that if the user has changed rows, the new hotel name will show. At the moment I've added this HTML:

```<code> <div id="footer">

 <div><?= hotel ?></div>

 <p><i class="fa fa-refresh" aria-hidden="true" id="testing"></i></p>

 </div>
</code>```

And this JQuery to the index file:

```<code>$("#testing").on('click', function buttonClick() {
google.script.run.buttonClick();
});
</code>```

And for the function I just copied the original function:

```<code>function buttonClick() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getSheetByName("Contract Registry Document");
var row=s.getActiveCell().getRow();
var column=9;
var hotelName = s.getRange(row, column).getValue();

// get the html template after retrieving the values
var html_template = HtmlService.createTemplateFromFile('index');

// set the value for the index.html `hotel` placeholder/scriptlet
html_template.hotel = hotelName;

// evaluate the template
var sidebar_html = html_template.evaluate();

SpreadsheetApp.getUi().showSidebar(sidebar_html);

Logger.log(hotelName);
}
</code>```

However, really I want the value of the cell to update asynchronously so that the sidebar doesn't re-load, just the hotel name...

Would this be possible??

答:
Getting data from a spreadsheet on loading a sidebar

Don't forget to select the row first before displaying the sidebar.

code.gs

```<code>function openThisSideBar()
{
  var html = HtmlService.createHtmlOutputFromFile('hotel').setTitle('MySideBar');
  SpreadsheetApp.getUi().showSidebar(html);
}

function getHotel()
{
  var s=SpreadsheetApp.getActive().getSheetByName("Contract Registry Document");
  var row=s.getActiveCell().getRow();
  var n=Utilities.formatString('Your Hotel is named: %s',s.getRange(row, 9).getValue());
  return n;
}

function onOpen()
{
  SpreadsheetApp.getUi().createMenu('MyTools')
    .addItem('Open Sidebar', 'openThisSideBar')
    .addToUi();
}
</code>```

hotel.html:

```<code><!DOCTYPE html>
<html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
    $(function()
    {
       google.script.run
           .withSuccessHandler(updateHotel)
           .getHotel();
    });
    function updateHotel(name)
    {
       document.getElementById('hotel').innerHTML=name;
    }
    console.log('MyCode');
    </script>
  </head>
  <body>
   <div id="hotel"></div>
  </body>
</html>
</code>```

You can add your refresh like this:

```<code><script>
function refresh()
    {
       google.script.run
          .withSuccessHandler(updateHotel)
          .getHotel();
    }
</script>
</code>```

And the new html:

```<code><input type="button" value="Refresh" onClick="refresh();" />
</code>```

That way you needn't refresh the entire page but just the div.

Body:
I have a google sheet where I have scripted a custom sidebar.

Within the sidebar, I want to display the value of column I within the active row.

I've managed to work out the script to store the variable 'I' when the sidebar is opened:

var hotelName = ""

function openSidebar() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi().showSidebar(html);
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getSheetByName("Contract Registry Document");
var row=s.getActiveCell().getRow();
var column=9;
hotelName = s.getRange(row, column).getValue();
Logger.log(hotelName);
}

However I now need this to appear in an empty DIV element in my sidebar. How do I export this variable?

UPDATE:

That works great. I've now added as well a button to the sidebar to refresh and what I want that to do is to update the script so that if the user has changed rows, the new hotel name will show. At the moment I've added this HTML:

<?= hotel ?>

And this JQuery to the index file:

$("#testing").on('click', function buttonClick() {
google.script.run.buttonClick();
});

And for the function I just copied the original function:

function buttonClick() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getSheetByName("Contract Registry Document");
var row=s.getActiveCell().getRow();
var column=9;
var hotelName = s.getRange(row, column).getValue();

// get the html template after retrieving the values
var html_template = HtmlService.createTemplateFromFile('index');

// set the value for the index.html `hotel` placeholder/scriptlet
html_template.hotel = hotelName;

// evaluate the template
var sidebar_html = html_template.evaluate();

SpreadsheetApp.getUi().showSidebar(sidebar_html);

Logger.log(hotelName);
}

However, really I want the value of the cell to update asynchronously so that the sidebar doesn't re-load, just the hotel name...

Would this be possible??

Body:
Getting data from a spreadsheet on loading a sidebar

Don't forget to select the row first before displaying the sidebar.

code.gs

function openThisSideBar()
{
  var html = HtmlService.createHtmlOutputFromFile('hotel').setTitle('MySideBar');
  SpreadsheetApp.getUi().showSidebar(html);
}

function getHotel()
{
  var s=SpreadsheetApp.getActive().getSheetByName("Contract Registry Document");
  var row=s.getActiveCell().getRow();
  var n=Utilities.formatString('Your Hotel is named: %s',s.getRange(row, 9).getValue());
  return n;
}

function onOpen()
{
  SpreadsheetApp.getUi().createMenu('MyTools')
    .addItem('Open Sidebar', 'openThisSideBar')
    .addToUi();
}

hotel.html:

<!DOCTYPE html>
<html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
    $(function()
    {
       google.script.run
           .withSuccessHandler(updateHotel)
           .getHotel();
    });
    function updateHotel(name)
    {
       document.getElementById('hotel').innerHTML=name;
    }
    console.log('MyCode');
    </script>
  </head>
  <body>
   <div id="hotel"></div>
  </body>
</html>

You can add your refresh like this:

<script>
function refresh()
    {
       google.script.run
          .withSuccessHandler(updateHotel)
          .getHotel();
    }
</script>

And the new html:

<input type="button" value="Refresh" onClick="refresh();" />

That way you needn't refresh the entire page but just the div.


问:
Load a directive function in js file to another controller js file
I have a main js file which has watch in the controller -

(function () {
    'use strict';

    angular
        .module('mainmodule')
        .controller('file1Ctrl', file1Ctrl);

    file1Ctrl.$inject = ['$scope','data'];
    function VendorDetailCtrl($scope,data){
    var vd = this;
    vd.data.id = data.id;
    activate();

    function activate() {
      $scope.$watch("vd.data.id", function (newValue, oldValue) {

                        if (newValue !== oldValue) {
                            callmainfunction();
                        }

                    });
    }
    })();
    ```
</div>
</div>
</p>

<p>And then I have another directive in another js file -</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>(function () {
    'use strict';

    angular
        .module('mainmodule')
        .directive('file2', file2)

    function file2() {
        var directive = {
            restrict: 'E',
            templateUrl: 'file2.html',
            scope: {
                data: '=',
            },

            controller: ['$scope',file2Ctrl],
            controllerAs: 'vm',
            bindToController: true
        }

        return directive;
        function file2Ctrl($scope, file2Ctrl) {
            var vm = this;
            activate();

            function activate(){
            neededfunc();
            }

            function neededfunc(){
            //do something
            }
      })();</code>```

I need to call the neededfunc() in the watch in first js file. I even tried adding watch in the directive but it only triggers on page reload and I need it to run after a button click Submit(). The watch is triggered when I click the button Submit(). So I needed to know how can I use the function in the watch or is there any other way I can call the function when the id value is changed.

答:
Adding function to $scope.$root helped. Following is the code -

// Declare the function

$scope.$root.neededFunction = function(){
//Do Something here
}

//Call the function

$scope.$root.neededFunction();```

Body:
I have a main js file which has watch in the controller -

(function () {
    'use strict';

    angular
        .module('mainmodule')
        .controller('file1Ctrl', file1Ctrl);

    file1Ctrl.$inject = ['$scope','data'];
    function VendorDetailCtrl($scope,data){
    var vd = this;
    vd.data.id = data.id;
    activate();

    function activate() {
      $scope.$watch("vd.data.id", function (newValue, oldValue) {

                        if (newValue !== oldValue) {
                            callmainfunction();
                        }

                    });
    }
    })();

And then I have another directive in another js file -

(function () {
    'use strict';

    angular
        .module('mainmodule')
        .directive('file2', file2)

    function file2() {
        var directive = {
            restrict: 'E',
            templateUrl: 'file2.html',
            scope: {
                data: '=',
            },

            controller: ['$scope',file2Ctrl],
            controllerAs: 'vm',
            bindToController: true
        }

        return directive;
        function file2Ctrl($scope, file2Ctrl) {
            var vm = this;
            activate();

            function activate(){
            neededfunc();
            }

            function neededfunc(){
            //do something
            }
      })();

I need to call the neededfunc() in the watch in first js file. I even tried adding watch in the directive but it only triggers on page reload and I need it to run after a button click Submit(). The watch is triggered when I click the button Submit(). So I needed to know how can I use the function in the watch or is there any other way I can call the function when the id value is changed.


问:
select 2 not working for ajax response
i have following JS code where i am tring to reload my modal, when my area reloads i cannot see the select2 related contents, tho they are in the DOM when i inspect them. I am using Select2 version 4.0.2

```<code>$("#add_meal_item").on('click', '#save_meal_item', function () {
                var meal_name = $("#add_meal_item_form").find('#meal_name').val();
                var meal_type = $("#add_meal_item_form").find('#meal_type').val();
                var logoImg = $("#add_meal_item_form").find('#meal_image').get(0).files[0];
                var formData = new FormData();
                formData.append('meal_image', logoImg);
                formData.append('meal_type', meal_type);
                formData.append('meal_name', meal_name);
                formData.append('_token', "{{ csrf_token() }}");
                console.log(formData);
                var ajax_url = baseurl + '/save_meal_item';
                $.ajax({
                    type: "POST",
                    url: ajax_url,
                    data: formData,
                    contentType: false,
                    processData: false,
                    cache: false,
                    success: function (response) {
                        $("#add_meal_item").modal('hide');
                        $("#form_meal_body").html(response);
                        ShowSvgImage();

                    }
                });
            });
</code>```

and following is my HTML generated after ajax response

```<code><div class="modal fade in" id="add-modal-rota-user" style="display: block;">
        <div class="modal-dialog routaPop" role="document">

            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span>
                    </button>
                    <h4 class="modal-title">Add Meal</h4>
                </div>
                <div class="modal-body inBodyForm" id="form_meal_body"><form action="" method="post" inbodyform="" form-horizontal="" id="add_assigin_meal">
    <div class="row">
        <div class="col-md-4">
            <div class="form-group">
                <label>Select Main Meal: *</label>
                <input type="hidden" name="meal_item_id" value="">
                <input type="hidden" name="meal_id" id="meal_id" value="">
                <div class="select">
                    <select id="main_meal" class="select2 select2-hidden-accessible" name="meal_item[]" multiple="">
                        <option value="">Select Meal</option>

                            <option value="1">boiled egg</option>

                            <option value="2">bread</option>

                            <option value="13">AAA</option>

                            <option value="14">123</option>

                            <option value="15">test123</option>

                            <option value="16">2231111</option>

                            <option value="17">ggggg</option>

                            <option value="18">kkkkkkkkkk</option>

                            <option value="19">test meal</option>

                            <option value="20">hello world</option>

                            <option value="21">ASDASDASD33333</option>
                                                <option value="other">Other</option>
                    </select>
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 129 129" enable-background="new 0 0 129 129" width="512px" height="512px" class="svg replaced-svg">
  <g>
    <path d="m88.6,121.3c0.8,0.8 1.8,1.2 2.9,1.2s2.1-0.4 2.9-1.2c1.6-1.6 1.6-4.2 0-5.8l-51-51 51-51c1.6-1.6 1.6-4.2 0-5.8s-4.2-1.6-5.8,0l-54,53.9c-1.6,1.6-1.6,4.2 0,5.8l54,53.9z" fill="#999999"></path>
  </g>
</svg>
                </div>

            </div>
        </div>
        <div class="col-md-4">
            <div class="form-group">
                <label>Select Drinks: *</label>
                <input type="hidden" name="meal_item_id" value="">
                <input type="hidden" name="meal_id" id="meal_id" value="">
                <div class="select">
                    <select id="drinks" class="select2 select2-hidden-accessible" name="meal_item[]" multiple="">
                        <option value="">Select Meal</option>

                            <option value="3">tea</option>

                            <option value="5">ASDASDASD</option>
                                                <option value="other">Other</option>
                    </select>
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 129 129" enable-background="new 0 0 129 129" width="512px" height="512px" class="svg replaced-svg">
  <g>
    <path d="m88.6,121.3c0.8,0.8 1.8,1.2 2.9,1.2s2.1-0.4 2.9-1.2c1.6-1.6 1.6-4.2 0-5.8l-51-51 51-51c1.6-1.6 1.6-4.2 0-5.8s-4.2-1.6-5.8,0l-54,53.9c-1.6,1.6-1.6,4.2 0,5.8l54,53.9z" fill="#999999"></path>
  </g>
</svg>
                </div>

            </div>
        </div>
        <div class="col-md-4">
            <div class="form-group">
                <label>Select Deserts: *</label>
                <input type="hidden" name="meal_item_id" value="">
                <input type="hidden" name="meal_id" id="meal_id" value="">
                <div class="select">
                    <select id="desserts" class="select2 select2-hidden-accessible" name="meal_item[]" multiple="">
                        <option value="">Select Meal</option>

                            <option value="4">cake</option>
                                                <option value="other">Other</option>
                    </select>
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 129 129" enable-background="new 0 0 129 129" width="512px" height="512px" class="svg replaced-svg">
  <g>
    <path d="m88.6,121.3c0.8,0.8 1.8,1.2 2.9,1.2s2.1-0.4 2.9-1.2c1.6-1.6 1.6-4.2 0-5.8l-51-51 51-51c1.6-1.6 1.6-4.2 0-5.8s-4.2-1.6-5.8,0l-54,53.9c-1.6,1.6-1.6,4.2 0,5.8l54,53.9z" fill="#999999"></path>
  </g>
</svg>
                </div>

            </div>
        </div>
        <div id="new_food_item_section" hidden="hidden">
            <div class="col-md-4">
                <div class="form-group">
                    <label>Add New Meal Item: *</label>
                    <div class="">
                        <input type="text" name="meal_name" id="meal_name">
                    </div>
                </div>
            </div>
            <div class="col-md-12">
                <div class="form-group">
                    <div class="form-group">
                        <label>Upload Meal Item Image: *</label>
                        <div class="file">
                            Upload
                            <input type="file" name="meal_image" id="meal_image" class="hidden">
                        </div>
                    </div>
                </div>
            </div>
        </div>

    </div>
    <input type="hidden" name="_token" value="iEfVgn5kv4ifAQmNrwOHA117nFqCHLyCIJVihmf4">
    <div class="hidden_form hidden"></div>
</form>
</div>
                <div class="modal-footer">
                    <button class="btn btn-default" href="" type="button" id="cancel_modal">Cancel
                    </button>
                    <button type="button" id="saveform" class="btn btn-primary">Save</button>
                </div>
            </div>
        </div>
    </div>
</code>```

答:
I hope this help some 1 else, since i was not using the Select2's own ajax, and most answers out there were referring to it. The easiest possible answer to this is to re initialize the select 2 and it saved me alot of pain, may be its not the optimal solution, but it's working for me.

This is the success method which i have changed from what i mentioned above.

```<code>   success: function (response) {
                        $("#add_meal_item").modal('hide');
                        $("#form_meal_body").html(response);
                        $(".select2").select2();
                        $(".select2_multi").select2({closeOnSelect: false});

                        ShowSvgImage();

                    }
</code>```

Title: select 2 not working for ajax response

Body:
i have following JS code where i am tring to reload my modal, when my area reloads i cannot see the select2 related contents, tho they are in the DOM when i inspect them. I am using Select2 version 4.0.2

$("#add_meal_item").on('click', '#save_meal_item', function () {
                var meal_name = $("#add_meal_item_form").find('#meal_name').val();
                var meal_type = $("#add_meal_item_form").find('#meal_type').val();
                var logoImg = $("#add_meal_item_form").find('#meal_image').get(0).files[0];
                var formData = new FormData();
                formData.append('meal_image', logoImg);
                formData.append('meal_type', meal_type);
                formData.append('meal_name', meal_name);
                formData.append('_token', "{{ csrf_token() }}");
                console.log(formData);
                var ajax_url = baseurl + '/save_meal_item';
                $.ajax({
                    type: "POST",
                    url: ajax_url,
                    data: formData,
                    contentType: false,
                    processData: false,
                    cache: false,
                    success: function (response) {
                        $("#add_meal_item").modal('hide');
                        $("#form_meal_body").html(response);
                        ShowSvgImage();

                    }
                });
            });

and following is my HTML generated after ajax response

                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">×
                    </button>

Add Meal

<form action="" method="post" inbodyform="" form-horizontal="" id="add_assigin_meal">

                Select Main Meal: *
                <input type="hidden" name="meal_item_id" value="">
                <input type="hidden" name="meal_id" id="meal_id" value="">

                    <select id="main_meal" class="select2 select2-hidden-accessible" name="meal_item[]" multiple="">
                        <option value="">Select Meal</option>

                            <option value="1">boiled egg</option>

                            <option value="2">bread</option>

                            <option value="13">AAA</option>

                            <option value="14">123</option>

                            <option value="15">test123</option>

                            <option value="16">2231111</option>

                            <option value="17">ggggg</option>

                            <option value="18">kkkkkkkkkk</option>

                            <option value="19">test meal</option>

                            <option value="20">hello world</option>

                            <option value="21">ASDASDASD33333</option>
                                                <option value="other">Other</option>
                    </select>
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 129 129" enable-background="new 0 0 129 129" width="512px" height="512px" class="svg replaced-svg">
  <g>
    <path d="m88.6,121.3c0.8,0.8 1.8,1.2 2.9,1.2s2.1-0.4 2.9-1.2c1.6-1.6 1.6-4.2 0-5.8l-51-51 51-51c1.6-1.6 1.6-4.2 0-5.8s-4.2-1.6-5.8,0l-54,53.9c-1.6,1.6-1.6,4.2 0,5.8l54,53.9z" fill="#999999"></path>
  </g>
</svg>

                Select Drinks: *
                <input type="hidden" name="meal_item_id" value="">
                <input type="hidden" name="meal_id" id="meal_id" value="">

                    <select id="drinks" class="select2 select2-hidden-accessible" name="meal_item[]" multiple="">
                        <option value="">Select Meal</option>

                            <option value="3">tea</option>

                            <option value="5">ASDASDASD</option>
                                                <option value="other">Other</option>
                    </select>
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 129 129" enable-background="new 0 0 129 129" width="512px" height="512px" class="svg replaced-svg">
  <g>
    <path d="m88.6,121.3c0.8,0.8 1.8,1.2 2.9,1.2s2.1-0.4 2.9-1.2c1.6-1.6 1.6-4.2 0-5.8l-51-51 51-51c1.6-1.6 1.6-4.2 0-5.8s-4.2-1.6-5.8,0l-54,53.9c-1.6,1.6-1.6,4.2 0,5.8l54,53.9z" fill="#999999"></path>
  </g>
</svg>

                Select Deserts: *
                <input type="hidden" name="meal_item_id" value="">
                <input type="hidden" name="meal_id" id="meal_id" value="">

                    <select id="desserts" class="select2 select2-hidden-accessible" name="meal_item[]" multiple="">
                        <option value="">Select Meal</option>

                            <option value="4">cake</option>
                                                <option value="other">Other</option>
                    </select>
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 129 129" enable-background="new 0 0 129 129" width="512px" height="512px" class="svg replaced-svg">
  <g>
    <path d="m88.6,121.3c0.8,0.8 1.8,1.2 2.9,1.2s2.1-0.4 2.9-1.2c1.6-1.6 1.6-4.2 0-5.8l-51-51 51-51c1.6-1.6 1.6-4.2 0-5.8s-4.2-1.6-5.8,0l-54,53.9c-1.6,1.6-1.6,4.2 0,5.8l54,53.9z" fill="#999999"></path>
  </g>
</svg>

                    Add New Meal Item: *

                        <input type="text" name="meal_name" id="meal_name">

                        Upload Meal Item Image: *

                            Upload
                            <input type="file" name="meal_image" id="meal_image" class="hidden">

    <input type="hidden" name="_token" value="iEfVgn5kv4ifAQmNrwOHA117nFqCHLyCIJVihmf4">

</form>

                    <button class="btn btn-default" href="" type="button" id="cancel_modal">Cancel
                    </button>
                    <button type="button" id="saveform" class="btn btn-primary">Save</button>

Body:
I hope this help some 1 else, since i was not using the Select2's own ajax, and most answers out there were referring to it. The easiest possible answer to this is to re initialize the select 2 and it saved me alot of pain, may be its not the optimal solution, but it's working for me.

This is the success method which i have changed from what i mentioned above.

   success: function (response) {
                        $("#add_meal_item").modal('hide');
                        $("#form_meal_body").html(response);
                        $(".select2").select2();
                        $(".select2_multi").select2({closeOnSelect: false});

                        ShowSvgImage();

                    }


问:
I have a trouble with lowagie pdf and Report Making. I cant include headerfooter on the first page
 This is an image of the problem I am working with the lowagie PDF library in a Java Spring development. I need to make a report on a landscape orientation. I have also added a headerfooter. The report has 5 pages. I have included a table. Everything seems to work fine on pages 2,3,4 and 5. But in page 1 I can not make it happen. The headerfooter and the paragraphs I added dont appear. Im terribly tired. I do not know what else to do. Does someone faced the same situation before? i would really appreciate some help.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

```<code>package com.gambbate.faqu.viewresolver;

import com.gambbate.faqu.model.Usuario;
import com.itextpdf.text.BaseColor;

import com.lowagie.text.Chunk;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.PageSize;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import java.awt.Color;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javafx.scene.layout.Border;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.view.document.AbstractPdfView;

/**
 *
 * @author Pisner-Lichtenstein
 */
public class PdfView extends AbstractPdfView {

    @Override
    protected void buildPdfDocument(Map<String, Object> map,
            Document dcmnt,
            PdfWriter writer,
            HttpServletRequest hsr,
            HttpServletResponse hsr1) throws Exception {

        List<Usuario> listadoDeUsuarios = (List<Usuario>) map.get("listadoDeUsuarios");

        PdfPTable tabla = new PdfPTable(8);
        tabla.setWidthPercentage(100);

        tabla.setWidths(new float[]{2.0f, 2.0f, 2.0f, 4.0f, 2.0f, 1.5f, 2.0f, 2.0f});

        PdfPCell encabezadoCelda = new PdfPCell();
        encabezadoCelda.setBackgroundColor(Color.WHITE);
        encabezadoCelda.setHorizontalAlignment(Element.ALIGN_CENTER);
        encabezadoCelda.setPadding(5);

        encabezadoCelda.setBorderColor(Color.LIGHT_GRAY);
        encabezadoCelda.setBorderWidth(0.15f);

        Font fuente = FontFactory.getFont(FontFactory.HELVETICA_BOLD);
        fuente.setSize(10);
        fuente.setColor(Color.BLACK);
        encabezadoCelda.setFixedHeight(30);
        encabezadoCelda.setPadding(5);
        encabezadoCelda.setVerticalAlignment(Element.ALIGN_MIDDLE);

        encabezadoCelda.setPhrase(new Phrase("Nombre", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Apellido", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Fecha de Nac.", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Email", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Celular", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Interno", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Gerencia", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Puesto", fuente));
        tabla.addCell(encabezadoCelda);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

        int colorDeFondo = 0;

        for (Usuario listadoDeUsuario : listadoDeUsuarios) {

            PdfPCell cd = new PdfPCell();

            cd.setBorderColor(Color.LIGHT_GRAY);
            cd.setBorderWidth(0.15f);

            fuente = FontFactory.getFont(FontFactory.HELVETICA);
            fuente.setColor(Color.DARK_GRAY);
            fuente.setSize(10);
            cd.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cd.setPadding(5);
            cd.setFixedHeight(30);

            if (colorDeFondo % 2 == 0) {
                cd.setBackgroundColor(Color.WHITE);
            } else {
                cd.setBackgroundColor(new Color(245, 245, 245));
            }

            colorDeFondo++;

            cd.setPhrase(new Phrase(listadoDeUsuario.getNombre(), fuente));
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getApellido(), fuente));
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(sdf.format(listadoDeUsuario.getFechaDeNacimiento()), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_RIGHT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getEmailCorporativo(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_LEFT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getCelular(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_RIGHT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getInterno(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_RIGHT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getGerencia().getGerencia(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_LEFT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getPuesto().getPuesto(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_LEFT);
            tabla.addCell(cd);

        }

        tabla.setSpacingBefore(25);
        tabla.setHeaderRows(1);

        Paragraph encabezado = new Paragraph(new Chunk("Gambbate - Faqu Soft", FontFactory.getFont(FontFactory.HELVETICA, 15)));
        Paragraph reporteTitulo = new Paragraph(new Chunk("Recursos Humanos - Listado de Uuarios", FontFactory.getFont(FontFactory.HELVETICA, 15)));
        Paragraph autor = new Paragraph(new Chunk("Emitido por:" + map.get("nombreDeUsuario"), FontFactory.getFont(FontFactory.HELVETICA, 15)));
        Paragraph fecha = new Paragraph(new Chunk("Fecha de Emision:" + new Date(), FontFactory.getFont(FontFactory.HELVETICA, 15)));

        HeaderFooter header = new HeaderFooter(new Phrase("fewfwfewwwe"), false);
        HeaderFooter footer = new HeaderFooter(new Phrase("aaaaaaaaaaaa"), false);

        dcmnt.setHeader(header);
        dcmnt.setFooter(footer);

        dcmnt.setPageSize(PageSize.A4.rotate());
        dcmnt.setMargins(60, 30, 30, 30);

        dcmnt.add(encabezado);
        dcmnt.add(reporteTitulo);
        dcmnt.add(tabla);

    }

}
</code>```

答:
As already mentioned in the comments to the question, if a page setting already is required at the creation time of a page (like its dimension and orientation), and if you want to change it already for the first page, you need to set the property before opening the Document because the first page is created during that opening routine.

In the case at hand the PageSize and the Margins are of interest. To change them already for the first page, you can do it like this:

```<code>Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("landscape.pdf"));
document.setPageSize(PageSize.A4.rotate());
document.setMargins(60, 30, 30, 30);
document.open();
document.add(new Paragraph("Test string for a landscape PDF."));
document.close();
</code>```

The result is:

As you see

the first page already is in landscape and

the first page uses the predefined margins, in particular the left margin is twice as large as the top margin which it is not by default.

Thus, all you have to do is search the calling code of your buildPdfDocument method, find the Document and PdfWriter instantiation in there (similar to

```<code>Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("landscape.pdf"));
</code>```

), and set the PageSize and the Margins (like

```<code>document.setPageSize(PageSize.A4.rotate());
document.setMargins(60, 30, 30, 30);
</code>```

) before the Document method open is called (like

```<code>document.open();
</code>```

).

In your case that code is in the method renderMergedOutputModel of the AbstractPdfView class from which your class is derived:

```<code>[...]
Document document = getDocument();
PdfWriter writer = newWriter(document, baos);

// Apply preferences and build metadata.
prepareWriter(model, writer, request);
buildPdfMetadata(model, document, request);

// Build PDF document.
document.open();
[...]
</code>```

But you do not have to patch this base class; as you see certain methods are called right before document.open(), in particular buildPdfMetadata which is documented as:

```<code>/**
 * Populate the iText Document's meta fields (author, title, etc.).
 * <br>Default is an empty implementation. Subclasses may override this method
 * to add meta fields such as title, subject, author, creator, keywords, etc.
 * This method is called after assigning a PdfWriter to the Document and
 * before calling <code>document.open()</code>.
 * @param model the model, in case meta information must be populated from it
 * @param document the iText document being populated
 * @param request in case we need locale etc. Shouldn't look at attributes.
 * @see com.lowagie.text.Document#addTitle
 * @see com.lowagie.text.Document#addSubject
 * @see com.lowagie.text.Document#addKeywords
 * @see com.lowagie.text.Document#addAuthor
 * @see com.lowagie.text.Document#addCreator
 * @see com.lowagie.text.Document#addProducer
 * @see com.lowagie.text.Document#addCreationDate
 * @see com.lowagie.text.Document#addHeader
*/
protected void buildPdfMetadata(Map model, Document document, HttpServletRequest request)
</code>```

This method is better for your use case than prepareWriter because it has the Document document as parameter.

Thus, all you have to do is override that method in your class:

```<code>protected void buildPdfMetadata(Map model, Document document, HttpServletRequest request) {
    super.buildPdfMetadata(model, document, request);
    document.setPageSize(PageSize.A4.rotate());
    document.setMargins(60, 30, 30, 30);
}
</code>```

Body:
 This is an image of the problem I am working with the lowagie PDF library in a Java Spring development. I need to make a report on a landscape orientation. I have also added a headerfooter. The report has 5 pages. I have included a table. Everything seems to work fine on pages 2,3,4 and 5. But in page 1 I can not make it happen. The headerfooter and the paragraphs I added dont appear. Im terribly tired. I do not know what else to do. Does someone faced the same situation before? i would really appreciate some help.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.gambbate.faqu.viewresolver;

import com.gambbate.faqu.model.Usuario;
import com.itextpdf.text.BaseColor;

import com.lowagie.text.Chunk;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.PageSize;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import java.awt.Color;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javafx.scene.layout.Border;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.view.document.AbstractPdfView;

/**
 *
 * @author Pisner-Lichtenstein
 */
public class PdfView extends AbstractPdfView {

    @Override
    protected void buildPdfDocument(Map<String, Object> map,
            Document dcmnt,
            PdfWriter writer,
            HttpServletRequest hsr,
            HttpServletResponse hsr1) throws Exception {

        List<Usuario> listadoDeUsuarios = (List<Usuario>) map.get("listadoDeUsuarios");

        PdfPTable tabla = new PdfPTable(8);
        tabla.setWidthPercentage(100);

        tabla.setWidths(new float[]{2.0f, 2.0f, 2.0f, 4.0f, 2.0f, 1.5f, 2.0f, 2.0f});

        PdfPCell encabezadoCelda = new PdfPCell();
        encabezadoCelda.setBackgroundColor(Color.WHITE);
        encabezadoCelda.setHorizontalAlignment(Element.ALIGN_CENTER);
        encabezadoCelda.setPadding(5);

        encabezadoCelda.setBorderColor(Color.LIGHT_GRAY);
        encabezadoCelda.setBorderWidth(0.15f);

        Font fuente = FontFactory.getFont(FontFactory.HELVETICA_BOLD);
        fuente.setSize(10);
        fuente.setColor(Color.BLACK);
        encabezadoCelda.setFixedHeight(30);
        encabezadoCelda.setPadding(5);
        encabezadoCelda.setVerticalAlignment(Element.ALIGN_MIDDLE);

        encabezadoCelda.setPhrase(new Phrase("Nombre", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Apellido", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Fecha de Nac.", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Email", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Celular", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Interno", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Gerencia", fuente));
        tabla.addCell(encabezadoCelda);

        encabezadoCelda.setPhrase(new Phrase("Puesto", fuente));
        tabla.addCell(encabezadoCelda);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");

        int colorDeFondo = 0;

        for (Usuario listadoDeUsuario : listadoDeUsuarios) {

            PdfPCell cd = new PdfPCell();

            cd.setBorderColor(Color.LIGHT_GRAY);
            cd.setBorderWidth(0.15f);

            fuente = FontFactory.getFont(FontFactory.HELVETICA);
            fuente.setColor(Color.DARK_GRAY);
            fuente.setSize(10);
            cd.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cd.setPadding(5);
            cd.setFixedHeight(30);

            if (colorDeFondo % 2 == 0) {
                cd.setBackgroundColor(Color.WHITE);
            } else {
                cd.setBackgroundColor(new Color(245, 245, 245));
            }

            colorDeFondo++;

            cd.setPhrase(new Phrase(listadoDeUsuario.getNombre(), fuente));
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getApellido(), fuente));
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(sdf.format(listadoDeUsuario.getFechaDeNacimiento()), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_RIGHT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getEmailCorporativo(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_LEFT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getCelular(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_RIGHT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getInterno(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_RIGHT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getGerencia().getGerencia(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_LEFT);
            tabla.addCell(cd);

            cd.setPhrase(new Phrase(listadoDeUsuario.getPuesto().getPuesto(), fuente));
            cd.setHorizontalAlignment(Element.ALIGN_LEFT);
            tabla.addCell(cd);

        }

        tabla.setSpacingBefore(25);
        tabla.setHeaderRows(1);

        Paragraph encabezado = new Paragraph(new Chunk("Gambbate - Faqu Soft", FontFactory.getFont(FontFactory.HELVETICA, 15)));
        Paragraph reporteTitulo = new Paragraph(new Chunk("Recursos Humanos - Listado de Uuarios", FontFactory.getFont(FontFactory.HELVETICA, 15)));
        Paragraph autor = new Paragraph(new Chunk("Emitido por:" + map.get("nombreDeUsuario"), FontFactory.getFont(FontFactory.HELVETICA, 15)));
        Paragraph fecha = new Paragraph(new Chunk("Fecha de Emision:" + new Date(), FontFactory.getFont(FontFactory.HELVETICA, 15)));

        HeaderFooter header = new HeaderFooter(new Phrase("fewfwfewwwe"), false);
        HeaderFooter footer = new HeaderFooter(new Phrase("aaaaaaaaaaaa"), false);

        dcmnt.setHeader(header);
        dcmnt.setFooter(footer);

        dcmnt.setPageSize(PageSize.A4.rotate());
        dcmnt.setMargins(60, 30, 30, 30);

        dcmnt.add(encabezado);
        dcmnt.add(reporteTitulo);
        dcmnt.add(tabla);

    }

}

Body:
As already mentioned in the comments to the question, if a page setting already is required at the creation time of a page (like its dimension and orientation), and if you want to change it already for the first page, you need to set the property before opening the Document because the first page is created during that opening routine.

In the case at hand the PageSize and the Margins are of interest. To change them already for the first page, you can do it like this:

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("landscape.pdf"));
document.setPageSize(PageSize.A4.rotate());
document.setMargins(60, 30, 30, 30);
document.open();
document.add(new Paragraph("Test string for a landscape PDF."));
document.close();

The result is:

As you see

the first page already is in landscape and

the first page uses the predefined margins, in particular the left margin is twice as large as the top margin which it is not by default.

Thus, all you have to do is search the calling code of your buildPdfDocument method, find the Document and PdfWriter instantiation in there (similar to

Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("landscape.pdf"));

), and set the PageSize and the Margins (like

document.setPageSize(PageSize.A4.rotate());
document.setMargins(60, 30, 30, 30);

) before the Document method open is called (like

document.open();

).

In your case that code is in the method renderMergedOutputModel of the AbstractPdfView class from which your class is derived:

[...]
Document document = getDocument();
PdfWriter writer = newWriter(document, baos);

// Apply preferences and build metadata.
prepareWriter(model, writer, request);
buildPdfMetadata(model, document, request);

// Build PDF document.
document.open();
[...]

But you do not have to patch this base class; as you see certain methods are called right before document.open(), in particular buildPdfMetadata which is documented as:

/**
 * Populate the iText Document's meta fields (author, title, etc.).
 * <br>Default is an empty implementation. Subclasses may override this method
 * to add meta fields such as title, subject, author, creator, keywords, etc.
 * This method is called after assigning a PdfWriter to the Document and
 * before calling <code>document.open()</code>.
 * @param model the model, in case meta information must be populated from it
 * @param document the iText document being populated
 * @param request in case we need locale etc. Shouldn't look at attributes.
 * @see com.lowagie.text.Document#addTitle
 * @see com.lowagie.text.Document#addSubject
 * @see com.lowagie.text.Document#addKeywords
 * @see com.lowagie.text.Document#addAuthor
 * @see com.lowagie.text.Document#addCreator
 * @see com.lowagie.text.Document#addProducer
 * @see com.lowagie.text.Document#addCreationDate
 * @see com.lowagie.text.Document#addHeader
*/
protected void buildPdfMetadata(Map model, Document document, HttpServletRequest request)

This method is better for your use case than prepareWriter because it has the Document document as parameter.

Thus, all you have to do is override that method in your class:

protected void buildPdfMetadata(Map model, Document document, HttpServletRequest request) {
    super.buildPdfMetadata(model, document, request);
    document.setPageSize(PageSize.A4.rotate());
    document.setMargins(60, 30, 30, 30);
}


问:
R visUpdateEdges: creates new edges instead of updating existing ones
I have a dynamic network which I want to represent with R shiny and visNetwork. Depending on the node which is chosen, colors of the nodes and edges should change according to some external protocol/data (nodeslist & edgeslist in the code below).

This works quite well for nodes: I select a node and in all future time steps the colors of the nodes change according to the data. For doing so, I use visUpdateNodes.

But when I try to do basically the same for the edges with visUpdateEdges, it doesn't work correctly: instead of only coloring the nodes, new nodes are created (with the correct colors).

A simple example is here:

```<code>library(shiny)
library(tidyverse)
library(visNetwork)

# some data - these values are for the updating process
nodeslist <- list(id1 = data_frame(R1 = c("red", "orange", "orange"), R2 = c("red",
  "black", "green"), R3 = c("red", "cyan", "yellow")), id2 = data_frame(R1 = c("orange",
  "red", "orange"), R2 = c("black", "red", "green"), R3 = c("orange", "red",
  "yellow")), id3 = data_frame(R1 = c("orange", "orange", "red"), R2 = c("black",
  "yellow", "red"), R3 = c("brown", "cyan", "red")))

edgeslist <- list(id1 = data_frame(R1 = c("red", "orange", "orange"), R2 = c("red",
  "black", "green"), R3 = rep("black", 3)), id2 = data_frame(R1 = c("orange",
  "red", "orange"), R2 = c("black", "red", "green"), R3 = rep("black", 3)),
  id3 = data_frame(R1 = c("orange", "orange", "red"), R2 = c("black", "yellow",
    "red"), R3 = rep("black", 3)))

# the updating functions
changeColorOfOtherNodes <- function(nodes, selected.node, index) {
  nodes %>% mutate(color = unlist(nodeslist[[as.numeric(selected.node)]][,
    index]))
}

changeColorOfEdges <- function(edges, selected.node, index) {
  edges %>% mutate(color = unlist(edgeslist[[as.numeric(selected.node)]][,
    index]))
}

# making the network
id <- c(1, 2, 3)
color <- rep("cyan", length(id))
nodes <- data_frame(id, color)

from <- c(1, 2, 3)
to <- c(2, 3, 1)
edges <- data_frame(from, to, color = rep("#333333", 3), value = c(2, 2, 2))

# shiny application
server <- shinyServer(function(input, output, session) {

  output$netplot <- renderVisNetwork({
    visNetwork(nodes, edges) %>% visOptions(nodesIdSelection = list(enabled = TRUE))
  })

  observe({
    if (!is.null(input$netplot_selected) && input$netplot_selected > 0) {

      for (i in 1:ncol(nodeslist[[as.numeric(input$netplot_selected)]])) {

        # updating works well for nodes
        nodes <- changeColorOfOtherNodes(nodes, input$netplot_selected,
          index = i)
        visNetworkProxy("netplot") %>% visUpdateNodes(nodes)
        Sys.sleep(1)
        # updating for edges -> new edges are creates, but don't know why
        edges <- changeColorOfEdges(edges, input$netplot_selected, index = i)
        visNetworkProxy("netplot") %>% visUpdateEdges(edges)
        Sys.sleep(1)
        print(edges)
      }

    }
  })

})

ui <- shinyUI(fluidPage(mainPanel(visNetworkOutput("netplot"))))
shinyApp(server = server, ui = ui)
</code>```

Has anyone an idea how to update colors of nodes with visUpdateEdges correctly? Why does visUpdateEdges create new edges instead of updating the existing one?

答:
You have to set id in edges data.frame and so use it to refer to existing edges in  visUpdateEdges

```<code>edge <- data.frame(id = 1:3, from = ....)
# update color of edge 1
visUpdateEdges(data.frame(id = 1, color = "red"))
</code>```

Body:
I have a dynamic network which I want to represent with R shiny and visNetwork. Depending on the node which is chosen, colors of the nodes and edges should change according to some external protocol/data (nodeslist & edgeslist in the code below).

This works quite well for nodes: I select a node and in all future time steps the colors of the nodes change according to the data. For doing so, I use visUpdateNodes.

But when I try to do basically the same for the edges with visUpdateEdges, it doesn't work correctly: instead of only coloring the nodes, new nodes are created (with the correct colors).

A simple example is here:

library(shiny)
library(tidyverse)
library(visNetwork)

# some data - these values are for the updating process
nodeslist <- list(id1 = data_frame(R1 = c("red", "orange", "orange"), R2 = c("red",
  "black", "green"), R3 = c("red", "cyan", "yellow")), id2 = data_frame(R1 = c("orange",
  "red", "orange"), R2 = c("black", "red", "green"), R3 = c("orange", "red",
  "yellow")), id3 = data_frame(R1 = c("orange", "orange", "red"), R2 = c("black",
  "yellow", "red"), R3 = c("brown", "cyan", "red")))

edgeslist <- list(id1 = data_frame(R1 = c("red", "orange", "orange"), R2 = c("red",
  "black", "green"), R3 = rep("black", 3)), id2 = data_frame(R1 = c("orange",
  "red", "orange"), R2 = c("black", "red", "green"), R3 = rep("black", 3)),
  id3 = data_frame(R1 = c("orange", "orange", "red"), R2 = c("black", "yellow",
    "red"), R3 = rep("black", 3)))

# the updating functions
changeColorOfOtherNodes <- function(nodes, selected.node, index) {
  nodes %>% mutate(color = unlist(nodeslist[[as.numeric(selected.node)]][,
    index]))
}

changeColorOfEdges <- function(edges, selected.node, index) {
  edges %>% mutate(color = unlist(edgeslist[[as.numeric(selected.node)]][,
    index]))
}

# making the network
id <- c(1, 2, 3)
color <- rep("cyan", length(id))
nodes <- data_frame(id, color)

from <- c(1, 2, 3)
to <- c(2, 3, 1)
edges <- data_frame(from, to, color = rep("#333333", 3), value = c(2, 2, 2))

# shiny application
server <- shinyServer(function(input, output, session) {

  output$netplot <- renderVisNetwork({
    visNetwork(nodes, edges) %>% visOptions(nodesIdSelection = list(enabled = TRUE))
  })

  observe({
    if (!is.null(input$netplot_selected) && input$netplot_selected > 0) {

      for (i in 1:ncol(nodeslist[[as.numeric(input$netplot_selected)]])) {

        # updating works well for nodes
        nodes <- changeColorOfOtherNodes(nodes, input$netplot_selected,
          index = i)
        visNetworkProxy("netplot") %>% visUpdateNodes(nodes)
        Sys.sleep(1)
        # updating for edges -> new edges are creates, but don't know why
        edges <- changeColorOfEdges(edges, input$netplot_selected, index = i)
        visNetworkProxy("netplot") %>% visUpdateEdges(edges)
        Sys.sleep(1)
        print(edges)
      }

    }
  })

})

ui <- shinyUI(fluidPage(mainPanel(visNetworkOutput("netplot"))))
shinyApp(server = server, ui = ui)

Has anyone an idea how to update colors of nodes with visUpdateEdges correctly? Why does visUpdateEdges create new edges instead of updating the existing one?

Body:
You have to set id in edges data.frame and so use it to refer to existing edges in  visUpdateEdges

edge <- data.frame(id = 1:3, from = ....)
# update color of edge 1
visUpdateEdges(data.frame(id = 1, color = "red"))


问:
Convert curl request to java request
I need to create http request to google web store for upload items.

I did it in curl and it worked.

```<code>curl -H "Authorization: Bearer Mytoken"  -H "x-goog-api-version: 2" -X POST -T /Users/mac/Downloads/file_name_3.25.10.zip -v https://www.googleapis.com/upload/chromewebstore/v1.1/items
</code>```

I want to know how to pass -T file value.
This is my code.

```<code>URL url = new URL("https://www.googleapis.com/upload/chromewebstore/v1.1/items");
Map<String, String> params  = new HashMap<String, String>();
params.put("FILE",filePath);
Map<String, String> requestPropertys  = new HashMap<String, String>();
requestPropertys.put("Authorization","Bearer " +
GoogleWebStoreDeveloperAuthService.getAccess_token());
requestPropertys.put("x-goog-api-version","2");
requestPropertys.put("Accept","*/*");
content = NetworkUtil.crossApplicationRequestPost(url, params, requestPropertys);
</code>```

public static  String crossApplicationRequestPost(URL url, Map params, Map requestPropertys ) {

```<code>    String result = null;

    String param = getQueryString(params);
    param = addHashQuery(param);

    /* End preparing params */
    byte[] postData = param.getBytes(Charset.forName("UTF-8"));
    int postDataLength = postData.length;

    log.info(" url :"+url);

    try {

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setInstanceFollowRedirects(false);
        connection.setRequestMethod("POST");
        for (Entry<String, T> entry : requestPropertys.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            connection.setRequestProperty(key, value.toString());

        }
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("charset", "utf-8");
        connection.setRequestProperty("Content-Length",Integer.toString(postDataLength));
        connection.setUseCaches(false);

        try (DataOutputStream wr = new DataOutputStream(
                connection.getOutputStream())) {
            wr.write(postData);
        }

        log.info(" crossApplicationRequestPost :"+connection.getResponseCode());

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            InputStream inputStream = connection.getInputStream();
            result = IOUtils.toString(inputStream, "UTF-8");
            inputStream.close();
        } else {
            log.severe("try fails. Connect to:" + url.toString());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
</code>```

答:
In this StackOverflow question you can get the solution for uploading a file using multipart POST HTTP request.

Aside from that, I really recommend you to use some type of helper to help you to make your requests easier. There are plenty of them, but a popular one (and with a lot of documentation) is Square's OKHTTP library

Title: Convert curl request to java request

Body:
I need to create http request to google web store for upload items.

I did it in curl and it worked.

curl -H "Authorization: Bearer Mytoken"  -H "x-goog-api-version: 2" -X POST -T /Users/mac/Downloads/file_name_3.25.10.zip -v https://www.googleapis.com/upload/chromewebstore/v1.1/items

I want to know how to pass -T file value.
This is my code.

URL url = new URL("https://www.googleapis.com/upload/chromewebstore/v1.1/items");
Map<String, String> params  = new HashMap<String, String>();
params.put("FILE",filePath);
Map<String, String> requestPropertys  = new HashMap<String, String>();
requestPropertys.put("Authorization","Bearer " +
GoogleWebStoreDeveloperAuthService.getAccess_token());
requestPropertys.put("x-goog-api-version","2");
requestPropertys.put("Accept","*/*");
content = NetworkUtil.crossApplicationRequestPost(url, params, requestPropertys);

public static  String crossApplicationRequestPost(URL url, Map params, Map requestPropertys ) {

    String result = null;

    String param = getQueryString(params);
    param = addHashQuery(param);

    /* End preparing params */
    byte[] postData = param.getBytes(Charset.forName("UTF-8"));
    int postDataLength = postData.length;

    log.info(" url :"+url);

    try {

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setInstanceFollowRedirects(false);
        connection.setRequestMethod("POST");
        for (Entry<String, T> entry : requestPropertys.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            connection.setRequestProperty(key, value.toString());

        }
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("charset", "utf-8");
        connection.setRequestProperty("Content-Length",Integer.toString(postDataLength));
        connection.setUseCaches(false);

        try (DataOutputStream wr = new DataOutputStream(
                connection.getOutputStream())) {
            wr.write(postData);
        }

        log.info(" crossApplicationRequestPost :"+connection.getResponseCode());

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            InputStream inputStream = connection.getInputStream();
            result = IOUtils.toString(inputStream, "UTF-8");
            inputStream.close();
        } else {
            log.severe("try fails. Connect to:" + url.toString());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}

ContentLicense: CC BY-SA 4.0


问:
How to check that a datetime exists in a given timezone in Python?
I need to read as dataframe temperature data provided to me as CSV. The date column is supposed to be localized Europe/Paris timezone but the data provider gives data even when the datetime does not exist because of daylight saving. So if I run:

```<code>import pandas as pd
from io import StringIO
from pytz import timezone

csv_string = StringIO("date;temp\n\
2014-03-29 22:00:00;12,5\n\
2014-03-29 23:00:00;12,4\n\
2014-03-30 00:00:00;10,7\n\
2014-03-30 01:00:00;11,7\n\
2014-03-30 02:00:00;12,4\n\
2014-03-30 03:00:00;12,4\n\
2014-03-30 04:00:00;10,7\n\
2014-03-30 05:00:00;10,4\n\
2014-03-30 06:00:00;9,4")

df = pd.read_csv(csv_string, sep=";", decimal=",")
df["date"] = pd.to_datetime(df["date"], infer_datetime_format=True)
df.set_index("date", inplace=True)
df.index = df.index.tz_localize(timezone('Europe/Paris'))
</code>```

I get:

pytz.exceptions.NonExistentTimeError: 2014-03-30 02:00:00

I am looking for a way to drop rows which will raise NonExistentTimeError. How can I test these rows using pandas, pytz or another lib?

答:
I ended up with the following:

```<code>import pandas as pd
from io import StringIO
from pytz import timezone

csv_string = StringIO("date;temp\n\
2014-03-29 22:00:00;12,5\n\
2014-03-29 23:00:00;12,4\n\
2014-03-30 00:00:00;10,7\n\
2014-03-30 01:00:00;11,7\n\
2014-03-30 02:00:00;12,4\n\
2014-03-30 03:00:00;12,4\n\
2014-03-30 04:00:00;10,7\n\
2014-03-30 05:00:00;10,4\n\
2014-03-30 06:00:00;9,4")

def datetime_exists_in_tz(dt, tz):
    try:
        dt.tz_localize(tz)
        return True
    except:
        return False

df = pd.read_csv(csv_string, sep=";", decimal=",")
df["date"] = pd.to_datetime(df["date"], infer_datetime_format=True)
df = df.loc[df["date"].apply(datetime_exists_in_tz, tz=timezone('Europe/Paris'))]
df.set_index("date", inplace=True)
df.index = df.index.tz_localize(timezone('Europe/Paris'))
</code>```

Still open to more elegant and more efficient solutions :)

Body:
I need to read as dataframe temperature data provided to me as CSV. The date column is supposed to be localized Europe/Paris timezone but the data provider gives data even when the datetime does not exist because of daylight saving. So if I run:

import pandas as pd
from io import StringIO
from pytz import timezone

csv_string = StringIO("date;temp\n\
2014-03-29 22:00:00;12,5\n\
2014-03-29 23:00:00;12,4\n\
2014-03-30 00:00:00;10,7\n\
2014-03-30 01:00:00;11,7\n\
2014-03-30 02:00:00;12,4\n\
2014-03-30 03:00:00;12,4\n\
2014-03-30 04:00:00;10,7\n\
2014-03-30 05:00:00;10,4\n\
2014-03-30 06:00:00;9,4")

df = pd.read_csv(csv_string, sep=";", decimal=",")
df["date"] = pd.to_datetime(df["date"], infer_datetime_format=True)
df.set_index("date", inplace=True)
df.index = df.index.tz_localize(timezone('Europe/Paris'))

I get:

pytz.exceptions.NonExistentTimeError: 2014-03-30 02:00:00

I am looking for a way to drop rows which will raise NonExistentTimeError. How can I test these rows using pandas, pytz or another lib?

Body:
I ended up with the following:

import pandas as pd
from io import StringIO
from pytz import timezone

csv_string = StringIO("date;temp\n\
2014-03-29 22:00:00;12,5\n\
2014-03-29 23:00:00;12,4\n\
2014-03-30 00:00:00;10,7\n\
2014-03-30 01:00:00;11,7\n\
2014-03-30 02:00:00;12,4\n\
2014-03-30 03:00:00;12,4\n\
2014-03-30 04:00:00;10,7\n\
2014-03-30 05:00:00;10,4\n\
2014-03-30 06:00:00;9,4")

def datetime_exists_in_tz(dt, tz):
    try:
        dt.tz_localize(tz)
        return True
    except:
        return False

df = pd.read_csv(csv_string, sep=";", decimal=",")
df["date"] = pd.to_datetime(df["date"], infer_datetime_format=True)
df = df.loc[df["date"].apply(datetime_exists_in_tz, tz=timezone('Europe/Paris'))]
df.set_index("date", inplace=True)
df.index = df.index.tz_localize(timezone('Europe/Paris'))

Still open to more elegant and more efficient solutions :)


问:
Difference between Software and Hardware Interrupts
I have recently started working on ARM Cortex Microcontrollers. While reading different articles over Internet, I usually found 2 common terms as Software Interrupt and Hardware Interrupt.
What is the actual difference in both? Can you explain with an example?</p>

答:
they are all interrupts it just has to do with the source.  there are some interrupts (these are signals too) that are generated by instructions or faults, etc (undefined, unaligned, etc).  And some that are available to the chip vendor.  ARM makes IP not chips, the chip vendor is provided with a number of interrupts they can choose to use however they wish.  Often they are tied to peripherals like usb, gpio, uart, spi, etc.

ARM has one called swi software interrupt or svc.  And like the number of soft interrupts in x86, this is for example so that an application can make a service call.  On a full sized arm this can be executed at the lower/est execution levels but is serviced by a higher more privileged mode or execution level.  basically allowing you to have an operating system.  Can use this feature on the cortex-m but doesnt have the protection layers it provides a common interface for example when you have downloaded an rtos and want to write applications for it, the rtos is generic-ish and the applications are yours doing what you want or need to get done and can make calls into the rtos (defined by the rtos) using this interface.  be it arm or x86 the calls are really arbitrary, logic doesnt dictate, the software dictates, traditionally x86 has bios handlers for specific interrupts, but that is arbitrary, you can write your own bios/handler that is incompatible with tradition and it will work just fine so long as both sides agree on the interface, likewise swi/svc calls for arm are not necessarily a standard, linux might have one but freertos doesnt have to conform to that if they dont want to.

another difference in the case of the cortex-m but is not necessarily a universal differences nor required, is that the so called external interrupts which are external to the core but generally tied to items provided by the chip vendor, have or may have an extra layer of masking, so that you can disable them using an interrupt controller, where the event type interrupts like undefined, systick, etc although are just signals do not go through a masked layer.  not universally true for all architectures from all vendors (arm, intel, mips, etc), but if I remember right in the case of the cortex-m this is how they implemented it.  granted there continue to be new cores coming out and there is no reason whatsoever for them to design all of them the same way.


问:
Compare a String to the elements of the ArrayList and return a String
I have an arrayList which I created using this code:

```<code>public List<String> Apps = new ArrayList<String>();
</code>```

This list contains strings in this format:

```<code>Data1+Description1
Data2+Description2
Data3+Description3
Data4+Description4
Data5+Description5
....
</code>```

Assume that the strings above have 3 parts. 1st part is the Data part. 2nd part is the + symbol and the 3rd part is the Description part.

and I have another function somewhere else in the code which returns a string. Now this string is of the form:

```<code>Retrieved_Name
</code>```

This Retrieved_Name will always match with one of the Data1...Data n above .i.e it will match with the 1st part of the above string till before the + symbol.

NOTE : This Retrieved_Name string always matches with the above strings till the + sign. and not after that.

My problem is that whenever the Retrieved_Name matches with the 1st part of the above String, I need to return the 3rd part .i.e. the description part of the string.

How can I implement this?

答:
I think you should use Map to retrieve value rather than looping through ArrayList.

This would be perfect candidate for HashMap.

AppUtils

```<code>import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AppUtils {
    public static Map<String, String> hMap = null;
    public static String TOKEN = "\\+";

    public static void main(String[] args) {

        List<String> apps = new ArrayList<String>();
        apps.add("Data1+Description1");
        apps.add("Data2+Description2");
        apps.add("Data3+Description3");
        apps.add("Data4+Description4");

        populateKeyValue(apps);
        String retrieved_Name = "Data1";
        System.out.println("Key : "+ retrieved_Name + ", Value : "+hMap.get(retrieved_Name));
        retrieved_Name = "Data3";
        System.out.println("Key : "+ retrieved_Name + ", Value : "+hMap.get(retrieved_Name));
    }

    public static void populateKeyValue(List<String> list) {
        hMap = list.stream().map(s -> s.split(TOKEN, -1))
                .filter(strings -> strings.length == 2)
                .collect(HashMap::new, (hashMap, str) -> hashMap.put(str[0],str[1]), HashMap::putAll);
    }
}
</code>```

Output

Key : Data1, Value : Description1

Key : Data3, Value : Description3

Body:
I have an arrayList which I created using this code:

public List<String> Apps = new ArrayList<String>();

This list contains strings in this format:

Data1+Description1
Data2+Description2
Data3+Description3
Data4+Description4
Data5+Description5
....

Assume that the strings above have 3 parts. 1st part is the Data part. 2nd part is the + symbol and the 3rd part is the Description part.

and I have another function somewhere else in the code which returns a string. Now this string is of the form:

Retrieved_Name

This Retrieved_Name will always match with one of the Data1...Data n above .i.e it will match with the 1st part of the above string till before the + symbol.

NOTE : This Retrieved_Name string always matches with the above strings till the + sign. and not after that.

My problem is that whenever the Retrieved_Name matches with the 1st part of the above String, I need to return the 3rd part .i.e. the description part of the string.

How can I implement this?

Body:
I think you should use Map to retrieve value rather than looping through ArrayList.

This would be perfect candidate for HashMap.

AppUtils

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AppUtils {
    public static Map<String, String> hMap = null;
    public static String TOKEN = "\\+";

    public static void main(String[] args) {

        List<String> apps = new ArrayList<String>();
        apps.add("Data1+Description1");
        apps.add("Data2+Description2");
        apps.add("Data3+Description3");
        apps.add("Data4+Description4");

        populateKeyValue(apps);
        String retrieved_Name = "Data1";
        System.out.println("Key : "+ retrieved_Name + ", Value : "+hMap.get(retrieved_Name));
        retrieved_Name = "Data3";
        System.out.println("Key : "+ retrieved_Name + ", Value : "+hMap.get(retrieved_Name));
    }

    public static void populateKeyValue(List<String> list) {
        hMap = list.stream().map(s -> s.split(TOKEN, -1))
                .filter(strings -> strings.length == 2)
                .collect(HashMap::new, (hashMap, str) -> hashMap.put(str[0],str[1]), HashMap::putAll);
    }
}

Output

Key : Data1, Value : Description1

Key : Data3, Value : Description3


问:
Save and load stroke from an InkCanvas to a variable
I need to save all the strokes of an InkCanvas in a variable (not a file) and later load them in the InkCanvaswhen the user needs it. The problem is that I get an unknown error every time I try to load the strokes.

This is the code I'm using to load them:

```<code>            foreach (InkStroke stroke in StrokesList)
        {
            var strokeBuilder = new InkStrokeBuilder();
            strokeBuilder.SetDefaultDrawingAttributes(stroke.DrawingAttributes);
            System.Numerics.Matrix3x2 matr = stroke.PointTransform;
            IReadOnlyList<InkPoint> inkPoints = stroke.GetInkPoints();
            InkStroke stk = strokeBuilder.CreateStrokeFromInkPoints(inkPoints, matr);
            InkCanvas.InkPresenter.StrokeContainer.AddStroke(stk);
        }
</code>```

I also tried InkCanvas.InkPresenter.StrokeContainer.AddStrokes(StrokesList); but it doesn't work either

EDIT: I'm saving the strokes like this:             IReadOnlyList<InkStroke> StrokesList = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();

答: If all you require is storing and then restoring the strokes, I recommend using StrokeContainer.SaveAsync to a InMemoryRandomAccessStream and then just loading that with StrokeContainer.LoadAsync.</p>

Body:
I need to save all the strokes of an InkCanvas in a variable (not a file) and later load them in the InkCanvaswhen the user needs it. The problem is that I get an unknown error every time I try to load the strokes.

This is the code I'm using to load them:

            foreach (InkStroke stroke in StrokesList)
        {
            var strokeBuilder = new InkStrokeBuilder();
            strokeBuilder.SetDefaultDrawingAttributes(stroke.DrawingAttributes);
            System.Numerics.Matrix3x2 matr = stroke.PointTransform;
            IReadOnlyList<InkPoint> inkPoints = stroke.GetInkPoints();
            InkStroke stk = strokeBuilder.CreateStrokeFromInkPoints(inkPoints, matr);
            InkCanvas.InkPresenter.StrokeContainer.AddStroke(stk);
        }

I also tried InkCanvas.InkPresenter.StrokeContainer.AddStrokes(StrokesList); but it doesn't work either

EDIT: I'm saving the strokes like this:             IReadOnlyList<InkStroke> StrokesList = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();


问:
smalltalk method call with parameters
I wrote the following method in smalltalk:

```<code>initializeWithStart: startWith step: theStep count: theCount

self initialize.
startNumber := startWith.
stepSize := theStep.
countUntil := theCount.
</code>```

and i just want to call this method after creating an object from the workspace. so I wrote:

```<code>mySq := ArithmeticsS new.
mySq initializeWithStart: '2' step:'4' count:'10'.
</code>```

why do I get error "MessageNotUnderstood:undefinedobject>>initializeWithStart:step:count:"?

答:
You should instantiate like this:</p>

```<code>mySq := ArithmeticsS new initializeWithStart: 2 step:4 count:10.
</code>```

Title: smalltalk method call with parameters

Body:
I wrote the following method in smalltalk:

initializeWithStart: startWith step: theStep count: theCount

self initialize.
startNumber := startWith.
stepSize := theStep.
countUntil := theCount.

and i just want to call this method after creating an object from the workspace. so I wrote:

mySq := ArithmeticsS new.
mySq initializeWithStart: '2' step:'4' count:'10'.

why do I get error "MessageNotUnderstood:undefinedobject>>initializeWithStart:step:count:"?

Body:
You should instantiate like this:

mySq := ArithmeticsS new initializeWithStart: 2 step:4 count:10.


问:
Google Maps with Bootstrap is not displaying in fulldomain
My map shows in my ISP provider URL and it doesn't on the full domain.

I am using this script for displaying a multimaker google map:

```<code>    var locations = [['<b>Base de Operaciones</b><br>Ruta 9 km450<br>Marcos Jurez, Cordoba<br>Tel: 701-555-1234<br>', -32.6836311,-62.1571096, 4], ['<b>Oficina Comercial</b><br>Champagnat 466<br>Marcos Juarez, Cordoba<br>Tel:  (+54) 3472-425-532 interno 32<br>', -32.6944151,-62.1001607, 5]];
   var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 13,
      /* Zoom level of your map */
      center: new google.maps.LatLng(-32.6935284,-62.1391514),
      /* coordinates for the center of your map */
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var infowindow = new google.maps.InfoWindow();

    var marker, i;

    for (i = 0; i < locations.length; i++) {
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });

      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }
</code>```

This is my HTML:

```<code><section id="location" class="map">
    <h2><center>Ubicaci&#243n</center></h2>
    <div class="embed-responsive embed-responsive-16by9">
    <div id="map_canvas" class="embed-responsive-item" >
    <div id="map"></div>
    <script src='https://maps.google.com/maps/api/js?sensor=false'></script>
    <script src="./js/index.js"></script>
    </div>
    </div>
    </section>
</code>```

答:
Check the js console to get to know what the problem is. Use your browsers inspector and navigate to the console. In your case it gives the following error:

Google Maps API error: MissingKeyMapError
  https://developers.google.com/maps/documentation/javascript/error-messages#missing-key-map-error

It seems that the script element that loads the API is missing the required authentication parameter.

Good luck! Hope this helps you!!

Body:
My map shows in my ISP provider URL and it doesn't on the full domain.

I am using this script for displaying a multimaker google map:

    var locations = [['Base de Operaciones
Ruta 9 km450
Marcos Jurez, Cordoba
Tel: 701-555-1234
', -32.6836311,-62.1571096, 4], ['Oficina Comercial
Champagnat 466
Marcos Juarez, Cordoba
Tel:  (+54) 3472-425-532 interno 32
', -32.6944151,-62.1001607, 5]];
   var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 13,
      /* Zoom level of your map */
      center: new google.maps.LatLng(-32.6935284,-62.1391514),
      /* coordinates for the center of your map */
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var infowindow = new google.maps.InfoWindow();

    var marker, i;

    for (i = 0; i < locations.length; i++) {
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });

      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }

This is my HTML:

Ubicaci&#243n


问:
Rails 3 and paperclip on update method issue
Paperclip is working well to save a user avatar but I find an issue on update.

In my view, if the user has an image saved in the model it will show an image tag with the current image next to the file upload field so you can see what your current avatar is.

If the image has no changes but the model validation fails (like no first_name), the original display image disappears, meaning that the user either has to correct the error and re-select an image and submit (update) or go back and start over without the error. Any ideas? Thanks in advance.

Heres the code:

Model

```<code>class User < ActiveRecord::Base

  # Validation
  validates :first_name, :presence => true

  # Paperclip
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "70x70#" }

end
</code>```

Controller

```<code>...
  # GET /users/1/edit
  def edit
    @user = User.find(params[:id])
  end

  # POST /users
  # POST /users.xml
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html { redirect_to(@user, :notice => 'User was successfully created.') }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /users/1
  # PUT /users/1.xml
  def update
    @user = User.find(params[:id])

    respond_to do |format|
      if @user.update_attributes(params[:user])
        format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end
...
</code>```

View

```<code><%= form_for @user, :html => {:multipart => true} do |f| %>
  <div class="row text">
    <%= f.label :first_name %>
    <div class="field">
      <%= f.text_field :first_name %>
    </div>
  </div>
  <div class="row">
    <%= f.label :avatar %>
    <div class="field">
      <%= image_tag @user.avatar.url(:thumb) %>
    </div>
    <div class="field" id="avatar_upload">
      <%= f.file_field :avatar %>
    </div>
  </div>
  <div class="row actions"><%= f.submit %> or <%= link_to 'cancel', users_path %>.</div>
<% end %>
</code>```

答:
This is being caused by your form sending 'nil' to the server (due to the field being blank since a new avatar is not being uploaded) when your page sends a POST request to your server. Short of mucking things up with hidden temporary fields, there are a few ways around this:

Client-side validation. Prevent your page from submitting if anything is wrong and you won't end up reaching the server-side validation failure that results in the missing image.

Move the avatar field to a separate FORM object on the same page that only handles the avatar. That will ensure that the page only ever sends avatar information in a POST message if it is related to an actual avatar edit.

Move the avatar upload/update functionality to a completely separate page that only handles the avatar. This works for the same reason the reason above this one works.

Body:
Paperclip is working well to save a user avatar but I find an issue on update.

In my view, if the user has an image saved in the model it will show an image tag with the current image next to the file upload field so you can see what your current avatar is.

If the image has no changes but the model validation fails (like no first_name), the original display image disappears, meaning that the user either has to correct the error and re-select an image and submit (update) or go back and start over without the error. Any ideas? Thanks in advance.

Heres the code:

Model

class User < ActiveRecord::Base

  # Validation
  validates :first_name, :presence => true

  # Paperclip
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "70x70#" }

end

Controller

...
  # GET /users/1/edit
  def edit
    @user = User.find(params[:id])
  end

  # POST /users
  # POST /users.xml
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html { redirect_to(@user, :notice => 'User was successfully created.') }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

  # PUT /users/1
  # PUT /users/1.xml
  def update
    @user = User.find(params[:id])

    respond_to do |format|
      if @user.update_attributes(params[:user])
        format.html { redirect_to(@user, :notice => 'User was successfully updated.') }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end
...

View

<%= form_for @user, :html => {:multipart => true} do |f| %>

    <%= f.label :first_name %>

      <%= f.text_field :first_name %>

    <%= f.label :avatar %>

      <%= image_tag @user.avatar.url(:thumb) %>

      <%= f.file_field :avatar %>

<%= f.submit %> or <%= link_to 'cancel', users_path %>.

<% end %>