问:
How to kill multiple threads in objective-c
I have created a UIButton and on click event, I am showing an image in the web view. Also, I am refreshing the image in every 30 sec. But when I click on button multiple times, refresh method get called multiple time as well.
I want it to work like, It saves last click time and refreshes as per that time instead of multiple times.

What can I do for it?

I tried to kill all previous thread instead of the current thread but that's not working.

Please help if anyone already know the answer.
Below is my image refresh code:

```<code>- (void)refreshBanner:(id)obj {
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        if (![SNRunTimeConfiguration sharedInstance].isInternetConnected) {
            [self removeBannerAdWithAdState:kADViewStateNotConnectedToInternet];
            return;
        }

        if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
            self.bannerPaused = YES;
            return;
        }

        self.adView.hidden = YES;

        UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
        topController = [SNADBannerView topViewControllerWithRootViewController:topController];
        if ([self checkInViewHierarchy:self parentView:topController.view]) {
            //        NSLog(@"Visible View Is: %@", self.adId);

            SNADMeta *meta = [[SNADDataBaseManager singletonInstance] adToShowWithBanner:YES excludeTyrooAd:YES audio:NO zoneId:self.adSoptZoneId fixedView:NO condition:nil contextualKeyword:nil onlyFromAJ:NO];
            SNADAdLocationType type = SNADAdLocationTypeHeader;
            if (self.bannerType == SmallViewTypeFooter) {
                type = SNADAdLocationTypeFooter;
            }

            if (self.isFromCustomEvent) {
                type = SNADAdLocationTypeAdMobBanner;
            }

            NSString *message = meta ? nil : kSNADOppMissReason_NoAdToShow;
            [SNRunTimeConfiguration fireOpportunityForAdLocation:type zoneId:self.adSoptZoneId reason:message];
            NSLog(@"******************* Opportuninty fired for refresh banner ***************************");

            if (meta) {
                self.meta = meta;
                [self updateContentForWebAd:nil];
                [self updateStatsForAd];

                //fireImpression
                [SNADBannerView fireImpression:self.meta];

                if ([meta.adSource isEqualToString:kSNADParameter_APC]) {
                    self.sdkMediation = [[SdkMediation alloc] init];
                    [self.sdkMediation fireTrackingAdType:self.meta.type isFill:YES];
                }

                // Ad Height Delegate.
                if ([self.meta.displayType isEqualToString:kSNADDisplayType_web]) {
                    self.adHeightDelegateCalled = YES;
                    NSInteger height = self.meta.height.integerValue;
                    self.bannerCH.constant = height;

                    if ([self.callBackDelegate respondsToSelector:@selector(adWillPresentWithHeight:adId:adType:)]) {
                        [self.callBackDelegate adWillPresentWithHeight:height adId:self.adId adType:SeventynineAdTypeMainStream];
                    }
                }
            } else {
                [self removeBannerAdWithAdState:kADViewStateNoAdToShow];

                if ([meta.adSource isEqualToString:kSNADParameter_APC]) {
                    [self.sdkMediation fireTrackingAdType:self.meta.type isFill:NO];
                }

                return;
            }
        } else {
            //        NSLog(@"View Which Is Not Visible Now: %@", self.adId);
        }

        SNAdConfiguration *configuration = [SNAdConfiguration sharedInstance];
        [self.timer invalidate];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:configuration.autoRefRate target:self selector:@selector(refreshBanner:) userInfo:nil repeats:NO];
    }];
}
</code>```

答:
I have resolved the issue.
Multiple threads created because a new view is created every time I call the API to display image. So now I am removing views if any available before displaying image, then only last object remains and refresh is called as per last called time.
Every View has it's own object that's why multiple threads has created.
By removing views my issue has been resolved.

Thanks everyone for replying.

Body:
I have created a UIButton and on click event, I am showing an image in the web view. Also, I am refreshing the image in every 30 sec. But when I click on button multiple times, refresh method get called multiple time as well.
I want it to work like, It saves last click time and refreshes as per that time instead of multiple times.

What can I do for it?

I tried to kill all previous thread instead of the current thread but that's not working.

Please help if anyone already know the answer.
Below is my image refresh code:

- (void)refreshBanner:(id)obj {
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        if (![SNRunTimeConfiguration sharedInstance].isInternetConnected) {
            [self removeBannerAdWithAdState:kADViewStateNotConnectedToInternet];
            return;
        }

        if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
            self.bannerPaused = YES;
            return;
        }

        self.adView.hidden = YES;

        UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
        topController = [SNADBannerView topViewControllerWithRootViewController:topController];
        if ([self checkInViewHierarchy:self parentView:topController.view]) {
            //        NSLog(@"Visible View Is: %@", self.adId);

            SNADMeta *meta = [[SNADDataBaseManager singletonInstance] adToShowWithBanner:YES excludeTyrooAd:YES audio:NO zoneId:self.adSoptZoneId fixedView:NO condition:nil contextualKeyword:nil onlyFromAJ:NO];
            SNADAdLocationType type = SNADAdLocationTypeHeader;
            if (self.bannerType == SmallViewTypeFooter) {
                type = SNADAdLocationTypeFooter;
            }

            if (self.isFromCustomEvent) {
                type = SNADAdLocationTypeAdMobBanner;
            }

            NSString *message = meta ? nil : kSNADOppMissReason_NoAdToShow;
            [SNRunTimeConfiguration fireOpportunityForAdLocation:type zoneId:self.adSoptZoneId reason:message];
            NSLog(@"******************* Opportuninty fired for refresh banner ***************************");

            if (meta) {
                self.meta = meta;
                [self updateContentForWebAd:nil];
                [self updateStatsForAd];

                //fireImpression
                [SNADBannerView fireImpression:self.meta];

                if ([meta.adSource isEqualToString:kSNADParameter_APC]) {
                    self.sdkMediation = [[SdkMediation alloc] init];
                    [self.sdkMediation fireTrackingAdType:self.meta.type isFill:YES];
                }

                // Ad Height Delegate.
                if ([self.meta.displayType isEqualToString:kSNADDisplayType_web]) {
                    self.adHeightDelegateCalled = YES;
                    NSInteger height = self.meta.height.integerValue;
                    self.bannerCH.constant = height;

                    if ([self.callBackDelegate respondsToSelector:@selector(adWillPresentWithHeight:adId:adType:)]) {
                        [self.callBackDelegate adWillPresentWithHeight:height adId:self.adId adType:SeventynineAdTypeMainStream];
                    }
                }
            } else {
                [self removeBannerAdWithAdState:kADViewStateNoAdToShow];

                if ([meta.adSource isEqualToString:kSNADParameter_APC]) {
                    [self.sdkMediation fireTrackingAdType:self.meta.type isFill:NO];
                }

                return;
            }
        } else {
            //        NSLog(@"View Which Is Not Visible Now: %@", self.adId);
        }

        SNAdConfiguration *configuration = [SNAdConfiguration sharedInstance];
        [self.timer invalidate];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:configuration.autoRefRate target:self selector:@selector(refreshBanner:) userInfo:nil repeats:NO];
    }];
}


来源: stackexchange

问:
how to make a tag change properties after a specific input is checked?
I am creating a quiz website for a school project. Whenever a correct answer is selected (input type=radio) then I want the line adjacent to it to become green and when an incorrect answer is selected I want the line to become red.

Is there any way to do this using css only and not JavaScript.

答:
You can see this tutorial:
https://css-tricks.com/form-validation-ux-html-css/

The beginning is in css without js.

See also all css selectors, you can find your happiness:
https://www.w3schools.com/cssref/css_selectors.asp

Good work !

ContentLicense: CC BY-SA 3.0


问:
Can you export multiple classes from a single Nodejs Module?
Currently, I have 4 Child Classes each in their own file. I'm requiring them all in the same file. I am wondering if I can contain all 4 of those classes in a single module. Currently, I'm importing them like this

```<code>var Jack = require('./Jack.js');
var JackInstance = new Jack();
var Jones = require('./Jones.js');
var JonesInstance = new Jones();
</code>```

I'd like to import them like this

```<code>var People = require('./People.js');
var JackInstance = new People.Jack();
</code>```

Or even

```<code>var Jack = require('./People.js').Jack;
var JackInstance = new Jack();
</code>```

My classes are defined like so

```<code>class Jack{
    //Memeber variables, functions, etc
}

module.exports = Jack;
</code>```

答:
You can also do this in a shorter form, using destructuring assignments (which are supported natively starting from Node.js v6.0.0):

```<code>// people.js

class Jack {
  // ...
}

class John {
  // ...
}

module.exports = { Jack, John }
</code>```

Importing:

```<code>// index.js

const { Jack, John } = require('./people.js');
</code>```

Or even like this if you want aliased require assignments:

```<code>// index.js

const {
  Jack: personJack, John: personJohn,
} = require('./people.js');
</code>```

In the latter case personJack and personJohn will reference your classes.

A word of warning:

Destructuring could be dangerous in sense that it's prone to producing unexpected errors. It's relatively easy to forget curly brackets on export or to accidentally include them on require.

Node.js 12 update:

Lately ECMAScript Modules received an extended support in Node.js 12.*, introducing the convenient usage of import statement to accomplish the same task (currently Node should be started with a flag --experimental-modules in order to make them available).

```<code>// people.mjs

export class Jack {
  // ...
}

export class John {
  // ...
}
</code>```

Notice that files that adhere to modules convention should have an .mjs extension.

```<code>// index.mjs

import {
  Jack as personJack, John as personJohn,
} from './people.mjs';
</code>```

This is much better in a sense of robustness and stability, as an attempt to import non-existing export from the module will throw an exception similar to:

SyntaxError: The requested module 'x' does not provide an export named
  'y'

Body:
Currently, I have 4 Child Classes each in their own file. I'm requiring them all in the same file. I am wondering if I can contain all 4 of those classes in a single module. Currently, I'm importing them like this

var Jack = require('./Jack.js');
var JackInstance = new Jack();
var Jones = require('./Jones.js');
var JonesInstance = new Jones();

I'd like to import them like this

var People = require('./People.js');
var JackInstance = new People.Jack();

Or even

var Jack = require('./People.js').Jack;
var JackInstance = new Jack();

My classes are defined like so

class Jack{
    //Memeber variables, functions, etc
}

module.exports = Jack;

Body:
You can also do this in a shorter form, using destructuring assignments (which are supported natively starting from Node.js v6.0.0):

// people.js

class Jack {
  // ...
}

class John {
  // ...
}

module.exports = { Jack, John }

Importing:

// index.js

const { Jack, John } = require('./people.js');

