Thursday, 26 October 2023

How to fixed left menu dropdown in active admin

 JS: app/assets/javascripts/active_admin.js

$(document).ready(function() {

  $(".menu_item.current").addClass("open");

});

----------------------------------------------------

CSS: app/assets/stylesheets/active_admin.scss

.header #tabs li.has_nested.open > a:nth-child(1)::after{

  content: "\f0de" !important; #this is open

}

.header #tabs li.has_nested > a:nth-child(1)::after{

  content: "\f0dd" !important; #this is close

}

.header #tabs li.has_nested.open > ul{

  display: block !important;

}

.header #tabs li.has_nested > ul{

  display: none !important;

}








Monday, 16 October 2023

How to add address picker in active admin step by step

1. app/admin/venues.rb 

ActiveAdmin.register BxBlockEvents::Venue, as: "Venue" do

  Formtastic::FormBuilder.perform_browser_validations = true

  actions :all, except: [:destroy]

  permit_params :name, address_attributes: [:id, :region_code, :address_criteria, :address1, :address2, :address3, :city, :country_code, :postal_code, :latitude, :longitude, :address_type, :_destroy]


  show :title => proc {|venue| venue.name.to_s } do

    attributes_table do

      row "Venue name" do |object|

        object&.name

      end

    end

    panel 'Venue address' do

      attributes_table_for venue.address do

        row :id

        row "State Code" do |object|

          object&.region_code

        end

        row :address_criteria

        row :address1

        row :address2

        row :address3

        row :city

        row :country_code

        row :postal_code

        row :latitude

        row :longitude

      end

    end

  end

  form do |f|

    f.inputs do

      f.input :name, label: 'Venue name'

    end

    f.inputs 'Venue address' do

      f.inputs :for => [:address, f.object.address || BxBlockEvents::Address.new] do |a|

        a.input :address_criteria, input_html: {required: true}

        a.input :address1, input_html: {required: true, maxlength: 35}

        a.input :address2, input_html: {maxlength: 35} 

        a.input :address3, input_html: {maxlength: 35}

        a.input :city, input_html: {id: 'city', required: true, maxlength: 30}

        a.input :region_code, label: 'State Code', input_html: {id: 'state', required: true, maxlength: 9}

        a.input :country_code, input_html: { id: 'country', maxlength: 3, readonly: true}

        a.input :postal_code, input_html: { id: 'postcode', maxlength: 24, readonly: true}

        a.input :latitude, as: :hidden, input_html: { id: 'latitude' }

        a.input :longitude, as: :hidden, input_html: { id: 'longitude' }

      end

    end

    f.actions

  end

end




================================================================

2. app/assets/javascripts/venue_address.js.erb

    2.1 isme state and country name short use kiye hai

        $(document).ready(function() {

  let input = document.getElementById('venue_address_attributes_address_criteria');

  let autocomplete = new google.maps.places.Autocomplete(input);


  autocomplete.addListener('place_changed', function() {

    let place = autocomplete.getPlace();

    if (place.geometry && place.geometry.location) {

      let addressComponents = place.address_components.map(function(component) {

        return {

          type: component.types[0],

          name: component.short_name

        };

      });


      addressComponents.sort(function(a, b) {

        return a.name.localeCompare(b.name);

      });


      let state = '';

      let country = '';


      for (let component of addressComponents) {

        if (component.type === 'administrative_area_level_1') {

          state = component.name;

        } else if (component.type === 'country') {

          country = component.name;

        }

      }


      document.getElementById('country').value = country;

      document.getElementById('state').value = state;

      document.getElementById('city').value = extractAddressComponent(place, 'locality');

      document.getElementById('postcode').value = extractAddressComponent(place, 'postal_code');

      document.getElementById('latitude').value = place.geometry.location.lat();

      document.getElementById('longitude').value = place.geometry.location.lng();

    }

  });

});


function extractAddressComponent(place, componentType) {

  for (let component of place.address_components) {

    for (let type of component.types) {

      if (type === componentType) {

        return component.long_name;

      }

    }

  }

  return '';

}

-------------------------------------------------------------------------------------------

2.2 Get full state name and country name of this code


    $(document).ready(function() {

      var input = document.getElementById('venue_address_attributes_address_criteria');

      var autocomplete = new google.maps.places.Autocomplete(input);


      // Listener for the 'place_changed' event on the current location autocomplete

      autocomplete.addListener('place_changed', function() {

        var place = autocomplete.getPlace();

        if (place.geometry && place.geometry.location) {

          document.getElementById('country').value = extractAddressComponent(place, 'country');

          document.getElementById('state').value = extractAddressComponent(place, 'administrative_area_level_1');

          document.getElementById('city').value = extractAddressComponent(place, 'locality');

          document.getElementById('postcode').value = extractAddressComponent(place, 'postal_code');

          document.getElementById('latitude').value = place.geometry.location.lat();

          document.getElementById('longitude').value = place.geometry.location.lng();

        }

      });

    });


    function extractAddressComponent(place, componentType) {

      for (var i = 0; i < place.address_components.length; i++) {

        for (var j = 0; j < place.address_components[i].types.length; j++) {

          if (place.address_components[i].types[j] === componentType) {

            return place.address_components[i].long_name;

          }

        }

      }

      return '';

    }


    google.maps.event.addDomListener(window, 'load', initialize);


