Categories
discuss

Attaching jQuery plugin calls to dynamically loaded elements via jQuery,on()

I have a portion of code that is dynamically loaded via an AJAX call by appending the result to a parent element, similar to this:

<div class="parent">
     <!-- Inner content loaded dynamically -->
     <div class="child">
     </div>
     <div class="child">
     </div>
     <!-- ... -->
</div>

Now, in order to hook up a mouseover event, I would do something like this:

$(".parent").on("mouseenter", ".child", function(){
 //Do fun stuff here
}

$(".parent").on("mouseleave", ".child", function(){
 //Undo fun stuff here
}

This works well enough for standard functions, but I want to attach this to a third-party plugin (in my case, HoverIntent, but really any plugin) –

The syntax for attaching the HoverIntent plugin is as so:

$(".child").hoverIntent( makeTall, makeShort )

… but I want this to work for my dynamic content that was not available at the time the document initially loaded, and something like $(".parent").on("hoverIntent", ".child", function(){}); doesn’t seem to be the right way to do this.

What is the correct approach to applying a plugin to elements loaded after the initial $(document).ready()?

Answer

jquery .on works by monitoring events on a parent object and then calling the handler if the event originated from a matched child selector. In your case, however, the event you want to monitor is that the element changed

Browsers fire the onchange event for input elements only (because they can be changed by a user).

If any other element changes, it must be because of javascript, hence you can call functions after created new content.

$(".child", parentElementContext).hoverIntent( makeTall, makeShort )

There are 2 practical solutions

1) What i typically do is create an init method that takes a context (such as the document).

MyPage.init = function(context) {
    $('.selector', context).hoverIntent();
    $('.other', context).dialog(); // any other plugins
};

Then I manually call init when I update the DOM (because i dont always need to call init when I update the dom)

$.ajax({
  url: url,
  data: data,
  success: function(data){ 
     var context = $('.parent'); 
     context.html(data);
     MyPage.init(context); //calls hoverIntent and other plugins
  }
});

2) If you really need to monitor everything, you can use this plugin http://james.padolsey.com/javascript/monitoring-dom-properties/

and then $('.parent').on('valuechange', function() { /* init plugins*/}

Categories
discuss

Is it OK to rely on an SQLiteConstraint and let SQLite do the checking for me? Is there a catch?

I have an SQLite database in Android and I use a ContentProvider to handle the operations, which are persisted to a table with a UNIQUE qualifier in a column.

Problem:

However, when I insert duplicated values into the database, it doesn’t break my code per se, but it still spits thousands of SQLiteConstraintException Log lines, and to my user that just feels like polluting the Log, something unpolished. I’ve tried catching the exception just to experiment, but it still logs.

Question:

So, how do I silent those log lines? Is that even possible?

Please read the comment below for the reason to ask the question.

Error:

Time column has the UNIQUE constraint:

Error inserting Factor=2.0 Time=1325375465000 Extra=none
android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
    at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
    at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:55)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1549)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1410)
    at mypackage.myapp.provider.DataProvider.bulkInsert(DataProvider.java:353)
    at android.content.ContentProvider$Transport.bulkInsert(ContentProvider.java:179)
    at android.content.ContentResolver.bulkInsert(ContentResolver.java:646)
    at mypackage.myapp.service.MyService.onHandleIntent(MyService.java:96)
    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:59)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.os.HandlerThread.run(HandlerThread.java:60)

Answer

If you can formulate or modify the SQL yourself, either for INSERT or for the initial CREATE TABLE, you can use SQLite’s conflict handling extensions. There are two options for how to do this:

  • When you insert, use INSERT OR IGNORE rather than just INSERT. You can also use OR REPLACE, OR ABORT, or any of several other reactions.
  • When you create the table, specify an ON CONFLICT IGNORE clause for the UNIQUE constraint. That will cause inserts or updates which violate the constraint to silently do nothing.

I find the idea of using INSERT OR IGNORE/INSERT OR REPLACE to handle duplicate data, particularly in concurrent environments, to be very clean. It checks for duplication once – in the database – and avoids race conditions where you check for existence first (admittedly not a problem if only one process/thread is accessing the database).

However, if the duplicates are a result of a bug (rather than duplicate events/actions that your code is just not explicitly de-duplicating), then this could just be hiding the bug rather than fixing it. Lack of explicit de-dulication, however, is not a bug in my opinion. So if the fix is to check for duplicates, use the database; if the real problem is that they were generated in the first place (at the actual application level, not the database row level), then I would probably look for that problem.

Categories
discuss

How to get language (locale) currently Android app displays?

How to get know language (locale) currently Android app uses to display texts to user?

I know I can use Locale.getDefault() to get default OS locale. But it may differ from locale used by app to display text and other resources, if this locale isn’t supported by app.


I need to determine language (locale) displayed by the app, thus the app can pass language to the server, so it can localise returned results.

Answer

My own solution is to add to strings.xml key-value pair locale=<locale code>, thus context.getResources().getString(R.string.locale) will return locale code specific for used locale.

Categories
discuss

How do you replace the document in a window?

var newDoc = document.implementation.createHTMLDocument('someTitle');
// swap newDoc with document

DOMImplementation.createHTMLDocument

  • Is it possible to swap the current document for a new document?
  • Is there any reasonable reason to do this?

Answer

You cannot replace the current document object or any document object with the Document object created with createHTMLDocument method.