Or even like this if you want aliased require assignments:

// index.js

const {
  Jack: personJack, John: personJohn,
} = require('./people.js');

In the latter case personJack and personJohn will reference your classes.

A word of warning:

Destructuring could be dangerous in sense that it's prone to producing unexpected errors. It's relatively easy to forget curly brackets on export or to accidentally include them on require.

Node.js 12 update:

Lately ECMAScript Modules received an extended support in Node.js 12.*, introducing the convenient usage of import statement to accomplish the same task (currently Node should be started with a flag --experimental-modules in order to make them available).

// people.mjs

export class Jack {
  // ...
}

export class John {
  // ...
}

Notice that files that adhere to modules convention should have an .mjs extension.

// index.mjs

import {
  Jack as personJack, John as personJohn,
} from './people.mjs';

This is much better in a sense of robustness and stability, as an attempt to import non-existing export from the module will throw an exception similar to:

SyntaxError: The requested module 'x' does not provide an export named
  'y'

ContentLicense: CC BY-SA 4.0


问:
Hide shopping cart if is empty
For a few days in a row I've tried to find a solution to hide an entire section if my shopping cart is empty and only be shown when I add a new item in cart. Shop is made entirely with javascript and jQuery.
Down below I will put the code , even a small idea is good.

P.S: I need to hide  the div.

            $(".add-to-cart").click(function(event){
                event.preventDefault();
                var name = $(this).attr("data-name");
                var price = Number($(this).attr("data-price"));

                shoppingCart.addItemToCart(name, price, 1);
                displayCart();
            });

            $("#clear-cart").click(function(event){
                shoppingCart.clearCart();
                displayCart();
            });

            function displayCart() {
                var cartArray = shoppingCart.listCart();
                console.log(cartArray);
                var output = "";

                for (var i in cartArray) {
                    output += "
"
                        +cartArray[i].name
                        +" <input class='item-count' type='number' data-name='"
                        +cartArray[i].name
                        +"' value='"+cartArray[i].count+"' >"
                        +" x "+cartArray[i].price
                        +" = "+cartArray[i].total
                        +" <button class='plus-item' data-name='"
                        +cartArray[i].name+"'>+</button>"
                        +" <button class='subtract-item' data-name='"
                        +cartArray[i].name+"'>-</button>"
                        +" <button class='delete-item' data-name='"
                        +cartArray[i].name+"'>X</button>"
                        +"
";
                }

                $("#show-cart").html(output);
                $("#count-cart").html( shoppingCart.countCart() );
                $("#total-cart").html( shoppingCart.totalCart() );
            }

            $("#show-cart").on("click", ".delete-item", function(event){
                var name = $(this).attr("data-name");
                shoppingCart.removeItemFromCartAll(name);
                displayCart();
            });

            $("#show-cart").on("click", ".subtract-item", function(event){
                var name = $(this).attr("data-name");
                shoppingCart.removeItemFromCart(name);
                displayCart();
            });

            $("#show-cart").on("click", ".plus-item", function(event){
                var name = $(this).attr("data-name");
                shoppingCart.addItemToCart(name, 0, 1);
                displayCart();
            });

            $("#show-cart").on("change", ".item-count", function(event){
                var name = $(this).attr("data-name");
                var count = Number($(this).val());
                shoppingCart.setCountForItem(name, count);
                displayCart();
            });

            displayCart();

// Shopping Cart functions

var shoppingCart = (function () {
    // Private methods and properties
    var cart = [];

    function Item(name, price, count) {
        this.name = name
        this.price = price
        this.count = count
    }

    function saveCart() {
        localStorage.setItem("shoppingCart", JSON.stringify(cart));
    }

    function loadCart() {
        cart = JSON.parse(localStorage.getItem("shoppingCart"));
        if (cart === null) {
            cart = []
        }
    }

    loadCart();

    // Public methods and properties
    var obj = {};

    obj.addItemToCart = function (name, price, count) {
        for (var i in cart) {
            if (cart[i].name === name) {
                cart[i].count += count;
                saveCart();
                return;
            }
        }

        console.log("addItemToCart:", name, price, count);

        var item = new Item(name, price, count);
        cart.push(item);
        saveCart();
    };

    obj.setCountForItem = function (name, count) {
        for (var i in cart) {
            if (cart[i].name === name) {
                cart[i].count = count;
                break;
            }
        }
        saveCart();
    };

    obj.removeItemFromCart = function (name) { // Removes one item
        for (var i in cart) {
            if (cart[i].name === name) { // "3" === 3 false
                cart[i].count--; // cart[i].count --
                if (cart[i].count === 0) {
                    cart.splice(i, 1);
                }
                break;
            }
        }
        saveCart();
    };

    obj.removeItemFromCartAll = function (name) { // removes all item name
        for (var i in cart) {
            if (cart[i].name === name) {
                cart.splice(i, 1);
                break;
            }
        }
        saveCart();
    };

    obj.clearCart = function () {
        cart = [];
        saveCart();
    }

    obj.countCart = function () { // -> return total count
        var totalCount = 0;
        for (var i in cart) {
            totalCount += cart[i].count;
        }

        return totalCount;
    };

    obj.totalCart = function () { // -> return total cost
        var totalCost = 0;
        for (var i in cart) {
            totalCost += cart[i].price * cart[i].count;
        }
        return totalCost.toFixed(2);
    };

    obj.listCart = function () { // -> array of Items
        var cartCopy = [];
        console.log("Listing cart");
        console.log(cart);
        for (var i in cart) {
            console.log(i);
            var item = cart[i];
            var itemCopy = {};
            for (var p in item) {
                itemCopy[p] = item[p];
            }
            itemCopy.total = (item.price * item.count).toFixed(2);
            cartCopy.push(itemCopy);
        }
        return cartCopy;
    };

    // ----------------------------
    return obj;
})();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
            <ul>
                <li>Apple $1.22</li>
                <li>Banana $1.33</li>
                <li>Shoe $22.33</li>
                <li>Frisbee $5.22</li>
            </ul>
            <button id="clear-cart">Clear Cart</button>
        </div>

        <div>
            <ul id="show-cart">
                <li>???????</li>
            </ul>
            <div>You have <span id="count-cart">X</span> items in your cart</div>
            <div>Total Cart:$<span id="total-cart"></span></div>
        </div></code>```

答:
To hide the div, you will need to modify the displayCart() as below.

```<code>function displayCart() {
    var cartArray = shoppingCart.listCart();
    console.log(cartArray);
    var output = "";
</code>```

```<code>    var divEl = $("#show-cart").parent();
    if(cartArray.length > 0) {
</code>```

```<code>        for (var i in cartArray) {
            output += "<li>"
                +cartArray[i].name
                +" <input class='item-count' type='number' data-name='"
                +cartArray[i].name
                +"' value='"+cartArray[i].count+"' >"
                +" x "+cartArray[i].price
                +" = "+cartArray[i].total
                +" <button class='plus-item' data-name='"
                +cartArray[i].name+"'>+</button>"
                +" <button class='subtract-item' data-name='"
                +cartArray[i].name+"'>-</button>"
                +" <button class='delete-item' data-name='"
                +cartArray[i].name+"'>X</button>"
                +"</li>";
        }
</code>```

```<code>        $(divEl).removeClass('hidden');
    } else {
        $(divEl).addClass('hidden');
    }
</code>```

```<code>    $("#show-cart").html(output);
    $("#count-cart").html( shoppingCart.countCart() );
    $("#total-cart").html( shoppingCart.totalCart() );
}
</code>```

So that way it will show or hide the div depending on the size of the object.
Try and comment.

PS: hidden is a bootstrap class. You will need to include the bootstrap library. Or instead just add the css picked up from the  library if you don't need it entirely.

```<code>.hidden {
    display: none !important;
}
</code>```

Title: Hide shopping cart if is empty

Body:
For a few days in a row I've tried to find a solution to hide an entire section if my shopping cart is empty and only be shown when I add a new item in cart. Shop is made entirely with javascript and jQuery.
Down below I will put the code , even a small idea is good.

P.S: I need to hide  the div.

            $(".add-to-cart").click(function(event){
                event.preventDefault();
                var name = $(this).attr("data-name");
                var price = Number($(this).attr("data-price"));

                shoppingCart.addItemToCart(name, price, 1);
                displayCart();
            });

            $("#clear-cart").click(function(event){
                shoppingCart.clearCart();
                displayCart();
            });

            function displayCart() {
                var cartArray = shoppingCart.listCart();
                console.log(cartArray);
                var output = "";

                for (var i in cartArray) {
                    output += "
"
                        +cartArray[i].name
                        +" <input class='item-count' type='number' data-name='"
                        +cartArray[i].name
                        +"' value='"+cartArray[i].count+"' >"
                        +" x "+cartArray[i].price
                        +" = "+cartArray[i].total
                        +" <button class='plus-item' data-name='"
                        +cartArray[i].name+"'>+</button>"
                        +" <button class='subtract-item' data-name='"
                        +cartArray[i].name+"'>-</button>"
                        +" <button class='delete-item' data-name='"
                        +cartArray[i].name+"'>X</button>"
                        +"
";
                }

                $("#show-cart").html(output);
                $("#count-cart").html( shoppingCart.countCart() );
                $("#total-cart").html( shoppingCart.totalCart() );
            }

            $("#show-cart").on("click", ".delete-item", function(event){
                var name = $(this).attr("data-name");
                shoppingCart.removeItemFromCartAll(name);
                displayCart();
            });

            $("#show-cart").on("click", ".subtract-item", function(event){
                var name = $(this).attr("data-name");
                shoppingCart.removeItemFromCart(name);
                displayCart();
            });

            $("#show-cart").on("click", ".plus-item", function(event){
                var name = $(this).attr("data-name");
                shoppingCart.addItemToCart(name, 0, 1);
                displayCart();
            });

            $("#show-cart").on("change", ".item-count", function(event){
                var name = $(this).attr("data-name");
                var count = Number($(this).val());
                shoppingCart.setCountForItem(name, count);
                displayCart();
            });

            displayCart();

// Shopping Cart functions

var shoppingCart = (function () {
    // Private methods and properties
    var cart = [];

    function Item(name, price, count) {
        this.name = name
        this.price = price
        this.count = count
    }

    function saveCart() {
        localStorage.setItem("shoppingCart", JSON.stringify(cart));
    }

    function loadCart() {
        cart = JSON.parse(localStorage.getItem("shoppingCart"));
        if (cart === null) {
            cart = []
        }
    }

    loadCart();

    // Public methods and properties
    var obj = {};

    obj.addItemToCart = function (name, price, count) {
        for (var i in cart) {
            if (cart[i].name === name) {
                cart[i].count += count;
                saveCart();
                return;
            }
        }

        console.log("addItemToCart:", name, price, count);

        var item = new Item(name, price, count);
        cart.push(item);
        saveCart();
    };

    obj.setCountForItem = function (name, count) {
        for (var i in cart) {
            if (cart[i].name === name) {
                cart[i].count = count;
                break;
            }
        }
        saveCart();
    };

    obj.removeItemFromCart = function (name) { // Removes one item
        for (var i in cart) {
            if (cart[i].name === name) { // "3" === 3 false
                cart[i].count--; // cart[i].count --
                if (cart[i].count === 0) {
                    cart.splice(i, 1);
                }
                break;
            }
        }
        saveCart();
    };

    obj.removeItemFromCartAll = function (name) { // removes all item name
        for (var i in cart) {
            if (cart[i].name === name) {
                cart.splice(i, 1);
                break;
            }
        }
        saveCart();
    };

    obj.clearCart = function () {
        cart = [];
        saveCart();
    }

    obj.countCart = function () { // -> return total count
        var totalCount = 0;
        for (var i in cart) {
            totalCount += cart[i].count;
        }

        return totalCount;
    };

    obj.totalCart = function () { // -> return total cost
        var totalCost = 0;
        for (var i in cart) {
            totalCost += cart[i].price * cart[i].count;
        }
        return totalCost.toFixed(2);
    };

    obj.listCart = function () { // -> array of Items
        var cartCopy = [];
        console.log("Listing cart");
        console.log(cart);
        for (var i in cart) {
            console.log(i);
            var item = cart[i];
            var itemCopy = {};
            for (var p in item) {
                itemCopy[p] = item[p];
            }
            itemCopy.total = (item.price * item.count).toFixed(2);
            cartCopy.push(itemCopy);
        }
        return cartCopy;
    };

    // ----------------------------
    return obj;
})();

Apple $1.22

Banana $1.33

Shoe $22.33

Frisbee $5.22

            <button id="clear-cart">Clear Cart</button>

???????

You have X items in your cart

Total Cart:$

Body:
To hide the div, you will need to modify the displayCart() as below.

function displayCart() {
    var cartArray = shoppingCart.listCart();
    console.log(cartArray);
    var output = "";

    var divEl = $("#show-cart").parent();
    if(cartArray.length > 0) {

        for (var i in cartArray) {
            output += "<li>"
                +cartArray[i].name
                +" <input class='item-count' type='number' data-name='"
                +cartArray[i].name
                +"' value='"+cartArray[i].count+"' >"
                +" x "+cartArray[i].price
                +" = "+cartArray[i].total
                +" <button class='plus-item' data-name='"
                +cartArray[i].name+"'>+</button>"
                +" <button class='subtract-item' data-name='"
                +cartArray[i].name+"'>-</button>"
                +" <button class='delete-item' data-name='"
                +cartArray[i].name+"'>X</button>"
                +"</li>";
        }

        $(divEl).removeClass('hidden');
    } else {
        $(divEl).addClass('hidden');
    }

    $("#show-cart").html(output);
    $("#count-cart").html( shoppingCart.countCart() );
    $("#total-cart").html( shoppingCart.totalCart() );
}

So that way it will show or hide the div depending on the size of the object.
Try and comment.

PS: hidden is a bootstrap class. You will need to include the bootstrap library. Or instead just add the css picked up from the  library if you don't need it entirely.

.hidden {
    display: none !important;
}


问:
How do I debug a kml file
I am editing kml files of maps of history and science of files that already appear on http://climateviewer.org/. I am editing them in Sublime text and/or Notepad since all I am doing is editing text, deleting extended data and switching links and references from my old web site MyReadingMapped to the new site which has far better technology. You can see images of the maps I made at http://climateviewer.org/myreadingmapped/

BTW, I am not a programmer or developer of software, but rather a retired marketing communications professional who understands just enough coding to make these changes and can do some html as well.

The problem I am having is that of the 30 or so files I have edited so far 4 have a parsing error that consistently involves closing a Placemark. Yet there appears to be nothing wrong with the code. I am testing the files by uploading them to Google Earth to get the error statements. And so far I have fixed many problems but I can't seem to solve this problem. Jim Lee, ClimateViewer's creator tells me to debug them.

How do I debug them and is it something I would be able to learn without formal training?

答:
There are several tools available to debug a KML file, which is simply an XML file that must conform to rules of the KML specification. As an XML file, all start and end tags must match. In addition, the tags are case-sensitive.

The easiest trick is using a web browser to validate it. Simply rename the KML file to an XML file (rename .kml extension to .xml) then drag the .xml file onto the open web browser. Parsing errors will be identified with row and column number.

Next, you can upload the KML file to KML Validator to get a list of potential errors that need to be fixed or run the standalone command-line XmlValidator tool.

Additional tips to fix KML files are described here along with details about KML validation.

Title: How do I debug a kml file


问:
Porting of Plural string from Localizable.strings to Localizable.stringsdict with %@ input formatter in the middle of stirng
In Localizable.strings, I have below plural strings with one and other

"User added %@ posts.##{one}" = "User added a post.";

"User added %@ posts.##{other}" = "User added %@ posts.";

I wish to remove it from Localizable.strings and add it to Localizable.stringsdict.

I have done this before for the basic strings with the input format (%d) at the start of string. But, I have never user Localizable.stringsdict for strings having input format in middle of the string

Could anyone help me with exporting the above string in below format?

```<code><key>Fill_Here</key>
<dict>
    <key>NSStringLocalizedFormatKey</key>
    <string>Fill_Here</string>
    <key>Fill_Here</key>
    <dict>
        <key>NSStringFormatSpecTypeKey</key>
        <string>NSStringPluralRuleType</string>
        <key>NSStringFormatValueTypeKey</key>
        <string>Fill_Here</string>
        <key>one</key>
        <string>Fill_Here</string>
        <key>other</key>
        <string>Fill_Here</string>
    </dict>