=======================================================

3. app/assets/javascripts/active_admin.js

# require venue_address.js file

//= require venue_address

===========================================================

4. app/config/initializers/active_admin.rb

    config.register_javascript "https://maps.googleapis.com/maps/api/js?key=#{ENV['GOOGLE_API_KEY']}&callback=initAutocomplete&libraries=places&v=weekly"


=============================================================

5. rails server restart: rails s



========================================


partial form: 

1. app/admin/users.rb

controller do

    def build_new_resource

      super.tap { |resource| resource.build_address }

    end


    def find_resource

      super.tap do |resource|

        resource.build_address unless resource.address.present?

      end

    end

end

form do |f|

    render 'form', context: self, f: f

  end

=====================================================

1. app/views/admin/venues/_form.html.erb

<% context.instance_eval do

    semantic_form_for resource, url: admin_venues_path do

  # f.semantic_errors *f.object.errors.keys

      f.inputs 'Vanue name' do

f.input :name, required: true, :as => :string, label: "Name"

  end

f.inputs 'Vanue address' do

    f.semantic_fields_for :address do |s|

          s.input :address_criteria

      s.input :address1

      s.input :address2

      s.input :address3

      s.input :city, input_html: { id: 'city', readonly: true }

      s.input :region_code, input_html: { id: 'state', readonly: true }

      s.input :postal_code, input_html: { id: 'postcode', readonly: true }

      s.input :country_code, input_html: { id: 'country', readonly: true }

      s.input :latitude, input_html: { id: 'latitude', readonly: true }

      s.input :longitude, input_html: { id: 'longitude', readonly: true }

    end

  end


  f.actions

  end

  end

%>

------------------------------------------------------------------
























Thursday, 5 October 2023

On Change get sub category, based on category in admin side

 1. app/assets/javascripts/active_admin.js

$(document).on('change', '#bx_block_latest_news_latest_new_category_id', function () {

  var categoryId = $(this).val();

  $.ajax({

    url: '/accounts/sub_categories.json',

    method: 'GET',

    data: { category_id: categoryId },

    dataType: 'json',

    success: function (data) {

      var subcategorySelect = $('#product_subcategory_id');

      subcategorySelect.empty();

      $.each(data, function (key, value) {

        subcategorySelect.append($('<option>').text(value.name).attr('value', value.id));

      });

    }

  });

});


-------------------------------------------------------------


2. Routes.rb

resources :accounts, :only => [:create, :destroy] do

      get 'sub_categories', on: :collection

    end

---------------------------------------------------------------

3. admin/users.rb


form do |f|

    f.inputs do

    f.input :category_id, as: :select, collection: BxBlockCategories::Category.all.map{|e| ["#{e.name}", e.id]}, :input_html => {}, include_blank: false

      f.input :title, as: :select, collection: [], input_html: { id: 'product_subcategory_id' }

      # f.input :title

      f.input :description, :as => :ckeditor

      f.input :image, label: 'Add image', as: :file, :input_html => {}

      span do

        image_tag(object.image, height: '80', width: '100') rescue nil

      end

    end

    f.actions do

      if resource.persisted?

        f.action :submit, as: :button, label: 'Update Latest news'

      else

        f.action :submit, as: :button, label: 'Create Latest News'

      end

      f.action :cancel, as: :link, label: 'Cancel'

    end

  end


------------------------------------------------------------------------------

4. accounts_controller.rb


def sub_categories

      all_df = BxBlockCategories::SubCategory.all

      render json: all_df

    end


--------------------------------------------------------


yadi update karte hai to, selected data ana chahiye

admin/users.rb

controller do

    helper_method :options_for_sub_categories

    def options_for_sub_categories

      categories_and_subcategories = []

      BxBlockCategories::Category.all.each do |category|

        categories_and_subcategories << ["Category: #{category.name}", category.id, { disabled: true }]

        category.sub_categories.each do |sub_category|

          categories_and_subcategories << ["#{sub_category.name}", sub_category.id]

        end

      end

      return categories_and_subcategories

    end

  end


---------------------------------------------------------------------

admin/users.rb

form do |f|

    f.inputs "Catalogue Details" do

      # f.input :category_id, as: :searchable_select, collection: BxBlockCategories::Category.all.collect {|var| [var.name, var.id] }, include_blank: false

      # f.input :sub_category_id, as: :searchable_select, collection: BxBlockCategories::SubCategory.all.collect {|var| [var.name, var.id] }, include_blank: false

      # f.input :sub_category, as: :select, collection: options_for_sub_categories(f.object.category_id), include_blank: 'Select a Sub-Category'