Showing posts with label checkbox. Show all posts
Showing posts with label checkbox. Show all posts

Thursday, November 30, 2017

Checkbox styling doesn't work on Safari mobile

Leave a Comment

I want to style the checkboxes like the following:

enter image description here

This is my CSS:

.checkboxcontact input[type="checkbox"] {     -webkit-appearance: none;     background-color: white;     border: 1px solid #d44803;     padding: 9px;     border-radius: 3px;     display: inline-block;     position: relative;     float:left; }  .checkboxcontact input[type="checkbox"]:checked {     background-color: #d44803;     border: 1px solid white;     color: #fff; }  .checkboxcontact input[type="checkbox"]:checked:after {     content: '\2714';     font-size: 14px;     position: absolute;     top: 0;     left: 3px;     color: #fff;     font-family: "FontAwesome"; } 

This shows perfect on desktop and Chrome on mobile phones.

enter image description here

But the problem is with Safari on iPhone. It shows like this:

enter image description here

How can I fix this? Is there a fallback or something?

3 Answers

Answers 1

Pseudo element :after or :before not working properly with input type element. So adding a pseudo element like after to them is not correct. So that add label next to checkbox and adding style for that.

.checkboxcontact label {      display: inline-block;      position: relative;      vertical-align: middle;      padding-left: 5px;  }  .checkboxcontact input[type="checkbox"] {      opacity: 0;  }  .checkboxcontact label::before {      content: "";      display: inline-block;      position: absolute;      width: 17px;      height: 17px;      left: 0;      margin-left: -20px;      border: 1px solid #d44803;      border-radius: 3px;      background-color: #fff;      }    .checkboxcontact input[type="checkbox"]:checked + label::before,  .checkboxcontact input[type="checkbox"]:focus + label::before {      background-color: #d44803;      border: 1px solid white;  }    .checkboxcontact input[type="checkbox"]:checked + label::after {      content: '\f00c';      font-size: 14px;      position: absolute;      top: 2px;      left: -17px;      color: #fff;      font-family: "FontAwesome";  }
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>  <div class="checkboxcontact">    <input type="checkbox" id="check1"/>    <label for="check1">        Check me out    </label>  </div>

Answers 2

Same issue i too faced once. I would suggest you to use images of check & uncheck as per your design. When user checked, image src should change to checked image. You can use javascript function for that. Make sure you use both same size of images. So that user can't feel those are 2 different images. For your reference, i'm attaching those images which i've used.

Check image

Uncheck image

Here is my code. Some where i've found for you. look over it. have given those images in my style sheet & rendering those in my javascript. When user clicked on checked image, 'selected' class i'm removing. So, that uncheck image will be shown to user.

function ClearSelection() {      $(".filterlist ul li").each(function () {          $(this).removeClass("selected");      });  }
.filterlist ul li  {  	padding:5px;  	border-bottom:1px solid gray;  	cursor:pointer;	  	background-image: url("../images/untick.png");  	background-repeat:no-repeat;  	background-position: 10 8;  }  .filterlist ul li.selected{background-image: url("../images/tick.png");}

Answers 3

as it was suggested above, pseudo elements don't work well with inputs, however, it would be a good idea to wrap the checkbox inside the label - it is w3c valid, so that it works as intended, and you don't have to use the for tag for the label, nor use id for the input checkbox.

Here is the HTML:

<label class="custom-checkbox">   <input type="checkbox" value="checkbox1">   <span>Checkbox</span> </label> 

The code is versatile enough, so if you need just the checkbox, without label, you just leave the span empty - you have to keep the tag though - or alternatively you can create your own custom class to apply the pseudo-elements on the label itself.

Here is the CSS:

.custom-checkbox {   position: relative;   display: block;   margin-top: 10px;   margin-bottom: 10px;   line-height: 20px; }  .custom-checkbox span {   display: block;   margin-left: 20px;   padding-left: 7px;   line-height: 20px;   text-align: left; }  .custom-checkbox span::before {   content: "";   display: block;   position: absolute;   width: 20px;   height: 20px;   top: 0;   left: 0;   background: #fdfdfd;   border: 1px solid #e4e5e7;   @include vendorize(box-shadow, inset 2px 2px 0px 0px rgba(0, 0, 0, 0.1)); }  .custom-checkbox span::after {   display: block;   position: absolute;   width: 20px;   height: 20px;   top: 0;   left: 0;   font-size: 18px;   color: #0087b7;   line-height: 20px;   text-align: center; }  .custom-checkbox input[type="checkbox"] {   opacity: 0;   z-index: -1;   position: absolute; }  .custom-checkbox input[type="checkbox"]:checked + span::after {   font-family: "FontAwesome";   content: "\f00c";   background:#d44803;   color:#fff; } 

And here is a working fiddle: https://jsfiddle.net/ee1uhb3g/

Verified tested on all browsers - FF, Chrome, Safari, IE, etc

Read More

Monday, September 11, 2017

Mediaplayers get muted/unmuted too late

Leave a Comment

I set up a Checkbox, If it is unchecked the mediaplayers should Immediately be unmuted, when checked ** immediately muted**, now I have the problem that when I check / uncheck the checkbox the sound will not be muted immediately bur as recently I restart the activity... How can I solve this problem? **Main code of the programm:

         public class QuizActivity extends AppCompatActivity {  private ActionBarDrawerToggle mToggle;  private QuestionLibrary mQuestionLibrary = new QuestionLibrary();  private TextView mScoreView; private TextView mQuestionView; private Button mButtonChoice1; private Button mButtonChoice2; private Button mButtonChoice3; private String mAnswer; private int mScore = 0; private int mQuestionNumber = 0; Dialog dialog; Dialog dialog2; TextView closeButton; TextView closeButton2; CheckBox checkBoxmp; private MediaPlayer mp, mp2;  SharedPreferences mypref; SharedPreferences.Editor editor;  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_quiz);       //Dialog 1     createDialog();     Button dialogButton = (Button) findViewById(R.id.dialogbtn);     dialogButton.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             dialog.show();          }     });      closeButton.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             dialog.dismiss();         }     });     //end Dialog 1      //Dialog 2     createDialog2();     Button dialogButton2 = (Button) findViewById(R.id.dialogbtn2);     dialogButton2.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             dialog2.show();          }     });       closeButton2.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             dialog2.dismiss();         }     });     //end Dialog 2      SharedPreferences mypref = getPreferences(MODE_PRIVATE);      final SharedPreferences.Editor editor = mypref.edit();      checkBoxmp.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {         @Override         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {             editor.putBoolean("playSounds", !isChecked);             editor.commit();             if (null != mp && null != mp2) {                 if (!isChecked) {                     mp.setVolume(1, 1);                     mp2.setVolume(1, 1);                 } else {                     mp.setVolume(0, 0);                     mp2.setVolume(0, 0);                 }             }         }     });      final boolean playSounds = mypref.getBoolean("playSounds", false);     checkBoxmp.setChecked(!playSounds);      TextView shareTextView = (TextView) findViewById(R.id.share);     shareTextView.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             Intent myIntent = new Intent(Intent.ACTION_SEND);             myIntent.setType("text/plain");             myIntent.putExtra(Intent.EXTRA_SUBJECT, "Hello!");             myIntent.putExtra(Intent.EXTRA_TEXT, "My highscore in Quizzi is very high! I bet you can't beat me except you are cleverer than me. Download the app now! https://play.google.com/store/apps/details?id=amapps.impossiblequiz");             startActivity(Intent.createChooser(myIntent, "Share with:"));         }     });      mQuestionLibrary.shuffle();      setSupportActionBar((Toolbar) findViewById(R.id.nav_action));     DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);     mToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.open, R.string.close);     mDrawerLayout.addDrawerListener(mToggle);     mToggle.syncState();     getSupportActionBar().setDisplayHomeAsUpEnabled(true); // Able to see the Navigation Burger "Button"      ((NavigationView) findViewById(R.id.nv1)).setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {         @Override         public boolean onNavigationItemSelected(MenuItem menuItem) {             switch (menuItem.getItemId()) {                 case R.id.nav_stats:                     startActivity(new Intent(QuizActivity.this, Menu2.class));                     break;                 case R.id.nav_about:                     startActivity(new Intent(QuizActivity.this, Menu3.class));                     break;             }             return true;         }     });      mScoreView = (TextView) findViewById(R.id.score_score);     mQuestionView = (TextView) findViewById(R.id.question);     mButtonChoice1 = (Button) findViewById(R.id.choice1);     mButtonChoice2 = (Button) findViewById(R.id.choice2);     mButtonChoice3 = (Button) findViewById(R.id.choice3);      final List<Button> choices = new ArrayList<>();     choices.add(mButtonChoice1);     choices.add(mButtonChoice2);     choices.add(mButtonChoice3);      updateQuestion();       //Code of the mediaplayer begins:      for (final Button choice : choices) {         choice.setOnClickListener(new View.OnClickListener() {              @Override             public void onClick(View view) {                 if (choice.getText().equals(mAnswer)) {                     try {                         mp = new MediaPlayer();                         if (playSounds) {                             mp.setVolume(1, 1);                         } else {                             mp.setVolume(0, 0);                         }                          AssetFileDescriptor afd;                         afd = getAssets().openFd("sample.mp3");                         mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());                         mp.prepare();                      } catch (IllegalStateException e) {                         e.printStackTrace();                     } catch (IOException e) {                         e.printStackTrace();                     }                     mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {                         @Override                         public void onCompletion(MediaPlayer mp) {                             mp.release();                         }                     });                     mp.start();                     updateScore();                     updateQuestion();                     Toast.makeText(QuizActivity.this, "Correct", Toast.LENGTH_SHORT).show();                  } else {                     try {                         mp2 = new MediaPlayer();                         if (playSounds) {                             mp2.setVolume(1, 1);                         } else {                             mp2.setVolume(0, 0);                         }                         AssetFileDescriptor afd;                         afd = getAssets().openFd("wrong.mp3");                         mp2.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());                         mp2.prepare();                      } catch (IllegalStateException e) {                         e.printStackTrace();                     } catch (IOException e) {                         e.printStackTrace();                     }                     mp2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {                         @Override                         public void onCompletion(MediaPlayer mp) {                             mp.release();                         }                     });                     mp2.start();                      Toast.makeText(QuizActivity.this, "Wrong... Try again!", Toast.LENGTH_SHORT).show();                     Intent intent = new Intent(QuizActivity.this, Menu2.class);                     intent.putExtra("score", mScore); // pass score to Menu2                     startActivity(intent);                 }             }         });     } }   //End mediaplayer main code private void updateQuestion() {     if (mQuestionNumber < mQuestionLibrary.getLength()) {         mQuestionView.setText(mQuestionLibrary.getQuestion(mQuestionNumber));         mButtonChoice1.setText(mQuestionLibrary.getChoice1(mQuestionNumber));         mButtonChoice2.setText(mQuestionLibrary.getChoice2(mQuestionNumber));         mButtonChoice3.setText(mQuestionLibrary.getChoice3(mQuestionNumber));         mAnswer = mQuestionLibrary.getCorrectAnswer(mQuestionNumber++);     } else {         Toast.makeText(QuizActivity.this, "Last Question! You are very intelligent!", Toast.LENGTH_SHORT).show();         Intent intent = new Intent(QuizActivity.this, Menu2.class);         intent.putExtra("score", mScore);         startActivity(intent);     } }  private void updateScore() {     mScoreView.setText(String.valueOf(++mScore));      SharedPreferences mypref = getPreferences(MODE_PRIVATE);     int highScore = mypref.getInt("highScore", 0);      if (mScore > highScore) {         SharedPreferences.Editor editor = mypref.edit();         editor.putInt("highScore", mScore);         editor.apply();     } }  @Override public boolean onOptionsItemSelected(MenuItem item) {     return mToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item); }  private void createDialog() {     dialog = new Dialog(this);     dialog.setTitle("Tutorial");     dialog.setContentView(R.layout.popup_menu1_1);     closeButton = (TextView) dialog.findViewById(R.id.closeTXT); }   private void createDialog2() {     dialog2 = new Dialog(this);     dialog2.setTitle("Settings");     dialog2.setContentView(R.layout.popup_menu1_2);     closeButton2 = (TextView) dialog2.findViewById(R.id.closeTXT2);     checkBoxmp = (CheckBox) dialog2.findViewById(R.id.ckeckBox); } 

}

3 Answers

Answers 1

Try Changing editor.commit to editor.apply as .commit blocks the UI while writing the shared preference to the disk and waits until the write is finished for the next line of code to execute where as .apply sends the shared preference writing to a worker thread thus executing the next line of code instantaneously as @Pavel has mentioned. look here for more info

Answers 2

final SharedPreferences.Editor editor = mypref.edit();
try to move this string into onCheckChanged()
and also use editor.apply() instead of editor.commit();

Answers 3

try editing in shared preference within onCheckChanged :

//end Dialog 2      SharedPreferences mypref = getPreferences(MODE_PRIVATE);      checkBoxmp.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {         @Override         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {             SharedPreferences.Editor editor = mypref.edit();             editor.putBoolean("playSounds", !isChecked);             editor.commit();             if (null != mp && null != mp2) {                 if (!isChecked) {                     mp.setVolume(1, 1);                     mp2.setVolume(1, 1);                 } else {                     mp.setVolume(0, 0);                     mp2.setVolume(0, 0);                 }             }         }     }); 
Read More

Thursday, August 3, 2017

List Box items with checkboxes, multiselect not working properly in WPF MVVM

Leave a Comment

So I have a ListBox with CheckBox-es that have the IsChecked property bound to the Item's property called IsSelected. That produces a weird behavior where if I click on the item itself it checks the checkbox (good) and sets the property on the item (good), but doesn't actually select the item in the list box, ie. the highlighting isn't there. I am guessing that the ListBox IsSelected property needs to be set as well for that right? Now, I am trying to get the multi-select behavior to work so I changed the SelectionMode to Extended. Now, I can select only Items, not the checkboxes. What happens is that if I use SHIFT + click by pointing at the area next to the item, not the item itself, then it select multiple items, but clicking on the items themselves doesn't do the trick of multi-selection not does it check the checkboxes. What is going on in here?

I would like to be able to select multiple items by holding shift etc, and have that trigger the property on the Elevation item so I know which ones are checked. Any help is appreciated.

Here's my XAML:

<ListBox x:Name="LevelsListBox"                          ItemsSource="{Binding Elevations, UpdateSourceTrigger=PropertyChanged}"                          SelectionMode="Extended"                          BorderThickness="0">                     <ListBox.ItemTemplate>                         <DataTemplate>                             <CheckBox IsChecked="{Binding IsSelected}" Content="{Binding Name}"/>                         </DataTemplate>                     </ListBox.ItemTemplate>                 </ListBox> 

My View Model:

public class AxoFromElevationViewModel : ViewModelBase     {         public AxoFromElevationModel Model { get; }         public RelayCommand CheckAll { get; }         public RelayCommand CheckNone { get; }          public AxoFromElevationViewModel(AxoFromElevationModel model)         {             Model = model;             Elevations = Model.CollectElevations();             CheckAll = new RelayCommand(OnCheckAll);             CheckNone = new RelayCommand(OnCheckNone);         }           private void OnCheckNone()         {             foreach (var e in Elevations)             {                 e.IsSelected = false;             }         }           private void OnCheckAll()         {             foreach (var e in Elevations)             {                 e.IsSelected = true;             }         }          /// <summary>         /// All Elevation Wrappers.         /// </summary>         private ObservableCollection<ElevationWrapper> _elevations = new ObservableCollection<ElevationWrapper>();         public ObservableCollection<ElevationWrapper> Elevations         {             get { return _elevations; }             set { _elevations = value; RaisePropertyChanged(() => Elevations); }         }     } 

Finally my Elevation Class:

public sealed class ElevationWrapper : INotifyPropertyChanged     {         public string Name { get; set; }         public ElementId Id { get; set; }         public object Self { get; set; }          private bool _isSelected;         public bool IsSelected         {             get { return _isSelected; }             set { _isSelected = value; RaisePropertyChanged("IsSelected"); }         }          public ElevationWrapper(View v)         {             Name = v.Name;             Id = v.Id;             Self = v;             IsSelected = false;         }          public event PropertyChangedEventHandler PropertyChanged;         private void RaisePropertyChanged(string propname)         {             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));         }     } 

2 Answers

Answers 1

You should bind the IsSelected property of your ListBoxItems to the IsSelected property of your view model. This way CheckBoxes will trigger the selection and when you select an item, the related CheckBox will be checked.

<ListBox.ItemContainerStyle>     <Style TargetType="ListBoxItem">         <Setter Property="IsSelected" Value="{Binding IsSelected}"/>     </Style> </ListBox.ItemContainerStyle> 

Answers 2

It seems to me you want to sync 3 properties ListBoxItem.IsSelected, CheckBox.IsChecked and your models IsSelected. My advice is that only one of the templates/styles should bind to the underlying model so I will add Yusuf answer as I will use the ListBoxItem style to bind to your model property. After that you should bind the Checkbox.IsChecked to the ListBoxItem.IsSelected and your ListBox should look like this:

    <ListBox x:Name="LevelsListBox"              ItemsSource="{Binding Elevations, UpdateSourceTrigger=PropertyChanged}"              SelectionMode="Extended"              BorderThickness="0">         <ListBox.ItemContainerStyle>             <Style TargetType="ListBoxItem">                 <Setter Property="IsSelected" Value="{Binding IsSelected}"/>             </Style>         </ListBox.ItemContainerStyle>         <ListBox.ItemTemplate>             <DataTemplate>                 <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Content="{Binding Name}"/>             </DataTemplate>         </ListBox.ItemTemplate>     </ListBox> 

Always try to bind XAML properties in a chain way, e.g. model.A binds to Model.B binds to Model.C, doing this should help you keep updates consistent and avoid wierd cases.

There is an issue with this code though, after you select multiple items and click one check box it will only unselect that item but if you click another item it will unselect all except that item.

Read More

Sunday, August 28, 2016

checkbox get disabled in ng-repeat of accordions

Leave a Comment

I have build a list of accordions, each accordion represent a group of items. I have used ng-repeat to iterate through group names,each group has a checkbox which indicate if it is chosen or not.

The example works fine for single group of accordion, but the moment I am putting the accordion inside ng-repeat, the checkbox can't be selected at all.

Here is the code, the main checkbox of each group title doesn't work apparently, I am try to figure out the reason for this.

My main Question is:

1.How can I make the checkboxes of Group1 and Group2 and Group3 active,so I can select them properly, In current situation, I can't select the checkboxes at all(of Group1,Group2 and Group3).

var app = angular.module('app',[]);    app.controller('mainCTRL',function($scope){    $('.collapse').collapse();    $scope.title="Hello World";    $scope.items1 = ['Group1','Group2','Group3']  })
.ui-checkbox {    display: none;  }  .ui-checkbox + label {    position: relative;    padding-left: 25px;    display: inline-block;    font-size: 14px;  }  .ui-checkbox + label:before {    background-color: #fff;    /**#fff*/    border: 1px solid #1279C6;    padding: 9px;    border-radius: 3px;    display: block;    position: absolute;    top: 0;    left: 0;    content: "";  }  .ui-checkbox:checked + label:before {    border: 1px solid #1279C6;    color: #99a1a7;  }  .ui-checkbox:checked + label:after {    content: '\2714';    font-size: 14px;    position: absolute;    top: 1px;    left: 4px;    color: #1279C6;  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">  </script>  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>    <div ng-app="app" ng-controller="mainCTRL">  <div ng-repeat="item in items1">      <div class="panel-group driving-license-settings" id="accordion-{{$index}}">          <div class="panel panel-default">              <div class="panel-heading">                  <h4 class="panel-title">                      <a data-toggle="collapse" data-parent="#accordion-{{$index}}"                         data-target="#collapseOne-{{$index}}">                          <input type="checkbox" class="ui-checkbox" id="chk1-{{$index}}" value="">                          <label for="chk1-{{$index}}">{{item}}</label>                      </a>                  </h4>              </div>              <div id="collapseOne-{{$index}}" class="panel-collapse collapse ">                  <div class="panel-body">                      <div class="driving-license-kind">                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-1" value="">                              <label for="chk2-cb-{{item}}-1">A</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-2" value="">                              <label for="chk2-cb-{{item}}-2">B</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-3" value="">                              <label for="chk2-cb-{{item}}-3">C</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-4" value="">                              <label for="chk2-cb-{{item}}-4">D</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-5" value="">                              <label for="chk2-cb-{{item}}-5">E</label>                          </div>                      </div>                  </div>              </div>          </div>      </div>  </div>  </div>

2 Answers

Answers 1

The problem is because your checkboxes are nested inside anchors. Simply change:

<a data-toggle="collapse" data-parent="#accordion-{{$index}}"                        data-target="#collapseOne-{{$index}}"> 

To:

<div data-toggle="collapse" data-parent="#accordion-{{$index}}"                        data-target="#collapseOne-{{$index}}"> 

See working example:

var app = angular.module('app',[]);    app.controller('mainCTRL',function($scope){    $('.collapse').collapse();    $scope.title="Hello World";    $scope.items1 = ['Group1','Group2','Group3']  })
.ui-checkbox {    display: none;  }  .ui-checkbox + label {    position: relative;    padding-left: 25px;    display: inline-block;    font-size: 14px;  }  .ui-checkbox + label:before {    background-color: #fff;    /**#fff*/    border: 1px solid #1279C6;    padding: 9px;    border-radius: 3px;    display: block;    position: absolute;    top: 0;    left: 0;    content: "";  }  .ui-checkbox:checked + label:before {    border: 1px solid #1279C6;    color: #99a1a7;  }  .ui-checkbox:checked + label:after {    content: '\2714';    font-size: 14px;    position: absolute;    top: 1px;    left: 4px;    color: #1279C6;  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">  </script>  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>    <div ng-app="app" ng-controller="mainCTRL">  <div ng-repeat="item in items1">      <div class="panel-group driving-license-settings" id="accordion-{{$index}}">          <div class="panel panel-default">              <div class="panel-heading">                  <h4 class="panel-title">                      <div data-toggle="collapse" data-parent="#accordion-{{$index}}"                         data-target="#collapseOne-{{$index}}">                          <input type="checkbox" class="ui-checkbox" id="chk1-{{$index}}" value="">                          <label for="chk1-{{$index}}">{{item}}</label>                      </div>                  </h4>              </div>              <div id="collapseOne-{{$index}}" class="panel-collapse collapse ">                  <div class="panel-body">                      <div class="driving-license-kind">                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-1" value="">                              <label for="chk2-cb-{{item}}-1">A</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-2" value="">                              <label for="chk2-cb-{{item}}-2">B</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-3" value="">                              <label for="chk2-cb-{{item}}-3">C</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-4" value="">                              <label for="chk2-cb-{{item}}-4">D</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-5" value="">                              <label for="chk2-cb-{{item}}-5">E</label>                          </div>                      </div>                  </div>              </div>          </div>      </div>  </div>  </div>

Answers 2

The problem is the ids you assigned. Make the ids unique, and the checkbox starts working. Here is the fixed snippet

var app = angular.module('app',[]);    app.controller('mainCTRL',function($scope){    $('.collapse').collapse();    $scope.title="Hello World";    $scope.items1 = ['Group1','Group2','Group3']  })
.ui-checkbox {    display: none;  }  .ui-checkbox + label {    position: relative;    padding-left: 25px;    display: inline-block;    font-size: 14px;  }  .ui-checkbox + label:before {    background-color: #fff;    /**#fff*/    border: 1px solid #1279C6;    padding: 9px;    border-radius: 3px;    display: block;    position: absolute;    top: 0;    left: 0;    content: "";  }  .ui-checkbox:checked + label:before {    border: 1px solid #1279C6;    color: #99a1a7;  }  .ui-checkbox:checked + label:after {    content: '\2714';    font-size: 14px;    position: absolute;    top: 1px;    left: 4px;    color: #1279C6;  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">  </script>  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>    <div ng-app="app" ng-controller="mainCTRL">  <div ng-repeat="item in items1">      <div class="panel-group driving-license-settings" id="accordion-{{$index}}">          <div class="panel panel-default">              <div class="panel-heading">                  <h4 class="panel-title">                      <a data-toggle="collapse" data-parent="#accordion-{{$index}}"                         data-target="#collapseOne-{{$index}}">                          <input type="checkbox" class="ui-checkbox" id="chk1-{{$index}}" value="">                          <label for="chk1-{{$index}}">{{item}}</label>                      </a>                  </h4>              </div>              <div id="collapseOne-{{$index}}" class="panel-collapse collapse ">                  <div class="panel-body">                      <div class="driving-license-kind">                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-1" value="">                              <label for="chk2-cb-{{item}}-1">A</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-2" value="">                              <label for="chk2-cb-{{item}}-2">B</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-3" value="">                              <label for="chk2-cb-{{item}}-3">C</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-4" value="">                              <label for="chk2-cb-{{item}}-4">D</label>                          </div>                          <div class="checkbox">                              <input type="checkbox" class="ui-checkbox" id="chk2-cb-{{item}}-5" value="">                              <label for="chk2-cb-{{item}}-5">E</label>                          </div>                      </div>                  </div>              </div>          </div>      </div>  </div>  </div>

Read More

Wednesday, May 4, 2016

Foreach is picking the first checkbox only if checked

Leave a Comment

I am working on the following code in order to pick checkboxes from a form. If i check the first checkbox everything works great. If i check another checkbox i get the "Undefined index" error. Keep in mind that i am getting the checkboxes with post method and the submit button is above the checkboxes due to the complexity of the location of the form and the fields. What i need essentially is to pick multiple checkboxes and add certain values to the database.

<?php    session_start();   if($_SESSION['admin_logged_in'] != true){     header("Location:login.html");     exit();   }   include 'db.php';    $from = mysql_real_escape_string($_GET['from']);   $room = mysql_real_escape_string($_POST['room']);    if(!empty($_POST['id'])) {     foreach($_POST['id'] as $check) {       $id = $check;        $sel = mysql_query("select * from $from where id = '$id' limit 1 ") or die(mysql_error());        while($row = mysql_fetch_array($sel)){         $preview = $row['preview'];         $text = $row['text'];         $title = $row['title'];         $images = $row['images'];       }        $ins = mysql_query("insert into $room (id, preview, text, title, images) values (' ', '$preview', '$text', '$title', '$images') ") or die(mysql_error());      }      header("Location:admin.php");   }  ?> 

The code of the form can be found below:

<form class="form-inline" name="bulkcopy" method="post" action="bulkcopy.php?from=sights"> <b>Bulk Copy:</b>      <select name='room' class="form-control">         <option>Select...</option>         <option value="Orhan">Orhan</option>         <option value="Deniz">Deniz</option>         <option value="Irini">Irini</option>         <option value="Katina">Katina</option>         <option value="Gulbin">Gulbin</option>         <option value="Mihalis">Mihalis</option>     </select>     <input class="btn btn-primary" type="submit" name="submit" value="Go"><br /><br /> </div> <table class="table table-bordered table-striped">     <th>Entry Name</th>     <th>Display Order</th>     <th>Copy to...</th>     <th>Status</th>     <th>Image</th>     <th>Edit</th>     <th>Delete</th>     <th>Duplicate</th>      <?php while($row = mysql_fetch_array($sel)) { ?>     <tr>         <td>             <input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>">             </form>             <?php echo $row['title']; ?>         </td>         <td>             <form name="order" method="post" action="sightorder.php?id=<?php echo htmlspecialchars($row['id']); ?>">                 <div class="col-md-4">                     <input class="form-control" type="number" name="order" value="<?php echo htmlspecialchars($row['ordernum']); ?>">                 </div>                 <div class="col-sm-3">                     <input type="submit" name="submit" value="Set Order" class="btn btn-primary">                 </div>             </form>         </td>         <td>              <form name="copyto" method="post" action="copyto.php?from=sights&id=<?php echo htmlspecialchars($row['id']); ?>">                 <input type="checkbox" name="room[]" value="Orhan"> O -                 <input type="checkbox" name="room[]" value="Deniz"> D -                 <input type="checkbox" name="room[]" value="Irini"> I -                 <input type="checkbox" name="room[]" value="Katina"> K -                 <input type="checkbox" name="room[]" value="Gulbin"> G -                 <input type="checkbox" name="room[]" value="Mihalis"> M                  <input type="submit" name="submit" value="Copy" class="btn btn-primary">             </form>          </td>         <td>             <a href="sightstatus.php?id=<?php echo htmlspecialchars($row['id']); ?>&status=<?php echo $row['status']; ?>"><?php if($row['status'] == 1){ ?><i class="fa fa-check fa-lg"></i><?php }else{ ?><i class="fa fa-times fa-lg"></i><?php } ?></a>         </td>         <td>             <a href="sightimages.php?id=<?php echo $row['id']; ?>"><i class="fa fa-image fa-lg"></i></a>         </td>         <td>             <a href="editsight.php?id=<?php echo htmlspecialchars($row['id']); ?>"><i class="fa fa-edit fa-lg"></i></a>         </td>         <td>             <a onclick="return confirmDelete()" href="delsight.php?id=<?php echo htmlspecialchars($row['id']); ?>"><i class="fa fa-trash fa-lg"></i></a>         </td>         <td>             <a href="duplicatesight.php?id=<?php echo htmlspecialchars($row['id']); ?>"><i class="fa fa-copy fa-lg"></i></a>         </td>     </tr>     <?php } ?> </table> 

Any help would be greatly appreciated. Thanks.

8 Answers

Answers 1

You have a problem here

<?php     while($row = mysql_fetch_array($sel)){ ?>         <tr><td><input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>"> <?php echo $row['title']; ?></td></form> 

There is no closing bracket for the while loop, and the form is closed after the first checkbox is added. So if that checkbox is not checked, then the input is not posted, thus the undefined index. Make sure you do not close the form until after all the rows have been added, like this

<?php     while($row = mysql_fetch_array($sel)){ ?>         <tr><td><input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>"> <?php echo $row['title']; ?></td></tr> <?php } ?>   </table> </form> 

Answers 2

After reviewing the raw HTML of the complete page you provided, it is clear that the problem is you're trying to nest multiple forms which is invalid HTML. Please refer to this answer for more information. This answer does link to a workaround, but it's an ugly hack and should probably be avoided.

I believe the appropriate, valid HTML solution in your case is to use a single form. Currently you have multiple nested forms submitting to the following locations:

  1. bulkcopy.php?from=sights
  2. sightorder.php?id=1
  3. copyto.php?from=sights&id=1
  4. copyto.php?from=sights&id=46
  5. etc...

What you can do is have a single form that determines which action to take based on which submit button was clicked. For example:

switch ($_POST['submit']) {     case 'Go':         // process bulkcopy         break;      case 'Set Order':         // process siteorder         break;      // etc... } 

Answers 3

if you the variable checkbox is a table $_POST['id'] the when you do this

foreach($_POST['id'] as $check) {   $id = $check;   ... } 

if you don't check the first input the first variable

$check = $_POST['id']['0'];  // is empty 

you can do another condition in the foreach

if(!empty($_POST['id'])) {   foreach($_POST['id'] as $k=>$v) {      if(!empty($v)){              $id = $v;         $sel = mysql_query("select * from $from where id = '$id' limit 1 ") or die(mysql_error());         while($row = mysql_fetch_array($sel)){            $preview = $row['preview'];            $text = $row['text'];            $title = $row['title'];            $images = $row['images'];        }         $ins = mysql_query("insert into $room (id, preview, text, title, images) values (' ', '$preview', '$text', '$title', '$images') ") or die(mysql_error());        }   }  header("Location:admin.php"); } 

Answers 4

You should use mysql_num_rows() to check if u actually have result before trying to access them and use them for insertion to database.The problem with your code is that the variables inside

 while($row = mysql_fetch_array($sel)){    ....    } 

are never defined in case the result set is empty.But although they are never defined you try to use them in an insert query later.So just check if you have results first:

 <?php session_start();  if($_SESSION['admin_logged_in'] != true){   header("Location:login.html");   exit(); }  include 'db.php';  $from = mysql_real_escape_string($_GET['from']); $room = mysql_real_escape_string($_POST['room']);  if(isset($_POST['id'])&&!empty($_POST['id'])) { foreach($_POST['id'] as $check) {   if(empty($check)) continue;   $id = $check;    $sel = mysql_query("select * from $from where id = '$id' limit 1 ") or die(mysql_error());  if(mysql_num_rows($sel)>0){   while($row = mysql_fetch_array($sel)){     $preview = $row['preview'];     $text = $row['text'];     $title = $row['title'];     $images = $row['images'];  }    $ins = mysql_query("insert into $room (id, preview, text, title, images) values (' ', '$preview', '$text', '$title', '$images') ") or die(mysql_error());   }  }  header("Location:admin.php"); }  ?> 

EDIT:

Also it seems there is a problem with your generated html code.You dont seem to close properly your tags.Try this:

         <?php          while($row = mysql_fetch_array($sel)){ ?>         <tr><td><input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>"> <?php echo $row['title']; ?></td></tr><?php }?></table></form> 

But since i do know the value of $sel I cannot help you more if you do not post your generated html.

Answers 5

Your form does not POST an input with the name 'room'. Therefore, when you try and check it with this line $room = mysql_real_escape_string($_POST['room']);, there is no item in the $_POST array with the index 'room', hence the undefined index error.

To debug this kind of thing, it's helpful to analyse the request/response headers of your form submission. If you use Chrome, press Ctrl+Shift+I to bring up the developer console, select the Network tab, and when you submit your form, view the details of the entry that pops up. You will be able to see here the names and values of the things being sent and will give you an idea of where things are going wrong. Other browsers are available, and each have their own respectable versions of this.

Also, before accessing any variables you didn't define yourself, or can't rely on (such as form submissions), you should use isset() to make sure the variable exists before using it - that will stop the error you are getting and also allow you to catch where it's going wrong more easily:

if (!isset($_POST['room'])) {   print('Please select something'); } else {   $room = $_POST['room']; // technically not needed tho :p   //... } 

Answers 6

which is tha page you are callling, sightorder.php or copyto.php? by which submit button, set order or copy?

in both cases you are sending the id by GET not by POST.

which is the line which produces the error?

Luca

Answers 7

  <form bulkcopy>   ....    <table>   <?php while: ?>       // </form> it must be deleted       ...       <div sightorder>          ...          <input submit onclick="return send_sightorder(this);">       </div>        ...       <div copyto action="copyto.php?from=sights&id=<?php echo htmlspecialchars($row['id']); ?>">           ...           <input submit onclick="return send_copy(this);">       </div>    <?php end while ?>   </table>   </form> // bulkcopy's close tag    <script>      /// Function send_sightorder is same.      function send_copy(clicked_element) {          var form = clicked_element.parent;          var inputs = form.getElementsByTagName("input");          var data = inputs[0].name + "=" + inputs[0],checked + "&";          var URL = window.location.host + form.getAttribute("action");                for (i=1; i<inputs.length-1; ++i) {              data = "&" + inputs[i].name + "=" + inputs[i].checked + "&";          }           xmlhttp = new XMLHttpRequest();          xmlhttp.onreadystatechange = function() {             if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {                // redirect to new page or something else ...                window.location = URL;             }          }          xmlhttp.open("POST", URL,true);          xmlhttp.send(data);           return false;      }   </script> 

Answers 8

the trick is to give your checkboxes fixed names with the value of the IDs

<input type="checkbox" name="id[<?php echo $row['id']; ?>]" value="1"> 

in your php code do like:

if (is_array($_POST['id'])) {      foreach ($_POST['id'] as $id => $val) {          // should always be 1 as most browsers don't send unchecked checkboxes...         // better to check it. also check for "on" because some browsers always send it as value for checked checkboxes         if (1 == $val || 'on' == $val) {               echo "Checkbox with ID ". $id . " was checked";         }     } } 
Read More