</dict>
</code>```

Thanks in advance

答:
I figured out a way to do this, by modifying dictionary as below

```<code><key>User added %@ posts.</key>
<dict>
    <key>NSStringLocalizedFormatKey</key>
    <string>%#@posts@</string>
    <key>posts</key>
    <dict>
        <key>NSStringFormatSpecTypeKey</key>
        <string>NSStringPluralRuleType</string>
        <key>NSStringFormatValueTypeKey</key>
        <string>d</string>
        <key>one</key>
        <string>User added %d post.</string>
        <key>other</key>
        <string>User added %d posts.</string>
    </dict>
</dict>
</code>```

Using %@ input format crashes the application in this case. So I modified it to use %d instead.

Body:
In Localizable.strings, I have below plural strings with one and other

"User added %@ posts.##{one}" = "User added a post.";

"User added %@ posts.##{other}" = "User added %@ posts.";

I wish to remove it from Localizable.strings and add it to Localizable.stringsdict.

I have done this before for the basic strings with the input format (%d) at the start of string. But, I have never user Localizable.stringsdict for strings having input format in middle of the string

Could anyone help me with exporting the above string in below format?

<key>Fill_Here</key>
<dict>
    <key>NSStringLocalizedFormatKey</key>
    <string>Fill_Here</string>
    <key>Fill_Here</key>
    <dict>
        <key>NSStringFormatSpecTypeKey</key>
        <string>NSStringPluralRuleType</string>
        <key>NSStringFormatValueTypeKey</key>
        <string>Fill_Here</string>
        <key>one</key>
        <string>Fill_Here</string>
        <key>other</key>
        <string>Fill_Here</string>
    </dict>
</dict>

Thanks in advance

Body:
I figured out a way to do this, by modifying dictionary as below

<key>User added %@ posts.</key>
<dict>
    <key>NSStringLocalizedFormatKey</key>
    <string>%#@posts@</string>
    <key>posts</key>
    <dict>
        <key>NSStringFormatSpecTypeKey</key>
        <string>NSStringPluralRuleType</string>
        <key>NSStringFormatValueTypeKey</key>
        <string>d</string>
        <key>one</key>
        <string>User added %d post.</string>
        <key>other</key>
        <string>User added %d posts.</string>
    </dict>
</dict>

Using %@ input format crashes the application in this case. So I modified it to use %d instead.


问:
I have Detail method in Home controller and I want no ajax call access Detail method in controller how its possible in mvc?
I need to create one Method in controller and protect like no any ajax call work on this method in mvc ?</p>

答:
There are a couple of ways of doing it.

If you want to prevent it from accessing the URL directly or through AJAX but access it through only the controller or view, you can use [ChildActionOnly] attribute.

If you want to declare a method and not use it as an Action method, you could have the attribute [NonAction] or make the method private. Note that this will result in the method not being visible to Http


问:
Skip certain calculated values (not cells themselves) in an AVERAGE or STDEV Excel formula based on a criterion
I have a series of paired measurements (two for each sample). I need to calculate the mean for each pair and then the general mean based on those pairwise averaged values, but I can only include those pairwise means that don't exceed a certain threshold.

I'm trying to work out an excel formula for the general mean that takes into account all of the above, without having to create additional rows/columns.

Now, the formula

```<code>=AVERAGE(IF(ABS(A1-A2)<$C$1,AVERAGE(A1,A2)),IF(ABS(A7-A8)<$C$1,AVERAGE(A7,A8)), ... )
</code>```

... doesn't do the job because it replaces with zeros those pairwise means that exceed the threshold (value of $C$1), while they just need to be skipped. "AVERAGEIF" doesn't work because it doesn't accept non-contiguous ranges (at least when they are entered as such), using "INDIRECT" to build non-contiguous ranges doesn't help either because it doesn't accept formulas. Any help appreciated.

答:
This is where Excel has some mysterious behaviour I think.

My first thought was to make each if statement return "" if the condition wasn't satisfied

```<code>=AVERAGE(IF(ABS(A1-A2)<$C$1,AVERAGE(A1,A2),""),IF(ABS(A7-A8)<$C$1,AVERAGE(A7,A8),""))
</code>```

but this just gives you an error.

However, if you make it return a reference to an empty cell (say B1) it works fine

```<code>=AVERAGE(IF(ABS(A1-A2)<$C$1,AVERAGE(A1,A2),$B$1),IF(ABS(A7-A8)<$C$1,AVERAGE(A7,A8),$B$1))
</code>```

Body:
I have a series of paired measurements (two for each sample). I need to calculate the mean for each pair and then the general mean based on those pairwise averaged values, but I can only include those pairwise means that don't exceed a certain threshold.

I'm trying to work out an excel formula for the general mean that takes into account all of the above, without having to create additional rows/columns.

Now, the formula

=AVERAGE(IF(ABS(A1-A2)<$C$1,AVERAGE(A1,A2)),IF(ABS(A7-A8)<$C$1,AVERAGE(A7,A8)), ... )

... doesn't do the job because it replaces with zeros those pairwise means that exceed the threshold (value of $C$1), while they just need to be skipped. "AVERAGEIF" doesn't work because it doesn't accept non-contiguous ranges (at least when they are entered as such), using "INDIRECT" to build non-contiguous ranges doesn't help either because it doesn't accept formulas. Any help appreciated.

Body:
This is where Excel has some mysterious behaviour I think.

My first thought was to make each if statement return "" if the condition wasn't satisfied

=AVERAGE(IF(ABS(A1-A2)<$C$1,AVERAGE(A1,A2),""),IF(ABS(A7-A8)<$C$1,AVERAGE(A7,A8),""))

but this just gives you an error.

However, if you make it return a reference to an empty cell (say B1) it works fine

=AVERAGE(IF(ABS(A1-A2)<$C$1,AVERAGE(A1,A2),$B$1),IF(ABS(A7-A8)<$C$1,AVERAGE(A7,A8),$B$1))


问:
Reference invalidated after std::vector push_back
I wrote an example which leads with Visual to a crash. I think the critical section is here:

```<code>A a;
B b(a);
pair p(a, b);
res.push_back(p);
</code>```

I assign a temporary which takes a reference to another temporary and move it into a vector. I also noticed that the program seems not to crash with GCC. I think the problem is, that the reference is invalidated since the moment I move the objects into the vector. Do I have to use new?

```<code>// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

