indrimuska / angular-selector

A native AngularJS directive that transform a simple <select> box into a full html select with typeahead.
http://indrimuska.github.io/angular-selector
MIT License
96 stars 36 forks source link

Remote parameter question #4

Closed scirelli closed 8 years ago

scirelli commented 8 years ago

For some reason angular-selector adds a "q" param to the remote config. So that the encode params becomes "?q=&myparams=something" for all requests that have parameters. Can you remove this please?

indrimuska commented 8 years ago

Hi @scirelli, "q" param stands for "query", it is the name of the query key in an ajax request, in order to perform a server side filtering. The name of this parameter ("q" by default) can be updated according to the remoteParam and its value is always equal to the text you type in the selector field.

To be more clear, let's take the Remote Fetching example (Plunker). It makes use of an external API available at http://services.groupkt.com/country/search, that performs server-side filtering by adding a text parameter. So, to make it available through Angular Selector you have to:

At this point, if you type "ita" inside the text field, you will see these three requests:

schermata 2015-11-05 alle 12 09 45

And this is the UI result:

remote-fetching

To conclude, remote-param is mandatory for ajax requests, so if you don't need it you could try to:

  1. perform a custom ajax initialization and update the options array dynamically (check out Change options dynamically example)
  2. set remote-param to a different value

What do you think about these solutions?

scirelli commented 8 years ago

Well, initially I'm trying to fill the select box from an ajax request that is not filtered. So the get request needs no parameters. Yet angular-select sends a "q" parameter. To get around this, in my remoteConfig I set

remoteConfig.param = ''

Now lets say I want to have an initial request with multiple params. I change remoteConfig.param to

remoteConfig.param = {param1:val1, param2:val2}

When I look at the request that is sent, angular-select adds another param "q". Is there a way to turn off angular-selects filter param?

Or are you saying I can set "remote-param" to an empty string and it will remove the "q" param that it adds?

On Thu, Nov 5, 2015 at 6:39 AM, indrimuska notifications@github.com wrote:

Hi @scirelli https://github.com/scirelli, "q" param stands for "query", it is the name of the query key in an ajax request, in order to perform a server side filtering. The name of this parameter ("q" by default) can be updated according to the remoteParam https://github.com/indrimuska/angular-selector#options and its value is always equal to the text you type in the selector field.

To be more clear, let's take the Remote Fetching example (Plunker). It makes use of an external API available at http://services.groupkt.com/country/search, that performs server-side filtering by adding a parameter `text. So, to make it available through Angular Selector you have to:

  • Add remote parameter
  • Add remote-param parameter and set it to text (instead of "q")

At this point, if you type "ita" inside the text field, you will see these three requests:

[image: schermata 2015-11-05 alle 12 09 45] https://cloud.githubusercontent.com/assets/1561134/10967147/c7779648-83b8-11e5-8f04-660c368d2af0.png

And this is the UI result:

[image: remote-fetching] https://cloud.githubusercontent.com/assets/1561134/10967184/fafb3312-83b8-11e5-8ff3-248d2334a649.png

