<!-- @group ROUTETOPA Polymer Core Elements The `select-visualization-form-controllet` is a slider container of elements. Pass to this component an array of components, a data url(CKAN api uri) and a string with one or multiple query in JsonPath format(separated by spaces) and it'll show a slider with all components initialized with data and query attributes ### Code Example @class select-visualization-form-controllet --> <link rel="import" href="../../bower_components/polymer/polymer.html"> <link rel="import" href="../../bower_components/paper-input/paper-input.html"> <link rel="import" href="../../bower_components/paper-button/paper-button.html"> <link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html"> <link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html"> <link rel="import" href="../../bower_components/paper-toast/paper-toast.html"> <dom-module id="datalet-selection-controllet"> <template> <link rel="stylesheet" href="../shared_js/bootstrap-3.3.4-dist/css/bootstrap.paper.style.min.css"> <link rel="stylesheet" href="../shared_js/bootstrap-toggle-master/css/bootstrap-toggle.min.css"> <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <style is="custom-style"> body { font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial; font-size: 14px; margin: 0; padding: 24px; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-touch-callout: none; } paper-input { width: 80%; } /*paper-dialog { position: fixed; top: 16px; right: 16px; width: 400px; height: 400px; }*/ html /deep/ paper-dialog { /*::shadow #datalet_dialog_content*/ /*position: fixed; top: 25%; left: 25%; bottom: 25%; right: 25%; margin: 0px;*/ width: 90%; height: 95%; } /*Toggle style*/ input.toggle { max-height: 0; max-width: 0; opacity: 0; } input.toggle + label { display: block; position: relative; box-shadow: inset 0 0 0px 1px #d5d5d5; text-indent: -5000px; height: 30px; width: 50px; border-radius: 15px; } input.toggle + label:before { content: ""; position: absolute; display: block; height: 30px; width: 30px; top: 0; left: 0; border-radius: 15px; background: rgba(19, 191, 17, 0); -moz-transition: .25s ease-in-out; -webkit-transition: .25s ease-in-out; transition: .25s ease-in-out; } input.toggle + label:after { content: ""; position: absolute; display: block; height: 30px; width: 30px; top: 0; left: 0px; border-radius: 15px; background: white; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .2), 0 2px 4px rgba(0, 0, 0, .2); -moz-transition: .25s ease-in-out; -webkit-transition: .25s ease-in-out; transition: .25s ease-in-out; } input.toggle:checked + label:before { width: 50px; background: rgba(19, 191, 17, 1); } input.toggle:checked + label:after { left: 20px; box-shadow: inset 0 0 0 1px rgba(19, 191, 17, 1), 0 2px 4px rgba(0, 0, 0, .2); } /deep/ #fields_order_placeholder { list-style-type: none; margin: 0; padding: 0; width: 60%; } /deep/ #fields_order_placeholder li { margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em; height: 1.5em; } /deep/ html>body #fields_order_placeholder li { height: 1.5em; line-height: 1.2em; } /deep/ .ui-state-highlight { height: 1.5em; line-height: 1.2em; } </style> <iron-ajax auto id="data_request" url={{dataUrl}} handle-as="json" verbose="true" on-response="handleResponseData" debounce-duration="300"> </iron-ajax> <iron-ajax id="datales_list_request" auto url={{dataletsListUrl}} handle-as="json" on-response="handleResponseDatalets" debounce-duration="300"> </iron-ajax> <div id="modals"> </div> <paper-dialog id="datalet_dialog" modal="true" transition="core-transition-center" closeAttribute="close"> <h2>Datalets preview</h2> <paper-dialog-scrollable id="datalet_dialog_content"> </paper-dialog-scrollable> <div class="buttons"> <paper-button dialog-dismiss>Close</paper-button> </div> </paper-dialog> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Data source</h3> </div> <div class="panel-body"> <section> <paper-input id="data_url" label="CKAN api data url" floatingLabel value="{{dataUrl}}"></paper-input> </section> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Selection data fileds to visualize</h3> </div> <div class="panel-body"> <section> <div class="horizontal center-justified layout"> <div id="fields_placeholder" class="horizontal-section"> </div> </div> </section> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Selection fileds order</h3> </div> <div class="panel-body"> <section> <div class="horizontal center-justified layout"> <ul id="fields_order_placeholder"> </ul> </div> </section> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Visualization tools selection</h3> </div> <div class="panel-body"> <div id="datalets_menu" class="layout"> <label for="datalets_selector">Available Datalets list:</label> <select class="form-control" id="datalets_selector"> </select> </div> </div> </div> <section> <paper-button on-click="goto" raised>Go to visualization</paper-button> </section> <paper-toast id="message" text=""></paper-toast> <content></content> </template> <script src="../shared_js/bootstrap-3.3.4-dist/js/bootstrap.min.js"></script> <script src="../shared_js/bootstrap-toggle-master/js/bootstrap-toggle.min.js"></script> <script src="../shared_js/jquery-ui-1.11.4.custom/jquery-ui.min.js"></script> <script src="../../../DEEPCLIENT/js/deepClient.js"></script> <script> DataletSelectionControllet = Polymer({ is: 'datalet-selection-controllet', listeners: { 'tap' : 'clickHandler' }, hostAttributes: { dataUrl: "http://demo.ckan.org/api/action/datastore_search?resource_id=8324a4c9-66d6-47bf-a898-94237cc39b9f&limit=50", deepUrl: "http://service.routetopa.eu/WebComponentsDEV/DEEP/", dataletsListUrl: "http://service.routetopa.eu/WebComponentsDEV/DEEP/datalets-list" }, properties: { /** * It represent the data url from CKAN api * * @attribute dataUrl * @type string * @default 'null' */ dataUrl: { type: String, value: "http://demo.ckan.org/api/action/datastore_search?resource_id=8324a4c9-66d6-47bf-a898-94237cc39b9f&limit=50", observer: '_dataUrlChanged' }, /** * It represent the DEEP url to get information about the datalets * * @attribute deepUrl * @type string * @default 'null' */ deepUrl: { type: String, value: "http://demo.ckan.org/api/action/datastore_search?resource_id=8324a4c9-66d6-47bf-a898-94237cc39b9f&limit=50" }, /** * It stores all tools available in WebComponent server * * @attribute tools * @type array * @default 'null' */ tools:{ type: Array, value: [] }, /** * It stores all fields related to data retrieved from CKAN api url * * @attribute fields * @type array * @default 'null' */ fields_order:{ type: String, value: [] }, fieldsMap: { type: Map, value: null }, datalet_query:{ type: String, value: "" } }, /** * data-url member changed watcher. It's called when dataUrl changes its value * * @method dataUrlChanged */ _dataUrlChanged: function(newValue, oldValue){ this.$.data_request.generateRequest(); }, createFieldsContainer: function(id, heading){ var panelDefault = document.createElement('div'); panelDefault.className = 'panel panel-default'; var panelHeading = document. createElement('div'); panelHeading.className = 'panel-heading'; panelHeading.innerHTML = heading; var panelBody = document. createElement('div'); panelBody.className = 'panel-body'; panelBody.id = id; var fieldPanel = document.createElement('div'); fieldPanel.className = 'panel-body'; panelBody.appendChild(fieldPanel); panelDefault.appendChild(panelHeading); panelDefault.appendChild(panelBody); return panelDefault; }, createCustomStyledToggle: function(id, label){ return '<div class="wrapper">' + '<input id="'+ id +'" type="checkbox" class="toggle">' + '<label for="'+ id +'">'+ label +'</label>' + label + '</div>'; }, /** * Callback to parse the data requested when dataUrl change its value * * @method handleResponseData */ handleResponseData: function(e){ //crete root node and insert it in to shadow dom var mainPanel = this.createFieldsContainer("root", "Data fields"); this.$.fields_placeholder.innerHTML = ""; this.$.fields_placeholder.appendChild(mainPanel); this.fieldsMap = new Map; this.fieldsMap["root"] = mainPanel; //call recursive analyze function for current json to get all fields user can select this.analyzeObject(new Array("root"), null, e.detail.response); }, analyzeObject: function(parent_list, curr_field, object) { if(curr_field != null){ if(object == null) object = ""; if(object.constructor == Array){//Deal with flat array case if(object[0].constructor != Object){ this.fieldsMap[parent_list[parent_list.length - 2]].childNodes[1].childNodes[0].innerHTML += this.createCustomStyledToggle(parent_list.toString(), curr_field); return; } } if(object.constructor == Array || object.constructor == Object){ var panel = this.createFieldsContainer(curr_field, parent_list[parent_list.length - 1]); this.fieldsMap[curr_field] = panel; this.fieldsMap[parent_list[parent_list.length - 2]].childNodes[1].appendChild(this.fieldsMap[curr_field]); }else{ //CUSTOM STYLED TOGGLE this.fieldsMap[parent_list[parent_list.length - 2]].childNodes[1].childNodes[0].innerHTML += this.createCustomStyledToggle(parent_list.toString(), curr_field); } } if(object.constructor == Array || object.constructor == Object) { var obj = (object.constructor == Array) ? object[0] : object; if(Object.prototype.toString.call(obj) === '[object String]') return;//Deal with flat array case for (var field in obj) { var parents = new Array(); parent_list.every(function (element, index, array) { parents.push(element); return true; }); parents.push(field); this.analyzeObject(parents, field, obj[field]); } } }, /** * Callback to parse the components response object * * @method handleResponseComponents */ handleResponseDatalets: function(e){ html = ""; for(var i=0;i < e.detail.response.length;i++){ html += '<option value="' + e.detail.response[i] + '"' + ((i==0) ? ' selected>' : '>') + e.detail.response[i] + '</option>'; } $(this.$.datalets_selector).append(html); }, /** * Callback called when "Go to visualization" button is pressed * * @method handleResponseComponents */ goto: function(){ var fields = Polymer.dom(this.$.fields_order_placeholder).querySelectorAll('li'); this.fields_order = ""; for(var i=0;i<fields.length;i++){ this.fields_order += fields[i].id + ","; } this.fields_order = this.fields_order.substring(0, this.fields_order.length - 1); var cbs = Polymer.dom(this.$.fields_placeholder).querySelectorAll('input[type=checkbox]:checked'); this.datalet_query = ""; if(cbs.length == 0){ this.$.message.text = "No fields selected."; this.$.message.show(); return; } var fields = Array(); for(var i=0;i<cbs.length;i++){ fields.push(cbs[i].id.replace("root,", "")); } var datalet_params ={ component : this.$.datalets_selector.options[this.$.datalets_selector.selectedIndex].text, params :{ 'data-url' : this.dataUrl, 'fields-order' : this.fields_order }, fields : fields, placeHolder : this.$.datalet_dialog_content }; ComponentService.deep_url = this.deepUrl; ComponentService.getComponent(datalet_params); document.getElementById("datalet_dialog").open(); }, clickHandler : function(e){ if(!e.target.control) { if (e.target.className == 'toggle') { (this.$.fields_order_placeholder).innerHTML = ""; var cbs = Polymer.dom(this.$.fields_placeholder).querySelectorAll('input[type=checkbox]:checked'); for(var i=0;i<cbs.length;i++) { var fields = cbs[i].id.split(','); var ele = document.createElement('li'); ele.className = "ui-state-default"; ele.id = i; ele.innerHTML = fields[fields.length -1]; (this.$.fields_order_placeholder).appendChild(ele); } } } }, ready: function(){ $(this.$.fields_order_placeholder).sortable({ placeholder: "ui-state-highlight" }); $(this.$.fields_order_placeholder).disableSelection(); } }); </script> </dom-module>