// Example program
#include <iostream>
#include <string>
#include <vector>
#include <math.h>

class Materials {
public:
  Materials() = default;
};

class A {
private:
  std::vector<Materials> _storage;

public:
  void setStorage(const std::vector<Materials> &val) {
    _storage = val;
  }
};

class B {
private:
  A &_a;

public:
  B(A &foo) : _a(foo) {}

  void run() {
    std::vector<Materials> val;
    for (int i = 0; i < 1000; i++) {
      val.push_back(Materials());
    }

    _a.setStorage(val);
  }
};

struct pair {
  pair(const A &a, const B &b)
    : _a(a)
    , _b(b)
  {
  }

  A _a;
  B _b;
};

std::vector<pair> make_list() {
  std::vector<pair> res;
  for (int i = 0; i < 10; i++) {
    A a;
    B b(a);
    pair p(a, b);
    res.push_back(p);
  }
  return res;
}

int main()
{
  std::vector<pair> list = make_list();
  B &ref = list[1]._b;
  ref.run();
}
</code>```

答:
```<code>#include <iostream>
#include <string>
#include <vector>
#include <math.h>

class Materials {
public:
    Materials() = default;
};

class A {
private:
    std::vector<Materials> _storage;

public:
    void setStorage(const std::vector<Materials> &val) {
        _storage = val;
    }
};

class B {
private:
    A _a;

public:
    B(A &foo) : _a(foo) {}

    void run() {
        std::vector<Materials> val;
        for (int i = 0; i < 1000; i++) {
            val.push_back(Materials{});
        }

        _a.setStorage(val);
    }
};

struct pair1 {
    pair1(const A &a, const B &b)
        : _a(a)
        , _b(b)
    {
    }
    //pair1(const pair1& p) :pair1(p._a, p._b) {}

    A _a;
    B _b;
};

std::vector<pair1> make_list() {
    std::vector<pair1> res;
    for (int i = 0; i < 10; i++) {
        A a;
        B b(a);
        pair1 p(a, b);
        res.push_back(p);
    }
    return res;
}

int main()
{
    std::vector<pair1> list = make_list();
    B &ref = list.at(1)._b;
    ref.run();
}
</code>```

1. You don't use move sematics

You can change Materials() because look like a function Materials{} look like a constructor

Problem is A &_a change to A _a

Probably name struct, because in standard library is pair, and you define too pair

You should use list.at(1) no list[1], because first solution give more information ( exception etc.)

Body:
I wrote an example which leads with Visual to a crash. I think the critical section is here:

A a;
B b(a);
pair p(a, b);
res.push_back(p);

I assign a temporary which takes a reference to another temporary and move it into a vector. I also noticed that the program seems not to crash with GCC. I think the problem is, that the reference is invalidated since the moment I move the objects into the vector. Do I have to use new?

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

// Example program
#include <iostream>
#include <string>
#include <vector>
#include <math.h>

class Materials {
public:
  Materials() = default;
};

class A {
private:
  std::vector<Materials> _storage;

public:
  void setStorage(const std::vector<Materials> &val) {
    _storage = val;
  }
};

class B {
private:
  A &_a;

public:
  B(A &foo) : _a(foo) {}

  void run() {
    std::vector<Materials> val;
    for (int i = 0; i < 1000; i++) {
      val.push_back(Materials());
    }

    _a.setStorage(val);
  }
};

struct pair {
  pair(const A &a, const B &b)
    : _a(a)
    , _b(b)
  {
  }

  A _a;
  B _b;
};

std::vector<pair> make_list() {
  std::vector<pair> res;
  for (int i = 0; i < 10; i++) {
    A a;
    B b(a);
    pair p(a, b);
    res.push_back(p);
  }
  return res;
}

int main()
{
  std::vector<pair> list = make_list();
  B &ref = list[1]._b;
  ref.run();
}

Body:
#include <iostream>
#include <string>
#include <vector>
#include <math.h>

class Materials {
public:
    Materials() = default;
};

class A {
private:
    std::vector<Materials> _storage;

public:
    void setStorage(const std::vector<Materials> &val) {
        _storage = val;
    }
};

class B {
private:
    A _a;

public:
    B(A &foo) : _a(foo) {}

    void run() {
        std::vector<Materials> val;
        for (int i = 0; i < 1000; i++) {
            val.push_back(Materials{});
        }

        _a.setStorage(val);
    }
};

struct pair1 {
    pair1(const A &a, const B &b)
        : _a(a)
        , _b(b)
    {
    }
    //pair1(const pair1& p) :pair1(p._a, p._b) {}

    A _a;
    B _b;
};

std::vector<pair1> make_list() {
    std::vector<pair1> res;
    for (int i = 0; i < 10; i++) {
        A a;
        B b(a);
        pair1 p(a, b);
        res.push_back(p);
    }
    return res;
}

int main()
{
    std::vector<pair1> list = make_list();
    B &ref = list.at(1)._b;
    ref.run();
}

1. You don't use move sematics

You can change Materials() because look like a function Materials{} look like a constructor

Problem is A &_a change to A _a

Probably name struct, because in standard library is pair, and you define too pair

You should use list.at(1) no list[1], because first solution give more information ( exception etc.)


问:
Send Intent from Activity to another Activity with RecyclerView
I have an Activity where I enter a phone number and a message and when I click on the send Button, I want to display the message and number I entered in the layout of another Activity which has a RecyclerView. I have tried to use an Intent but it displays "NUMBER" and "NUMBER" in both TextViews.
This is some of the code below.

```<code>public class NewMessageActivity extends AppCompatActivity {

private String message, number;
private EditText mComposeMessage, mPhoneNumber;
private Button mSendButton, mCancelButton;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.new_message_layout);

    mPhoneNumber = (EditText) findViewById(R.id.phone_number_et);
    mComposeMessage = (EditText) findViewById(R.id.compose_et);
    mSendButton = (Button) findViewById(R.id.send_button);
    mCancelButton = (Button) findViewById(R.id.cancel_button);

    number = mPhoneNumber.getText().toString();
    message = mComposeMessage.getText().toString();

    mSendButton.setOnClickListener(mButtonClickListener);
    mCancelButton.setOnClickListener(mButtonClickListener);
}

private View.OnClickListener mButtonClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int id = v.getId();

        switch (id) {
            case R.id.send_button:
                Intent intent = new Intent(v.getContext(), SentActivity.class);
                intent.putExtra(getString(R.string.key_message), message);
                intent.putExtra("NUMBER", number);
                startActivity(intent);
                break;

            case R.id.cancel_button:
                break;
        }
    }
};

}
</code>```

This is my Adapter

```<code>public class SentMessageAdapter extends RecyclerView.Adapter<SentMessageAdapter.MessageHolder> {
private List<String> mMessages;

public static class MessageHolder extends RecyclerView.ViewHolder {
    private TextView mSentMessageTv;
    private TextView mRecipientNumberTv;
    private TextView mRecipientTv;

    public MessageHolder(View v){
        super(v);
        mSentMessageTv = (TextView) v.findViewById(R.id.sent_message_tv);
        mRecipientNumberTv = (TextView) v.findViewById(R.id.recipient_number_tv);
        mRecipientTv = (TextView) v.findViewById(R.id.recipient_tv);
    }
}

public SentMessageAdapter(List<String> messages){
    mMessages = messages;
}

@Override
public MessageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.sent_list_item, parent, false);
    MessageHolder vH = new MessageHolder(v);
    return vH;
}

@Override
public void onBindViewHolder(MessageHolder holder, int position) {
    holder.mSentMessageTv.setText(mMessages.get(position));
    holder.mRecipientNumberTv.setText(mMessages.get(position));
    holder.mRecipientTv.setText(R.string.to);
}

@Override
public int getItemCount() {
    return mMessages.size();
}

}
</code>```

Activity where the text should be displayed

```<code>public class SentActivity extends AppCompatActivity {

private static final String LOG_TAG = SentActivity.class.getSimpleName();

private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;

final ArrayList<String> messages = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.message_recycler_list);

    Bundle extras = getIntent().getExtras();
    String message = null;

    if (extras != null){
        message = extras.getString(String.valueOf(R.string.key_message), String.valueOf("NUMBER"));
    }

    if (message == null){
        message = "text";
    }
    Log.d(LOG_TAG, message);
    messages.add(0, message);

    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();

    mRecyclerView = (RecyclerView) findViewById(R.id.message_recycler_view);
    mLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLayoutManager);

    mAdapter = new SentMessageAdapter(messages);
    mRecyclerView.setAdapter(mAdapter);
    mAdapter.notifyDataSetChanged();
}

}
</code>```

Layout for the Activity

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">

<TextView
    android:id="@+id/sent_message_tv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dp"
    tools:text="Hello world"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="4dp"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/recipient_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="@string/to"/>

    <TextView
        android:id="@+id/recipient_number_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="4dp"
        android:paddingStart="4dp"
        android:paddingRight="4dp"
        android:paddingEnd="4dp" />
</LinearLayout>

</LinearLayout>
</code>```