The createHTMLDocument was first introduced in one of the drafts of the DOM Level 2 Core, but was later removed from the final recommendation.

It was later added to the HTML5 spec as there was no programmatic way to create an HTML document.

Some of the use cases provided for programmatic creation of an HTML document were,

  • Create a non-rendered HTML document to upload via XMLHttpRequest (instead of sending an XML document).

  • Feature-test the HTML DOM in library code in a way that is guaranteed to avoid side effects on the displayed document.

  • Create an isolated non-rendered document from a rich text editing area, so client-side cleanup can be done before uploading without disturbing the live DOM that the user may still edit further.

  • Implement HTML5 parsing algorithm client-side in JavaScript for testing and comparison purposes, or for virtualization or object-capability-based security.

    An invisible iframe can be used for most of these purposes but that is more expensive in terms of resources. W3C mailing list

The conversation on W3C mailing lists that brought the method back into the spec, [Bug 7842] New: No programmatic way to make an HTML document – consider adding createHTMLDocument

Categories
discuss

Converting JSONArray to normal Array

I created a a JSON Array from a normal array of user defined object.How do i convert the JSONArray back to a normal array of the user-defined type..? I’m using Json for shared preference in android.Using this code i found on the net:

import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;

import android.content.Context;
import android.content.SharedPreferences;

public class JSONSharedPreferences {
    private static final String PREFIX = "json";

    public static void saveJSONObject(Context c, String prefName, String key, JSONObject object) {
        SharedPreferences settings = c.getSharedPreferences(prefName, 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putString(JSONSharedPreferences.PREFIX+key, object.toString());
        editor.commit();
    }

    public static void saveJSONArray(Context c, String prefName, String key, JSONArray array) {
        SharedPreferences settings = c.getSharedPreferences(prefName, 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putString(JSONSharedPreferences.PREFIX+key, array.toString());
        editor.commit();
    }

    public static JSONObject loadJSONObject(Context c, String prefName, String key) throws JSONException {
        SharedPreferences settings = c.getSharedPreferences(prefName, 0);
        return new JSONObject(settings.getString(JSONSharedPreferences.PREFIX+key, "{}"));
    }

    public static JSONArray loadJSONArray(Context c, String prefName, String key) throws JSONException {
        SharedPreferences settings = c.getSharedPreferences(prefName, 0);
        return new JSONArray(settings.getString(JSONSharedPreferences.PREFIX+key, "[]"));
    }

    public static void remove(Context c, String prefName, String key) {
        SharedPreferences settings = c.getSharedPreferences(prefName, 0);
        if (settings.contains(JSONSharedPreferences.PREFIX+key)) {
            SharedPreferences.Editor editor = settings.edit();
            editor.remove(JSONSharedPreferences.PREFIX+key);
            editor.commit();
        }
    }
}

I’m trying to convert a user defined object array into jsonarray and storing it in jsonshared preference and later trying to retrive it.Having problem knowing how to retrive it. Thanks.

Answer

If you’re using JSONObject that comes with Android its tedious to convert from User defined types to JSONObject/JSONArray then back again. There are other libraries out there that will do this transformation automatically so it’s simple one or two line to decode/encode JSON.

ProductLineItem lineItem = ...;
JSONObject json = new JSONObject();
json.put( "name", lineItem.getName() );
json.put( "quantity", lineItem.getCount() );
json.put( "price", lineItem.getPrice() );
... // do this for each property in your user defined class
String jsonStr = json.toString();

This could all be encapsulated within ProductLineItem.toJSON(). Parsing is similar. I like to create a constructor that takes a JSONObject and creates the object like: ProductLineItem obj = new ProductLineItem( jsonObject ):

public class ProductLineItem {
    private String name;
    private int quantity;
    private float price;

   public MyObject( JSONObject json ) {
      name = json.getString("name");
      count = json.getInt("quantity");
      price = json.optFloat("price");
   }
}

Handling arrays is very much the same. So something like:

public class ShoppingCart {

     float totalPrice;
     List<Rebate> rebates = new ArrayList<Rebate>();
     List<ProductLineItem> lineItems = new ArrayList<ProductLineItem>();


    public ShoppingCart( JSONObject json ) {
        totalPrice = json.getFloat("totalPrice");

        for( JSONObject rebateJson : json.getArray("rebates") ) {
            rebates.add( new Rebate( rebateJson ) );
        }

        for( JSONObject productJson : json.getArray("lineItems") ) {
            lineItems.add( new ProductLineItem( productJson ) );
        }
    }

    public JSONObject toJSON() {
        JSONObject json = new JSONObject();
        json.put("totalPrice", totalPrice );

        JSONArray rebatesArray = new JSONArray();
        for( Rebate rebate : rebates ) {
            rebatesArray.put( rebate.toJSON() );
        }

        JSONArray lineItemsArray = new JSONArray();
        for( ProductLineItem lineItem : lineItems ) {
            lineItemsArray.put( lineItem.toJSON() );
        }

        json.put( "rebates", rebatesArray );
        json.put( "lineItems", lineItemsArray );

        return json;
    }
}

You can see just for a simple 2 objects this boiler plate code is quite significant. So you can continue to do this or you can use a library that handles all of this for you:

http://flexjson.sourceforge.net

// serialize
String json = new JSONSerializer().serialize( shoppingCart );
// deserialize
ShoppingCart cart = new JSONDeserializer<ShoppingCart>().deserialize( json, ShoppingCart.class );
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..