To conclude, remote-param is mandatory for ajax requests, so if you don't need it you could try to:

  1. perform a custom ajax initialization and update the options array (check out Change options dynamically example http://indrimuska.github.io/angular-selector/)
  2. rename remote-param to a different value

What are your thoughts?

— Reply to this email directly or view it on GitHub https://github.com/indrimuska/angular-selector/issues/4#issuecomment-154037780 .

Steve Cirelli Cell: 347-618-1144 KK4FRG

Email Charter http://emailcharter.org/

indrimuska commented 8 years ago

Ok, now I better understand your problem. You have just ONE ajax request at initialization and you don't want to change the options depending on what users type.

If so, the simples way you have to do that is to initialize the options array from a manual ajax request like this:

<select selector model="myModel" options="myOptions"></select>
$scope.myOptions = [];

$http.get('...').then(function (data) {
    $scope.myOptions = data.options;
});

This Plunker shows the above use case for the country select example.

scirelli commented 8 years ago

Okay. Thanks. That's pretty much what I ended up doing. Now I better understand that the remote is not for initially filling the selectbox but for filtering only.

thanks!

On Thu, Nov 5, 2015 at 9:24 AM, indrimuska notifications@github.com wrote:

Ok, now I better understand your problem. You have just ONE ajax request at initialization and you don't want to change the options depending on what users type.

If so, the simples way you have to do that is to initialize the options array from a manual ajax request like this:

$scope.myOptions = [];

$http.get('...').then(function (data) { $scope.myOptions = data.options; });

This Plunker http://plnkr.co/edit/kThvpO?p=preview shows the above use case for the country select example.

— Reply to this email directly or view it on GitHub https://github.com/indrimuska/angular-selector/issues/4#issuecomment-154072216 .

Steve Cirelli Cell: 347-618-1144 KK4FRG

Email Charter http://emailcharter.org/

indrimuska commented 8 years ago

Delighted to help you to solve your problem! :+1:

scirelli commented 8 years ago

I have another question that I can't figure out.

I'm trying to loop over a config object using ng-repeat, and create selector select boxes from the config. The config object contains the model name and the options model name.

For example:

<select selector multi="fields.uiProps.multi" model="fields.uiProps.model" options="fields.uiProps.options" value-attr="value">

This isn't working, I think because the expression isn't evaluated to a string, and that string name used to look up the model? If I try to use {{}} expression I get a vague angular error.

Config object example: $scope.someModelName = []; $scope.someOptionsModelName = [...];

    //Eventually this config will by loaded via xhr request
    $scope.aQuerierFieldConfigs = [
        {
            ...
            "uiType":"select",
            "uiProps":{
                "multi":true,
                "labelAttr":"name",
                "valueAttr":"value",
                "placeholder":"Department",
                "model":"someModelName",
                "options":"someOptionsModelName"
            },
        }
    ];

On Thu, Nov 5, 2015 at 10:47 AM, indrimuska notifications@github.com wrote:

Closed #4 https://github.com/indrimuska/angular-selector/issues/4.

— Reply to this email directly or view it on GitHub https://github.com/indrimuska/angular-selector/issues/4#event-455864020.

Steve Cirelli Cell: 347-618-1144 KK4FRG

Email Charter http://emailcharter.org/

indrimuska commented 8 years ago

Hi @scirelli, value-attr is a one-way property, so if you have a variable that defines its value you got to surround it by double curly braces:

<select selector .. value-attr="{{value}}"></select>
scirelli commented 8 years ago

What about the "model" and "options" attributes? Those are the ones I'm trying to set with a different value each iteration from the config object.

In the example above

fields.uiProps.model //string, name of actual model.

On each iteration in ng-repeat, the model value will be the name of a different model. I tried {{fields.uiProps.model}} But I get a vague angular error.

So in my example the config object contains the string name of the model. On Dec 1, 2015 12:01 PM, "indrimuska" notifications@github.com wrote:

Hi @scirelli, Value-attr is a one-way property, so if you have a variable that defines its value you got to surround variable name by double curly braces:

<select selector .. value-attr="{{value}}">

— Reply to this email directly or view it on GitHub.

indrimuska commented 8 years ago

To let you understand how Angular Selector works I created this Plunker that may help you: http://plnkr.co/edit/0YMdkWSU2EZSoyXz4L5P?p=preview

It makes use of an options object to iterate multiple selectors.

ctrl.options = {
  color: {
    options: [
      { value: 1, label: 'red' },
      { value: 2, label: 'blue' },
      { value: 3, label: 'green' }
    ],
    valueAttr: 'value'
  },
  font: {
    options: [
      { id: 1, label: 'Arial' },
      { id: 2, label: 'Courier' },
      { id: 3, label: 'Times' }
    ],
    valueAttr: 'id'
  }
};

Check it out and let me know if there's something you can't figure out yet.

scirelli commented 8 years ago

Ah, I see what you are doing and I think I can make it work.

There's two things I just learned from your example.

  1. I forgot I could use the this pointer in a controller. I was attaching everything to the $scope. I guess that's what I've been seeing mostly tutorials. I'm going to go read up on $scope, refresh my memory about it.
  2. You created a model on the fly, attached to the config object. Which I think I can make work for me. I don't know why i thought I had to have the models already created on $scope before I could use them in a directive.

What I was asking/saying is I had already created the models on the $scope, and the config object had the name of that object stored in a property called "model". I guess for whatever reason, I thought that I had to have the model's created on the $scope before I could call/use them in a directive. What I was trying to do is get "config.model" to be evaluated to get the name of the model attached to $scope. So that it was as if I had just passed the name of the model to the directive.

$scope.myModel = [];

$scope.optionsList = [ "value1", "value2", ...];

configs = [{ myModelsName:"myModel", myOptionsListName:"optionsList" }, ...];

<select selector model="config.myModelsName" options="config.myOptionsListName" ...>

Thanks again! I tried googling the answer but I was taken down a bunch of different paths that didn't seem right.

On Tue, Dec 1, 2015 at 2:31 PM, indrimuska notifications@github.com wrote:

To let you understand how Angular Selector works I created this Plunker that may help you: http://plnkr.co/edit/0YMdkWSU2EZSoyXz4L5P?p=preview

It makes use of an options object to iterate multiple selectors.

ctrl.options = { color: { options: [ { value: 1, label: 'red' }, { value: 2, label: 'blue' }, { value: 3, label: 'green' } ], valueAttr: 'value' }, font: { options: [ { id: 1, label: 'Arial' }, { id: 2, label: 'Courier' }, { id: 3, label: 'Times' } ], valueAttr: 'id' } };

Check it out and let me know if there's something you can't figure out yet.

— Reply to this email directly or view it on GitHub https://github.com/indrimuska/angular-selector/issues/4#issuecomment-161071269 .

Steve Cirelli Cell: 347-618-1144 KK4FRG

Email Charter http://emailcharter.org/

indrimuska commented 8 years ago

I can't deny I don't think I have completely understood your problems, but it seem you got a little bit confusion with one-way/two-way binding properties.

You don't have to write the name of the variable as string (as you've done in config = [ { myModelsName:"myModel", ...} ]) to attach an object to another object. Remember that Angular still remain a javascript framework - with a little bit magic, I know - so every construction valid for JS is also valid for Angular: { myModelsName: myModel, ...} or { myModelsName: [...], ...}.

Anyway, variable initialization before use is always a best practice: when Angular compiles your directives (basically transforms the string "config" to the object $scope.config, plus some other stuffs) it simply check if they exists and creates them for you - if not.

Unfortunately, this is not the right place where to talk it, but I hope you've better understood how Angular works. Good luck with your projects. :)