答:
My mistake. I have fixed it now. I created a POJO class

```<code>public class Message {
private String mMessage;
private String mNumber;

public Message(String number, String message){
    mNumber = number;
    mMessage = message;
}

public String getMessage() {
    return mMessage;
}

public String getNumber() {
    return mNumber;
}

}
</code>```

Then I changed the onBindViewHolder() to

```<code>@Override
public void onBindViewHolder(MessageHolder holder, int position) {
    holder.mSentMessageTv.setText(mMessages.get(position).getMessage());
    holder.mRecipientNumberTv.setText(mMessages.get(position).getNumber());
    holder.mRecipientTv.setText(R.string.to);
}
</code>```

I also changed to

```<code>String message = null;
    String number = null;

    if (extras != null){
        message = extras.getString(String.valueOf("MESSAGE"));
        number = extras.getString(String.valueOf("NUMBER"));

    }

    messages.add(new Message(number, message));
</code>```

Finally, I changed all generics to

```<code><Message>
</code>```

Body:
I have an Activity where I enter a phone number and a message and when I click on the send Button, I want to display the message and number I entered in the layout of another Activity which has a RecyclerView. I have tried to use an Intent but it displays "NUMBER" and "NUMBER" in both TextViews.
This is some of the code below.

public class NewMessageActivity extends AppCompatActivity {

private String message, number;
private EditText mComposeMessage, mPhoneNumber;
private Button mSendButton, mCancelButton;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.new_message_layout);

    mPhoneNumber = (EditText) findViewById(R.id.phone_number_et);
    mComposeMessage = (EditText) findViewById(R.id.compose_et);
    mSendButton = (Button) findViewById(R.id.send_button);
    mCancelButton = (Button) findViewById(R.id.cancel_button);

    number = mPhoneNumber.getText().toString();
    message = mComposeMessage.getText().toString();

    mSendButton.setOnClickListener(mButtonClickListener);
    mCancelButton.setOnClickListener(mButtonClickListener);
}

private View.OnClickListener mButtonClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int id = v.getId();

        switch (id) {
            case R.id.send_button:
                Intent intent = new Intent(v.getContext(), SentActivity.class);
                intent.putExtra(getString(R.string.key_message), message);
                intent.putExtra("NUMBER", number);
                startActivity(intent);
                break;

            case R.id.cancel_button:
                break;
        }
    }
};

}

This is my Adapter

public class SentMessageAdapter extends RecyclerView.Adapter<SentMessageAdapter.MessageHolder> {
private List<String> mMessages;

public static class MessageHolder extends RecyclerView.ViewHolder {
    private TextView mSentMessageTv;
    private TextView mRecipientNumberTv;
    private TextView mRecipientTv;

    public MessageHolder(View v){
        super(v);
        mSentMessageTv = (TextView) v.findViewById(R.id.sent_message_tv);
        mRecipientNumberTv = (TextView) v.findViewById(R.id.recipient_number_tv);
        mRecipientTv = (TextView) v.findViewById(R.id.recipient_tv);
    }
}

public SentMessageAdapter(List<String> messages){
    mMessages = messages;
}

@Override
public MessageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.sent_list_item, parent, false);
    MessageHolder vH = new MessageHolder(v);
    return vH;
}

@Override
public void onBindViewHolder(MessageHolder holder, int position) {
    holder.mSentMessageTv.setText(mMessages.get(position));
    holder.mRecipientNumberTv.setText(mMessages.get(position));
    holder.mRecipientTv.setText(R.string.to);
}

@Override
public int getItemCount() {
    return mMessages.size();
}

}

Activity where the text should be displayed

public class SentActivity extends AppCompatActivity {

private static final String LOG_TAG = SentActivity.class.getSimpleName();

private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;

final ArrayList<String> messages = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.message_recycler_list);

    Bundle extras = getIntent().getExtras();
    String message = null;

    if (extras != null){
        message = extras.getString(String.valueOf(R.string.key_message), String.valueOf("NUMBER"));
    }

    if (message == null){
        message = "text";
    }
    Log.d(LOG_TAG, message);
    messages.add(0, message);

    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();

    mRecyclerView = (RecyclerView) findViewById(R.id.message_recycler_view);
    mLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLayoutManager);

    mAdapter = new SentMessageAdapter(messages);
    mRecyclerView.setAdapter(mAdapter);
    mAdapter.notifyDataSetChanged();
}

}

Layout for the Activity

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">

<TextView
    android:id="@+id/sent_message_tv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="4dp"
    tools:text="Hello world"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="4dp"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/recipient_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="@string/to"/>

    <TextView
        android:id="@+id/recipient_number_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="4dp"
        android:paddingStart="4dp"
        android:paddingRight="4dp"
        android:paddingEnd="4dp" />
</LinearLayout>

</LinearLayout>

Body:
My mistake. I have fixed it now. I created a POJO class

public class Message {
private String mMessage;
private String mNumber;

public Message(String number, String message){
    mNumber = number;
    mMessage = message;
}

public String getMessage() {
    return mMessage;
}

public String getNumber() {
    return mNumber;
}

}

Then I changed the onBindViewHolder() to

@Override
public void onBindViewHolder(MessageHolder holder, int position) {
    holder.mSentMessageTv.setText(mMessages.get(position).getMessage());
    holder.mRecipientNumberTv.setText(mMessages.get(position).getNumber());
    holder.mRecipientTv.setText(R.string.to);
}

I also changed to

String message = null;
    String number = null;

    if (extras != null){
        message = extras.getString(String.valueOf("MESSAGE"));
        number = extras.getString(String.valueOf("NUMBER"));

    }

    messages.add(new Message(number, message));

Finally, I changed all generics to

<Message>


问:
AngularJS jQuery include old project
I have a very large project written with jQuery. Now I'm using AngularJS, but I need to load (possibly in a div tag) my old project. It seems to use ng-include, but my old project includes many scripts and some JS code generated by PHP. So using ng-include isn't helpful because the JS code inside this old-project.php doesn't work. Is there any way to open my old-project.php in a div in my AngularJS app?

答: Adding ng-include would include your project inside the angular js framework like a partial view so jquery script wont work inside angularjs framework. Using iframe would add your project as an seperate frame so that wont affect the framework and also your scripts inside the iframe</p>

Title: AngularJS jQuery include old project


问:
How do I change the letter spacing in a UILabel?
I want to change the spacing between digits in a UIKit UILabel so that it is equal.

With standard spacing, the label looks like this:

I'd like it to look like this:

How can this be achieved?

答:
The NSKernAttributeName can be used.

But in correction to the other answers: Do not apply to the full text length, but (text.length - 1).

The negative or positive spacing is added to the letter and this is not required for the last one. Assume you would add a positive spacing it would end up in a spacing after the last letter. A centered string would not appear to be centered anymore. The same applies for negative spacing.

```<code>NSString *text = @"Sample Text";
UILabel *label = [UILabel new]

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString: text];
[attributedString addAttribute:NSKernAttributeName value:[NSNumber numberWithDouble:-1.0] range:NSMakeRange(0, text.length-1)];

[label setAttributedTitle:attributedString forState:UIControlStateNormal];
</code>```

Applied to full text length.

Applied to (text length - 1).

Body:
The NSKernAttributeName can be used.

But in correction to the other answers: Do not apply to the full text length, but (text.length - 1).

The negative or positive spacing is added to the letter and this is not required for the last one. Assume you would add a positive spacing it would end up in a spacing after the last letter. A centered string would not appear to be centered anymore. The same applies for negative spacing.

NSString *text = @"Sample Text";
UILabel *label = [UILabel new]

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString: text];
[attributedString addAttribute:NSKernAttributeName value:[NSNumber numberWithDouble:-1.0] range:NSMakeRange(0, text.length-1)];

[label setAttributedTitle:attributedString forState:UIControlStateNormal];

Applied to full text length.

Applied to (text length - 1).


问:
javascript - Google Maps Full Screen Button Not Working ( Non-google maps app )
As shown below, beides the '+' icon is the full screen button.

When clicked on it, it does not go full screen.

I tried basic jQuery :

```<code> $("#fullScreen-btn").css({height: 100%, width: 100%});
</code>```

This does not seem to work.

I need it to work like we press F11 on browsers, it must go full screen on mobile (not the google maps app)

Can anyone help me out here ?

答:
You can activate full screen mode using JavaScript without jQuery.

```<code><!DOCTYPE html>

<html>

<head>
    <title>Full Screen Test</title>
</head>

<body id="body">
    <h1>test</h1>

    <script>
    var elem = document.getElementById("body");

    elem.onclick = function() {
        req = elem.requestFullScreen || elem.webkitRequestFullScreen || elem.mozRequestFullScreen;
        req.call(elem);
    }
    </script>
</body>

</html>
</code>```

One thing that is important to note, you can only request full screen mode  when a user performs an action (e.g. a click). You can't request full screen mode without a user action1 (e.g. on page load).

Here is a cross browser function to toggle full screen mode (as obtained from the MDN):

```<code>function toggleFullScreen() {
  if (!document.fullscreenElement &&    // alternative standard method
      !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {  // current working methods
    if (document.documentElement.requestFullscreen) {
      document.documentElement.requestFullscreen();
    } else if (document.documentElement.msRequestFullscreen) {
      document.documentElement.msRequestFullscreen();
    } else if (document.documentElement.mozRequestFullScreen) {
      document.documentElement.mozRequestFullScreen();
    } else if (document.documentElement.webkitRequestFullscreen) {
      document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
    }
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
  }
}
</code>```

For more information, check out the MDN page on full screen APIs.

If you need a plugin that supports versions of IE prior to IE11 (IE8-10), take a look at jQuery.fullscreen. IE did not support this feature natively until IE11.

Body:
As shown below, beides the '+' icon is the full screen button.

When clicked on it, it does not go full screen.

I tried basic jQuery :

 $("#fullScreen-btn").css({height: 100%, width: 100%});

This does not seem to work.

I need it to work like we press F11 on browsers, it must go full screen on mobile (not the google maps app)

Can anyone help me out here ?

Body:
You can activate full screen mode using JavaScript without jQuery.

<!DOCTYPE html>

<html>

<head>
    <title>Full Screen Test</title>
</head>

<body id="body">
    <h1>test</h1>

    <script>
    var elem = document.getElementById("body");

    elem.onclick = function() {
        req = elem.requestFullScreen || elem.webkitRequestFullScreen || elem.mozRequestFullScreen;
        req.call(elem);
    }
    </script>
</body>

</html>

One thing that is important to note, you can only request full screen mode  when a user performs an action (e.g. a click). You can't request full screen mode without a user action1 (e.g. on page load).

Here is a cross browser function to toggle full screen mode (as obtained from the MDN):

function toggleFullScreen() {
  if (!document.fullscreenElement &&    // alternative standard method
      !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {  // current working methods
    if (document.documentElement.requestFullscreen) {
      document.documentElement.requestFullscreen();
    } else if (document.documentElement.msRequestFullscreen) {
      document.documentElement.msRequestFullscreen();
    } else if (document.documentElement.mozRequestFullScreen) {
      document.documentElement.mozRequestFullScreen();
    } else if (document.documentElement.webkitRequestFullscreen) {
      document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
    }
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
  }
}

For more information, check out the MDN page on full screen APIs.

If you need a plugin that supports versions of IE prior to IE11 (IE8-10), take a look at jQuery.fullscreen. IE did not support this feature natively until IE11.


问:
(D3) dispatching "mousedown" event to selection with drag behaviour throws error
Title says pretty much all, trying to dispatch mousedown event to selection that have drag behaviour set up throws "TypeError: Cannot read property 'document' of undefined", example is in snippet.

I'm trying to think of some workaround, because I have to pass mousedown to element I add at mouse cursor to drag it without pressing mouse button twice. Any input is very appreciated.

d3.select('#dragable').call(d3.drag().on('drag', function() {
  d3.select(this).style('left', d3.event.x + 'px');
  d3.select(this).style('top', d3.event.y + 'px');
}))

d3.select('#dragable').dispatch('mousedown');```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#dragable {
  position: absolute;
  left: 0;
  top: 0;
  background: red;
  width: 50px;
  height: 50px;
}</code>```

```

EDIT:

I tinkered around in debugger, and it seems that when firing from dispatcher, CustomEvent object passed to d3-drag is missing view variable. So theoreticaly adding Window object to it could fix it. I have no idea though how to do it, or rather how to do it without modifying d3 source.

答:
Try to add

.on('start', function() {
  dispatch.call("mousedown", this);
});

to drag function and after

```<code>var dispatch = d3.dispatch('mousedown');
dispatch.on('mousedown', function(){ });
</code>```

Body:
Title says pretty much all, trying to dispatch mousedown event to selection that have drag behaviour set up throws "TypeError: Cannot read property 'document' of undefined", example is in snippet.

I'm trying to think of some workaround, because I have to pass mousedown to element I add at mouse cursor to drag it without pressing mouse button twice. Any input is very appreciated.

d3.select('#dragable').call(d3.drag().on('drag', function() {
  d3.select(this).style('left', d3.event.x + 'px');
  d3.select(this).style('top', d3.event.y + 'px');
}))

d3.select('#dragable').dispatch('mousedown');

#dragable {
  position: absolute;
  left: 0;
  top: 0;
  background: red;
  width: 50px;
  height: 50px;
}

EDIT:

I tinkered around in debugger, and it seems that when firing from dispatcher, CustomEvent object passed to d3-drag is missing view variable. So theoreticaly adding Window object to it could fix it. I have no idea though how to do it, or rather how to do it without modifying d3 source.

Body:
Try to add

.on('start', function() {
  dispatch.call("mousedown", this);
});

to drag function and after

var dispatch = d3.dispatch('mousedown');
dispatch.on('mousedown', function(){ });


问:
Wrong value returned when using MIN Fuctions with nested IF - Excel
I'm currently using the following function to calulcate the min value of any array based on several criteria and getting the correct answer:

```<code>=MIN(IF(Table5[G]="M"; IF(Table5[Level]=A3;Table5[Salary]);"-"))
</code>```

But I wanted to expand the function by adding an OR statement in the second IF statement:

```<code> =MIN(IF(Table5[G]="M"; IF(***OR(Table5[Level]=TEXT(A2;0);Table5[Level]=VALUE(A2))**;*Table5[Salary]);"-"))
</code>```

For the range of A2:A16 I'm getting the exact same number ( Min value ) which is incorrect.

Any Ideas?

答:
Without data (and its format) I am not sure quite what is required but you are dealing with structured references that are arrays so may need syntax like this:</p>

```<code>=MIN(IF((Table5[G]="M")*((Table5[Level]=A2)+(Table5[Level]=TEXT(A2;"0")));(Table5[Salary]);"-"))
</code>```

Body:
I'm currently using the following function to calulcate the min value of any array based on several criteria and getting the correct answer:

=MIN(IF(Table5[G]="M"; IF(Table5[Level]=A3;Table5[Salary]);"-"))

But I wanted to expand the function by adding an OR statement in the second IF statement:

 =MIN(IF(Table5[G]="M"; IF(***OR(Table5[Level]=TEXT(A2;0);Table5[Level]=VALUE(A2))**;*Table5[Salary]);"-"))

For the range of A2:A16 I'm getting the exact same number ( Min value ) which is incorrect.

Any Ideas?

Body:
Without data (and its format) I am not sure quite what is required but you are dealing with structured references that are arrays so may need syntax like this:

=MIN(IF((Table5[G]="M")*((Table5[Level]=A2)+(Table5[Level]=TEXT(A2;"0")));(Table5[Salary]);"-"))


问:
how set LocalContainerEntityManagerFactoryBean to JpaTransactionManager?
In oficial documentation of spring this write next:

```<code>@Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.acme.domain");
    factory.setDataSource(dataSource());
    return factory;
  }

  @Bean
  public PlatformTransactionManager transactionManager() {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory());
    return txManager;
  }
</code>```

and

It’s important to create LocalContainerEntityManagerFactoryBean and
  not EntityManagerFactory directly since the former also participates
  in exception translation mechanisms besides simply creating
  EntityManagerFactory.

But when I tried use it I get error:

```<code>setEntityManagerFactory
(javax.persistence.EntityManagerFactory)
in JpaTransactionManager cannot be applied
to
(org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean)
</code>```

it is my imports:

```<code>import org.apache.tomcat.jdbc.pool.DataSourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
</code>```

答:
Your configuration looks correct. Only change your transactionManager definition as below:

```<code>@Bean
public PlatformTransactionManager transactionManager() {

  JpaTransactionManager txManager = new JpaTransactionManager();
  txManager.setEntityManagerFactory(entityManagerFactory().getObject());
  return txManager;
}
</code>```

The getObject() method return singleton EntityManagerFactory.

Body:
In oficial documentation of spring this write next:

@Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.acme.domain");
    factory.setDataSource(dataSource());
    return factory;
  }

  @Bean
  public PlatformTransactionManager transactionManager() {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory());
    return txManager;
  }

and

It’s important to create LocalContainerEntityManagerFactoryBean and
  not EntityManagerFactory directly since the former also participates
  in exception translation mechanisms besides simply creating
  EntityManagerFactory.

But when I tried use it I get error:

setEntityManagerFactory
(javax.persistence.EntityManagerFactory)
in JpaTransactionManager cannot be applied
to
(org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean)

it is my imports:

import org.apache.tomcat.jdbc.pool.DataSourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

Body:
Your configuration looks correct. Only change your transactionManager definition as below:

@Bean
public PlatformTransactionManager transactionManager() {

  JpaTransactionManager txManager = new JpaTransactionManager();
  txManager.setEntityManagerFactory(entityManagerFactory().getObject());
  return txManager;
}

The getObject() method return singleton EntityManagerFactory.


问:
Javascript EJS string literal
I am trying to pull a graphviz format string from my database and pass to a javascript function on my browser front end. I am using NodeJS and EJS as the view engine. The following code is on my index.ejs to take the array of graph formats, graph_format and send to the viz.js function:

```<code>    <script>
window.onload=function(){
  console.log("converting ejs to javascrpt")

  var jscgraph=[];
  <% graph_formats.forEach(function(graph){%>
    for(var i=0;i<graph_formats.length;i++){
      var r = "";
      r=r.concat("\"");
      r=r.concat(<%- graph%>;
      r=r.concat("\"");
      document.body.innerHTML += Viz(r);
    }
  <%
  })
  %>

  console.log("now printing javascript variable 1"+jscgraph[1])
}
</script>
</code>```

However, I get a "SyntaxError: missing ) after argument list[Learn More]  graphviz:206:24" error in the console of my browser and the lines "
      console.log("converting ejs to javascrpt")" and
      "console.log("now printing javascript variable 1"+jscgraph[1])" do not run.

When I go to the browser debugger at line 206 as per error message, I see the following:

```<code><script>
window.onload=function(){
  console.log("converting ejs to javascrpt")

  var jscgraph=[];

    for(var i=0;i<graph_formats.length;i++){
      var r = "";
      r=r.concat("\"");
      r=r.concat(digraph{
});
      r=r.concat("\"");
      document.body.innerHTML += Viz(r);
    }
</code>```

Where 206 is the line r=r.concat(digraph{});

He is the graph_format array copied and pasted from the nodejs console for completeness:

[ 'digraph{\n}\n\n\n\n\n\n',
  'digraph{\n0 [label="PUSH4", style=filled, color=antiquewhite]\n1 [label="PUSH1", style=filled, color=antiquewhite]\n2 [label="PUSH1", style=filled, color=antiquewhite]\n3 [label="EXP", style=filled, color=coral4]\n1 -> 3 [label="00000000000000000000000000000000000000000000000000000000000000e0", fontcolor=antiquewhite]\n2 -> 3 [label="0000000000000000000000000000000000000000000000000000000000000002", fontcolor=antiquewhite]\n4 [label="PUSH1", style=filled, color=antiquewhite]\n5 [label="CALLDATALOAD", style=filled, color=darkorchid4]\n4 -> 5 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n6 [label="DIV", style=filled, color=chocolate3]\n3 -> 6 [label="0000000100000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n5 -> 6 [label="1896f70a8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88", fontcolor=antiquewhite]\n7 [label="EQ", style=filled, color=gold4]\n0 -> 7 [label="000000000000000000000000000000000000000000000000000000000178b8bf", fontcolor=antiquewhite]\n6 -> 7 [label="000000000000000000000000000000000000000000000000000000001896f70a", fontcolor=antiquewhite]\n8 [label="ISZERO", style=filled, color=goldenrod]\n7 -> 8 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n9 [label="PUSH2", style=filled, color=antiquewhite]\n10 [label="JUMPI", style=filled, color=burlywood1]\n8 -> 10 [label="0000000000000000000000000000000000000000000000000000000000000001", fontcolor=antiquewhite]\n9 -> 10 [label="0000000000000000000000000000000000000000000000000000000000000023", fontcolor=antiquewhite]\n11 [label="JUMPDEST", style=filled, color=magenta]\n12 [label="PUSH4", style=filled, color=antiquewhite]\n13 [label="PUSH1", style=filled, color=antiquewhite]\n14 [label="PUSH1", style=filled, color=antiquewhite]\n15 [label="EXP", style=filled, color=coral4]\n13 -> 15 [label="00000000000000000000000000000000000000000000000000000000000000e0", fontcolor=antiquewhite]\n14 -> 15 [label="0000000000000000000000000000000000000000000000000000000000000002", fontcolor=antiquewhite]\n16 [label="PUSH1", style=filled, color=antiquewhite]\n17 [label="CALLDATALOAD", style=filled, color=darkorchid4]\n16 -> 17 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n18 [label="DIV", style=filled, color=chocolate3]\n15 -> 18 [label="0000000100000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n17 -> 18 [label="1896f70a8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88", fontcolor=antiquewhite]\n19 [label="EQ", style=filled, color=gold4]\n12 -> 19 [label="0000000000000000000000000000000000000000000000000000000002571be3", fontcolor=antiquewhite]\n18 -> 19 [label="000000000000000000000000000000000000000000000000000000001896f70a", fontcolor=antiquewhite]\n20 [label="ISZERO", style=filled, color=goldenrod]\n19 -> 20 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n21 [label="PUSH2", style=filled, color=antiquewhite]\n22 [label="JUMPI", style=filled, color=burlywood1]\n20 -> 22 [label="0000000000000000000000000000000000000000000000000000000000000001", fontcolor=antiquewhite]\n21 -> 22 [label="0000000000000000000000000000000000000000000000000000000000000047", fontcolor=antiquewhite]\n23 [label="JUMPDEST", style=filled, color=magenta]\n24 [label="PUSH4", style=filled, color=antiquewhite]\n25 [label="PUSH1", style=filled, color=antiquewhite]\n26 [label="PUSH1", style=filled, color=antiquewhite]\n27 [label="EXP", style=filled, color=coral4]\n25 -> 27 [label="00000000000000000000000000000000000000000000000000000000000000e0", fontcolor=antiquewhite]\n26 -> 27 [label="0000000000000000000000000000000000000000000000000000000000000002", fontcolor=antiquewhite]\n28 [label="PUSH1", style=filled, color=antiquewhite]\n29 [label="CALLDATALOAD", style=filled, color=darkorchid4]\n28 -> 29 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n30 [label="DIV", style=filled, color=chocolate3]\n27 -> 30 [label="0000000100000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n29 -> 30 [label="1896f70a8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88", fontcolor=antiquewhite]\n31 [label="EQ", style=filled, color=gold4]\n24 -> 31 [label="0000000000000000000000000000000000000000000000000000000016a25cbd", fontcolor=antiquewhite]\n30 -> 31 [label="000000000000000000000000000000000000000000000000000000001896f70a", fontcolor=antiquewhite]\n32 [label="ISZERO", style=filled, color=goldenrod]\n31 -> 32 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n33 [label="PUSH2", style=filled, color=antiquewhite]\n34 [label="JUMPI", style=filled, color=burlywood1]\n32 -> 34 [label="0000000000000000000000000000000000000000000000000000000000000001", fontcolor=antiquewhite]\n33 -> 34 [label="000000000000000000000000000000000000000000000000000000000000006b", fontcolor=antiquewhite]\n35 [label="JUMPDEST", style=filled, color=magenta]\n36 [label="PUSH4", style=filled, color=antiquewhite]\n37 [label="PUSH1", style=filled, color=antiquewhite]\n38 [label="PUSH1", style=filled, color=antiquewhite]\n39 [label="EXP", style=filled, color=coral4]\n37 -> 39 [label="00000000000000000000000000000000000000000000000000000000000000e0", fontcolor=antiquewhite]\n38 -> 39 [label="0000000000000000000000000000000000000000000000000000000000000002", fontcolor=antiquewhite]\n40 [label="PUSH1", style=filled, color=antiquewhite]\n41 [label="CALLDATALOAD", style=filled, color=darkorchid4]\n40 -> 41 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n42 [label="DIV", style=filled, color=chocolate3]\n39 -> 42 [label="0000000100000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n41 -> 42 [label="1896f70a8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88", fontcolor=antiquewhite]\n43 [label="EQ", style=filled, color=gold4]\n36 -> 43 [label="000000000000000000000000000000000000000000000000000000005b0fc9c3", fontcolor=antiquewhite]\n42 -> 43 [label="000000000000000000000000000000000000000000000000000000001896f70a", fontcolor=antiquewhite]\n44 [label="ISZERO", style=filled, color=goldenrod]\n43 -> 44 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n45 [label="PUSH2", style=filled, color=antiquewhite]\n46 [label="JUMPI", style=filled, color=burlywood1]\n44 -> 46 [label="0000000000000000000000000000000000000000000000000000000000000001", fontcolor=antiquewhite]\n45 -> 46 [label="00000000000000000000000000000000000000000000000000000000000000b8", fontcolor=antiquewhite]\n47 [label="JUMPDEST", style=filled, color=magenta]\n48 [label="PUSH4", style=filled, color=antiquewhite]\n49 [label="PUSH1", style=filled, color=antiquewhite]\n50 [label="PUSH1", style=filled, color=antiquewhite]\n51 [label="EXP", style=filled, color=coral4]\n49 -> 51 [label="00000000000000000000000000000000000000000000000000000000000000e0", fontcolor=antiquewhite]\n50 -> 51 [label="0000000000000000000000000000000000000000000000000000000000000002", fontcolor=antiquewhite]\n52 [label="PUSH1", style=filled, color=antiquewhite]\n53 [label="CALLDATALOAD", style=filled, color=darkorchid4]\n52 -> 53 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n54 [label="DIV", style=filled, color=chocolate3]\n51 -> 54 [label="0000000100000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n53 -> 54 [label="1896f70a8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88", fontcolor=antiquewhite]\n55 [label="EQ", style=filled, color=gold4]\n48 -> 55 [label="0000000000000000000000000000000000000000000000000000000006ab5923", fontcolor=antiquewhite]\n54 -> 55 [label="000000000000000000000000000000000000000000000000000000001896f70a", fontcolor=antiquewhite]\n56 [label="ISZERO", style=filled, color=goldenrod]\n55 -> 56 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n57 [label="PUSH2", style=filled, color=antiquewhite]\n58 [label="JUMPI", style=filled, color=burlywood1]\n56 -> 58 [label="0000000000000000000000000000000000000000000000000000000000000001", fontcolor=antiquewhite]\n57 -> 58 [label="0000000000000000000000000000000000000000000000000000000000000116", fontcolor=antiquewhite]\n59 [label="JUMPDEST", style=filled, color=magenta]\n60 [label="PUSH4", style=filled, color=antiquewhite]\n61 [label="PUSH1", style=filled, color=antiquewhite]\n62 [label="PUSH1", style=filled, color=antiquewhite]\n63 [label="EXP", style=filled, color=coral4]\n61 -> 63 [label="00000000000000000000000000000000000000000000000000000000000000e0", fontcolor=antiquewhite]\n62 -> 63 [label="0000000000000000000000000000000000000000000000000000000000000002", fontcolor=antiquewhite]\n64 [label="PUSH1", style=filled, color=antiquewhite]\n65 [label="CALLDATALOAD", style=filled, color=darkorchid4]\n64 -> 65 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n66 [label="DIV", style=filled, color=chocolate3]\n63 -> 66 [label="0000000100000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n65 -> 66 [label="1896f70a8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88", fontcolor=antiquewhite]\n67 [label="EQ", style=filled, color=gold4]\n60 -> 67 [label="000000000000000000000000000000000000000000000000000000001896f70a", fontcolor=antiquewhite]\n66 -> 67 [label="000000000000000000000000000000000000000000000000000000001896f70a", fontcolor=antiquewhite]\n68 [label="ISZERO", style=filled, color=goldenrod]\n67 -> 68 [label="0000000000000000000000000000000000000000000000000000000000000001", fontcolor=antiquewhite]\n69 [label="PUSH2", style=filled, color=antiquewhite]\n70 [label="JUMPI", style=filled, color=burlywood1]\n68 -> 70 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n69 -> 70 [label="0000000000000000000000000000000000000000000000000000000000000163", fontcolor=antiquewhite]\n71 [label="PUSH1", style=filled, color=antiquewhite]\n72 [label="PUSH1", style=filled, color=antiquewhite]\n73 [label="CALLDATALOAD", style=filled, color=darkorchid4]\n72 -> 73 [label="0000000000000000000000000000000000000000000000000000000000000004", fontcolor=antiquewhite]\n74 [label="ADD", style=filled, color=chocolate]\n71 -> 74 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n73 -> 74 [label="8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88f650c575", fontcolor=antiquewhite]\n75 [label="SLOAD", style=filled, color=chartreuse]\n74 -> 75 [label="8851b17a825ca0cfde09020276ebce9c64cb69476c3b2e27299ccc88f650c575", fontcolor=antiquewhite]\n76 [label="CALLER", style=filled, color=darkorchid2]\n77 [label="EQ", style=filled, color=gold4]\n75 -> 77 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n76 -> 77 [label="00000000000000000000000065ddc3a1f2762f3d0669bbeea44e16b2b38090a5", fontcolor=antiquewhite]\n78 [label="ISZERO", style=filled, color=goldenrod]\n77 -> 78 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n79 [label="ISZERO", style=filled, color=goldenrod]\n78 -> 79 [label="0000000000000000000000000000000000000000000000000000000000000001", fontcolor=antiquewhite]\n80 [label="PUSH2", style=filled, color=antiquewhite]\n81 [label="JUMPI", style=filled, color=burlywood1]\n79 -> 81 [label="0000000000000000000000000000000000000000000000000000000000000000", fontcolor=antiquewhite]\n80 -> 81 [label="000000000000000000000000000000000000000000000000000000000000013d", fontcolor=antiquewhite]\n82 [label="PUSH1", style=filled, color=antiquewhite]\n83 [label="JUMP", style=filled, color=burlywood1]\n82 -> 83 [label="0000000000000000000000000000000000000000000000000000000000000002", fontcolor=antiquewhite]\n84 [label="JUMP", style=filled, color=burlywood1]\n}\n\n\n\n\n\n' ]```

Can someone please tell me what I need to do to get the viz.js function to accept this string? It accepts strings in the form of result = Viz("digraph { a -> b; }"); as per https://www.npmjs.com/package/viz.js

Thanks

答:
digraph{} is not valid JavaScript.

If you want to use an existing variable, do:

```<code>r=r.concat(digraph);
</code>```

But digraph has to be declared and initialized before.

Title: Javascript EJS string literal

Body:
I am trying to pull a graphviz format string from my database and pass to a javascript function on my browser front end. I am using NodeJS and EJS as the view engine. The following code is on my index.ejs to take the array of graph formats, graph_format and send to the viz.js function:

However, I get a "SyntaxError: missing ) after argument list[Learn More]  graphviz:206:24" error in the console of my browser and the lines "
      console.log("converting ejs to javascrpt")" and
      "console.log("now printing javascript variable 1"+jscgraph[1])" do not run.

When I go to the browser debugger at line 206 as per error message, I see the following:

Body:
digraph{} is not valid JavaScript.

If you want to use an existing variable, do:

r=r.concat(digraph);

But digraph has to be declared and initialized before.


问:
Change :hover CSS properties with JavaScript
How can JavaScript change CSS :hover properties?

For example:

HTML

```<code><table>
  <tr>
    <td>Hover 1</td>
    <td>Hover 2</td>
  </tr>
</table>
</code>```

CSS

```<code>table td:hover {
background:#ff0000;
}
</code>```

How can the td :hover properties be modified to, say, background:#00ff00, with JavaScript? I know I could access the style background property using JavaScript with:

```<code>document.getElementsByTagName("td").style.background="#00ff00";
</code>```

But I don't know of a .style JavaScript equivalent for :hover.

答:
I'd recommend to replace all :hover properties to :active when you detect that device supports touch. Just call this function when you do so as touch()

```<code>   function touch() {
      if ('ontouchstart' in document.documentElement) {
        for (var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
          var sheet = document.styleSheets[sheetI];
          if (sheet.cssRules) {
            for (var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
              var rule = sheet.cssRules[ruleI];

              if (rule.selectorText) {
                rule.selectorText = rule.selectorText.replace(':hover', ':active');
              }
            }
          }
        }
      }
    }
</code>```

Body:
How can JavaScript change CSS :hover properties?

For example:

HTML

    Hover 1
    Hover 2

CSS

table td:hover {
background:#ff0000;
}

How can the td :hover properties be modified to, say, background:#00ff00, with JavaScript? I know I could access the style background property using JavaScript with:

document.getElementsByTagName("td").style.background="#00ff00";

But I don't know of a .style JavaScript equivalent for :hover.

Body:
I'd recommend to replace all :hover properties to :active when you detect that device supports touch. Just call this function when you do so as touch()

   function touch() {
      if ('ontouchstart' in document.documentElement) {
        for (var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
          var sheet = document.styleSheets[sheetI];
          if (sheet.cssRules) {
            for (var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
              var rule = sheet.cssRules[ruleI];

              if (rule.selectorText) {
                rule.selectorText = rule.selectorText.replace(':hover', ':active');
              }
            }
          }
        }
      }
    }


问:
angularJs shift table item index to up or down
I have a table where I would like to change the order or rows by moving an item Up or Down. The element select here(T17180054) with index 3 should move up and have a new index of 2 and keep the selection preferably.

This is my HTML:

```<code><table st-safe-src="flow3.dataSet" st-table="flow3.displayed" class="table table-striped">
    <thead>
        <tr>
            <th st-sort="method">Method</th>
            <th st-sort="sample">Sample</th>
            <th st-sort="parameters">Parameters</th>
        </tr>
    </thead>
    <tbody ui-sortable ng-model="flow3.displayed">
        <tr ng-repeat="row in flow3.displayed track by $index" style="cursor: move;"
            ng-click="row.selected = !row.selected; flow3.selectRow($event, row, index)"
            ng-class="{success: row.selected}">>
            <td>{{row.method.name}}</td>
            <td>{{row.sample}}</td>
            <td>
                <span ng-repeat="parameter in row.parameters">
                    {{parameter.methodInputParameter.name}} : {{parameter.value}}<br/></span>
            </td>
            <td>
                <button type="button" ng-click="flow3.removeItem(row)"
                    class="btn btn-danger btn-sm btn-round pull-right"
                    ng-disabled="flow3.confirmDisabled">
                        <i class="glyphicon glyphicon-trash"></i>
                </button>
            </td>
        </tr>
    </tbody>
</table>
</code>```

This is my two Up and Down buttons

```<code><div class="row">
    <div class="col-xs-6">
        <div class="btn btn-info btn-lg btn-full-width">
            <span class="glyphicon glyphicon-menu-up" ng-click="flow3.moveItemUp();"></span> Up
        </div>
    </div>
    <div class="col-xs-6">
        <div class="btn btn-info btn-lg btn-full-width">
            <span class="glyphicon glyphicon-menu-down" ng-click="flow3.moveItemDown();"></span> Down
        </div>
    </div>
</div>
</code>```

This is my JS :
I have tried to use the splice method by I had wrong results each time.
Is there a better alternative?

```<code>flow3.moveItemDown = function moveItemDown() {
    var index = flow3.dataSet.indexOf(flow3.selectedItem);

    if(index == 0) {
        return;
    } else {
        flow3.dataSet.splice(?, ?, ? , ?)
    }
}
</code>```

答:
You can try this also. Its working fine for me.        </p>

```<code>// Move list items up or down or swap
    $scope.moveItem = function (origin, destination) {
        var temp = $scope.list[destination];
        $scope.list[destination] = $scope.list[origin];
        $scope.list[origin] = temp;
    };

    // Move list item Up
    $scope.listItemUp = function (itemIndex) {
        $scope.moveItem(itemIndex, itemIndex - 1);
    };

    // Move list item Down
    $scope.listItemDown = function (itemIndex) {
        $scope.moveItem(itemIndex, itemIndex + 1);
    };
</code>```

Body:
I have a table where I would like to change the order or rows by moving an item Up or Down. The element select here(T17180054) with index 3 should move up and have a new index of 2 and keep the selection preferably.

This is my HTML:

            Method
            Sample
            Parameters

>
            {{row.method.name}}
            {{row.sample}}

                    {{parameter.methodInputParameter.name}} : {{parameter.value}}

                <button type="button" ng-click="flow3.removeItem(row)"
                    class="btn btn-danger btn-sm btn-round pull-right"
                    ng-disabled="flow3.confirmDisabled">

                </button>

This is my two Up and Down buttons

             Up

             Down

This is my JS :
I have tried to use the splice method by I had wrong results each time.
Is there a better alternative?

flow3.moveItemDown = function moveItemDown() {
    var index = flow3.dataSet.indexOf(flow3.selectedItem);

    if(index == 0) {
        return;
    } else {
        flow3.dataSet.splice(?, ?, ? , ?)
    }
}

Body:
You can try this also. Its working fine for me.

// Move list items up or down or swap
    $scope.moveItem = function (origin, destination) {
        var temp = $scope.list[destination];
        $scope.list[destination] = $scope.list[origin];
        $scope.list[origin] = temp;
    };

    // Move list item Up
    $scope.listItemUp = function (itemIndex) {
        $scope.moveItem(itemIndex, itemIndex - 1);
    };

    // Move list item Down
    $scope.listItemDown = function (itemIndex) {
        $scope.moveItem(itemIndex, itemIndex + 1);
    };


问:
ag-grid angular wrong row order after initialization
I am experiencing weird behavior in ag-grid for angular and don't know if I am doing something wrong or that is a bug.

After initializing aggrid with

```<code>this.gridOptions = {
  enableSorting: true,
  rowHeight: 50,
  suppressDragLeaveHidesColumns: true,
  enableColResize: true,
  domLayout: 'autoHeight',
  rowSelection: 'single',
};
</code>```

and

```<code>  <ag-grid-angular
    #agGrid
    [rowData]="articleArray"
    [gridOptions]="gridOptions"
    (cellClicked)="showDetails($event)"
    (gridReady)="onGridReady()"
    (modelUpdated)="onModelUpdated()"
    (gridSizeChanged)="sizeToFit()"
  ></ag-grid-angular>
</code>```

And getting the resulted order of rows in the grid by

```<code>  updateArticleOrder() {
    const result: string[] = [];
    this.gridOptions.api.forEachNodeAfterFilterAndSort(rowNode => result.push(rowNode.data.id));
    this.articleOrderChanged$.emit(result);
  }
</code>```

I notice that the order is different from the original input used in [rowData]="articleArray". To be precise, 11 items have been shifted to the bottom of the grid and the grid starts at original index 11. Why is that and how can I avoid it? After sorting and updateArticleOrder() being called inside onModelUpdated() I get the right order again, with index 0 displayed when I click the first row.

[EDIT] I notice that I get this problem only when initializing the grid. When my articleArray updates after the grid is already visible, this.gridOptions.api.forEachNodeAfterFilterAndSort gives me the new items in the correct order.

答: This is probably a bug which comes from using [domLayout]="'autoHeight'". As a temporary solution try to set [rowBuffer] to some high number, eg [rowBuffer]="10000"</p>

Body:
I am experiencing weird behavior in ag-grid for angular and don't know if I am doing something wrong or that is a bug.

After initializing aggrid with

this.gridOptions = {
  enableSorting: true,
  rowHeight: 50,
  suppressDragLeaveHidesColumns: true,
  enableColResize: true,
  domLayout: 'autoHeight',
  rowSelection: 'single',
};

and

  <ag-grid-angular
    #agGrid
    [rowData]="articleArray"
    [gridOptions]="gridOptions"
    (cellClicked)="showDetails($event)"
    (gridReady)="onGridReady()"
    (modelUpdated)="onModelUpdated()"
    (gridSizeChanged)="sizeToFit()"
  ></ag-grid-angular>

And getting the resulted order of rows in the grid by

  updateArticleOrder() {
    const result: string[] = [];
    this.gridOptions.api.forEachNodeAfterFilterAndSort(rowNode => result.push(rowNode.data.id));
    this.articleOrderChanged$.emit(result);
  }

I notice that the order is different from the original input used in [rowData]="articleArray". To be precise, 11 items have been shifted to the bottom of the grid and the grid starts at original index 11. Why is that and how can I avoid it? After sorting and updateArticleOrder() being called inside onModelUpdated() I get the right order again, with index 0 displayed when I click the first row.

[EDIT] I notice that I get this problem only when initializing the grid. When my articleArray updates after the grid is already visible, this.gridOptions.api.forEachNodeAfterFilterAndSort gives me the new items in the correct order.